mirror of https://github.com/arendst/Tasmota.git
Support added for DS18B20 temperature sensor and reduction of variables in heating structure
This commit is contained in:
parent
d7f81899a7
commit
98dc4d8c4d
|
@ -22,13 +22,16 @@
|
||||||
#define XDRV_39 39
|
#define XDRV_39 39
|
||||||
|
|
||||||
// Enable/disable debugging
|
// Enable/disable debugging
|
||||||
//#define DEBUG_THERMOSTAT
|
#define DEBUG_THERMOSTAT
|
||||||
|
|
||||||
|
// Use attached temperature sensor
|
||||||
|
#define THERMOSTAT_USE_LOCAL_SENSOR
|
||||||
|
|
||||||
#ifdef DEBUG_THERMOSTAT
|
#ifdef DEBUG_THERMOSTAT
|
||||||
#define DOMOTICZ_IDX1 791
|
#define DOMOTICZ_IDX1 791
|
||||||
#define DOMOTICZ_IDX2 792
|
#define DOMOTICZ_IDX2 792
|
||||||
#define DOMOTICZ_IDX3 793
|
#define DOMOTICZ_IDX3 793
|
||||||
#endif
|
#endif // DEBUG_THERMOSTAT
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
#define D_CMND_THERMOSTATMODESET "ThermostatModeSet"
|
#define D_CMND_THERMOSTATMODESET "ThermostatModeSet"
|
||||||
|
@ -43,6 +46,7 @@
|
||||||
#define D_CMND_TEMPMEASUREDREAD "TempMeasuredRead"
|
#define D_CMND_TEMPMEASUREDREAD "TempMeasuredRead"
|
||||||
#define D_CMND_TEMPMEASUREDGRDREAD "TempMeasuredGrdRead"
|
#define D_CMND_TEMPMEASUREDGRDREAD "TempMeasuredGrdRead"
|
||||||
#define D_CMND_TEMPSENSNUMBERSET "TempSensNumberSet"
|
#define D_CMND_TEMPSENSNUMBERSET "TempSensNumberSet"
|
||||||
|
#define D_CMND_SENSORINPUTSET "SensorInputSet"
|
||||||
#define D_CMND_STATEEMERGENCYSET "StateEmergencySet"
|
#define D_CMND_STATEEMERGENCYSET "StateEmergencySet"
|
||||||
#define D_CMND_POWERMAXSET "PowerMaxSet"
|
#define D_CMND_POWERMAXSET "PowerMaxSet"
|
||||||
#define D_CMND_TIMEMANUALTOAUTOSET "TimeManualToAutoSet"
|
#define D_CMND_TIMEMANUALTOAUTOSET "TimeManualToAutoSet"
|
||||||
|
@ -70,6 +74,7 @@ enum ControllerHybridPhases { CTR_HYBRID_RAMP_UP, CTR_HYBRID_PI };
|
||||||
enum InterfaceStates { IFACE_OFF, IFACE_ON };
|
enum InterfaceStates { IFACE_OFF, IFACE_ON };
|
||||||
enum CtrCycleStates { CYCLE_OFF, CYCLE_ON };
|
enum CtrCycleStates { CYCLE_OFF, CYCLE_ON };
|
||||||
enum EmergencyStates { EMERGENCY_OFF, EMERGENCY_ON };
|
enum EmergencyStates { EMERGENCY_OFF, EMERGENCY_ON };
|
||||||
|
enum SensorType { SENSOR_MQTT, SENSOR_DS18B20, SENSOR_MAX };
|
||||||
enum ThermostatSupportedInputSwitches {
|
enum ThermostatSupportedInputSwitches {
|
||||||
THERMOSTAT_INPUT_NONE,
|
THERMOSTAT_INPUT_NONE,
|
||||||
THERMOSTAT_INPUT_SWT1 = 1, // Buttons
|
THERMOSTAT_INPUT_SWT1 = 1, // Buttons
|
||||||
|
@ -90,28 +95,32 @@ enum ThermostatSupportedOutputRelays {
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
uint16_t data;
|
uint32_t data;
|
||||||
struct {
|
struct {
|
||||||
uint16_t thermostat_mode : 2; // Operation mode of the thermostat system
|
uint32_t thermostat_mode : 2; // Operation mode of the thermostat system
|
||||||
uint16_t controller_mode : 2; // Operation mode of the thermostat controller
|
uint32_t controller_mode : 2; // Operation mode of the thermostat controller
|
||||||
uint16_t sensor_alive : 1; // Flag stating if temperature sensor is alive (0 = inactive, 1 = active)
|
uint32_t sensor_alive : 1; // Flag stating if temperature sensor is alive (0 = inactive, 1 = active)
|
||||||
uint16_t command_output : 1; // Flag stating state to save the command to the output (0 = inactive, 1 = active)
|
uint32_t sensor_type : 1; // Sensor type: MQTT/local
|
||||||
uint16_t phase_hybrid_ctr : 1; // Phase of the hybrid controller (Ramp-up or PI)
|
uint32_t command_output : 1; // Flag stating state to save the command to the output (0 = inactive, 1 = active)
|
||||||
uint16_t status_output : 1; // Status of the output switch
|
uint32_t phase_hybrid_ctr : 1; // Phase of the hybrid controller (Ramp-up or PI)
|
||||||
uint16_t status_cycle_active : 1; // Status showing if cycle is active (Output ON) or not (Output OFF)
|
uint32_t status_output : 1; // Status of the output switch
|
||||||
uint16_t state_emergency : 1; // State for thermostat emergency
|
uint32_t status_cycle_active : 1; // Status showing if cycle is active (Output ON) or not (Output OFF)
|
||||||
uint16_t counter_seconds : 6; // Second counter used to track minutes
|
uint32_t state_emergency : 1; // State for thermostat emergency
|
||||||
|
uint32_t counter_seconds : 6; // Second counter used to track minutes
|
||||||
|
uint32_t output_relay_number : 4; // Output relay number
|
||||||
|
uint32_t input_switch_number : 3; // Input switch number
|
||||||
|
uint32_t free : 8; // Free bits in Bitfield
|
||||||
};
|
};
|
||||||
} ThermostatBitfield;
|
} ThermostatBitfield;
|
||||||
|
|
||||||
#ifdef DEBUG_THERMOSTAT
|
#ifdef DEBUG_THERMOSTAT
|
||||||
const char DOMOTICZ_MES[] PROGMEM = "{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"%s\"}";
|
const char DOMOTICZ_MES[] PROGMEM = "{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"%s\"}";
|
||||||
#endif
|
#endif // DEBUG_THERMOSTAT
|
||||||
|
|
||||||
const char kThermostatCommands[] PROGMEM = "|" D_CMND_THERMOSTATMODESET "|" D_CMND_TEMPFROSTPROTECTSET "|"
|
const char kThermostatCommands[] PROGMEM = "|" D_CMND_THERMOSTATMODESET "|" D_CMND_TEMPFROSTPROTECTSET "|"
|
||||||
D_CMND_CONTROLLERMODESET "|" D_CMND_INPUTSWITCHSET "|" D_CMND_OUTPUTRELAYSET "|" D_CMND_TIMEALLOWRAMPUPSET "|"
|
D_CMND_CONTROLLERMODESET "|" D_CMND_INPUTSWITCHSET "|" D_CMND_OUTPUTRELAYSET "|" D_CMND_TIMEALLOWRAMPUPSET "|"
|
||||||
D_CMND_TEMPMEASUREDSET "|" D_CMND_TEMPTARGETSET "|" D_CMND_TEMPTARGETREAD "|"
|
D_CMND_TEMPMEASUREDSET "|" D_CMND_TEMPTARGETSET "|" D_CMND_TEMPTARGETREAD "|"
|
||||||
D_CMND_TEMPMEASUREDREAD "|" D_CMND_TEMPMEASUREDGRDREAD "|" D_CMND_TEMPSENSNUMBERSET "|"
|
D_CMND_TEMPMEASUREDREAD "|" D_CMND_TEMPMEASUREDGRDREAD "|" D_CMND_SENSORINPUTSET "|"
|
||||||
D_CMND_STATEEMERGENCYSET "|" D_CMND_POWERMAXSET "|" D_CMND_TIMEMANUALTOAUTOSET "|" D_CMND_TIMEONLIMITSET "|"
|
D_CMND_STATEEMERGENCYSET "|" D_CMND_POWERMAXSET "|" D_CMND_TIMEMANUALTOAUTOSET "|" D_CMND_TIMEONLIMITSET "|"
|
||||||
D_CMND_PROPBANDSET "|" D_CMND_TIMERESETSET "|" D_CMND_TIMEPICYCLESET "|" D_CMND_TEMPANTIWINDUPRESETSET "|"
|
D_CMND_PROPBANDSET "|" D_CMND_TIMERESETSET "|" D_CMND_TIMEPICYCLESET "|" D_CMND_TEMPANTIWINDUPRESETSET "|"
|
||||||
D_CMND_TEMPHYSTSET "|" D_CMND_TIMEMAXACTIONSET "|" D_CMND_TIMEMINACTIONSET "|" D_CMND_TIMEMINTURNOFFACTIONSET "|"
|
D_CMND_TEMPHYSTSET "|" D_CMND_TIMEMAXACTIONSET "|" D_CMND_TIMEMINACTIONSET "|" D_CMND_TIMEMINTURNOFFACTIONSET "|"
|
||||||
|
@ -121,7 +130,7 @@ const char kThermostatCommands[] PROGMEM = "|" D_CMND_THERMOSTATMODESET "|" D_CM
|
||||||
void (* const ThermostatCommand[])(void) PROGMEM = {
|
void (* const ThermostatCommand[])(void) PROGMEM = {
|
||||||
&CmndThermostatModeSet, &CmndTempFrostProtectSet, &CmndControllerModeSet, &CmndInputSwitchSet, &CmndOutputRelaySet,
|
&CmndThermostatModeSet, &CmndTempFrostProtectSet, &CmndControllerModeSet, &CmndInputSwitchSet, &CmndOutputRelaySet,
|
||||||
&CmndTimeAllowRampupSet, &CmndTempMeasuredSet, &CmndTempTargetSet, &CmndTempTargetRead,
|
&CmndTimeAllowRampupSet, &CmndTempMeasuredSet, &CmndTempTargetSet, &CmndTempTargetRead,
|
||||||
&CmndTempMeasuredRead, &CmndTempMeasuredGrdRead, &CmndTempSensNumberSet, &CmndStateEmergencySet,
|
&CmndTempMeasuredRead, &CmndTempMeasuredGrdRead, &CmndSensorInputSet, &CmndStateEmergencySet,
|
||||||
&CmndPowerMaxSet, &CmndTimeManualToAutoSet, &CmndTimeOnLimitSet, &CmndPropBandSet, &CmndTimeResetSet,
|
&CmndPowerMaxSet, &CmndTimeManualToAutoSet, &CmndTimeOnLimitSet, &CmndPropBandSet, &CmndTimeResetSet,
|
||||||
&CmndTimePiCycleSet, &CmndTempAntiWindupResetSet, &CmndTempHystSet, &CmndTimeMaxActionSet,
|
&CmndTimePiCycleSet, &CmndTempAntiWindupResetSet, &CmndTempHystSet, &CmndTimeMaxActionSet,
|
||||||
&CmndTimeMinActionSet, &CmndTimeMinTurnoffActionSet, &CmndTempRupDeltInSet, &CmndTempRupDeltOutSet,
|
&CmndTimeMinActionSet, &CmndTimeMinTurnoffActionSet, &CmndTempRupDeltInSet, &CmndTempRupDeltOutSet,
|
||||||
|
@ -129,6 +138,7 @@ void (* const ThermostatCommand[])(void) PROGMEM = {
|
||||||
&CmndTimePiIntegrRead, &CmndTimeSensLostSet };
|
&CmndTimePiIntegrRead, &CmndTimeSensLostSet };
|
||||||
|
|
||||||
struct THERMOSTAT {
|
struct THERMOSTAT {
|
||||||
|
ThermostatBitfield status; // Bittfield including states as well as several flags
|
||||||
uint32_t timestamp_temp_measured_update = 0; // Timestamp of latest measurement update
|
uint32_t timestamp_temp_measured_update = 0; // Timestamp of latest measurement update
|
||||||
uint32_t timestamp_temp_meas_change_update = 0; // Timestamp of latest measurement value change (> or < to previous)
|
uint32_t timestamp_temp_meas_change_update = 0; // Timestamp of latest measurement value change (> or < to previous)
|
||||||
uint32_t timestamp_output_off = 0; // Timestamp of latest thermostat output Off state
|
uint32_t timestamp_output_off = 0; // Timestamp of latest thermostat output Off state
|
||||||
|
@ -137,8 +147,8 @@ struct THERMOSTAT {
|
||||||
uint32_t time_ctr_checkpoint = 0; // Time to finalize the control cycle within the PI strategy or to switch to PI from Rampup
|
uint32_t time_ctr_checkpoint = 0; // Time to finalize the control cycle within the PI strategy or to switch to PI from Rampup
|
||||||
uint32_t time_ctr_changepoint = 0; // Time until switching off output within the controller in seconds
|
uint32_t time_ctr_changepoint = 0; // Time until switching off output within the controller in seconds
|
||||||
int32_t temp_measured_gradient = 0; // Temperature measured gradient from sensor in thousandths of degrees per hour
|
int32_t temp_measured_gradient = 0; // Temperature measured gradient from sensor in thousandths of degrees per hour
|
||||||
int16_t temp_target_level = THERMOSTAT_TEMP_INIT; // Target level of the thermostat in tenths of degrees
|
int16_t temp_target_level = THERMOSTAT_TEMP_INIT; // Target level of the thermostat in tenths of degrees
|
||||||
int16_t temp_target_level_ctr = THERMOSTAT_TEMP_INIT; // Target level set for the controller
|
int16_t temp_target_level_ctr = THERMOSTAT_TEMP_INIT; // Target level set for the controller
|
||||||
int16_t temp_pi_accum_error = 0; // Temperature accumulated error for the PI controller in hundredths of degrees
|
int16_t temp_pi_accum_error = 0; // Temperature accumulated error for the PI controller in hundredths of degrees
|
||||||
int16_t temp_pi_error = 0; // Temperature error for the PI controller in hundredths of degrees
|
int16_t temp_pi_error = 0; // Temperature error for the PI controller in hundredths of degrees
|
||||||
int32_t time_proportional_pi; // Time proportional part of the PI controller
|
int32_t time_proportional_pi; // Time proportional part of the PI controller
|
||||||
|
@ -151,15 +161,13 @@ struct THERMOSTAT {
|
||||||
uint32_t time_rampup_deadtime = 0; // Time constant of the thermostat system (step response time)
|
uint32_t time_rampup_deadtime = 0; // Time constant of the thermostat system (step response time)
|
||||||
uint32_t time_rampup_nextcycle = 0; // Time where the ramp-up controller shall start the next cycle
|
uint32_t time_rampup_nextcycle = 0; // Time where the ramp-up controller shall start the next cycle
|
||||||
int16_t temp_measured = 0; // Temperature measurement received from sensor in tenths of degrees
|
int16_t temp_measured = 0; // Temperature measurement received from sensor in tenths of degrees
|
||||||
|
int16_t temp_rampup_output_off = 0; // Temperature to swith off relay output within the ramp-up controller in tenths of degrees
|
||||||
uint8_t time_output_delay = THERMOSTAT_TIME_OUTPUT_DELAY; // Output delay between state change and real actuation event (f.i. valve open/closed)
|
uint8_t time_output_delay = THERMOSTAT_TIME_OUTPUT_DELAY; // Output delay between state change and real actuation event (f.i. valve open/closed)
|
||||||
uint8_t counter_rampup_cycles = 0; // Counter of ramp-up cycles
|
uint8_t counter_rampup_cycles = 0; // Counter of ramp-up cycles
|
||||||
uint8_t output_relay_number = THERMOSTAT_RELAY_NUMBER; // Output relay number
|
|
||||||
uint8_t input_switch_number = THERMOSTAT_SWITCH_NUMBER; // Input switch number
|
|
||||||
uint8_t temp_sens_number = THERMOSTAT_TEMP_SENS_NUMBER; // Temperature sensor number
|
|
||||||
uint8_t temp_rampup_pi_acc_error = THERMOSTAT_TEMP_PI_RAMPUP_ACC_E; // Accumulated error when switching from ramp-up controller to PI
|
uint8_t temp_rampup_pi_acc_error = THERMOSTAT_TEMP_PI_RAMPUP_ACC_E; // Accumulated error when switching from ramp-up controller to PI
|
||||||
uint8_t temp_rampup_delta_out = THERMOSTAT_TEMP_RAMPUP_DELTA_OUT; // Minimum delta temperature to target to get out of the rampup mode, in tenths of degrees celsius
|
uint8_t temp_rampup_delta_out = THERMOSTAT_TEMP_RAMPUP_DELTA_OUT; // Minimum delta temperature to target to get out of the rampup mode, in tenths of degrees celsius
|
||||||
uint8_t temp_rampup_delta_in = THERMOSTAT_TEMP_RAMPUP_DELTA_IN; // Minimum delta temperature to target to get into rampup mode, in tenths of degrees celsius
|
uint8_t temp_rampup_delta_in = THERMOSTAT_TEMP_RAMPUP_DELTA_IN; // Minimum delta temperature to target to get into rampup mode, in tenths of degrees celsius
|
||||||
int16_t temp_rampup_output_off = 0; // Temperature to swith off relay output within the ramp-up controller in tenths of degrees
|
uint8_t val_prop_band = THERMOSTAT_PROP_BAND; // Proportional band of the PI controller in degrees celsius
|
||||||
int16_t temp_rampup_start = 0; // Temperature at start of ramp-up controller in tenths of degrees celsius
|
int16_t temp_rampup_start = 0; // Temperature at start of ramp-up controller in tenths of degrees celsius
|
||||||
int16_t temp_rampup_cycle = 0; // Temperature set at the beginning of each ramp-up cycle in tenths of degrees
|
int16_t temp_rampup_cycle = 0; // Temperature set at the beginning of each ramp-up cycle in tenths of degrees
|
||||||
uint16_t time_rampup_max = THERMOSTAT_TIME_RAMPUP_MAX; // Time maximum ramp-up controller duration in minutes
|
uint16_t time_rampup_max = THERMOSTAT_TIME_RAMPUP_MAX; // Time maximum ramp-up controller duration in minutes
|
||||||
|
@ -168,34 +176,36 @@ struct THERMOSTAT {
|
||||||
uint16_t time_sens_lost = THERMOSTAT_TIME_SENS_LOST; // Maximum time w/o sensor update to set it as lost
|
uint16_t time_sens_lost = THERMOSTAT_TIME_SENS_LOST; // Maximum time w/o sensor update to set it as lost
|
||||||
uint16_t time_manual_to_auto = THERMOSTAT_TIME_MANUAL_TO_AUTO; // Time without input switch active to change from manual to automatic in minutes
|
uint16_t time_manual_to_auto = THERMOSTAT_TIME_MANUAL_TO_AUTO; // Time without input switch active to change from manual to automatic in minutes
|
||||||
uint16_t time_on_limit = THERMOSTAT_TIME_ON_LIMIT; // Maximum time with output active in minutes
|
uint16_t time_on_limit = THERMOSTAT_TIME_ON_LIMIT; // Maximum time with output active in minutes
|
||||||
uint32_t time_reset = THERMOSTAT_TIME_RESET; // Reset time of the PI controller in seconds
|
|
||||||
uint16_t time_pi_cycle = THERMOSTAT_TIME_PI_CYCLE; // Cycle time for the thermostat controller in seconds
|
uint16_t time_pi_cycle = THERMOSTAT_TIME_PI_CYCLE; // Cycle time for the thermostat controller in seconds
|
||||||
|
uint32_t time_reset = THERMOSTAT_TIME_RESET; // Reset time of the PI controller in seconds
|
||||||
uint16_t time_max_action = THERMOSTAT_TIME_MAX_ACTION; // Maximum thermostat time per cycle in minutes
|
uint16_t time_max_action = THERMOSTAT_TIME_MAX_ACTION; // Maximum thermostat time per cycle in minutes
|
||||||
uint16_t time_min_action = THERMOSTAT_TIME_MIN_ACTION; // Minimum thermostat time per cycle in minutes
|
uint16_t time_min_action = THERMOSTAT_TIME_MIN_ACTION; // Minimum thermostat time per cycle in minutes
|
||||||
uint16_t time_min_turnoff_action = THERMOSTAT_TIME_MIN_TURNOFF_ACTION; // Minimum turnoff time in minutes, below it the thermostat will be held on
|
uint16_t time_min_turnoff_action = THERMOSTAT_TIME_MIN_TURNOFF_ACTION; // Minimum turnoff time in minutes, below it the thermostat will be held on
|
||||||
uint8_t val_prop_band = THERMOSTAT_PROP_BAND; // Proportional band of the PI controller in degrees celsius
|
|
||||||
uint8_t temp_reset_anti_windup = THERMOSTAT_TEMP_RESET_ANTI_WINDUP; // Range where reset antiwindup is disabled, in tenths of degrees celsius
|
uint8_t temp_reset_anti_windup = THERMOSTAT_TEMP_RESET_ANTI_WINDUP; // Range where reset antiwindup is disabled, in tenths of degrees celsius
|
||||||
int8_t temp_hysteresis = THERMOSTAT_TEMP_HYSTERESIS; // Range hysteresis for temperature PI controller, in tenths of degrees celsius
|
int8_t temp_hysteresis = THERMOSTAT_TEMP_HYSTERESIS; // Range hysteresis for temperature PI controller, in tenths of degrees celsius
|
||||||
uint8_t temp_frost_protect = THERMOSTAT_TEMP_FROST_PROTECT; // Minimum temperature for frost protection, in tenths of degrees celsius
|
|
||||||
uint16_t power_max = THERMOSTAT_POWER_MAX; // Maximum output power in Watt
|
uint16_t power_max = THERMOSTAT_POWER_MAX; // Maximum output power in Watt
|
||||||
ThermostatBitfield status; // Bittfield including states as well as several flags
|
uint8_t temp_frost_protect = THERMOSTAT_TEMP_FROST_PROTECT; // Minimum temperature for frost protection, in tenths of degrees celsius
|
||||||
} Thermostat;
|
} Thermostat;
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
void ThermostatInit(void)
|
void ThermostatInit(void)
|
||||||
{
|
{
|
||||||
ExecuteCommandPower(Thermostat.output_relay_number, POWER_OFF, SRC_THERMOSTAT); // Make sure the Output is OFF
|
|
||||||
// Init Thermostat.status bitfield:
|
// Init Thermostat.status bitfield:
|
||||||
Thermostat.status.thermostat_mode = THERMOSTAT_OFF;
|
Thermostat.status.thermostat_mode = THERMOSTAT_OFF;
|
||||||
Thermostat.status.controller_mode = CTR_HYBRID;
|
Thermostat.status.controller_mode = CTR_HYBRID;
|
||||||
Thermostat.status.sensor_alive = IFACE_OFF;
|
Thermostat.status.sensor_alive = IFACE_OFF;
|
||||||
|
Thermostat.status.sensor_type = SENSOR_MQTT;
|
||||||
Thermostat.status.command_output = IFACE_OFF;
|
Thermostat.status.command_output = IFACE_OFF;
|
||||||
Thermostat.status.phase_hybrid_ctr = CTR_HYBRID_PI;
|
Thermostat.status.phase_hybrid_ctr = CTR_HYBRID_PI;
|
||||||
Thermostat.status.status_output = IFACE_OFF;
|
Thermostat.status.status_output = IFACE_OFF;
|
||||||
Thermostat.status.status_cycle_active = CYCLE_OFF;
|
Thermostat.status.status_cycle_active = CYCLE_OFF;
|
||||||
Thermostat.status.state_emergency = EMERGENCY_OFF;
|
Thermostat.status.state_emergency = EMERGENCY_OFF;
|
||||||
Thermostat.status.counter_seconds = 0;
|
Thermostat.status.counter_seconds = 0;
|
||||||
|
Thermostat.status.output_relay_number = THERMOSTAT_RELAY_NUMBER;
|
||||||
|
Thermostat.status.input_switch_number = THERMOSTAT_SWITCH_NUMBER;
|
||||||
|
// Make sure the Output is OFF
|
||||||
|
ExecuteCommandPower(Thermostat.status.output_relay_number, POWER_OFF, SRC_THERMOSTAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThermostatMinuteCounter(void)
|
bool ThermostatMinuteCounter(void)
|
||||||
|
@ -240,7 +250,7 @@ void ThermostatSignalProcessingSlow(void)
|
||||||
|
|
||||||
void ThermostatSignalProcessingFast(void)
|
void ThermostatSignalProcessingFast(void)
|
||||||
{
|
{
|
||||||
if (ThermostatSwitchStatus(Thermostat.input_switch_number)) { // Check if input switch active and register last update
|
if (ThermostatSwitchStatus(Thermostat.status.input_switch_number)) { // Check if input switch active and register last update
|
||||||
Thermostat.timestamp_input_on = uptime;
|
Thermostat.timestamp_input_on = uptime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,7 +307,7 @@ void ThermostatHybridCtrPhase(void)
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_THERMOSTAT
|
#ifdef DEBUG_THERMOSTAT
|
||||||
ThermostatVirtualSwitchCtrState();
|
ThermostatVirtualSwitchCtrState();
|
||||||
#endif
|
#endif // DEBUG_THERMOSTAT
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HeatStateAutoToManual(void)
|
bool HeatStateAutoToManual(void)
|
||||||
|
@ -307,7 +317,7 @@ bool HeatStateAutoToManual(void)
|
||||||
// If switch input is active
|
// If switch input is active
|
||||||
// OR temperature sensor is not alive
|
// OR temperature sensor is not alive
|
||||||
// then go to manual
|
// then go to manual
|
||||||
if ((ThermostatSwitchStatus(Thermostat.input_switch_number) == 1)
|
if ((ThermostatSwitchStatus(Thermostat.status.input_switch_number) == 1)
|
||||||
|| (Thermostat.status.sensor_alive == IFACE_OFF)) {
|
|| (Thermostat.status.sensor_alive == IFACE_OFF)) {
|
||||||
change_state = true;
|
change_state = true;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +332,7 @@ bool HeatStateManualToAuto(void)
|
||||||
// AND sensor alive
|
// AND sensor alive
|
||||||
// AND no switch input action (time in current state) bigger than a pre-defined time
|
// AND no switch input action (time in current state) bigger than a pre-defined time
|
||||||
// then go to automatic
|
// then go to automatic
|
||||||
if ((ThermostatSwitchStatus(Thermostat.input_switch_number) == 0)
|
if ((ThermostatSwitchStatus(Thermostat.status.input_switch_number) == 0)
|
||||||
&&(Thermostat.status.sensor_alive == IFACE_ON)
|
&&(Thermostat.status.sensor_alive == IFACE_ON)
|
||||||
&& ((uptime - Thermostat.timestamp_input_on) > ((uint32_t)Thermostat.time_manual_to_auto * 60))) {
|
&& ((uptime - Thermostat.timestamp_input_on) > ((uint32_t)Thermostat.time_manual_to_auto * 60))) {
|
||||||
change_state = true;
|
change_state = true;
|
||||||
|
@ -370,32 +380,32 @@ void ThermostatState(void)
|
||||||
|
|
||||||
void ThermostatOutputRelay(bool active)
|
void ThermostatOutputRelay(bool active)
|
||||||
{
|
{
|
||||||
// TODO: See if the real output state can be read by f.i. bitRead(power, Thermostat.output_relay_number))
|
// TODO: See if the real output state can be read by f.i. bitRead(power, Thermostat.status.output_relay_number))
|
||||||
// If command received to enable output
|
// If command received to enable output
|
||||||
// AND current output status is OFF
|
// AND current output status is OFF
|
||||||
// then switch output to ON
|
// then switch output to ON
|
||||||
if ((active == true)
|
if ((active == true)
|
||||||
&& (Thermostat.status.status_output == IFACE_OFF)) {
|
&& (Thermostat.status.status_output == IFACE_OFF)) {
|
||||||
#ifndef DEBUG_THERMOSTAT
|
#ifndef DEBUG_THERMOSTAT
|
||||||
ExecuteCommandPower(Thermostat.output_relay_number, POWER_ON, SRC_THERMOSTAT);
|
ExecuteCommandPower(Thermostat.status.output_relay_number, POWER_ON, SRC_THERMOSTAT);
|
||||||
#endif
|
#endif // DEBUG_THERMOSTAT
|
||||||
Thermostat.status.status_output = IFACE_ON;
|
Thermostat.status.status_output = IFACE_ON;
|
||||||
#ifdef DEBUG_THERMOSTAT
|
#ifdef DEBUG_THERMOSTAT
|
||||||
ThermostatVirtualSwitch();
|
ThermostatVirtualSwitch();
|
||||||
#endif
|
#endif // DEBUG_THERMOSTAT
|
||||||
}
|
}
|
||||||
// If command received to disable output
|
// If command received to disable output
|
||||||
// AND current output status is ON
|
// AND current output status is ON
|
||||||
// then switch output to OFF
|
// then switch output to OFF
|
||||||
else if ((active == false) && (Thermostat.status.status_output == IFACE_ON)) {
|
else if ((active == false) && (Thermostat.status.status_output == IFACE_ON)) {
|
||||||
#ifndef DEBUG_THERMOSTAT
|
#ifndef DEBUG_THERMOSTAT
|
||||||
ExecuteCommandPower(Thermostat.output_relay_number, POWER_OFF, SRC_THERMOSTAT);
|
ExecuteCommandPower(Thermostat.status.output_relay_number, POWER_OFF, SRC_THERMOSTAT);
|
||||||
#endif
|
#endif // DEBUG_THERMOSTAT
|
||||||
Thermostat.timestamp_output_off = uptime;
|
Thermostat.timestamp_output_off = uptime;
|
||||||
Thermostat.status.status_output = IFACE_OFF;
|
Thermostat.status.status_output = IFACE_OFF;
|
||||||
#ifdef DEBUG_THERMOSTAT
|
#ifdef DEBUG_THERMOSTAT
|
||||||
ThermostatVirtualSwitch();
|
ThermostatVirtualSwitch();
|
||||||
#endif
|
#endif // DEBUG_THERMOSTAT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,7 +750,7 @@ void ThermostatWork(void)
|
||||||
break;
|
break;
|
||||||
case THERMOSTAT_MANUAL_OP: // State manual operation following input switch
|
case THERMOSTAT_MANUAL_OP: // State manual operation following input switch
|
||||||
Thermostat.time_ctr_checkpoint = 0;
|
Thermostat.time_ctr_checkpoint = 0;
|
||||||
if (ThermostatSwitchStatus(Thermostat.input_switch_number) == 1) {
|
if (ThermostatSwitchStatus(Thermostat.status.input_switch_number) == 1) {
|
||||||
Thermostat.status.command_output = IFACE_ON;
|
Thermostat.status.command_output = IFACE_ON;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -810,7 +820,35 @@ void ThermostatVirtualSwitchCtrState(void)
|
||||||
//Response_P(DOMOTICZ_MES, DOMOTICZ_IDX3, (0 == Thermostat.time_ctr_changepoint) ? 0 : 1, "");
|
//Response_P(DOMOTICZ_MES, DOMOTICZ_IDX3, (0 == Thermostat.time_ctr_changepoint) ? 0 : 1, "");
|
||||||
//MqttPublish(domoticz_in_topic);
|
//MqttPublish(domoticz_in_topic);
|
||||||
}
|
}
|
||||||
#endif
|
#endif // DEBUG_THERMOSTAT
|
||||||
|
|
||||||
|
#ifdef THERMOSTAT_USE_LOCAL_SENSOR
|
||||||
|
void ThermostatGetLocalSensor(void) {
|
||||||
|
DynamicJsonBuffer jsonBuffer;
|
||||||
|
JsonObject& root = jsonBuffer.parseObject((const char*)mqtt_data);
|
||||||
|
if (root.success()) {
|
||||||
|
const char* value_c = root["DS18B20"]["Temperature"];
|
||||||
|
if (value_c != NULL && strlen(value_c) > 0 && (isdigit(value_c[0]) || (value_c[0] == '-' && isdigit(value_c[1])) ) ) {
|
||||||
|
int16_t value = (int16_t)(CharToFloat(value_c) * 10);
|
||||||
|
if ( (value >= -1000)
|
||||||
|
&& (value <= 1000)
|
||||||
|
&& (Thermostat.status.sensor_type == SENSOR_DS18B20)) {
|
||||||
|
uint32_t timestamp = uptime;
|
||||||
|
// Calculate temperature gradient if temperature value has changed
|
||||||
|
if (value != Thermostat.temp_measured) {
|
||||||
|
int32_t temp_delta = (value - Thermostat.temp_measured); // in tenths of degrees
|
||||||
|
uint32_t time_delta = (timestamp - Thermostat.timestamp_temp_meas_change_update); // in seconds
|
||||||
|
Thermostat.temp_measured_gradient = (int32_t)((360000 * temp_delta) / ((int32_t)time_delta)); // hundreths of degrees per hour
|
||||||
|
Thermostat.temp_measured = value;
|
||||||
|
Thermostat.timestamp_temp_meas_change_update = timestamp;
|
||||||
|
}
|
||||||
|
Thermostat.timestamp_temp_measured_update = timestamp;
|
||||||
|
Thermostat.status.sensor_alive = IFACE_ON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // THERMOSTAT_USE_LOCAL_SENSOR
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Commands
|
* Commands
|
||||||
|
@ -855,11 +893,22 @@ void CmndInputSwitchSet(void)
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
uint8_t value = (uint8_t)(XdrvMailbox.payload);
|
uint8_t value = (uint8_t)(XdrvMailbox.payload);
|
||||||
if (ThermostatSwitchIdValid(value)) {
|
if (ThermostatSwitchIdValid(value)) {
|
||||||
Thermostat.input_switch_number = value;
|
Thermostat.status.input_switch_number = value;
|
||||||
Thermostat.timestamp_input_on = uptime;
|
Thermostat.timestamp_input_on = uptime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResponseCmndNumber((int)Thermostat.input_switch_number);
|
ResponseCmndNumber((int)Thermostat.status.input_switch_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmndSensorInputSet(void)
|
||||||
|
{
|
||||||
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
uint8_t value = (uint8_t)(XdrvMailbox.payload);
|
||||||
|
if ((value >= 0) && (value < SENSOR_MAX)) {
|
||||||
|
Thermostat.status.sensor_type = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ResponseCmndNumber((int)Thermostat.status.sensor_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndOutputRelaySet(void)
|
void CmndOutputRelaySet(void)
|
||||||
|
@ -867,10 +916,10 @@ void CmndOutputRelaySet(void)
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
uint8_t value = (uint8_t)(XdrvMailbox.payload);
|
uint8_t value = (uint8_t)(XdrvMailbox.payload);
|
||||||
if (ThermostatRelayIdValid(value)) {
|
if (ThermostatRelayIdValid(value)) {
|
||||||
Thermostat.output_relay_number = value;
|
Thermostat.status.output_relay_number = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResponseCmndNumber((int)Thermostat.output_relay_number);
|
ResponseCmndNumber((int)Thermostat.status.output_relay_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndTimeAllowRampupSet(void)
|
void CmndTimeAllowRampupSet(void)
|
||||||
|
@ -888,7 +937,9 @@ void CmndTempMeasuredSet(void)
|
||||||
{
|
{
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
int16_t value = (int16_t)(CharToFloat(XdrvMailbox.data) * 10);
|
int16_t value = (int16_t)(CharToFloat(XdrvMailbox.data) * 10);
|
||||||
if ((value >= -1000) && (value <= 1000)) {
|
if ( (value >= -1000)
|
||||||
|
&& (value <= 1000)
|
||||||
|
&& (Thermostat.status.sensor_type == SENSOR_MQTT)) {
|
||||||
uint32_t timestamp = uptime;
|
uint32_t timestamp = uptime;
|
||||||
// Calculate temperature gradient if temperature value has changed
|
// Calculate temperature gradient if temperature value has changed
|
||||||
if (value != Thermostat.temp_measured) {
|
if (value != Thermostat.temp_measured) {
|
||||||
|
@ -909,7 +960,7 @@ void CmndTempTargetSet(void)
|
||||||
{
|
{
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
uint16_t value = (uint16_t)(CharToFloat(XdrvMailbox.data) * 10);
|
uint16_t value = (uint16_t)(CharToFloat(XdrvMailbox.data) * 10);
|
||||||
if ((value >= -1000)
|
if ( (value >= -1000)
|
||||||
&& (value <= 1000)
|
&& (value <= 1000)
|
||||||
&& (value >= (int16_t)Thermostat.temp_frost_protect)) {
|
&& (value >= (int16_t)Thermostat.temp_frost_protect)) {
|
||||||
Thermostat.temp_target_level = value;
|
Thermostat.temp_target_level = value;
|
||||||
|
@ -933,17 +984,6 @@ void CmndTempMeasuredGrdRead(void)
|
||||||
ResponseCmndFloat((float)(Thermostat.temp_measured_gradient) / 1000, 1);
|
ResponseCmndFloat((float)(Thermostat.temp_measured_gradient) / 1000, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndTempSensNumberSet(void)
|
|
||||||
{
|
|
||||||
if (XdrvMailbox.data_len > 0) {
|
|
||||||
uint8_t value = (uint8_t)(XdrvMailbox.payload);
|
|
||||||
if ((value >= 0) && (value <= 255)) {
|
|
||||||
Thermostat.temp_sens_number = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ResponseCmndNumber((int)Thermostat.temp_sens_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CmndStateEmergencySet(void)
|
void CmndStateEmergencySet(void)
|
||||||
{
|
{
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
@ -1160,7 +1200,7 @@ bool Xdrv39(uint8_t function)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_THERMOSTAT
|
#ifdef DEBUG_THERMOSTAT
|
||||||
char result_chr[FLOATSZ];
|
char result_chr[FLOATSZ];
|
||||||
#endif
|
#endif // DEBUG_THERMOSTAT
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
switch (function) {
|
switch (function) {
|
||||||
|
@ -1235,9 +1275,14 @@ bool Xdrv39(uint8_t function)
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat.time_rampup_deadtime: %s"), result_chr);
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat.time_rampup_deadtime: %s"), result_chr);
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("------ Thermostat End ------"));
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("------ Thermostat End ------"));
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(""));
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(""));
|
||||||
#endif
|
#endif // DEBUG_THERMOSTAT
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case FUNC_SHOW_SENSOR:
|
||||||
|
#ifdef THERMOSTAT_USE_LOCAL_SENSOR
|
||||||
|
ThermostatGetLocalSensor();
|
||||||
|
#endif // THERMOSTAT_USE_LOCAL_SENSOR
|
||||||
|
break;
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
result = DecodeCommand(kThermostatCommands, ThermostatCommand);
|
result = DecodeCommand(kThermostatCommands, ThermostatCommand);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue