From 5aaeecdbe8fceccaa490e268942708b750a106b5 Mon Sep 17 00:00:00 2001 From: Grzegorz Date: Sun, 3 Nov 2024 10:40:46 +0100 Subject: [PATCH] New features for MiElHVAC (#22395) * Add prohibit function for MiElHVAC Add Prohibit functions: * Power * Temperature * Mode and all combinations of this functions Updated VaneV names for better identify * Fixed Compressor and Operation for MiElHVAC Changed Widevane position name from ISEE to AUTO sam as in MELCLoud * Revert "Fixed Compressor and Operation for MiElHVAC" This reverts commit f0973c84d4915e776f715c0749a593efc6f55953. * New feature for MiElHVAC * Added Compressor map * Added Operation Power in Watts * Added Operation Energy in kWh * Changed Widevane position name from ISEE to AUTO, displays sam as in * Changed all map value to lover case MELCloud * New feature for MiElHVAC * Add device operation time in minutes * New feature Outdoor Temperature for MiElHVAC * Add Outdoor Temperature * New feature Compressor Frequency for MiElHVAC * Added Outdoor Temperature * Renamed internal properties due typo operating and oprating to operation * New feature Auto Clear Remote Temp for MiElHVAC * This PR add auto clear remote temperature function * This funcion is call on first run and after 10 sec the remote temperature stop refresh its value * Send manually Clear command is also available * change function name, small corrections * added auto clear time configurable using cmnd * Improvements to remote temp, auto clear time for MiElHVAC * Added min = 1000ms and max 600000ms limit to remotetemp auto clear time function * Changed function name to use sam format as other * Added RemoteTemperatureSensor to the sensor * more improvements to auto clear time * Changed RemoteTemperatureSensor to RemoteTemperatureSensorState * Added RemoteTemperatureSensorAutoClearTime to the sensor output * New feature Timers for MiElHVAC * Added Timers to the sensor output: * TimerMode - none, on, off, on_and_off * TimerOn - display time to ON * TimerOnRemaining - display remaining time to ON * TimerOff - display time to OFF * TimerOffRemaining - display remaining time to OFF * New feature for Stage and more for MiElHVAC * Added to sensor output: * Added PrerunStage - on/off, report compressor prepare stage before start working * FanStage - off, quiet, 1, 2, 3 ,4 ,5, report current fan stage * ModeStage - manual(heat, dry, cool, fan_only, heat_isee, dry_isee, cool_isee), auto_fan, auto_heat, auto_cool, report current mode * Renamed Bytes to Settings for raw data * Renamed const UPDATE to SETTINGS * Moved SETTINGS const from miel_hvac_msg_settings to miel_hvac_data_settings * Renamed some functions name to get better code readable * Removed some empty lines * Refactor some structure of code to make more clean and better readable * remove duplicate settings request --- .../tasmota_xdrv_driver/xdrv_44_miel_hvac.ino | 1443 +++++++++-------- 1 file changed, 754 insertions(+), 689 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino index 429e026f9..2635cfee5 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino @@ -22,10 +22,10 @@ * Mitsubishi Electric HVAC serial interface \*********************************************************************************************/ -#define XDRV_44 44 +#define XDRV_44 44 #ifndef nitems -#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) #endif #ifndef CTASSERT @@ -33,7 +33,7 @@ __attribute__((__unused__)) #endif -#define MIEL_HVAC_LOGNAME "MiElHVAC" +#define MIEL_HVAC_LOGNAME "MiElHVAC" #define D_CMND_MIEL_HVAC_SETFANSPEED "HVACSetFanSpeed" #define D_CMND_MIEL_HVAC_SETMODE "HVACSetMode" @@ -54,85 +54,171 @@ bool remotetemp_clear = true; unsigned long remotetemp_auto_clear_time = 10000; unsigned long remotetemp_last_call_time = 0; -struct miel_hvac_header { - uint8_t start; -#define MIEL_HVAC_H_START 0xfc - uint8_t type; -#define MIEL_HVAC_H_TYPE_UPDATED 0x61 -#define MIEL_HVAC_H_TYPE_DATA 0x62 -#define MIEL_HVAC_H_TYPE_CONNECTED 0x7a - uint8_t middle1; -#define MIEL_HVAC_H_MIDDLE1 0x01 - uint8_t middle2; -#define MIEL_HVAC_H_MIDDLE2 0x30 - uint8_t len; +struct miel_hvac_header +{ + uint8_t start; +#define MIEL_HVAC_H_START 0xfc + uint8_t type; +#define MIEL_HVAC_H_TYPE_UPDATED 0x61 +#define MIEL_HVAC_H_TYPE_DATA 0x62 +#define MIEL_HVAC_H_TYPE_CONNECTED 0x7a + uint8_t middle1; +#define MIEL_HVAC_H_MIDDLE1 0x01 + uint8_t middle2; +#define MIEL_HVAC_H_MIDDLE2 0x30 + uint8_t len; }; -struct miel_hvac_data_settings { - uint8_t _pad1[2]; - uint8_t power; - uint8_t mode; -#define MIEL_HVAC_SETTINGS_MODE_MASK 0x7f - uint8_t temp; - uint8_t fan; - uint8_t vane; - uint8_t prohibit; - uint8_t _pad2[1]; - uint8_t widevane; -#define MIEL_HVAC_SETTTINGS_WIDEVANE_MASK \ - 0x0f - uint8_t temp05; - uint8_t _pad3[2]; - uint8_t airdirection; +struct miel_hvac_data_settings +{ + uint8_t _pad1[2]; + uint8_t power; +#define MIEL_HVAC_SETTINGS_POWER_OFF 0x00 +#define MIEL_HVAC_SETTINGS_POWER_ON 0x01 + uint8_t mode; +#define MIEL_HVAC_SETTINGS_MODE_MASK 0x7f +#define MIEL_HVAC_SETTINGS_MODE_HEAT 0x01 +#define MIEL_HVAC_SETTINGS_MODE_DRY 0x02 +#define MIEL_HVAC_SETTINGS_MODE_COOL 0x03 +#define MIEL_HVAC_SETTINGS_MODE_FAN 0x07 +#define MIEL_HVAC_SETTINGS_MODE_AUTO 0x08 +#define MIEL_HVAC_SETTINGS_MODE_HEAT_ISEE 0x09 +#define MIEL_HVAC_SETTINGS_MODE_DRY_ISEE 0x0a +#define MIEL_HVAC_SETTINGS_MODE_COOL_ISEE 0x0b + uint8_t temp; +#ifndef MIEL_HVAC_SETTINGS_TEMP_MIN +#define MIEL_HVAC_SETTINGS_TEMP_MIN 10 +#endif +#ifndef MIEL_HVAC_SETTINGS_TEMP_MAX +#define MIEL_HVAC_SETTINGS_TEMP_MAX 31 +#endif + uint8_t fan; +#define MIEL_HVAC_SETTINGS_FAN_AUTO 0x00 +#define MIEL_HVAC_SETTINGS_FAN_QUIET 0x01 +#define MIEL_HVAC_SETTINGS_FAN_1 0x02 +#define MIEL_HVAC_SETTINGS_FAN_2 0x03 +#define MIEL_HVAC_SETTINGS_FAN_3 0x05 +#define MIEL_HVAC_SETTINGS_FAN_4 0x06 + uint8_t vane; +#define MIEL_HVAC_SETTINGS_VANE_AUTO 0x00 +#define MIEL_HVAC_SETTINGS_VANE_1 0x01 +#define MIEL_HVAC_SETTINGS_VANE_2 0x02 +#define MIEL_HVAC_SETTINGS_VANE_3 0x03 +#define MIEL_HVAC_SETTINGS_VANE_4 0x04 +#define MIEL_HVAC_SETTINGS_VANE_5 0x05 +#define MIEL_HVAC_SETTINGS_VANE_SWING 0x07 + uint8_t prohibit; +#define MIEL_HVAC_SETTINGS_PROHIBIT_OFF 0x00 +#define MIEL_HVAC_SETTINGS_PROHIBIT_POWER 0x01 +#define MIEL_HVAC_SETTINGS_PROHIBIT_MODE 0x02 +#define MIEL_HVAC_SETTINGS_PROHIBIT_MODE_POWER 0x03 +#define MIEL_HVAC_SETTINGS_PROHIBIT_TEMP 0x04 +#define MIEL_HVAC_SETTINGS_PROHIBIT_TEMP_POWER 0x05 +#define MIEL_HVAC_SETTINGS_PROHIBIT_TEMP_MODE 0x06 +#define MIEL_HVAC_SETTINGS_PROHIBIT_ALL 0x07 + uint8_t _pad2[1]; + uint8_t widevane; +#define MIEL_HVAC_SETTINGS_WIDEVANE_MASK 0x0f +#define MIEL_HVAC_SETTINGS_WIDEVANE_AUTO 0x00 +#define MIEL_HVAC_SETTINGS_WIDEVANE_LL 0x01 +#define MIEL_HVAC_SETTINGS_WIDEVANE_L 0x02 +#define MIEL_HVAC_SETTINGS_WIDEVANE_C 0x03 +#define MIEL_HVAC_SETTINGS_WIDEVANE_R 0x04 +#define MIEL_HVAC_SETTINGS_WIDEVANE_RR 0x05 +#define MIEL_HVAC_SETTINGS_WIDEVANE_LR 0x08 +#define MIEL_HVAC_SETTINGS_WIDEVANE_SWING 0x0c +#define MIEL_HVAC_SETTINGS_WIDEVANE_ADJ 0x80 + uint8_t temp05; + uint8_t _pad3[2]; + uint8_t airdirection; +#define MIEL_HVAC_SETTINGS_AIRDIRECTION_EVEN 0x00 +#define MIEL_HVAC_SETTINGS_AIRDIRECTION_INDIRECT 0x01 +#define MIEL_HVAC_SETTINGS_AIRDIRECTION_DIRECT 0x02 }; -struct miel_hvac_data_roomtemp { - uint8_t _pad1[2]; - uint8_t temp; - uint8_t _pad2[1]; - uint8_t outdoortemp; - uint8_t temp05; - uint8_t settemp; - uint8_t _pad3[3]; - uint8_t operationtime; - uint8_t operationtime1; - uint8_t operationtime2; +struct miel_hvac_data_roomtemp +{ + uint8_t _pad1[2]; + uint8_t temp; + uint8_t _pad2[1]; + uint8_t outdoortemp; + uint8_t temp05; + uint8_t settemp; + uint8_t _pad3[3]; + uint8_t operationtime; + uint8_t operationtime1; + uint8_t operationtime2; }; -struct miel_hvac_data_status { - uint8_t _pad1[2]; - uint8_t compressorfrequency; - uint8_t compressor; -#define MIEL_HVAC_STATUS_COMPRESSOR_OFF 0x00 -#define MIEL_HVAC_STATUS_COMPRESSOR_ON 0x01 - uint8_t operationpower; - uint8_t operationpower1; - uint8_t operationenergy; - uint8_t operationenergy1; +struct miel_hvac_data_timers +{ + uint8_t _pad1[2]; + uint8_t mode; +#define MIEL_HVAC_TIMER_MODE_NONE 0x00 +#define MIEL_HVAC_TIMER_MODE_OFF 0x01 +#define MIEL_HVAC_TIMER_MODE_ON 0x02 +#define MIEL_HVAC_TIMER_MODE_BOTH 0x03 + uint8_t onminutes; + uint8_t offminutes; + uint8_t onminutesremaining; + uint8_t offminutesremaining; }; -struct miel_hvac_data { - uint8_t type; -#define MIEL_HVAC_DATA_T_SETTINGS 0x02 -#define MIEL_HVAC_DATA_T_ROOMTEMP 0x03 -#define MIEL_HVAC_DATA_T_TIMER 0x05 -#define MIEL_HVAC_DATA_T_STATUS 0x06 -#define MIEL_HVAC_DATA_T_STAGE 0x09 +struct miel_hvac_data_status +{ + uint8_t _pad1[2]; + uint8_t compressorfrequency; + uint8_t compressor; +#define MIEL_HVAC_STATUS_COMPRESSOR_OFF 0x00 +#define MIEL_HVAC_STATUS_COMPRESSOR_ON 0x01 + uint8_t operationpower; + uint8_t operationpower1; + uint8_t operationenergy; + uint8_t operationenergy1; +}; - union { - struct miel_hvac_data_settings - settings; - struct miel_hvac_data_roomtemp - roomtemp; - struct miel_hvac_data_status - status; +struct miel_hvac_data_stage +{ + uint8_t _pad1[2]; + uint8_t prerun; +#define MIEL_HVAC_STAGE_PRERUN_OFF 0x00 +#define MIEL_HVAC_STAGE_PRERUN_ON 0x04 + uint8_t fan; +#define MIEL_HVAC_STAGE_FAN_OFF 0x00 +#define MIEL_HVAC_STAGE_FAN_1 0x01 +#define MIEL_HVAC_STAGE_FAN_2 0x02 +#define MIEL_HVAC_STAGE_FAN_3 0x03 +#define MIEL_HVAC_STAGE_FAN_4 0x04 +#define MIEL_HVAC_STAGE_FAN_5 0x05 +#define MIEL_HVAC_STAGE_FAN_QUIT 0x06 + uint8_t mode; +#define MIEL_HVAC_STAGE_MODE_MANUAL 0x00 +#define MIEL_HVAC_STAGE_MODE_AUTO_FAN 0x01 +#define MIEL_HVAC_STAGE_MODE_AUTO_HEAT 0x02 +#define MIEL_HVAC_STAGE_MODE_AUTO_COOL 0x03 +}; - uint8_t bytes[15]; - } data; +struct miel_hvac_data +{ + uint8_t type; +#define MIEL_HVAC_DATA_T_SETTINGS 0x02 +#define MIEL_HVAC_DATA_T_ROOMTEMP 0x03 +#define MIEL_HVAC_DATA_T_TIMERS 0x05 +#define MIEL_HVAC_DATA_T_STATUS 0x06 +#define MIEL_HVAC_DATA_T_STAGE 0x09 + + union + { + struct miel_hvac_data_settings settings; + struct miel_hvac_data_roomtemp roomtemp;; + struct miel_hvac_data_timers timers; + struct miel_hvac_data_status status; + struct miel_hvac_data_stage stage; + uint8_t bytes[15]; + } data; }; CTASSERT(sizeof(struct miel_hvac_data) == 16); - CTASSERT(offsetof(struct miel_hvac_data, data.settings.power) == 3); CTASSERT(offsetof(struct miel_hvac_data, data.settings.mode) == 4); CTASSERT(offsetof(struct miel_hvac_data, data.settings.temp) == 5); @@ -151,6 +237,16 @@ CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.operationtime) == 11); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.operationtime1) == 12); CTASSERT(offsetof(struct miel_hvac_data, data.roomtemp.operationtime2) == 13); +CTASSERT(offsetof(struct miel_hvac_data, data.timers.mode) == 3); +CTASSERT(offsetof(struct miel_hvac_data, data.timers.onminutes) == 4); +CTASSERT(offsetof(struct miel_hvac_data, data.timers.offminutes) == 5); +CTASSERT(offsetof(struct miel_hvac_data, data.timers.onminutesremaining) == 6); +CTASSERT(offsetof(struct miel_hvac_data, data.timers.offminutesremaining) == 7); + +CTASSERT(offsetof(struct miel_hvac_data, data.stage.prerun) == 3); +CTASSERT(offsetof(struct miel_hvac_data, data.stage.fan) == 4); +CTASSERT(offsetof(struct miel_hvac_data, data.stage.mode) == 5); + CTASSERT(offsetof(struct miel_hvac_data, data.status.compressorfrequency) == 3); CTASSERT(offsetof(struct miel_hvac_data, data.status.compressor) == 4); CTASSERT(offsetof(struct miel_hvac_data, data.status.operationpower) == 5); @@ -160,143 +256,100 @@ CTASSERT(offsetof(struct miel_hvac_data, data.status.operationenergy1) == 8); /* to hvac */ -#define MIEL_HVAC_H_TYPE_CONNECT 0x5a -static const uint8_t miel_hvac_msg_connect[] = { 0xca, 0x01 }; +#define MIEL_HVAC_H_TYPE_CONNECT 0x5a +static const uint8_t miel_hvac_msg_connect[] = {0xca, 0x01}; -#define MIEL_HVAC_H_TYPE_REQUEST 0x42 +#define MIEL_HVAC_H_TYPE_REQUEST 0x42 -struct miel_hvac_msg_request { - uint8_t type; -#define MIEL_HVAC_REQUEST_SETTINGS 0x02 -#define MIEL_HVAC_REQUEST_ROOMTEMP 0x03 -#define MIEL_HVAC_REQUEST_TIMERS 0x05 -#define MIEL_HVAC_REQUEST_STATUS 0x06 -#define MIEL_HVAC_REQUEST_STAGE 0x09 - uint8_t zero[15]; +struct miel_hvac_msg_request +{ + uint8_t type; +#define MIEL_HVAC_REQUEST_SETTINGS 0x02 +#define MIEL_HVAC_REQUEST_ROOMTEMP 0x03 +#define MIEL_HVAC_REQUEST_TIMERS 0x05 +#define MIEL_HVAC_REQUEST_STATUS 0x06 +#define MIEL_HVAC_REQUEST_STAGE 0x09 + uint8_t zero[15]; }; -#define MIEL_HVAC_H_TYPE_UPDATE 0x41 +#define MIEL_HVAC_H_TYPE_UPDATE 0x41 -struct miel_hvac_msg_update { - uint8_t one; - uint16_t flags; -#define MIEL_HVAC_UPDATE_F_WIDEVANE (1 << 0) -#define MIEL_HVAC_UPDATE_F_POWER (1 << 8) -#define MIEL_HVAC_UPDATE_F_MODE (1 << 9) -#define MIEL_HVAC_UPDATE_F_TEMP (1 << 10) -#define MIEL_HVAC_UPDATE_F_FAN (1 << 11) -#define MIEL_HVAC_UPDATE_F_VANE (1 << 12) -#define MIEL_HVAC_UPDATE_F_PROHIBIT (1 << 13) -#define MIEL_HVAC_UPDATE_F_AIRDIRECTION (1 << 14) - uint8_t power; -#define MIEL_HVAC_UPDATE_POWER_OFF 0x00 -#define MIEL_HVAC_UPDATE_POWER_ON 0x01 - uint8_t mode; -#define MIEL_HVAC_UPDATE_MODE_HEAT 0x01 -#define MIEL_HVAC_UPDATE_MODE_DRY 0x02 -#define MIEL_HVAC_UPDATE_MODE_COOL 0x03 -#define MIEL_HVAC_UPDATE_MODE_FAN 0x07 -#define MIEL_HVAC_UPDATE_MODE_AUTO 0x08 -#define MIEL_HVAC_UPDATE_MODE_HEAT_ISEE 0x09 -#define MIEL_HVAC_UPDATE_MODE_DRY_ISEE 0x0a -#define MIEL_HVAC_UPDATE_MODE_COOL_ISEE 0x0b - uint8_t temp; -#ifndef MIEL_HVAC_UPDATE_TEMP_MIN -#define MIEL_HVAC_UPDATE_TEMP_MIN 10 -#endif -#ifndef MIEL_HVAC_UPDATE_TEMP_MAX -#define MIEL_HVAC_UPDATE_TEMP_MAX 31 -#endif - uint8_t fan; -#define MIEL_HVAC_UPDATE_FAN_AUTO 0x00 -#define MIEL_HVAC_UPDATE_FAN_QUIET 0x01 -#define MIEL_HVAC_UPDATE_FAN_1 0x02 -#define MIEL_HVAC_UPDATE_FAN_2 0x03 -#define MIEL_HVAC_UPDATE_FAN_3 0x05 -#define MIEL_HVAC_UPDATE_FAN_4 0x06 - uint8_t vane; -#define MIEL_HVAC_UPDATE_VANE_AUTO 0x00 -#define MIEL_HVAC_UPDATE_VANE_1 0x01 -#define MIEL_HVAC_UPDATE_VANE_2 0x02 -#define MIEL_HVAC_UPDATE_VANE_3 0x03 -#define MIEL_HVAC_UPDATE_VANE_4 0x04 -#define MIEL_HVAC_UPDATE_VANE_5 0x05 -#define MIEL_HVAC_UPDATE_VANE_SWING 0x07 - uint8_t prohibit; -#define MIEL_HVAC_UPDATE_PROHIBIT_OFF 0x00 -#define MIEL_HVAC_UPDATE_PROHIBIT_POWER 0x01 -#define MIEL_HVAC_UPDATE_PROHIBIT_MODE 0x02 -#define MIEL_HVAC_UPDATE_PROHIBIT_MODE_POWER 0x03 -#define MIEL_HVAC_UPDATE_PROHIBIT_TEMP 0x04 -#define MIEL_HVAC_UPDATE_PROHIBIT_TEMP_POWER 0x05 -#define MIEL_HVAC_UPDATE_PROHIBIT_TEMP_MODE 0x06 -#define MIEL_HVAC_UPDATE_PROHIBIT_ALL 0x07 - uint8_t _pad1[4]; - uint8_t widevane; -#define MIEL_HVAC_UPDATE_WIDEVANE_MASK 0x0f -#define MIEL_HVAC_UPDATE_WIDEVANE_AUTO 0x00 -#define MIEL_HVAC_UPDATE_WIDEVANE_LL 0x01 -#define MIEL_HVAC_UPDATE_WIDEVANE_L 0x02 -#define MIEL_HVAC_UPDATE_WIDEVANE_C 0x03 -#define MIEL_HVAC_UPDATE_WIDEVANE_R 0x04 -#define MIEL_HVAC_UPDATE_WIDEVANE_RR 0x05 -#define MIEL_HVAC_UPDATE_WIDEVANE_LR 0x08 -#define MIEL_HVAC_UPDATE_WIDEVANE_SWING 0x0c -#define MIEL_HVAC_UPDATE_WIDEVANE_ADJ 0x80 - uint8_t temp05; - uint8_t airdirection; -#define MIEL_HVAC_UPDATE_AIRDIRECTION_EVEN 0x00 -#define MIEL_HVAC_UPDATE_AIRDIRECTION_INDIRECT 0x01 -#define MIEL_HVAC_UPDATE_AIRDIRECTION_DIRECT 0x02 +struct miel_hvac_msg_update_settings +{ + uint8_t one; + uint16_t flags; +#define MIEL_HVAC_SETTINGS_F_WIDEVANE (1 << 0) +#define MIEL_HVAC_SETTINGS_F_POWER (1 << 8) +#define MIEL_HVAC_SETTINGS_F_MODE (1 << 9) +#define MIEL_HVAC_SETTINGS_F_TEMP (1 << 10) +#define MIEL_HVAC_SETTINGS_F_FAN (1 << 11) +#define MIEL_HVAC_SETTINGS_F_VANE (1 << 12) +#define MIEL_HVAC_SETTINGS_F_PROHIBIT (1 << 13) +#define MIEL_HVAC_SETTINGS_F_AIRDIRECTION (1 << 14) + uint8_t power; + uint8_t mode; + uint8_t temp; + uint8_t fan; + uint8_t vane; + uint8_t prohibit; + uint8_t _pad1[4]; + uint8_t widevane; + uint8_t temp05; + uint8_t airdirection; } __packed; -CTASSERT(sizeof(struct miel_hvac_msg_update) == 16); +CTASSERT(sizeof(struct miel_hvac_msg_update_settings) == 16); #define MIEL_HVAC_OFFS(_v) ((_v) - sizeof(struct miel_hvac_header)) -CTASSERT(offsetof(struct miel_hvac_msg_update, flags) == MIEL_HVAC_OFFS(6)); -CTASSERT(offsetof(struct miel_hvac_msg_update, power) == MIEL_HVAC_OFFS(8)); -CTASSERT(offsetof(struct miel_hvac_msg_update, mode) == MIEL_HVAC_OFFS(9)); -CTASSERT(offsetof(struct miel_hvac_msg_update, temp) == MIEL_HVAC_OFFS(10)); -CTASSERT(offsetof(struct miel_hvac_msg_update, fan) == MIEL_HVAC_OFFS(11)); -CTASSERT(offsetof(struct miel_hvac_msg_update, vane) == MIEL_HVAC_OFFS(12)); -CTASSERT(offsetof(struct miel_hvac_msg_update, prohibit) == MIEL_HVAC_OFFS(13)); -CTASSERT(offsetof(struct miel_hvac_msg_update, widevane) == MIEL_HVAC_OFFS(18)); -CTASSERT(offsetof(struct miel_hvac_msg_update, temp05) == MIEL_HVAC_OFFS(19)); -CTASSERT(offsetof(struct miel_hvac_msg_update, airdirection) == MIEL_HVAC_OFFS(20)); - +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, flags) == MIEL_HVAC_OFFS(6)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, power) == MIEL_HVAC_OFFS(8)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, mode) == MIEL_HVAC_OFFS(9)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, temp) == MIEL_HVAC_OFFS(10)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, fan) == MIEL_HVAC_OFFS(11)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, vane) == MIEL_HVAC_OFFS(12)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, prohibit) == MIEL_HVAC_OFFS(13)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, widevane) == MIEL_HVAC_OFFS(18)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, temp05) == MIEL_HVAC_OFFS(19)); +CTASSERT(offsetof(struct miel_hvac_msg_update_settings, airdirection) == MIEL_HVAC_OFFS(20)); static inline uint8_t miel_hvac_deg2temp(float deg) { - if (!temp_type) { + if (!temp_type) + { return (31 - deg); } - else { - deg = 2*deg + 128; - return ((uint8_t) deg); + else + { + deg = 2 * deg + 128; + return ((uint8_t)deg); } } static inline float miel_hvac_temp2deg(uint8_t temp) { - if (!temp_type) { + if (!temp_type) + { return (31 - temp); } - else { + else + { temp -= 128; - return ((float) temp/2); + return ((float)temp / 2); } } static inline float miel_hvac_roomtemp2deg(uint8_t roomtemp) { - if (!temp_type) { + if (!temp_type) + { return ((unsigned int)roomtemp + 10); } - else { + else + { roomtemp -= 128; - return ((float) roomtemp/2); + return ((float)roomtemp / 2); } } @@ -304,29 +357,30 @@ static inline float miel_hvac_outdoortemp2deg(uint8_t outdoortemp) { outdoortemp -= 128; - return ((float) outdoortemp/2); + return ((float)outdoortemp / 2); } -struct miel_hvac_msg_remotetemp { - uint8_t seven; - uint8_t control; -#define MIEL_HVAC_REMOTETEMP_CLR 0x00 -#define MIEL_HVAC_REMOTETEMP_SET 0x01 +struct miel_hvac_msg_update_remotetemp +{ + uint8_t seven; + uint8_t control; +#define MIEL_HVAC_REMOTETEMP_CLR 0x00 +#define MIEL_HVAC_REMOTETEMP_SET 0x01 /* setting for older units expressed as .5C units starting at 8C */ - uint8_t temp_old; -#define MIEL_HVAC_REMOTETEMP_OLD_MIN 8 -#define MIEL_HVAC_REMOTETEMP_OLD_MAX 38 -#define MIEL_HVAC_REMOTETEMP_OLD_FACTOR 2 + uint8_t temp_old; +#define MIEL_HVAC_REMOTETEMP_OLD_MIN 8 +#define MIEL_HVAC_REMOTETEMP_OLD_MAX 38 +#define MIEL_HVAC_REMOTETEMP_OLD_FACTOR 2 /* setting for newer units expressed as .5C units starting at -63C */ - uint8_t temp; -#define MIEL_HVAC_REMOTETEMP_MIN -63 -#define MIEL_HVAC_REMOTETEMP_MAX 63 -#define MIEL_HVAC_REMOTETEMP_OFFSET 64 -#define MIEL_HVAC_REMOTETEMP_FACTOR 2 - uint8_t _pad2[12]; + uint8_t temp; +#define MIEL_HVAC_REMOTETEMP_MIN -63 +#define MIEL_HVAC_REMOTETEMP_MAX 63 +#define MIEL_HVAC_REMOTETEMP_OFFSET 64 +#define MIEL_HVAC_REMOTETEMP_FACTOR 2 + uint8_t _pad2[12]; }; -CTASSERT(sizeof(struct miel_hvac_msg_remotetemp) == 16); +CTASSERT(sizeof(struct miel_hvac_msg_update_remotetemp) == 16); static inline uint8_t miel_hvac_cksum_fini(uint8_t sum) @@ -334,80 +388,111 @@ miel_hvac_cksum_fini(uint8_t sum) return (0xfc - sum); } -struct miel_hvac_map { - uint8_t byte; - const char *name; +struct miel_hvac_map +{ + uint8_t byte; + const char *name; }; static const struct miel_hvac_map miel_hvac_power_map[] = { - { MIEL_HVAC_UPDATE_POWER_OFF, "off" }, - { MIEL_HVAC_UPDATE_POWER_ON, "on" }, + {MIEL_HVAC_SETTINGS_POWER_OFF, "off"}, + {MIEL_HVAC_SETTINGS_POWER_ON, "on"}, }; static const struct miel_hvac_map miel_hvac_mode_map[] = { - { MIEL_HVAC_UPDATE_MODE_HEAT, "heat" }, - { MIEL_HVAC_UPDATE_MODE_DRY, "dry" }, - { MIEL_HVAC_UPDATE_MODE_COOL, "cool" }, - { MIEL_HVAC_UPDATE_MODE_FAN, "fan_only" }, - { MIEL_HVAC_UPDATE_MODE_AUTO, "auto" }, - { MIEL_HVAC_UPDATE_MODE_HEAT_ISEE, "heat_isee" }, - { MIEL_HVAC_UPDATE_MODE_DRY_ISEE, "dry_isee" }, - { MIEL_HVAC_UPDATE_MODE_COOL_ISEE, "cool_isee" }, + {MIEL_HVAC_SETTINGS_MODE_HEAT, "heat"}, + {MIEL_HVAC_SETTINGS_MODE_DRY, "dry"}, + {MIEL_HVAC_SETTINGS_MODE_COOL, "cool"}, + {MIEL_HVAC_SETTINGS_MODE_FAN, "fan_only"}, + {MIEL_HVAC_SETTINGS_MODE_AUTO, "auto"}, + {MIEL_HVAC_SETTINGS_MODE_HEAT_ISEE, "heat_isee"}, + {MIEL_HVAC_SETTINGS_MODE_DRY_ISEE, "dry_isee"}, + {MIEL_HVAC_SETTINGS_MODE_COOL_ISEE, "cool_isee"}, }; static const struct miel_hvac_map miel_hvac_fan_map[] = { - { MIEL_HVAC_UPDATE_FAN_AUTO, "auto" }, - { MIEL_HVAC_UPDATE_FAN_QUIET, "quiet" }, - { MIEL_HVAC_UPDATE_FAN_1, "1" }, - { MIEL_HVAC_UPDATE_FAN_2, "2" }, - { MIEL_HVAC_UPDATE_FAN_3, "3" }, - { MIEL_HVAC_UPDATE_FAN_4, "4" }, + {MIEL_HVAC_SETTINGS_FAN_AUTO, "auto"}, + {MIEL_HVAC_SETTINGS_FAN_QUIET, "quiet"}, + {MIEL_HVAC_SETTINGS_FAN_1, "1"}, + {MIEL_HVAC_SETTINGS_FAN_2, "2"}, + {MIEL_HVAC_SETTINGS_FAN_3, "3"}, + {MIEL_HVAC_SETTINGS_FAN_4, "4"}, }; static const struct miel_hvac_map miel_hvac_vane_map[] = { - { MIEL_HVAC_UPDATE_VANE_AUTO, "auto" }, - { MIEL_HVAC_UPDATE_VANE_1, "up" }, - { MIEL_HVAC_UPDATE_VANE_2, "up_middle" }, - { MIEL_HVAC_UPDATE_VANE_3, "center" }, - { MIEL_HVAC_UPDATE_VANE_4, "down_middle" }, - { MIEL_HVAC_UPDATE_VANE_5, "down" }, - { MIEL_HVAC_UPDATE_VANE_SWING, "swing" }, + {MIEL_HVAC_SETTINGS_VANE_AUTO, "auto"}, + {MIEL_HVAC_SETTINGS_VANE_1, "up"}, + {MIEL_HVAC_SETTINGS_VANE_2, "up_middle"}, + {MIEL_HVAC_SETTINGS_VANE_3, "center"}, + {MIEL_HVAC_SETTINGS_VANE_4, "down_middle"}, + {MIEL_HVAC_SETTINGS_VANE_5, "down"}, + {MIEL_HVAC_SETTINGS_VANE_SWING, "swing"}, }; static const struct miel_hvac_map miel_hvac_widevane_map[] = { - { MIEL_HVAC_UPDATE_WIDEVANE_AUTO, "auto" }, - { MIEL_HVAC_UPDATE_WIDEVANE_LL, "left" }, - { MIEL_HVAC_UPDATE_WIDEVANE_L, "left_middle" }, - { MIEL_HVAC_UPDATE_WIDEVANE_C, "center" }, - { MIEL_HVAC_UPDATE_WIDEVANE_R, "right" }, - { MIEL_HVAC_UPDATE_WIDEVANE_RR, "right_middle" }, - { MIEL_HVAC_UPDATE_WIDEVANE_LR, "split" }, - { MIEL_HVAC_UPDATE_WIDEVANE_SWING, "swing" }, + {MIEL_HVAC_SETTINGS_WIDEVANE_AUTO, "auto"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_LL, "left"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_L, "left_middle"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_C, "center"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_R, "right"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_RR, "right_middle"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_LR, "split"}, + {MIEL_HVAC_SETTINGS_WIDEVANE_SWING, "swing"}, }; static const struct miel_hvac_map miel_hvac_prohibit_map[] = { - { MIEL_HVAC_UPDATE_PROHIBIT_OFF, "off" }, - { MIEL_HVAC_UPDATE_PROHIBIT_POWER, "power" }, - { MIEL_HVAC_UPDATE_PROHIBIT_MODE, "mode" }, - { MIEL_HVAC_UPDATE_PROHIBIT_MODE_POWER, "mode_power" }, - { MIEL_HVAC_UPDATE_PROHIBIT_TEMP, "temp" }, - { MIEL_HVAC_UPDATE_PROHIBIT_TEMP_POWER, "temp_power" }, - { MIEL_HVAC_UPDATE_PROHIBIT_TEMP_MODE, "temp_mode" }, - { MIEL_HVAC_UPDATE_PROHIBIT_ALL, "all" }, + {MIEL_HVAC_SETTINGS_PROHIBIT_OFF, "off"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_POWER, "power"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_MODE, "mode"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_MODE_POWER, "mode_power"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_TEMP, "temp"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_TEMP_POWER, "temp_power"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_TEMP_MODE, "temp_mode"}, + {MIEL_HVAC_SETTINGS_PROHIBIT_ALL, "all"}, }; static const struct miel_hvac_map miel_hvac_airdirection_map[] = { - { MIEL_HVAC_UPDATE_AIRDIRECTION_EVEN, "even" }, - { MIEL_HVAC_UPDATE_AIRDIRECTION_INDIRECT, "indirect" }, - { MIEL_HVAC_UPDATE_AIRDIRECTION_DIRECT, "direct" }, + {MIEL_HVAC_SETTINGS_AIRDIRECTION_EVEN, "even"}, + {MIEL_HVAC_SETTINGS_AIRDIRECTION_INDIRECT, "indirect"}, + {MIEL_HVAC_SETTINGS_AIRDIRECTION_DIRECT, "direct"}, }; static const struct miel_hvac_map miel_hvac_compressor_map[] = { - { MIEL_HVAC_STATUS_COMPRESSOR_OFF, "off" }, - { MIEL_HVAC_STATUS_COMPRESSOR_ON, "on" }, + {MIEL_HVAC_STATUS_COMPRESSOR_OFF, "off"}, + {MIEL_HVAC_STATUS_COMPRESSOR_ON, "on"}, }; -enum miel_hvac_parser_state { +static const struct miel_hvac_map miel_hvac_timer_mode_map[] = { + {MIEL_HVAC_TIMER_MODE_NONE, "none"}, + {MIEL_HVAC_TIMER_MODE_OFF, "off"}, + {MIEL_HVAC_TIMER_MODE_ON, "on"}, + {MIEL_HVAC_TIMER_MODE_BOTH, "on_and_off"}, +}; + +static const struct miel_hvac_map miel_hvac_stage_prerun_map[] = { + {MIEL_HVAC_STAGE_PRERUN_OFF, "off"}, + {MIEL_HVAC_STAGE_PRERUN_ON, "on"}, +}; + +static const struct miel_hvac_map miel_hvac_stage_fan_map[] = { + {MIEL_HVAC_STAGE_FAN_OFF, "off"}, + {MIEL_HVAC_STAGE_FAN_QUIT, "quiet"}, + {MIEL_HVAC_STAGE_FAN_1, "1"}, + {MIEL_HVAC_STAGE_FAN_2, "2"}, + {MIEL_HVAC_STAGE_FAN_3, "3"}, + {MIEL_HVAC_STAGE_FAN_4, "4"}, + {MIEL_HVAC_STAGE_FAN_5, "5"}, +}; + +static const struct miel_hvac_map miel_hvac_stage_mode_map[] = { + {MIEL_HVAC_STAGE_MODE_MANUAL, "manual"}, + {MIEL_HVAC_STAGE_MODE_AUTO_FAN, "auto_fan"}, + {MIEL_HVAC_STAGE_MODE_AUTO_HEAT, "auto_heat"}, + {MIEL_HVAC_STAGE_MODE_AUTO_COOL, "auto_cool"}, +}; + +enum miel_hvac_parser_state +{ MIEL_HVAC_P_START, MIEL_HVAC_P_TYPE, MIEL_HVAC_P_MIDDLE1, @@ -415,60 +500,55 @@ enum miel_hvac_parser_state { MIEL_HVAC_P_LEN, MIEL_HVAC_P_DATA, MIEL_HVAC_P_CKSUM, - MIEL_HVAC_P_SKIP, MIEL_HVAC_P_SKIP_CKSUM, }; -#define MIEL_HVAC_DATABUFLEN 64 +#define MIEL_HVAC_DATABUFLEN 64 -struct miel_hvac_parser { - enum miel_hvac_parser_state - p_state; - uint8_t p_tmo; - uint8_t p_type; - uint8_t p_sum; - uint8_t p_len; - uint8_t p_off; - uint8_t p_data[MIEL_HVAC_DATABUFLEN]; +struct miel_hvac_parser +{ + enum miel_hvac_parser_state p_state; + uint8_t p_tmo; + uint8_t p_type; + uint8_t p_sum; + uint8_t p_len; + uint8_t p_off; + uint8_t p_data[MIEL_HVAC_DATABUFLEN]; }; -struct miel_hvac_softc { - TasmotaSerial *sc_serial; - struct miel_hvac_parser sc_parser; +struct miel_hvac_softc +{ + TasmotaSerial *sc_serial; + struct miel_hvac_parser sc_parser; - unsigned int sc_device; - unsigned int sc_tick; - bool sc_settings_set; - bool sc_connected; + unsigned int sc_device; + unsigned int sc_tick; + bool sc_settings_set; + bool sc_connected; - struct miel_hvac_data sc_settings; - struct miel_hvac_data sc_temp; - struct miel_hvac_data sc_status; - struct miel_hvac_data sc_stage; + struct miel_hvac_data sc_settings; + struct miel_hvac_data sc_roomtemp; + struct miel_hvac_data sc_timers; + struct miel_hvac_data sc_status; + struct miel_hvac_data sc_stage; - struct miel_hvac_msg_update - sc_update; - struct miel_hvac_msg_remotetemp - sc_remotetemp; + struct miel_hvac_msg_update_settings sc_settings_update; + struct miel_hvac_msg_update_remotetemp sc_remotetemp_update; }; static inline bool -miel_hvac_update_pending(struct miel_hvac_softc *sc) +miel_hvac_update_settings_pending(struct miel_hvac_softc *sc) { - struct miel_hvac_msg_update *update = &sc->sc_update; - + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; return (update->flags != htons(0)); } -static struct miel_hvac_softc *miel_hvac_sc = nullptr; +static struct miel_hvac_softc *miel_hvac_sc = nullptr; -static void miel_hvac_input_connected(struct miel_hvac_softc *, - const void *, size_t); -static void miel_hvac_input_data(struct miel_hvac_softc *, - const void *, size_t); -static void miel_hvac_input_updated(struct miel_hvac_softc *, - const void *, size_t); +static void miel_hvac_input_connected(struct miel_hvac_softc *, const void *, size_t); +static void miel_hvac_input_data(struct miel_hvac_softc *, const void *, size_t); +static void miel_hvac_input_updated(struct miel_hvac_softc *, const void *, size_t); static enum miel_hvac_parser_state miel_hvac_parse(struct miel_hvac_softc *sc, uint8_t byte) @@ -476,7 +556,8 @@ miel_hvac_parse(struct miel_hvac_softc *sc, uint8_t byte) struct miel_hvac_parser *p = &sc->sc_parser; enum miel_hvac_parser_state nstate = p->p_state; - switch (p->p_state) { + switch (p->p_state) + { case MIEL_HVAC_P_START: if (byte != MIEL_HVAC_H_START) return (MIEL_HVAC_P_START); @@ -484,84 +565,74 @@ miel_hvac_parse(struct miel_hvac_softc *sc, uint8_t byte) /* reset state */ p->p_sum = 0; p->p_tmo = 0; - nstate = MIEL_HVAC_P_TYPE; break; - case MIEL_HVAC_P_TYPE: p->p_type = byte; nstate = MIEL_HVAC_P_MIDDLE1; break; - case MIEL_HVAC_P_MIDDLE1: - if (byte != MIEL_HVAC_H_MIDDLE1) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": parse state MIDDLE1 expected %02x got %02x" - ", restarting"), MIEL_HVAC_H_MIDDLE1, byte); + if (byte != MIEL_HVAC_H_MIDDLE1) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": parse state MIDDLE1 expected %02x got %02x" + ", restarting"), + MIEL_HVAC_H_MIDDLE1, byte); return (MIEL_HVAC_P_START); } - nstate = MIEL_HVAC_P_MIDDLE2; break; - case MIEL_HVAC_P_MIDDLE2: - if (byte != MIEL_HVAC_H_MIDDLE2) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": parse state MIDDLE2 expected %02x got %02x" - ", restarting"), MIEL_HVAC_H_MIDDLE2, byte); + if (byte != MIEL_HVAC_H_MIDDLE2) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": parse state MIDDLE2 expected %02x got %02x" + ", restarting"), + MIEL_HVAC_H_MIDDLE2, byte); return (MIEL_HVAC_P_START); } - nstate = MIEL_HVAC_P_LEN; break; - case MIEL_HVAC_P_LEN: - if (byte == 0) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": skipping 0 byte message type 0x%02x"), - p->p_type); + if (byte == 0) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": skipping 0 byte message type 0x%02x"), p->p_type); return (MIEL_HVAC_P_SKIP_CKSUM); } - p->p_len = byte; p->p_off = 0; - switch (p->p_type) { + switch (p->p_type) + { case MIEL_HVAC_H_TYPE_CONNECTED: case MIEL_HVAC_H_TYPE_DATA: case MIEL_HVAC_H_TYPE_UPDATED: break; default: - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": skipping unknown message type 0x%02x"), - p->p_type); + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": skipping unknown message type 0x%02x"), p->p_type); return (MIEL_HVAC_P_SKIP); } - if (byte > sizeof(p->p_data)) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": skipping %u data bytes of message type 0x%02x"), - p->p_len, p->p_type); + if (byte > sizeof(p->p_data)) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": skipping %u data bytes of message type 0x%02x"), p->p_len, p->p_type); return (MIEL_HVAC_P_SKIP); } - nstate = MIEL_HVAC_P_DATA; break; - case MIEL_HVAC_P_DATA: p->p_data[p->p_off++] = byte; if (p->p_off >= p->p_len) nstate = MIEL_HVAC_P_CKSUM; - break; + break; case MIEL_HVAC_P_CKSUM: - if (miel_hvac_cksum_fini(p->p_sum) != byte) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": checksum failed, restarting")); + if (miel_hvac_cksum_fini(p->p_sum) != byte) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": checksum failed, restarting")); return (MIEL_HVAC_P_START); } - switch (p->p_type) { + switch (p->p_type) + { case MIEL_HVAC_H_TYPE_CONNECTED: miel_hvac_input_connected(sc, p->p_data, p->p_len); break; @@ -575,7 +646,6 @@ miel_hvac_parse(struct miel_hvac_softc *sc, uint8_t byte) /* this message is done, wait for another */ return (MIEL_HVAC_P_START); - case MIEL_HVAC_P_SKIP: if (++p->p_off >= p->p_len) return (MIEL_HVAC_P_SKIP_CKSUM); @@ -583,7 +653,6 @@ miel_hvac_parse(struct miel_hvac_softc *sc, uint8_t byte) case MIEL_HVAC_P_SKIP_CKSUM: return (MIEL_HVAC_P_START); } - p->p_sum += byte; return (nstate); @@ -596,7 +665,8 @@ miel_hvac_write(struct miel_hvac_softc *sc, const uint8_t *bytes, size_t len) uint8_t cksum = 0; size_t i; - for (i = 0; i < len; i++) { + for (i = 0; i < len; i++) + { uint8_t b = bytes[i]; serial->write(b); cksum += b; @@ -606,8 +676,7 @@ miel_hvac_write(struct miel_hvac_softc *sc, const uint8_t *bytes, size_t len) } static void -miel_hvac_send(struct miel_hvac_softc *sc, uint8_t type, - const void *data, size_t len) +miel_hvac_send(struct miel_hvac_softc *sc, uint8_t type, const void *data, size_t len) { TasmotaSerial *serial = sc->sc_serial; struct miel_hvac_header h = { @@ -624,28 +693,24 @@ miel_hvac_send(struct miel_hvac_softc *sc, uint8_t type, char hex_h[(sizeof(h) + 1) * 2]; char hex_d[(len + 1) * 2]; - AddLog(LOG_LEVEL_DEBUG, - PSTR(MIEL_HVAC_LOGNAME ": sending %s %s %02x"), - ToHex_P((uint8_t *)&h, sizeof(h), hex_h, sizeof(hex_h)), - ToHex_P((uint8_t *)data, len, hex_d, sizeof(hex_d)), - miel_hvac_cksum_fini(cksum)); + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": sending %s %s %02x"), ToHex_P((uint8_t *)&h, sizeof(h), hex_h, sizeof(hex_h)), ToHex_P((uint8_t *)data, len, hex_d, sizeof(hex_d)), miel_hvac_cksum_fini(cksum)); serial->write(miel_hvac_cksum_fini(cksum)); serial->flush(); } -#define miel_hvac_send_connect(_sc) \ - miel_hvac_send((_sc), MIEL_HVAC_H_TYPE_CONNECT, \ - miel_hvac_msg_connect, sizeof(miel_hvac_msg_connect)) +#define miel_hvac_send_connect(_sc) \ + miel_hvac_send((_sc), MIEL_HVAC_H_TYPE_CONNECT, \ + miel_hvac_msg_connect, sizeof(miel_hvac_msg_connect)) static const struct miel_hvac_map * -miel_hvac_map_byname(const char *name, - const struct miel_hvac_map *m, size_t n) +miel_hvac_map_byname(const char *name, const struct miel_hvac_map *m, size_t n) { const struct miel_hvac_map *e; size_t i; - for (i = 0; i < n; i++) { + for (i = 0; i < n; i++) + { e = &m[i]; if (strcasecmp(e->name, name) == 0) return (e); @@ -655,13 +720,13 @@ miel_hvac_map_byname(const char *name, } static const char * -miel_hvac_map_byval(uint8_t byte, - const struct miel_hvac_map *m, size_t n) +miel_hvac_map_byval(uint8_t byte, const struct miel_hvac_map *m, size_t n) { const struct miel_hvac_map *e; size_t i; - for (i = 0; i < n; i++) { + for (i = 0; i < n; i++) + { e = &m[i]; if (byte == e->byte) return (e->name); @@ -673,46 +738,40 @@ miel_hvac_map_byval(uint8_t byte, static void miel_hvac_request(struct miel_hvac_softc *sc, uint8_t type) { - struct miel_hvac_msg_request request = { type }; - - miel_hvac_send(sc, MIEL_HVAC_H_TYPE_REQUEST, - &request, sizeof(request)); + struct miel_hvac_msg_request request = {type}; + miel_hvac_send(sc, MIEL_HVAC_H_TYPE_REQUEST, &request, sizeof(request)); } static void -miel_hvac_init_update(struct miel_hvac_msg_update *update) +miel_hvac_init_update_settings(struct miel_hvac_msg_update_settings *update) { memset(update, 0, sizeof(*update)); update->one = 1; } static inline void -miel_hvac_send_update(struct miel_hvac_softc *sc, - const struct miel_hvac_msg_update *update) +miel_hvac_send_update_settings(struct miel_hvac_softc *sc, const struct miel_hvac_msg_update_settings *update) { miel_hvac_send(sc, MIEL_HVAC_H_TYPE_UPDATE, update, sizeof(*update)); } static inline void -miel_hvac_send_remotetemp(struct miel_hvac_softc *sc, - const struct miel_hvac_msg_remotetemp *remotetemp) +miel_hvac_send_update_remotetemp(struct miel_hvac_softc *sc, const struct miel_hvac_msg_update_remotetemp *update) { - miel_hvac_send(sc, MIEL_HVAC_H_TYPE_UPDATE, - remotetemp, sizeof(*remotetemp)); + miel_hvac_send(sc, MIEL_HVAC_H_TYPE_UPDATE, update, sizeof(*update)); } static bool miel_hvac_set_power(struct miel_hvac_softc *sc) { - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; uint16_t source = XdrvMailbox.payload; if (source == SRC_SWITCH) return (false); - update->flags |= htons(MIEL_HVAC_UPDATE_F_POWER); - update->power = (XdrvMailbox.index & (1 << sc->sc_device)) ? - MIEL_HVAC_UPDATE_POWER_ON : MIEL_HVAC_UPDATE_POWER_OFF; + update->flags |= htons(MIEL_HVAC_SETTINGS_F_POWER); + update->power = (XdrvMailbox.index & (1 << sc->sc_device)) ? MIEL_HVAC_SETTINGS_POWER_ON : MIEL_HVAC_SETTINGS_POWER_OFF; return (true); } @@ -727,20 +786,19 @@ static void miel_hvac_cmnd_setfanspeed(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_fan_map, nitems(miel_hvac_fan_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_fan_map, nitems(miel_hvac_fan_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_FAN); + update->flags |= htons(MIEL_HVAC_SETTINGS_F_FAN); update->fan = e->byte; ResponseCmndChar_P(e->name); @@ -750,20 +808,19 @@ static void miel_hvac_cmnd_setmode(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_mode_map, nitems(miel_hvac_mode_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_mode_map, nitems(miel_hvac_mode_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_MODE); + update->flags |= htons(MIEL_HVAC_SETTINGS_F_MODE); update->mode = e->byte; ResponseCmndChar_P(e->name); @@ -773,15 +830,16 @@ static void miel_hvac_cmnd_sethamode(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - if (strcasecmp(XdrvMailbox.data, "off") == 0) { - update->flags |= htons(MIEL_HVAC_UPDATE_F_POWER); - update->power = MIEL_HVAC_UPDATE_POWER_OFF; + if (strcasecmp(XdrvMailbox.data, "off") == 0) + { + update->flags |= htons(MIEL_HVAC_SETTINGS_F_POWER); + update->power = MIEL_HVAC_SETTINGS_POWER_OFF; ResponseCmndChar_P(PSTR("off")); return; } @@ -791,16 +849,14 @@ miel_hvac_cmnd_sethamode(void) * but that would mean power gets turned on even if there's * an invalid argument. */ - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_mode_map, nitems(miel_hvac_mode_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_mode_map, nitems(miel_hvac_mode_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_POWER) | - htons(MIEL_HVAC_UPDATE_F_MODE); - update->power = MIEL_HVAC_UPDATE_POWER_ON; + update->flags |= htons(MIEL_HVAC_SETTINGS_F_POWER) | htons(MIEL_HVAC_SETTINGS_F_MODE); + update->power = MIEL_HVAC_SETTINGS_POWER_ON; update->mode = e->byte; ResponseCmndChar_P(e->name); @@ -810,25 +866,27 @@ static void miel_hvac_cmnd_settemp(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; float degc; if (XdrvMailbox.data_len == 0) return; degc = strtof(XdrvMailbox.data, nullptr); - if (degc < MIEL_HVAC_UPDATE_TEMP_MIN || - degc > MIEL_HVAC_UPDATE_TEMP_MAX) { + if (degc < MIEL_HVAC_SETTINGS_TEMP_MIN || degc > MIEL_HVAC_SETTINGS_TEMP_MAX) + { miel_hvac_respond_unsupported(); return; } - update->flags |= htons(MIEL_HVAC_UPDATE_F_TEMP); - if (!temp_type) { + update->flags |= htons(MIEL_HVAC_SETTINGS_F_TEMP); + if (!temp_type) + { update->temp = miel_hvac_deg2temp(degc); update->temp05 = 0; } - else { + else + { update->temp = 0; update->temp05 = miel_hvac_deg2temp(degc); } @@ -840,20 +898,19 @@ static void miel_hvac_cmnd_setvane(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_vane_map, nitems(miel_hvac_vane_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_vane_map, nitems(miel_hvac_vane_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_VANE); + update->flags |= htons(MIEL_HVAC_SETTINGS_F_VANE); update->vane = e->byte; ResponseCmndChar_P(e->name); @@ -863,20 +920,19 @@ static void miel_hvac_cmnd_setprohibit(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_prohibit_map, nitems(miel_hvac_prohibit_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_prohibit_map, nitems(miel_hvac_prohibit_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_PROHIBIT); + update->flags |= htons(MIEL_HVAC_SETTINGS_F_PROHIBIT); update->prohibit = e->byte; ResponseCmndChar_P(e->name); @@ -886,20 +942,19 @@ static void miel_hvac_cmnd_setwidevane(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_widevane_map, nitems(miel_hvac_widevane_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_widevane_map, nitems(miel_hvac_widevane_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_WIDEVANE); + update->flags |= htons(MIEL_HVAC_SETTINGS_F_WIDEVANE); update->widevane = e->byte; ResponseCmndChar_P(e->name); @@ -909,20 +964,19 @@ static void miel_hvac_cmnd_setairdirection(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_update *update = &sc->sc_update; + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; const struct miel_hvac_map *e; if (XdrvMailbox.data_len == 0) return; - e = miel_hvac_map_byname(XdrvMailbox.data, - miel_hvac_airdirection_map, nitems(miel_hvac_airdirection_map)); - if (e == NULL) { + e = miel_hvac_map_byname(XdrvMailbox.data, miel_hvac_airdirection_map, nitems(miel_hvac_airdirection_map)); + if (e == NULL) + { miel_hvac_respond_unsupported(); return; } - - update->flags |= htons(MIEL_HVAC_UPDATE_F_AIRDIRECTION); + update->flags |= htons(MIEL_HVAC_SETTINGS_F_AIRDIRECTION); update->airdirection = e->byte; ResponseCmndChar_P(e->name); @@ -944,24 +998,22 @@ miel_hvac_remotetemp_degc2old(long degc) else if (degc > MIEL_HVAC_REMOTETEMP_OLD_MAX) degc = MIEL_HVAC_REMOTETEMP_OLD_MIN; - return ((degc - MIEL_HVAC_REMOTETEMP_OLD_MIN) * - MIEL_HVAC_REMOTETEMP_OLD_FACTOR); + return ((degc - MIEL_HVAC_REMOTETEMP_OLD_MIN) * MIEL_HVAC_REMOTETEMP_OLD_FACTOR); } static void -miel_hvac_remotetemp_auto_clear(void) +miel_hvac_remotetemp_auto_clear(void) { - struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_remotetemp *rt = &sc->sc_remotetemp; + struct miel_hvac_softc *sc = miel_hvac_sc; + struct miel_hvac_msg_update_remotetemp *update = &sc->sc_remotetemp_update; uint8_t control = MIEL_HVAC_REMOTETEMP_CLR; long degc = 0; - memset(rt, 0, sizeof(*rt)); - rt->seven = 0x7; - rt->control = control; - rt->temp_old = miel_hvac_remotetemp_degc2old(degc); - rt->temp = (degc + MIEL_HVAC_REMOTETEMP_OFFSET) * MIEL_HVAC_REMOTETEMP_OLD_FACTOR; - + memset(update, 0, sizeof(*update)); + update->seven = 0x7; + update->control = control; + update->temp_old = miel_hvac_remotetemp_degc2old(degc); + update->temp = (degc + MIEL_HVAC_REMOTETEMP_OFFSET) * MIEL_HVAC_REMOTETEMP_OLD_FACTOR; remotetemp_clear = false; } @@ -972,7 +1024,8 @@ miel_hvac_cmnd_remotetemp_auto_clear_time(void) return; unsigned long clear_time = strtoul(XdrvMailbox.data, nullptr, 10); - if (clear_time < 1000 || clear_time > 600000) { + if (clear_time < 1000 || clear_time > 600000) + { miel_hvac_respond_unsupported(); return; } @@ -985,20 +1038,22 @@ static void miel_hvac_cmnd_remotetemp(void) { struct miel_hvac_softc *sc = miel_hvac_sc; - struct miel_hvac_msg_remotetemp *rt = &sc->sc_remotetemp; + struct miel_hvac_msg_update_remotetemp *update = &sc->sc_remotetemp_update; uint8_t control = MIEL_HVAC_REMOTETEMP_SET; long degc; if (XdrvMailbox.data_len == 0) return; - if (strcasecmp(XdrvMailbox.data, "clear") == 0) { + if (strcasecmp(XdrvMailbox.data, "clear") == 0) + { control = MIEL_HVAC_REMOTETEMP_CLR; degc = 0; ResponseCmndChar_P("clear"); - remotetemp_last_call_time = 0; - } else { + } + else + { degc = strtol(XdrvMailbox.data, nullptr, 0); /* clamp the argument to supported values */ @@ -1008,12 +1063,10 @@ miel_hvac_cmnd_remotetemp(void) degc = MIEL_HVAC_REMOTETEMP_MAX; ResponseCmndNumber(degc); - remotetemp_last_call_time = millis(); } - - memset(rt, 0, sizeof(*rt)); - rt->seven = 0x7; - rt->control = control; + memset(update, 0, sizeof(*update)); + update->seven = 0x7; + update->control = control; /* * Different HVACs (or more likely different generations @@ -1022,11 +1075,11 @@ miel_hvac_cmnd_remotetemp(void) * support all known types of HVACs. */ - rt->temp_old = miel_hvac_remotetemp_degc2old(degc); - rt->temp = (degc + MIEL_HVAC_REMOTETEMP_OFFSET) * - MIEL_HVAC_REMOTETEMP_OLD_FACTOR; + update->temp_old = miel_hvac_remotetemp_degc2old(degc); + update->temp = (degc + MIEL_HVAC_REMOTETEMP_OFFSET) * MIEL_HVAC_REMOTETEMP_OLD_FACTOR; - remotetemp_clear = control == MIEL_HVAC_REMOTETEMP_SET ? true : false; + remotetemp_last_call_time = control == MIEL_HVAC_REMOTETEMP_SET ? millis() : 0; + remotetemp_clear = control == MIEL_HVAC_REMOTETEMP_SET ? true : false; } #ifdef MIEL_HVAC_DEBUG @@ -1050,116 +1103,97 @@ miel_hvac_cmnd_request(void) */ static void -miel_hvac_log_bytes(struct miel_hvac_softc *sc, const char *name, - const void *buf, size_t len) +miel_hvac_log_bytes(struct miel_hvac_softc *sc, const char *name, const void *buf, size_t len) { char hex[(MIEL_HVAC_DATABUFLEN + 1) * 2]; const unsigned char *b = (const unsigned char *)buf; - - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": response %s %s"), name, ToHex_P(b, len, hex, sizeof(hex))); + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": response %s %s"), name, ToHex_P(b, len, hex, sizeof(hex))); } static void -miel_hvac_input_connected(struct miel_hvac_softc *sc, - const void *buf, size_t len) +miel_hvac_input_connected(struct miel_hvac_softc *sc, const void *buf, size_t len) { - AddLog(LOG_LEVEL_INFO, - PSTR(MIEL_HVAC_LOGNAME ": connected to Mitsubishi Electric HVAC")); + AddLog(LOG_LEVEL_INFO, PSTR(MIEL_HVAC_LOGNAME ": connected to Mitsubishi Electric HVAC")); sc->sc_connected = 1; } static void miel_hvac_publish_settings(struct miel_hvac_softc *sc) { - const struct miel_hvac_data_settings *set = - &sc->sc_settings.data.settings; + const struct miel_hvac_data_settings *set = &sc->sc_settings.data.settings; char hex[(sizeof(sc->sc_settings) + 1) * 2]; char temp[33]; const char *name; const char *name_swing_h; - name = miel_hvac_map_byval(set->power, - miel_hvac_power_map, nitems(miel_hvac_power_map)); - if (name != NULL) { - Response_P(PSTR("{\"" D_JSON_IRHVAC_POWER "\":\"%s\""), - name); - } + name = miel_hvac_map_byval(set->power, miel_hvac_power_map, nitems(miel_hvac_power_map)); + if (name != NULL) + { + Response_P(PSTR("{\"" D_JSON_IRHVAC_POWER "\":\"%s\""), name); + } - name = miel_hvac_map_byval( set->mode & - MIEL_HVAC_SETTINGS_MODE_MASK, - miel_hvac_mode_map, nitems(miel_hvac_mode_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_MODE "\":\"%s\""), - name); - ResponseAppend_P(PSTR(",\"HA" D_JSON_IRHVAC_MODE "\":\"%s\""), - set->power ? name : "off"); + name = miel_hvac_map_byval(set->mode & MIEL_HVAC_SETTINGS_MODE_MASK, miel_hvac_mode_map, nitems(miel_hvac_mode_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_MODE "\":\"%s\""), name); + ResponseAppend_P(PSTR(",\"HA" D_JSON_IRHVAC_MODE "\":\"%s\""), set->power ? name : "off"); } - if (set->temp05 == 0) { - dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp)), - Settings->flag2.temperature_resolution, temp); + if (set->temp05 == 0) + { + dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp)), Settings->flag2.temperature_resolution, temp); } - else { + else + { temp_type = true; - dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp05)), - Settings->flag2.temperature_resolution, temp); + dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp05)), Settings->flag2.temperature_resolution, temp); } ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_TEMP "\":%s"), temp); - name = miel_hvac_map_byval(set->fan, - miel_hvac_fan_map, nitems(miel_hvac_fan_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_FANSPEED "\":\"%s\""), - name); + name = miel_hvac_map_byval(set->fan, miel_hvac_fan_map, nitems(miel_hvac_fan_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_FANSPEED "\":\"%s\""), name); } - name = miel_hvac_map_byval(set->vane, - miel_hvac_vane_map, nitems(miel_hvac_vane_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_SWINGV "\":\"%s\""), - name); + name = miel_hvac_map_byval(set->vane, miel_hvac_vane_map, nitems(miel_hvac_vane_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_SWINGV "\":\"%s\""), name); } - name_swing_h = miel_hvac_map_byval(set->widevane & - MIEL_HVAC_SETTTINGS_WIDEVANE_MASK, - miel_hvac_widevane_map, nitems(miel_hvac_widevane_map)); - if (name_swing_h != NULL) { - ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_SWINGH "\":\"%s\""), - name_swing_h); + name_swing_h = miel_hvac_map_byval(set->widevane & MIEL_HVAC_SETTINGS_WIDEVANE_MASK, miel_hvac_widevane_map, nitems(miel_hvac_widevane_map)); + if (name_swing_h != NULL) + { + ResponseAppend_P(PSTR(",\"" D_JSON_IRHVAC_SWINGH "\":\"%s\""), name_swing_h); } - name = miel_hvac_map_byval(set->airdirection, - miel_hvac_airdirection_map, nitems(miel_hvac_airdirection_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"AirDirection\":\"%s\""), - name_swing_h == "auto" ? name : "OFF"); + name = miel_hvac_map_byval(set->airdirection, miel_hvac_airdirection_map, nitems(miel_hvac_airdirection_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"AirDirection\":\"%s\""), name_swing_h == "auto" ? name : "OFF"); } - name = miel_hvac_map_byval(set->prohibit, - miel_hvac_prohibit_map, nitems(miel_hvac_prohibit_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"Prohibit\":\"%s\""), - name); + name = miel_hvac_map_byval(set->prohibit, miel_hvac_prohibit_map, nitems(miel_hvac_prohibit_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"Prohibit\":\"%s\""), name); } - ResponseAppend_P(PSTR(",\"Bytes\":\"%s\""), - ToHex_P((uint8_t *)&sc->sc_settings, sizeof(sc->sc_settings), - hex, sizeof(hex))); - + ResponseAppend_P(PSTR(",\"Settings\":\"%s\""), ToHex_P((uint8_t *)&sc->sc_settings, sizeof(sc->sc_settings), hex, sizeof(hex))); ResponseAppend_P(PSTR("}")); MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR("HVACSettings")); } static void -miel_hvac_input_settings(struct miel_hvac_softc *sc, - const struct miel_hvac_data *d) +miel_hvac_input_settings(struct miel_hvac_softc *sc, const struct miel_hvac_data *d) { const struct miel_hvac_data_settings *set = &d->data.settings; uint32_t state = set->power ? 1 : 0; /* see ExecuteCommandPower */ bool publish; - if (miel_hvac_update_pending(sc)) { + if (miel_hvac_update_settings_pending(sc)) + { /* * Don't flop around printing settings that we might be * changing, but also force them to be published again. @@ -1171,8 +1205,7 @@ miel_hvac_input_settings(struct miel_hvac_softc *sc, if (bitRead(TasmotaGlobal.power, sc->sc_device) != !!state) ExecuteCommandPower(sc->sc_device, state, SRC_SWITCH); - publish = (sc->sc_settings_set == 0) || - (memcmp(d, &sc->sc_settings, sizeof(sc->sc_settings)) != 0); + publish = (sc->sc_settings_set == 0) || (memcmp(d, &sc->sc_settings, sizeof(sc->sc_settings)) != 0); sc->sc_settings_set = 1; sc->sc_settings = *d; @@ -1181,52 +1214,47 @@ miel_hvac_input_settings(struct miel_hvac_softc *sc, } static void -miel_hvac_data_response(struct miel_hvac_softc *sc, - const struct miel_hvac_data *d) +miel_hvac_data_response(struct miel_hvac_softc *sc, const struct miel_hvac_data *d) { char hex[(sizeof(*d) + 1) * 2]; - - Response_P(PSTR("{\"Bytes\":\"%s\"}"), - ToHex_P((uint8_t *)d, sizeof(*d), hex, sizeof(hex))); - + Response_P(PSTR("{\"Bytes\":\"%s\"}"), ToHex_P((uint8_t *)d, sizeof(*d), hex, sizeof(hex))); MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR("HVACData")); } static void -miel_hvac_input_sensor(struct miel_hvac_softc *sc, struct miel_hvac_data *dst, - const struct miel_hvac_data *src) +miel_hvac_input_sensor(struct miel_hvac_softc *sc, struct miel_hvac_data *dst, const struct miel_hvac_data *src) { bool publish; - publish = (memcmp(dst, src, sizeof(*dst)) != 0); *dst = *src; if (publish) MqttPublishSensor(); - } static void -miel_hvac_input_data(struct miel_hvac_softc *sc, - const void *buf, size_t len) +miel_hvac_input_data(struct miel_hvac_softc *sc, const void *buf, size_t len) { const struct miel_hvac_data *d; miel_hvac_log_bytes(sc, "data", buf, len); - if (len < sizeof(*d)) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": short data response (%zu < %zu)"), len, sizeof(*d)); + if (len < sizeof(*d)) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": short data response (%zu < %zu)"), len, sizeof(*d)); return; } - d = (const struct miel_hvac_data *)buf; - switch (d->type) { + switch (d->type) + { case MIEL_HVAC_DATA_T_SETTINGS: miel_hvac_input_settings(sc, d); break; case MIEL_HVAC_DATA_T_ROOMTEMP: - miel_hvac_input_sensor(sc, &sc->sc_temp, d); + miel_hvac_input_sensor(sc, &sc->sc_roomtemp, d); + break; + case MIEL_HVAC_DATA_T_TIMERS: + miel_hvac_input_sensor(sc, &sc->sc_timers, d); break; case MIEL_HVAC_DATA_T_STATUS: miel_hvac_input_sensor(sc, &sc->sc_status, d); @@ -1241,8 +1269,7 @@ miel_hvac_input_data(struct miel_hvac_softc *sc, } static void -miel_hvac_input_updated(struct miel_hvac_softc *sc, - const void *buf, size_t len) +miel_hvac_input_updated(struct miel_hvac_softc *sc, const void *buf, size_t len) { miel_hvac_log_bytes(sc, "updated", buf, len); } @@ -1261,35 +1288,36 @@ miel_hvac_pre_init(void) return; sc = (struct miel_hvac_softc *)malloc(sizeof(*sc)); - if (sc == NULL) { - AddLog(LOG_LEVEL_ERROR, - PSTR(MIEL_HVAC_LOGNAME ": unable to allocate state")); + if (sc == NULL) + { + AddLog(LOG_LEVEL_ERROR, PSTR(MIEL_HVAC_LOGNAME ": unable to allocate state")); return; } memset(sc, 0, sizeof(*sc)); - miel_hvac_init_update(&sc->sc_update); + miel_hvac_init_update_settings(&sc->sc_settings_update); - sc->sc_serial = new TasmotaSerial(Pin(GPIO_MIEL_HVAC_RX), - Pin(GPIO_MIEL_HVAC_TX), 2); - - if (!sc->sc_serial->begin(baudrate, SERIAL_8E1)) { + sc->sc_serial = new TasmotaSerial(Pin(GPIO_MIEL_HVAC_RX), Pin(GPIO_MIEL_HVAC_TX), 2); + if (!sc->sc_serial->begin(baudrate, SERIAL_8E1)) + { AddLog(LOG_LEVEL_ERROR, - PSTR(MIEL_HVAC_LOGNAME ": unable to begin serial " - "(baudrate %d)"), baudrate); + PSTR(MIEL_HVAC_LOGNAME ": unable to begin serial " + "(baudrate %d)"), + baudrate); goto del; } - if (sc->sc_serial->hardwareSerial()) { + if (sc->sc_serial->hardwareSerial()) + { ClaimSerial(); SetSerial(baudrate, TS_SERIAL_8E1); } #ifdef ESP32 - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": Serial UART%d"), sc->sc_serial->getUart()); + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": Serial UART%d"), sc->sc_serial->getUart()); #endif sc->sc_device = TasmotaGlobal.devices_present; - UpdateDevicesPresent(1); /* claim a POWER device slot */ + UpdateDevicesPresent(1); /* claim a POWER device slot */ miel_hvac_sc = sc; return; @@ -1304,9 +1332,9 @@ miel_hvac_loop(struct miel_hvac_softc *sc) { TasmotaSerial *serial = sc->sc_serial; - while (serial->available()) { + while (serial->available()) + { yield(); - sc->sc_parser.p_state = miel_hvac_parse(sc, serial->read()); } } @@ -1314,163 +1342,199 @@ miel_hvac_loop(struct miel_hvac_softc *sc) static void miel_hvac_sensor(struct miel_hvac_softc *sc) { - const struct miel_hvac_data_settings *set = - &sc->sc_settings.data.settings; - char hex[(sizeof(sc->sc_settings) + 1) * 2]; - char temp[33]; const char *name; + const char *mode; const char *name_swing_h; - ResponseAppend_P(PSTR("," "\"MiElHVAC\":{")); + ResponseAppend_P(PSTR(",\"MiElHVAC\":{")); - name = miel_hvac_map_byval(set->power, - miel_hvac_power_map, nitems(miel_hvac_power_map)); - if (name != NULL) { - ResponseAppend_P(PSTR("\"Power\":\"%s\""), - name); + if (sc->sc_settings.type != 0) + { + const struct miel_hvac_data_settings *set = &sc->sc_settings.data.settings; + char hex[(sizeof(sc->sc_settings) + 1) * 2]; + char temp[33]; + + name = miel_hvac_map_byval(set->power, miel_hvac_power_map, nitems(miel_hvac_power_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR("\"Power\":\"%s\""), name); + } + + mode = miel_hvac_map_byval(set->mode & MIEL_HVAC_SETTINGS_MODE_MASK, miel_hvac_mode_map, nitems(miel_hvac_mode_map)); + if (mode != NULL) + { + ResponseAppend_P(PSTR(",\"Mode\":\"%s\""), mode); + } + + if (set->temp05 == 0) + { + dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp)), Settings->flag2.temperature_resolution, temp); + } + else + { + temp_type = true; + dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp05)), Settings->flag2.temperature_resolution, temp); + } + ResponseAppend_P(PSTR(",\"SetTemperature\":\"%s\""), temp); + + name = miel_hvac_map_byval(set->fan, miel_hvac_fan_map, nitems(miel_hvac_fan_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"FanSpeed\":\"%s\""), name); + } + + name = miel_hvac_map_byval(set->vane, miel_hvac_vane_map, nitems(miel_hvac_vane_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"SwingV\":\"%s\""), name); + } + + name_swing_h = miel_hvac_map_byval(set->widevane & MIEL_HVAC_SETTINGS_WIDEVANE_MASK, miel_hvac_widevane_map, nitems(miel_hvac_widevane_map)); + if (name_swing_h != NULL) + { + ResponseAppend_P(PSTR(",\"SwingH\":\"%s\""), name_swing_h); + } + + name = miel_hvac_map_byval(set->airdirection, miel_hvac_airdirection_map, nitems(miel_hvac_airdirection_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"AirDirection\":\"%s\""), name_swing_h == "auto" ? name : "off"); + } + + name = miel_hvac_map_byval(set->prohibit, miel_hvac_prohibit_map, nitems(miel_hvac_prohibit_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"Prohibit\":\"%s\""), name); + } + + ResponseAppend_P(PSTR(",\"Settings\":\"%s\""), ToHex_P((uint8_t *)&sc->sc_settings, sizeof(sc->sc_settings), hex, sizeof(hex))); } - name = miel_hvac_map_byval( set->mode & - MIEL_HVAC_SETTINGS_MODE_MASK, - miel_hvac_mode_map, nitems(miel_hvac_mode_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"Mode\":\"%s\""), - name); - } - if (set->temp05 == 0) { - dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp)), - Settings->flag2.temperature_resolution, temp); - } - else { - temp_type = true; - dtostrfd(ConvertTemp(miel_hvac_temp2deg(set->temp05)), - Settings->flag2.temperature_resolution, temp); - } - ResponseAppend_P(PSTR(",\"SetTemperature\":\"%s\""), temp); - - name = miel_hvac_map_byval(set->fan, - miel_hvac_fan_map, nitems(miel_hvac_fan_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"FanSpeed\":\"%s\""), - name); - } - - name = miel_hvac_map_byval(set->vane, - miel_hvac_vane_map, nitems(miel_hvac_vane_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"SwingV\":\"%s\""), - name); - } - - name_swing_h = miel_hvac_map_byval(set->widevane & - MIEL_HVAC_SETTTINGS_WIDEVANE_MASK, - miel_hvac_widevane_map, nitems(miel_hvac_widevane_map)); - if (name_swing_h != NULL) { - ResponseAppend_P(PSTR(",\"SwingH\":\"%s\""), - name_swing_h); - } - - name = miel_hvac_map_byval(set->airdirection, - miel_hvac_airdirection_map, nitems(miel_hvac_airdirection_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"AirDirection\":\"%s\""), - name_swing_h == "auto" ? name : "off"); - } - - name = miel_hvac_map_byval(set->prohibit, - miel_hvac_prohibit_map, nitems(miel_hvac_prohibit_map)); - if (name != NULL) { - ResponseAppend_P(PSTR(",\"Prohibit\":\"%s\""), - name); - } - - ResponseAppend_P(PSTR(",\"Bytes\":\"%s\""), - ToHex_P((uint8_t *)&sc->sc_settings, sizeof(sc->sc_settings), - hex, sizeof(hex))); - - if (sc->sc_temp.type != 0) { - const struct miel_hvac_data_roomtemp *rt = - &sc->sc_temp.data.roomtemp; + if (sc->sc_roomtemp.type != 0) + { + const struct miel_hvac_data_roomtemp *rt = &sc->sc_roomtemp.data.roomtemp; + char hex[(sizeof(sc->sc_roomtemp) + 1) * 2]; char room_temp[33]; - if(rt->temp05 == 0) { + if (rt->temp05 == 0) + { unsigned int temp = miel_hvac_roomtemp2deg(rt->temp); - dtostrfd(ConvertTemp(temp), - Settings->flag2.temperature_resolution, room_temp); - } - else { + dtostrfd(ConvertTemp(temp), Settings->flag2.temperature_resolution, room_temp); + } + else + { temp_type = true; float temp = miel_hvac_roomtemp2deg(rt->temp05); - dtostrfd(ConvertTemp(temp), - Settings->flag2.temperature_resolution, room_temp); + dtostrfd(ConvertTemp(temp), Settings->flag2.temperature_resolution, room_temp); } - ResponseAppend_P(PSTR(",\"Temperature\":\"%s\""), - room_temp); + ResponseAppend_P(PSTR(",\"Temperature\":\"%s\""), room_temp); + ResponseAppend_P(PSTR(",\"RemoteTemperatureSensorState\":\"%s\""), remotetemp_clear ? "on" : "off"); - ResponseAppend_P(PSTR(",\"RemoteTemperatureSensorState\":\"%s\""), - remotetemp_clear ? "ON" : "OFF"); + char remotetempautocleartime[33]; + ultoa(remotetemp_auto_clear_time, remotetempautocleartime, 10); + ResponseAppend_P(PSTR(",\"RemoteTemperatureSensorAutoClearTime\":\"%s\""), remotetempautocleartime); - char remotetempautocleartime[33]; - ultoa(remotetemp_auto_clear_time, remotetempautocleartime, 10); - ResponseAppend_P(PSTR(",\"RemoteTemperatureSensorAutoClearTime\":\"%s\""), - remotetempautocleartime); - - if(rt->outdoortemp > 1) { - char outdoor_temp[33]; - float temp = miel_hvac_outdoortemp2deg(rt->outdoortemp); - dtostrfd(ConvertTemp(temp), 1, outdoor_temp); - ResponseAppend_P(PSTR(",\"OutdoorTemperature\":\"%s\""), - outdoor_temp); + if (rt->outdoortemp > 1) + { + char outdoor_temp[33]; + float temp = miel_hvac_outdoortemp2deg(rt->outdoortemp); + dtostrfd(ConvertTemp(temp), 1, outdoor_temp); + ResponseAppend_P(PSTR(",\"OutdoorTemperature\":\"%s\""), outdoor_temp); } uint32_t combined_time = ((uint32_t)rt->operationtime << 16) | ((uint32_t)rt->operationtime1 << 8) | (uint32_t)rt->operationtime2; float operationtime_in_min = (float)combined_time; - char operationtime[33]; - dtostrf(operationtime_in_min, 1, 0, operationtime); - ResponseAppend_P(PSTR(",\"OperationTime\":\"%s\""), - operationtime); + char operationtime[33]; + dtostrf(operationtime_in_min, 1, 0, operationtime); + ResponseAppend_P(PSTR(",\"OperationTime\":\"%s\""), operationtime); - ResponseAppend_P(PSTR(",\"RoomTemp\":\"%s\""), - ToHex_P((uint8_t *)&sc->sc_temp, sizeof(sc->sc_temp), - hex, sizeof(hex))); + ResponseAppend_P(PSTR(",\"RoomTemp\":\"%s\""), ToHex_P((uint8_t *)&sc->sc_roomtemp, sizeof(sc->sc_roomtemp), hex, sizeof(hex))); } - if (sc->sc_status.type != 0) { - const struct miel_hvac_data_status *status = - &sc->sc_status.data.status; + if (sc->sc_timers.type != 0) + { + const struct miel_hvac_data_timers *timer = &sc->sc_timers.data.timers; + char hex[(sizeof(sc->sc_timers) + 1) * 2]; - name = miel_hvac_map_byval(status->compressor, - miel_hvac_compressor_map, nitems(miel_hvac_compressor_map)); - ResponseAppend_P(PSTR(",\"Compressor\":\"%s\""), - name != NULL ? name : "N/A"); + name = miel_hvac_map_byval(timer->mode, miel_hvac_timer_mode_map, nitems(miel_hvac_timer_mode_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"TimerMode\":\"%s\""), name); + + unsigned int on_timer = timer->onminutes * 10; + char timeron[33]; + utoa(on_timer, timeron, 10); + ResponseAppend_P(PSTR(",\"TimerOn\":\"%s\""), timeron); + + unsigned int timer_on_remaining = timer->onminutesremaining * 10; + char timeronremaining[33]; + utoa(timer_on_remaining, timeronremaining, 10); + ResponseAppend_P(PSTR(",\"TimerOnRemaining\":\"%s\""), timeronremaining); + + unsigned int off_timer = timer->offminutes * 10; + char timeroff[33]; + utoa(off_timer, timeroff, 10); + ResponseAppend_P(PSTR(",\"TimerOff\":\"%s\""), timeroff); + + unsigned int timer_off_remaining = timer->offminutesremaining * 10; + char timeroffremaining[33]; + utoa(timer_off_remaining, timeroffremaining, 10); + ResponseAppend_P(PSTR(",\"TimerOffRemaining\":\"%s\""), timeroffremaining); + } + + ResponseAppend_P(PSTR(",\"Timers\":\"%s\""), ToHex_P((uint8_t *)&sc->sc_timers, sizeof(sc->sc_timers), hex, sizeof(hex))); + } + + if (sc->sc_status.type != 0) + { + const struct miel_hvac_data_status *status = &sc->sc_status.data.status; + char hex[(sizeof(sc->sc_status) + 1) * 2]; + + name = miel_hvac_map_byval(status->compressor, miel_hvac_compressor_map, nitems(miel_hvac_compressor_map)); + ResponseAppend_P(PSTR(",\"Compressor\":\"%s\""), name != NULL ? name : "N/A"); unsigned int compressor_frequency = status->compressorfrequency; - char compressorfrequency[33]; - utoa(compressor_frequency, compressorfrequency, 10); - ResponseAppend_P(PSTR(",\"CompressorFrequency\":\"%s\""), - compressorfrequency); + char compressorfrequency[33]; + utoa(compressor_frequency, compressorfrequency, 10); + ResponseAppend_P(PSTR(",\"CompressorFrequency\":\"%s\""), compressorfrequency); - uint16_t combined_power = ((uint16_t)status->operationpower << 8) | (uint16_t)status->operationpower1; - char operationpower[33]; - dtostrfd((float)combined_power, 0, operationpower); - ResponseAppend_P(PSTR(",\"OperationPower\":\"%s\""), - operationpower); + uint16_t combined_power = ((uint16_t)status->operationpower << 8) | (uint16_t)status->operationpower1; + char operationpower[33]; + dtostrfd((float)combined_power, 0, operationpower); + ResponseAppend_P(PSTR(",\"OperationPower\":\"%s\""), operationpower); uint16_t combined_energy = ((uint16_t)status->operationenergy << 8) | (uint16_t)status->operationenergy1; float operationenergy_in_kWh = (float)combined_energy / 10.0; - char operationenergy[33]; - dtostrfd((float)operationenergy_in_kWh, 1, operationenergy); - ResponseAppend_P(PSTR(",\"OperationEnergy\":\"%s\""), - operationenergy); + char operationenergy[33]; + dtostrfd((float)operationenergy_in_kWh, 1, operationenergy); + ResponseAppend_P(PSTR(",\"OperationEnergy\":\"%s\""), operationenergy); - ResponseAppend_P(PSTR(",\"Status\":\"%s\""), - ToHex_P((uint8_t *)&sc->sc_status, sizeof(sc->sc_status), - hex, sizeof(hex))); + ResponseAppend_P(PSTR(",\"Status\":\"%s\""), ToHex_P((uint8_t *)&sc->sc_status, sizeof(sc->sc_status), hex, sizeof(hex))); } - if (sc->sc_stage.type != 0) { - ResponseAppend_P(PSTR(",\"Stage\":\"%s\""), - ToHex_P((uint8_t *)&sc->sc_stage, sizeof(sc->sc_stage), - hex, sizeof(hex))); + if (sc->sc_stage.type != 0) + { + const struct miel_hvac_data_stage *stage = &sc->sc_stage.data.stage; + char hex[(sizeof(sc->sc_stage) + 1) * 2]; + + name = miel_hvac_map_byval(stage->prerun, miel_hvac_stage_prerun_map, nitems(miel_hvac_stage_prerun_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"PrerunStage\":\"%s\""), name); + } + + name = miel_hvac_map_byval(stage->fan, miel_hvac_stage_fan_map, nitems(miel_hvac_stage_fan_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"FanStage\":\"%s\""), name); + } + + name = miel_hvac_map_byval(stage->mode, miel_hvac_stage_mode_map, nitems(miel_hvac_stage_mode_map)); + if (name != NULL) + { + ResponseAppend_P(PSTR(",\"ModeStage\":\"%s\""), name == "manual" ? mode : name); + } + + ResponseAppend_P(PSTR(",\"Stage\":\"%s\""), ToHex_P((uint8_t *)&sc->sc_stage, sizeof(sc->sc_stage), hex, sizeof(hex))); } ResponseAppend_P(PSTR("}")); @@ -1484,12 +1548,12 @@ miel_hvac_sensor(struct miel_hvac_softc *sc) * and published. Posting new settings preempts queries for information. */ -enum miel_hvac_connect_states { +enum miel_hvac_connect_states +{ MIEL_HVAC_CONNECT_S_2400_MSG, MIEL_HVAC_CONNECT_S_9600, MIEL_HVAC_CONNECT_S_9600_MSG, MIEL_HVAC_CONNECT_S_2400, - MIEL_HVAC_CONNECT_S_COUNT, }; @@ -1501,8 +1565,8 @@ miel_hvac_connect(struct miel_hvac_softc *sc) unsigned int state; state = (sc->sc_tick++ % MIEL_HVAC_CONNECT_S_COUNT); - - switch (state) { + switch (state) + { case MIEL_HVAC_CONNECT_S_2400: baudrate = 2400; break; @@ -1527,7 +1591,8 @@ miel_hvac_tick(struct miel_hvac_softc *sc) MIEL_HVAC_REQUEST_STATUS, MIEL_HVAC_REQUEST_SETTINGS, MIEL_HVAC_REQUEST_ROOMTEMP, - + MIEL_HVAC_REQUEST_SETTINGS, + MIEL_HVAC_REQUEST_TIMERS, MIEL_HVAC_REQUEST_SETTINGS, /* MUZ-GA80VA doesnt respond :( */ MIEL_HVAC_REQUEST_STAGE, @@ -1536,40 +1601,42 @@ miel_hvac_tick(struct miel_hvac_softc *sc) struct miel_hvac_parser *p = &sc->sc_parser; unsigned int i; - if (p->p_state != MIEL_HVAC_P_START) { - if (p->p_tmo) { - AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME - ": read timeout")); + if (p->p_state != MIEL_HVAC_P_START) + { + if (p->p_tmo) + { + AddLog(LOG_LEVEL_DEBUG, PSTR(MIEL_HVAC_LOGNAME ": read timeout")); sc->sc_parser.p_state = MIEL_HVAC_P_START; - } else { + } + else + { p->p_tmo = 1; return; } } - if (miel_hvac_update_pending(sc)) { - struct miel_hvac_msg_update *update = &sc->sc_update; + if (miel_hvac_update_settings_pending(sc)) + { + struct miel_hvac_msg_update_settings *update = &sc->sc_settings_update; - miel_hvac_send_update(sc, update); - - miel_hvac_init_update(update); + miel_hvac_send_update_settings(sc, update); + miel_hvac_init_update_settings(update); /* refresh settings on next tick */ sc->sc_tick = 0; return; } - if (sc->sc_remotetemp.seven) { - struct miel_hvac_msg_remotetemp *remotetemp = - &sc->sc_remotetemp; + if (sc->sc_remotetemp_update.seven) + { + struct miel_hvac_msg_update_remotetemp *remotetemp = &sc->sc_remotetemp_update; - miel_hvac_send_remotetemp(sc, remotetemp); + miel_hvac_send_update_remotetemp(sc, remotetemp); memset(remotetemp, 0, sizeof(*remotetemp)); return; } i = (sc->sc_tick++ % nitems(updates)); - miel_hvac_request(sc, updates[i]); } @@ -1590,7 +1657,8 @@ static const char miel_hvac_cmnd_names[] PROGMEM = "|" D_CMND_MIEL_HVAC_REMOTETEMP "|" D_CMND_MIEL_HVAC_REMOTETEMP_AUTO_CLEAR_TIME #ifdef MIEL_HVAC_DEBUG - "|" "HVACRequest" + "|" + "HVACRequest" #endif ; @@ -1610,11 +1678,13 @@ static void (*const miel_hvac_cmnds[])(void) PROGMEM = { #endif }; -bool Xdrv44(uint32_t function) { +bool Xdrv44(uint32_t function) +{ bool result = false; struct miel_hvac_softc *sc = miel_hvac_sc; - switch (function) { + switch (function) + { case FUNC_PRE_INIT: miel_hvac_pre_init(); return (false); @@ -1623,31 +1693,29 @@ bool Xdrv44(uint32_t function) { if (sc == NULL) return (false); - switch (function) { + switch (function) + { case FUNC_LOOP: miel_hvac_loop(sc); break; - case FUNC_SET_DEVICE_POWER: result = miel_hvac_set_power(sc); break; - case FUNC_EVERY_250_MSECOND: if (sc->sc_connected) miel_hvac_tick(sc); else miel_hvac_connect(sc); break; - case FUNC_EVERY_50_MSECOND: case FUNC_EVERY_100_MSECOND: case FUNC_EVERY_200_MSECOND: case FUNC_EVERY_SECOND: - if (remotetemp_clear && ((millis() - remotetemp_last_call_time) > remotetemp_auto_clear_time || remotetemp_last_call_time == 0)) { - miel_hvac_remotetemp_auto_clear(); - } + if (remotetemp_clear && ((millis() - remotetemp_last_call_time) > remotetemp_auto_clear_time || remotetemp_last_call_time == 0)) + { + miel_hvac_remotetemp_auto_clear(); + } break; - case FUNC_JSON_APPEND: miel_hvac_sensor(sc); break; @@ -1655,17 +1723,14 @@ bool Xdrv44(uint32_t function) { if (sc->sc_settings_set) miel_hvac_publish_settings(sc); break; - case FUNC_COMMAND: result = DecodeCommand(miel_hvac_cmnd_names, miel_hvac_cmnds); break; - - case FUNC_ACTIVE: - result = true; - break; + case FUNC_ACTIVE: + result = true; + break; } - return (result); } -#endif // USE_MIEL_HVAC +#endif // USE_MIEL_HVAC