|
|
|
@ -107,9 +107,64 @@ static void timerCallback(TimerHandle_t xTimer) { |
|
|
|
|
if (gState.blind_position >= gSettings.blind_time) { |
|
|
|
|
act_motor_power_set(gState.set_power); |
|
|
|
|
|
|
|
|
|
// Stop condition
|
|
|
|
|
if (gState.real_direction == gAct.dir) { |
|
|
|
|
if (gState.run_time >= gSettings.recup_time) { |
|
|
|
|
if (gState.real_direction == gAct.dir && gState.run_time >= gSettings.min_recup_time) { |
|
|
|
|
// Stop condition
|
|
|
|
|
bool do_switch = false; |
|
|
|
|
|
|
|
|
|
// TODO questionable logic, verify
|
|
|
|
|
|
|
|
|
|
if (gSettings.recup_mode == RECUP_MODE_TIME) { |
|
|
|
|
do_switch = gState.run_time >= gSettings.recup_time; |
|
|
|
|
} else if (gState.run_time >= gSettings.max_recup_time) { |
|
|
|
|
do_switch = true; |
|
|
|
|
} else { |
|
|
|
|
// temp-based switching - magic(tm)
|
|
|
|
|
const int16_t ideal_delta = gState.t_indoor - gState.t_outdoor; |
|
|
|
|
int16_t delta, stop_delta; |
|
|
|
|
bool allow_temp_switch = false; |
|
|
|
|
if (gState.real_direction == MOTOR_DIR_OUT) { |
|
|
|
|
delta = gState.t_indoor - gState.t_exhaust; |
|
|
|
|
// 100% factor = nadoraz
|
|
|
|
|
stop_delta = ((int32_t)ideal_delta |
|
|
|
|
* (int32_t)(100 - gSettings.recup_factor)) / 100; |
|
|
|
|
// Delta = IN - OUT
|
|
|
|
|
if (gState.valid_t_indoor && gState.valid_t_exhaust && gState.valid_t_outdoor) { |
|
|
|
|
allow_temp_switch = true; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
// IN
|
|
|
|
|
delta = gState.t_inflow - gState.t_outdoor; |
|
|
|
|
// 100% factor = nadoraz
|
|
|
|
|
stop_delta = ((int32_t)ideal_delta |
|
|
|
|
* (int32_t)(gSettings.recup_factor)) / 100; |
|
|
|
|
// Delta = IN - OUT
|
|
|
|
|
if (gState.valid_t_intake && gState.valid_t_indoor && gState.valid_t_outdoor) { |
|
|
|
|
allow_temp_switch = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (allow_temp_switch) { |
|
|
|
|
if (gSettings.summer_mode) { |
|
|
|
|
if (ideal_delta < 0) { |
|
|
|
|
// warmer outside, trying to keep cool in
|
|
|
|
|
if (delta >= stop_delta) { |
|
|
|
|
do_switch = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// colder outside - no stopping (will run to max recup time)
|
|
|
|
|
} else { |
|
|
|
|
if (ideal_delta > 0) { |
|
|
|
|
// colder outside, trying to keep warmth in
|
|
|
|
|
if (delta <= stop_delta) { |
|
|
|
|
do_switch = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// warmer outside - no stopping (will run to max recup time)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (do_switch) { |
|
|
|
|
// zmena smeru
|
|
|
|
|
gState.run_time = 0; |
|
|
|
|
act_motor_direction_set(1 - gAct.dir); |
|
|
|
@ -132,25 +187,27 @@ static void timerCallback(TimerHandle_t xTimer) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (end_temp_meas) { |
|
|
|
|
uint16_t t1 = (uint16_t) (gState.t1_aggr / gState.t_aggr_cnt); |
|
|
|
|
uint16_t t2 = (uint16_t) (gState.t2_aggr / gState.t_aggr_cnt); |
|
|
|
|
switch (gState.real_direction) { |
|
|
|
|
case MOTOR_DIR_IN: |
|
|
|
|
gState.t_outdoor = t2; |
|
|
|
|
gState.t_intake = t1; |
|
|
|
|
gState.valid_t_outdoor = gState.valid_t_intake = true; |
|
|
|
|
if (gState.effective_vent_mode == VENT_MODE_IN) { |
|
|
|
|
gState.valid_t_indoor = gState.valid_t_exhaust = false; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case MOTOR_DIR_OUT: |
|
|
|
|
gState.t_indoor = t1; |
|
|
|
|
gState.t_exhaust = t2; |
|
|
|
|
gState.valid_t_indoor = gState.valid_t_exhaust = true; |
|
|
|
|
if (gState.effective_vent_mode == VENT_MODE_OUT) { |
|
|
|
|
gState.valid_t_outdoor = gState.valid_t_intake = false; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
if (gState.t_aggr_cnt > 0) { |
|
|
|
|
uint16_t t1 = (uint16_t) (gState.t1_aggr / gState.t_aggr_cnt); |
|
|
|
|
uint16_t t2 = (uint16_t) (gState.t2_aggr / gState.t_aggr_cnt); |
|
|
|
|
switch (gState.real_direction) { |
|
|
|
|
case MOTOR_DIR_IN: |
|
|
|
|
gState.t_outdoor = t2; |
|
|
|
|
gState.t_inflow = t1; |
|
|
|
|
gState.valid_t_outdoor = gState.valid_t_intake = true; |
|
|
|
|
if (gState.effective_vent_mode == VENT_MODE_IN) { |
|
|
|
|
gState.valid_t_indoor = gState.valid_t_exhaust = false; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case MOTOR_DIR_OUT: |
|
|
|
|
gState.t_indoor = t1; |
|
|
|
|
gState.t_exhaust = t2; |
|
|
|
|
gState.valid_t_indoor = gState.valid_t_exhaust = true; |
|
|
|
|
if (gState.effective_vent_mode == VENT_MODE_OUT) { |
|
|
|
|
gState.valid_t_outdoor = gState.valid_t_intake = false; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
gState.t1_aggr = gState.t2_aggr = gState.t_aggr_cnt = 0; |
|
|
|
|
} |
|
|
|
@ -185,8 +242,10 @@ void fan_set_vent_mode(enum ventilation_mode mode) { |
|
|
|
|
|
|
|
|
|
gState.set_vent_mode = mode; |
|
|
|
|
gState.t1_aggr = gState.t2_aggr = gState.t_aggr_cnt = 0; |
|
|
|
|
if (gState.set_power != 0) { |
|
|
|
|
if (gState.set_power != 0 || mode == VENT_MODE_FREE) { |
|
|
|
|
gState.effective_vent_mode = mode; |
|
|
|
|
} else if (gState.set_power == 0) { |
|
|
|
|
gState.effective_vent_mode = VENT_MODE_OFF; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (mode == VENT_MODE_OFF || mode == VENT_MODE_FREE) { |
|
|
|
|