From e71f27c464d1ffccb6006ed55fa7fc65a1be855c Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Wed, 20 Jan 2021 19:26:16 +0100 Subject: [PATCH 01/19] Fix faulty allocation --- tasmota/xsns_83_neopool.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/xsns_83_neopool.ino b/tasmota/xsns_83_neopool.ino index c0902699c..e8cdbd7e3 100644 --- a/tasmota/xsns_83_neopool.ino +++ b/tasmota/xsns_83_neopool.ino @@ -751,7 +751,7 @@ uint8_t NeoPoolWriteRegister(uint16_t addr, uint16_t *data, uint16_t cnt) neopool_poll = false; numbytes = 7+cnt*2; - frame = (uint8_t*)malloc(numbytes); + frame = (uint8_t*)malloc(numbytes+2); if (nullptr == frame) { #ifdef DEBUG_TASMOTA_SENSOR AddLog_P(LOG_LEVEL_DEBUG, PSTR("NEO: addr 0x%04X write out of memory"), addr); @@ -778,10 +778,10 @@ uint8_t NeoPoolWriteRegister(uint16_t addr, uint16_t *data, uint16_t cnt) NeoPoolModbus->flush(); NeoPoolModbus->write(frame, numbytes+2); - free(frame); timeoutMS = millis() + 1 * NEOPOOL_READ_TIMEOUT; // Max delay before we timeout while (!(data_ready = NeoPoolModbus->ReceiveReady()) && millis() < timeoutMS) { delay(1); } + free(frame); if (data_ready) { uint8_t buffer[9]; uint8_t error = NeoPoolModbus->ReceiveBuffer(buffer, 1); @@ -799,7 +799,7 @@ uint8_t NeoPoolWriteRegister(uint16_t addr, uint16_t *data, uint16_t cnt) } } neopool_poll = true; - // delay(2); + delay(2); return NEOPOOL_OK; } #ifdef DEBUG_TASMOTA_SENSOR From b4d02c00b3c07139853cecdaff9b7aab9e41d34b Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Thu, 21 Jan 2021 09:13:17 +0100 Subject: [PATCH 02/19] Fix cmnd examples --- tasmota/xsns_83_neopool.ino | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tasmota/xsns_83_neopool.ino b/tasmota/xsns_83_neopool.ino index e8cdbd7e3..d63211fdb 100644 --- a/tasmota/xsns_83_neopool.ino +++ b/tasmota/xsns_83_neopool.ino @@ -1085,7 +1085,7 @@ void NeoPoolShow(bool json) * * Read filtration status (manual mode = 1) MBF_PAR_FILT_MANUAL_STATE * Sensor83 1 0x413 - * RESULT = {"Sensor83":{"cmnd":1,"Address":"0x0413","Data":{"Base10":1,"Base16":"0x0001"}}} + * RESULT = {"Sensor83":{"Command":1,"Address":"0x0413","Data":0}} * * Read Heating setpoint temperature MBF_PAR_HEATING_TEMP * Sensor83 1 0x416 @@ -1093,17 +1093,18 @@ void NeoPoolShow(bool json) * * Read system time MBF_PAR_TIME_* using hex output * Sensor83 16 0x408,2 - * RESULT = {"Sensor83":{"cmnd":16,"Address":"0x0408","Data":["0x9293","0x6005"]}} + * RESULT = {"Sensor83":{"Command":1,"Address":"0x0416","Data":28}} * * Enable temperature module by setting MBF_PAR_TEMPERATURE_ACTIVE - * Sensor83 2 0x40F,1 - * RESULT = {"Sensor83":{"Address":"0x040F","Data":{"Base10":1,"Base16":"0x0001"}}} + * Sensor83 3 0x40F,1 + * RESULT = {"Sensor83":{"Command":3,"Address":"0x040F","Data":[1]}} * and set it permanent by using a write to MBF_SAVE_TO_EEPROM (0x02F0) - * Sensor83 2 0x2F0,1 - * RESULT = {"Sensor83":{"Address":"0x02F0","Data":{"Base10":1,"Base16":"0x0001"}}} + * Sensor83 3 0x2F0,1 + * RESULT = {"Sensor83":{"Command":3,"Address":"0x2F0","Data":[1]}} * * Hide auxiliary relay display from main menu by setting bit 3 of MBF_PAR_UICFG_VISUAL_OPTIONS - * Sensor83 3 0x0605,3,1 + * Sensor83 2 0x0605,3,1 + * RESULT = {"Sensor83":{"Command":2,"Address":"0x0605","Bit":3,"Data":1}} * *********************************************************************************************/ #define NEOPOOL_CMND_READ_REG 1 From ab22a9e0e5e3f2e420ef975914f677354db97940 Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Thu, 21 Jan 2021 09:14:34 +0100 Subject: [PATCH 03/19] Change write/readwrite bit cmnds --- tasmota/xsns_83_neopool.ino | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tasmota/xsns_83_neopool.ino b/tasmota/xsns_83_neopool.ino index d63211fdb..06a8d256e 100644 --- a/tasmota/xsns_83_neopool.ino +++ b/tasmota/xsns_83_neopool.ino @@ -1096,20 +1096,20 @@ void NeoPoolShow(bool json) * RESULT = {"Sensor83":{"Command":1,"Address":"0x0416","Data":28}} * * Enable temperature module by setting MBF_PAR_TEMPERATURE_ACTIVE - * Sensor83 3 0x40F,1 + * Sensor83 2 0x40F,1 * RESULT = {"Sensor83":{"Command":3,"Address":"0x040F","Data":[1]}} * and set it permanent by using a write to MBF_SAVE_TO_EEPROM (0x02F0) - * Sensor83 3 0x2F0,1 + * Sensor83 2 0x2F0,1 * RESULT = {"Sensor83":{"Command":3,"Address":"0x2F0","Data":[1]}} * * Hide auxiliary relay display from main menu by setting bit 3 of MBF_PAR_UICFG_VISUAL_OPTIONS - * Sensor83 2 0x0605,3,1 + * Sensor83 3 0x0605,3,1 * RESULT = {"Sensor83":{"Command":2,"Address":"0x0605","Bit":3,"Data":1}} * *********************************************************************************************/ #define NEOPOOL_CMND_READ_REG 1 -#define NEOPOOL_CMND_READWRITE_BIT 2 -#define NEOPOOL_CMND_WRITE_REG 3 +#define NEOPOOL_CMND_WRITE_REG 2 +#define NEOPOOL_CMND_READWRITE_BIT 3 #define NEOPOOL_CMND_FILTRATION 4 #define NEOPOOL_CMND_FILTRATION_MODE 5 #define NEOPOOL_CMND_TIME 6 From 52d42512ee15b5736e463a234d6fdc1b52dc522c Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Thu, 21 Jan 2021 09:34:35 +0100 Subject: [PATCH 04/19] Optimze time cmnd --- tasmota/xsns_83_neopool.ino | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/tasmota/xsns_83_neopool.ino b/tasmota/xsns_83_neopool.ino index 06a8d256e..811d75878 100644 --- a/tasmota/xsns_83_neopool.ino +++ b/tasmota/xsns_83_neopool.ino @@ -1228,7 +1228,6 @@ bool NeoPoolCmnd(void) { char dt[20]; TIME_T tmpTime; - uint16_t t_low, t_high; if (1 == params_cnt) { uint32_t new_time = Rtc.local_time; @@ -1238,31 +1237,28 @@ bool NeoPoolCmnd(void) if (value[1]>1) { new_time = value[1]; } - t_low = (uint16_t)(new_time & 0xFFFF); - t_high = (uint16_t)((new_time>>16) & 0xFFFF); + data[0] = (uint16_t)(new_time & 0xFFFF); + data[1] = (uint16_t)((new_time>>16) & 0xFFFF); #ifdef DEBUG_TASMOTA_SENSOR - AddLog_P(LOG_LEVEL_DEBUG, PSTR("NEO: set time to %ld (%04X%04X)"), new_time, t_low, t_high); + AddLog_P(LOG_LEVEL_DEBUG, PSTR("NEO: set time to %ld (%04X%04X)"), new_time, data[0], data[1]); #endif // DEBUG_TASMOTA_SENSOR - serviced = (NEOPOOL_OK == NeoPoolWriteRegister(MBF_PAR_TIME_HIGH, &t_high, 1)); - if (serviced) { - serviced = (NEOPOOL_OK == NeoPoolWriteRegister(MBF_PAR_TIME_LOW, &t_low, 1)); - } + serviced = (NEOPOOL_OK == NeoPoolWriteRegister(MBF_PAR_TIME_LOW, data, 2)); if (serviced) { uint16_t set=0; serviced = (NEOPOOL_OK == NeoPoolWriteRegister(MBF_ACTION_COPY_TO_RTC, &set, 1)); } } else if (0 == params_cnt) { - serviced = (NEOPOOL_OK == NeoPoolReadRegister(MBF_PAR_TIME_LOW, &t_low, 1) && NEOPOOL_OK == NeoPoolReadRegister(MBF_PAR_TIME_HIGH, &t_high, 1)); + serviced = (NEOPOOL_OK == NeoPoolReadRegister(MBF_PAR_TIME_LOW, data, 2)); #ifdef DEBUG_TASMOTA_SENSOR - AddLog_P(LOG_LEVEL_DEBUG, PSTR("NEO: time read 0x%04X%04X %ld"), t_high, t_low, (uint32_t)t_low + ((uint32_t)t_high << 16)); + AddLog_P(LOG_LEVEL_DEBUG, PSTR("NEO: time read 0x%04X%04X %ld"), data[1], data[0], (uint32_t)data[0] + ((uint32_t)data[1] << 16)); #endif // DEBUG_TASMOTA_SENSOR } else { serviced = false; } if (serviced) { - BreakTime((uint32_t)t_low + ((uint32_t)t_high << 16), tmpTime); + BreakTime((uint32_t)data[0] + ((uint32_t)data[1] << 16), tmpTime); snprintf_P(dt, sizeof(dt), PSTR("%04d" D_YEAR_MONTH_SEPARATOR "%02d" D_MONTH_DAY_SEPARATOR "%02d" D_DATE_TIME_SEPARATOR "%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), tmpTime.year +1970, tmpTime.month, tmpTime.day_of_month, tmpTime.hour, tmpTime.minute, tmpTime.second); Response_P(PSTR("{\"" D_CMND_SENSOR "%d\":{\"" D_JSON_TIME "\":\"%s\"}}"), XSNS_83, dt); From a17eca7e473704433e65d174fd450565faa43fc4 Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Thu, 21 Jan 2021 10:34:49 +0100 Subject: [PATCH 05/19] Fix bit write cmnd --- tasmota/xsns_83_neopool.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xsns_83_neopool.ino b/tasmota/xsns_83_neopool.ino index 811d75878..72a293700 100644 --- a/tasmota/xsns_83_neopool.ino +++ b/tasmota/xsns_83_neopool.ino @@ -1178,7 +1178,7 @@ bool NeoPoolCmnd(void) data[0] = (data[0] >> bit) & 0x0001; } if (3 == params_cnt) { - if (NEOPOOL_OK != NeoPoolReadRegister(addr, &tempdata, 1)) { + if (NEOPOOL_OK == NeoPoolReadRegister(addr, &tempdata, 1)) { tempdata &= ~(1< Date: Thu, 21 Jan 2021 13:48:54 +0100 Subject: [PATCH 06/19] Add read/write 32bit cmnds --- tasmota/xsns_83_neopool.ino | 107 ++++++++++++++++++++++++++++-------- 1 file changed, 83 insertions(+), 24 deletions(-) diff --git a/tasmota/xsns_83_neopool.ino b/tasmota/xsns_83_neopool.ino index 72a293700..1a4d3ff09 100644 --- a/tasmota/xsns_83_neopool.ino +++ b/tasmota/xsns_83_neopool.ino @@ -163,18 +163,18 @@ enum NeoPoolRegister { MBF_PAR_RELAY_MODE, // 0x0432 Behavior of the system when the dosing time is exceeded (see MBMSK_PAR_RELAY_MODE_* and MBV_PAR_RELAY_MODE_*) MBF_PAR_RELAY_ACTIVATION_DELAY, // 0x0433 Delay time in seconds for the pH pump when the measured pH value is outside the allowable pH setpoints. The system internally adds an extra time of 10 seconds to the value stored here. The pump starts the dosing operation once the condition of pH out of valid interval is maintained during the time specified in this register. MBF_PAR_TIMER_BLOCK_BASE, // 0x0434 This block of 180 registers holds the configuration of the system timers. The system has a set of 12 fully configurable timers, each one assigned to a specific function, described below: - MBF_PAR_TIMER_BLOCK_FILT_INT1=0x0434,//0x0434 Filtration interval 1 (15 register - see PAR_TIMER_BLOCK_OFF* for desc) - MBF_PAR_TIMER_BLOCK_FILT_INT2=0x0443,//0x0443 Filtration interval 2 (15 register - see PAR_TIMER_BLOCK_OFF* for desc) - MBF_PAR_TIMER_BLOCK_FILT_INT3=0x0452,//0x0452 Filtration interval 3 (15 register - see PAR_TIMER_BLOCK_OFF* for desc) - MBF_PAR_TIMER_BLOCK_AUX1_INT2=0x0461,//0x0461 Auxiliary relay 1 - 2. interval (15 register - see PAR_TIMER_BLOCK_OFF* for desc) - MBF_PAR_TIMER_BLOCK_LIGHT_INT=0x0470,//0x0470 Lighting interval (15 register - see PAR_TIMER_BLOCK_OFF* for desc) - MBF_PAR_TIMER_BLOCK_AUX2_INT2=0x047F,//0x047F Auxiliary relay 2 - 2. interval (15 register - see PAR_TIMER_BLOCK_OFF* for desc) - MBF_PAR_TIMER_BLOCK_AUX3_INT2=0x048E,//0x048E Auxiliary relay 3 - 2. interval (15 register - see PAR_TIMER_BLOCK_OFF* for desc) - MBF_PAR_TIMER_BLOCK_AUX4_INT2=0x049D,//0x049D Auxiliary relay 4 - 2. interval (15 register - see PAR_TIMER_BLOCK_OFF* for desc) - MBF_PAR_TIMER_BLOCK_AUX1_INT1=0x04AC,//0x04AC Auxiliary relay 1 - 1. interval (15 register - see PAR_TIMER_BLOCK_OFF* for desc) - MBF_PAR_TIMER_BLOCK_AUX2_INT1=0x04BB,//0x04BB Auxiliary relay 2 - 1. interval (15 register - see PAR_TIMER_BLOCK_OFF* for desc) - MBF_PAR_TIMER_BLOCK_AUX3_INT1=0x04CA,//0x04CA Auxiliary relay 3 - 1. interval (15 register - see PAR_TIMER_BLOCK_OFF* for desc) - MBF_PAR_TIMER_BLOCK_AUX4_INT1=0x04D9,//0x04D9 Auxiliary relay 4 - 1. interval (15 register - see PAR_TIMER_BLOCK_OFF* for desc) + MBF_PAR_TIMER_BLOCK_FILT_INT1=0x0434,//0x0434 Filtration interval 1 (15 register - see MBV_TIMER_OFFMB_* for desc) + MBF_PAR_TIMER_BLOCK_FILT_INT2=0x0443,//0x0443 Filtration interval 2 (15 register - see MBV_TIMER_OFFMB_* for desc) + MBF_PAR_TIMER_BLOCK_FILT_INT3=0x0452,//0x0452 Filtration interval 3 (15 register - see MBV_TIMER_OFFMB_* for desc) + MBF_PAR_TIMER_BLOCK_AUX1_INT2=0x0461,//0x0461 Auxiliary relay 1 - 2. interval (15 register - see MBV_TIMER_OFFMB_* for desc) + MBF_PAR_TIMER_BLOCK_LIGHT_INT=0x0470,//0x0470 Lighting interval (15 register - see MBV_TIMER_OFFMB_* for desc) + MBF_PAR_TIMER_BLOCK_AUX2_INT2=0x047F,//0x047F Auxiliary relay 2 - 2. interval (15 register - see MBV_TIMER_OFFMB_* for desc) + MBF_PAR_TIMER_BLOCK_AUX3_INT2=0x048E,//0x048E Auxiliary relay 3 - 2. interval (15 register - see MBV_TIMER_OFFMB_* for desc) + MBF_PAR_TIMER_BLOCK_AUX4_INT2=0x049D,//0x049D Auxiliary relay 4 - 2. interval (15 register - see MBV_TIMER_OFFMB_* for desc) + MBF_PAR_TIMER_BLOCK_AUX1_INT1=0x04AC,//0x04AC Auxiliary relay 1 - 1. interval (15 register - see MBV_TIMER_OFFMB_* for desc) + MBF_PAR_TIMER_BLOCK_AUX2_INT1=0x04BB,//0x04BB Auxiliary relay 2 - 1. interval (15 register - see MBV_TIMER_OFFMB_* for desc) + MBF_PAR_TIMER_BLOCK_AUX3_INT1=0x04CA,//0x04CA Auxiliary relay 3 - 1. interval (15 register - see MBV_TIMER_OFFMB_* for desc) + MBF_PAR_TIMER_BLOCK_AUX4_INT1=0x04D9,//0x04D9 Auxiliary relay 4 - 1. interval (15 register - see MBV_TIMER_OFFMB_* for desc) MBF_PAR_FILTVALVE_ENABLE=0x04E8, // 0x04E8 Filter cleaning functionality mode (0=off, 1=Besgo) MBF_PAR_FILTVALVE_MODE, // 0x04E9 Filter cleaning valve timing mode, possible modes: MBV_PAR_CTIMER_ENABLED, MBV_PAR_CTIMER_ALWAYS_ON, MBV_PAR_CTIMER_ALWAYS_OFF MBF_PAR_FILTVALVE_GPIO, // 0x04EA Relay associated with the filter cleaning function. default AUX2 (value 5) @@ -423,7 +423,7 @@ enum NeoPoolConstAndBitMask { MBV_TIMER_OFFMB_TIMER_PERIOD = 5, // Time in seconds between starting points (32-bit, LSB first), e.g. 86400 means daily MBV_TIMER_OFFMB_TIMER_INTERVAL = 7, // Time in seconds that the timer has to run when started (32-bit, LSB first) MBV_TIMER_OFFMB_TIMER_COUNTDOWN = 9, // Time remaining in seconds for the countdown mode (32-bit, LSB first) - MBV_TIMER_OFFMB_TIMER_FUNCTION = 11, // Function assigned to this timer, see + MBV_TIMER_OFFMB_TIMER_FUNCTION = 11, // Function assigned to this timer, see MBV_PAR_CTIMER_FCT_* MBV_TIMER_OFFMB_TIMER_WORK_TIME = 13, // Number of seconds that the timer has been operating // MBV_TIMER_OFFMB_TIMER_ENABLE working modes: MBV_PAR_CTIMER_DISABLE = 0, // Timer disabled @@ -708,6 +708,9 @@ uint8_t NeoPoolReadRegister(uint16_t addr, uint16_t *data, uint16_t cnt) neopool_poll = false; *data = 0; +#ifdef DEBUG_TASMOTA_SENSOR + AddLog_P(LOG_LEVEL_DEBUG, PSTR("NEO: NeoPoolReadRegister(0x%04X, %p, %d)"), addr, data, cnt); +#endif // DEBUG_TASMOTA_SENSOR NeoPoolModbus->Send(NEOPOOL_MODBUS_ADDRESS, NEOPOOL_READ_REGISTER, addr, cnt); timeoutMS = millis() + cnt * NEOPOOL_READ_TIMEOUT; // Max delay before we timeout while (!(data_ready = NeoPoolModbus->ReceiveReady()) && millis() < timeoutMS) { delay(1); } @@ -749,6 +752,9 @@ uint8_t NeoPoolWriteRegister(uint16_t addr, uint16_t *data, uint16_t cnt) bool data_ready; uint32_t timeoutMS; +#ifdef DEBUG_TASMOTA_SENSOR + AddLog_P(LOG_LEVEL_DEBUG, PSTR("NEO: NeoPoolWriteRegister(0x%04X, %p, %d)"), addr, data, cnt); +#endif // DEBUG_TASMOTA_SENSOR neopool_poll = false; numbytes = 7+cnt*2; frame = (uint8_t*)malloc(numbytes+2); @@ -1055,13 +1061,13 @@ void NeoPoolShow(bool json) * Sensor83 1 () * read 16-bit register (cnt=1..30, cnt=1 if omitted) * - * Sensor83 2 () + * Sensor83 2 (...) + * write 16-bit register (data=0..65535, max 8 times) + * + * Sensor83 3 () * read/write register bit (bit=0..15, data=0|1) * read if param is omitted otherwise set to new * - * Sensor83 3 (...) - * write 16-bit register (data=0..65535, max 8 times) - * * Sensor83 4 () * get/set manual filtration (state=0|1) * get filtration state if param is omitted otherwise set new state @@ -1080,6 +1086,16 @@ void NeoPoolShow(bool json) * Sensor83 16 () * same as "Sensor83 1" but using hex data output * + * Sensor83 21 () + * read 32-bit register (cnt=1..15, cnt=1 if omitted) + * + * Sensor83 22 (...) + * write 32-bit register (data=0..0xffffffff, max 8 times) + * + * Sensor83 26 () + * same as "Sensor83 21" but using hex data output + * + * * * Examples: * @@ -1106,6 +1122,19 @@ void NeoPoolShow(bool json) * Sensor83 3 0x0605,3,1 * RESULT = {"Sensor83":{"Command":2,"Address":"0x0605","Bit":3,"Data":1}} * + * Read Filtration interval 1-3 settings + * Backlog Sensor83 1 0x434;Sensor83 21 0x435 7;Sensor83 1 0x0443;Sensor83 21 0x0444 7;Sensor83 1 0x0452;Sensor83 21 0x0453 7 + * RESULT = {"Sensor83":{"Command":1,"Address":"0x0434","Data":1}} + * RESULT = {"Sensor83":{"Command":21,"Address":"0x0435","Data":[28800,0,86400,14400,0,1,0]}} + * RESULT = {"Sensor83":{"Command":1,"Address":"0x0443","Data":1}} + * RESULT = {"Sensor83":{"Command":21,"Address":"0x0444","Data":[43200,0,86400,21600,0,1,0]}} + * RESULT = {"Sensor83":{"Command":1,"Address":"0x0452","Data":1}} + * RESULT = {"Sensor83":{"Command":21,"Address":"0x0453","Data":[0,0,86400,0,0,1,0]}} + * + * Set Filtration interval 1 to daily 9:00 - 12:30 (9:00: 3600 * 9 ≙ 32400 / 12:30 ≙ 3,5h = 12600) + * Sensor83 22 0x435 32400 0 86400 12600 + * RESULT = {"Sensor83":{"Command":22,"Address":"0x0435","Data":[32400,0,86400,12600]}} + * *********************************************************************************************/ #define NEOPOOL_CMND_READ_REG 1 #define NEOPOOL_CMND_WRITE_REG 2 @@ -1114,6 +1143,9 @@ void NeoPoolShow(bool json) #define NEOPOOL_CMND_FILTRATION_MODE 5 #define NEOPOOL_CMND_TIME 6 #define NEOPOOL_CMND_READ_REG_HEX 16 +#define NEOPOOL_CMND_READ_REG32 21 +#define NEOPOOL_CMND_WRITE_REG32 22 +#define NEOPOOL_CMND_READ_REG_HEX32 26 bool NeoPoolCmnd(void) { @@ -1121,6 +1153,7 @@ bool NeoPoolCmnd(void) char sub_string[XdrvMailbox.data_len +1]; uint16_t cmnd, addr, data[30], cnt=1; int8_t bit; + bool bits32 = false; uint32_t value[10] = { 0 }; uint32_t params_cnt = ParseParameters(ARRAY_SIZE(value), value); @@ -1133,34 +1166,44 @@ bool NeoPoolCmnd(void) params_cnt--; cmnd = value[0]; + bits32 = (NEOPOOL_CMND_READ_REG32 == cmnd || NEOPOOL_CMND_WRITE_REG32 == cmnd || NEOPOOL_CMND_READ_REG_HEX32 == cmnd); switch (cmnd) { case NEOPOOL_CMND_READ_REG: // () case NEOPOOL_CMND_READ_REG_HEX: + case NEOPOOL_CMND_READ_REG_HEX32: + case NEOPOOL_CMND_READ_REG32: { addr = value[1]; cnt = 1; if (2 == params_cnt) { cnt = value[2]; } - if (cnt > ARRAY_SIZE(data)) { + if (cnt > (bits32 ? (ARRAY_SIZE(data)/2) : ARRAY_SIZE(data))) { serviced = false; } else { - serviced = (NEOPOOL_OK == NeoPoolReadRegister(addr, data, cnt)); + serviced = (NEOPOOL_OK == NeoPoolReadRegister(addr, data, bits32 ? (cnt*2) : cnt)); } } break; case NEOPOOL_CMND_WRITE_REG: // (...) + case NEOPOOL_CMND_WRITE_REG32: { addr = value[1]; if (params_cnt >= 2) { cnt = params_cnt-1; for(uint32_t i=0; i>16; // MSB + } + else { + data[i] = value[i+2]; + } } - serviced = (NEOPOOL_OK == NeoPoolWriteRegister(addr, data, cnt)); + serviced = (NEOPOOL_OK == NeoPoolWriteRegister(addr, data, bits32 ? (cnt*2) : cnt)); } } break; @@ -1265,6 +1308,10 @@ bool NeoPoolCmnd(void) } } break; + + default: + AddLog_P(LOG_LEVEL_DEBUG, PSTR("NEO: Unknown " D_CMND_SENSOR "%d cmnd %d"), XSNS_83, cmnd); + break; } } @@ -1278,17 +1325,29 @@ bool NeoPoolCmnd(void) default: { Response_P(PSTR("{\"" D_CMND_SENSOR "%d\":{\"" D_JSON_COMMAND "\":%d,\"" D_JSON_ADDRESS "\":\"0x%04X\",\"" D_JSON_DATA"\":"), XSNS_83, cmnd, addr); - if ( cnt>1 || params_cnt>1 ) { + if ( cnt > 1 ) { char sdel[2] = {0}; ResponseAppend_P(PSTR("[")); for(uint32_t i=0; i Date: Fri, 22 Jan 2021 09:49:35 +0100 Subject: [PATCH 07/19] Add inverted alarms --- tasmota/xsns_83_neopool.ino | 56 ++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/tasmota/xsns_83_neopool.ino b/tasmota/xsns_83_neopool.ino index 1a4d3ff09..cfbb892f2 100644 --- a/tasmota/xsns_83_neopool.ino +++ b/tasmota/xsns_83_neopool.ino @@ -558,7 +558,7 @@ const char kNeoPoolpHAlarms[] PROGMEM = #define D_STR_BIT "Bit" #endif // D_STR_BIT -const char HTTP_SNS_NEOPOOL_PH[] PROGMEM = "{s}%s " D_PH "{m}%s " "%s%s" "{e}"; +const char HTTP_SNS_NEOPOOL_PH[] PROGMEM = "{s}%s " D_PH "{m}%s " " %s " "{e}"; const char HTTP_SNS_NEOPOOL_TIME[] PROGMEM = "{s}%s " D_NEOPOOL_TIME "{m}%s" "{e}"; const char HTTP_SNS_NEOPOOL_PPM_REDOX[] PROGMEM = "{s}%s " D_NEOPOOL_REDOX "{m}%s " D_UNIT_PARTS_PER_MILLION "{e}"; const char HTTP_SNS_NEOPOOL_PPM_CHLORINE[] PROGMEM = "{s}%s " D_NEOPOOL_CHLORINE "{m}%s " D_UNIT_PARTS_PER_MILLION "{e}"; @@ -839,12 +839,20 @@ uint32_t NeoPoolGetSpeedIndex(uint16_t speedvalue) return 0; } +char *NeoPoolGetInverse(char *scss, size_t size) +{ + char scolor[10]; + GetTextIndexed(scolor, sizeof(scolor), COL_BACKGROUND, kWebColors); + snprintf_P(scss, size, PSTR(" style=\"background-color:%s;filter:invert(1);\""),scolor); + return scss; +} + void NeoPoolShow(bool json) { char parameter[FLOATSZ]; char *neopool_type; - char stemp[128]; - char smachine[32]; + char stemp[160]; + char smachine[60]; if (neopool_error) { return; @@ -951,12 +959,13 @@ void NeoPoolShow(bool json) // pH if (NeoPoolGetData(MBF_PH_STATUS) & MBMSK_PH_STATUS_MEASURE_ACTIVE) { + char scss[60]; dtostrfd((float)NeoPoolGetData(MBF_MEASURE_PH)/100, 2, parameter); *stemp = 0; if ((NeoPoolGetData(MBF_PH_STATUS) & MBMSK_PH_STATUS_ALARM) >=1 && (NeoPoolGetData(MBF_PH_STATUS) & MBMSK_PH_STATUS_ALARM) <= 3) { GetTextIndexed(stemp, sizeof(stemp), NeoPoolGetData(MBF_PH_STATUS) & MBMSK_PH_STATUS_ALARM, kNeoPoolpHAlarms); } - WSContentSend_PD(HTTP_SNS_NEOPOOL_PH, neopool_type, parameter, *stemp ? PSTR(" " D_NEOPOOL_ALARM) : PSTR(""), stemp); + WSContentSend_PD(HTTP_SNS_NEOPOOL_PH, neopool_type, parameter, *stemp ? NeoPoolGetInverse(scss, sizeof(scss)) : PSTR(""), stemp); } // Redox @@ -995,18 +1004,19 @@ void NeoPoolShow(bool json) //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("NEO: MBF_PAR_MODEL 0x%04X MBF_HIDRO_STATUS 0x%04X"), NeoPoolGetData(MBF_PAR_MODEL), NeoPoolGetData(MBF_HIDRO_STATUS)); #endif // DEBUG_TASMOTA_SENSOR if ((NeoPoolGetData(MBF_PAR_MODEL) & MBMSK_MODEL_HIDRO) && (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_MODULE_ACTIVE)) { - dtostrfd((float)NeoPoolGetData(MBF_HIDRO_CURRENT), 1, parameter); char spol[32]; + char scss[60]; + dtostrfd((float)NeoPoolGetData(MBF_HIDRO_CURRENT), 1, parameter); sprintf_P(spol,PSTR(" " D_NEOPOOL_POLARIZATION "%d"),NeoPoolGetData(MBF_HIDRO_STATUS)>>13); - sprintf_P(stemp, PSTR("%s%s%s%s%s%s%s%s"), + sprintf_P(stemp, PSTR("%s%s%s%s %s%s%s"), NeoPoolGetData(MBF_HIDRO_STATUS)>>13?spol:PSTR(""), - NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_ON_TARGET ? PSTR(" " D_NEOPOOL_SETPOINT_OK) : PSTR(""), - NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_COVER ? PSTR(" " D_NEOPOOL_COVER) : PSTR(""), - NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_SHOCK_ENABLED ? PSTR(" " D_NEOPOOL_SHOCK) : PSTR(""), - (NeoPoolGetData(MBF_HIDRO_STATUS) ^(MBMSK_HIDRO_STATUS_FL1|MBMSK_HIDRO_STATUS_FL2)) & (MBMSK_HIDRO_STATUS_LOW|MBMSK_HIDRO_STATUS_FL1|MBMSK_HIDRO_STATUS_FL2) ? PSTR(" " D_NEOPOOL_ALARM) : PSTR(""), - NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_LOW ? PSTR(" " D_NEOPOOL_LOW) : PSTR(""), - !(NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_FL1) ? PSTR(" " D_NEOPOOL_FLOW1) : PSTR(""), - !(NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_FL2) ? PSTR(" " D_NEOPOOL_FLOW2) : PSTR("") + NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_ON_TARGET ? PSTR(" " D_NEOPOOL_SETPOINT_OK " ") : PSTR(""), + NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_COVER ? PSTR(" " D_NEOPOOL_COVER " ") : PSTR(""), + NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_SHOCK_ENABLED ? PSTR(" " D_NEOPOOL_SHOCK " ") : PSTR(""), + (NeoPoolGetData(MBF_HIDRO_STATUS) ^(MBMSK_HIDRO_STATUS_FL1|MBMSK_HIDRO_STATUS_FL2)) & (MBMSK_HIDRO_STATUS_LOW|MBMSK_HIDRO_STATUS_FL1|MBMSK_HIDRO_STATUS_FL2) ? NeoPoolGetInverse(scss, sizeof(scss)) : PSTR(""), + NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_LOW ? PSTR(" " D_NEOPOOL_LOW " ") : PSTR(""), + !(NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_FL1) ? PSTR(" " D_NEOPOOL_FLOW1 " ") : PSTR(""), + !(NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_FL2) ? PSTR(" " D_NEOPOOL_FLOW2 " ") : PSTR("") ); WSContentSend_PD(HTTP_SNS_NEOPOOL_HYDROLYSIS, neopool_type, parameter, *stemp ? PSTR("/") : PSTR(""), stemp); } @@ -1058,41 +1068,41 @@ void NeoPoolShow(bool json) /*********************************************************************************************\ * Supported commands for Sensor83: * - * Sensor83 1 () + * Sensor83 1 {} * read 16-bit register (cnt=1..30, cnt=1 if omitted) * - * Sensor83 2 (...) + * Sensor83 2 {...} * write 16-bit register (data=0..65535, max 8 times) * - * Sensor83 3 () + * Sensor83 3 {} * read/write register bit (bit=0..15, data=0|1) * read if param is omitted otherwise set to new * - * Sensor83 4 () + * Sensor83 4 {} * get/set manual filtration (state=0|1) * get filtration state if param is omitted otherwise set new state * - * Sensor83 5 () + * Sensor83 5 {} * get/set filtration mode (mode=0..4|13) * get mode if param is omitted otherwise set new mode * - * Sensor83 6 (