Neopool enhancements for HA (#19857)

* Add NeoPool hydrolysis setpoint and max

* Add NeoPool command ``NPFiltrationSpeed``

* Change NeoPool topic ``Power`` to ``Powerunit``

* Add ``SO157`` for NeoPool output sensitive data
This commit is contained in:
Norbert Richter 2023-10-28 14:07:49 +02:00 committed by GitHub
parent 75ec9da8a2
commit b65f32c5f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 14 deletions

View File

@ -16,8 +16,12 @@ All notable changes to this project will be documented in this file.
- Command ``GpioRead`` to show input state (#19810) - Command ``GpioRead`` to show input state (#19810)
- ESP32 core v3 auto TasConsole USB or Serial connection by @staars - ESP32 core v3 auto TasConsole USB or Serial connection by @staars
- Support for Winsen XH03x dust particle sensors using USE_PMS5003 and PMS_MODEL_ZH03X (#19850) - Support for Winsen XH03x dust particle sensors using USE_PMS5003 and PMS_MODEL_ZH03X (#19850)
- NeoPool hydrolysis setpoint and max
- NeoPool command ``NPFiltrationSpeed`` to set non-standard filtration type speed
- NeoPool ``SetOption157`` to output sensitive data
### Breaking Changed ### Breaking Changed
- NeoPool SENSOR topic ``Power`` renamed to ``Powerunit``
### Changed ### Changed
- Prepare I2C drivers for bus2 support - Prepare I2C drivers for bus2 support

View File

@ -190,7 +190,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t berry_light_scheme : 1; // bit 8 (v12.5.0.3) - SetOption154 - (Berry) Handle berry led using RMT0 as additional WS2812 scheme uint32_t berry_light_scheme : 1; // bit 8 (v12.5.0.3) - SetOption154 - (Berry) Handle berry led using RMT0 as additional WS2812 scheme
uint32_t zcfallingedge : 1; // bit 9 (v13.0.0.1) - SetOption155 - (ZCDimmer) Enable rare falling Edge dimmer instead of leading edge uint32_t zcfallingedge : 1; // bit 9 (v13.0.0.1) - SetOption155 - (ZCDimmer) Enable rare falling Edge dimmer instead of leading edge
uint32_t sen5x_passive_mode : 1; // bit 10 (v13.1.0.1) - SetOption156 - (Sen5x) Run in passive mode when there is another I2C master (e.g. Ikea Vindstyrka), i.e. do not set up Sen5x sensor, higher polling interval uint32_t sen5x_passive_mode : 1; // bit 10 (v13.1.0.1) - SetOption156 - (Sen5x) Run in passive mode when there is another I2C master (e.g. Ikea Vindstyrka), i.e. do not set up Sen5x sensor, higher polling interval
uint32_t spare11 : 1; // bit 11 uint32_t neopool_outputsensitive : 1; // bit 11 (v13.2.0.1) - SetOption157 - (NeoPool) Output sensitive data (1)
uint32_t spare12 : 1; // bit 12 uint32_t spare12 : 1; // bit 12
uint32_t spare13 : 1; // bit 13 uint32_t spare13 : 1; // bit 13
uint32_t spare14 : 1; // bit 14 uint32_t spare14 : 1; // bit 14

View File

@ -662,6 +662,7 @@ NeoPoolResMBitfield neopool_resolution {
#define D_NEOPOOL_JSON_FILTRATION_INTELLIGENT "Intelligent" #define D_NEOPOOL_JSON_FILTRATION_INTELLIGENT "Intelligent"
#define D_NEOPOOL_JSON_FILTRATION_BACKWASH "Backwash" #define D_NEOPOOL_JSON_FILTRATION_BACKWASH "Backwash"
#define D_NEOPOOL_JSON_MODULES "Modules" #define D_NEOPOOL_JSON_MODULES "Modules"
#define D_NEOPOOL_JSON_POWERUNIT "Powerunit"
#define D_NEOPOOL_JSON_CHLORINE "Chlorine" #define D_NEOPOOL_JSON_CHLORINE "Chlorine"
#define D_NEOPOOL_JSON_CONDUCTIVITY "Conductivity" #define D_NEOPOOL_JSON_CONDUCTIVITY "Conductivity"
#define D_NEOPOOL_JSON_FILTRATION "Filtration" #define D_NEOPOOL_JSON_FILTRATION "Filtration"
@ -806,6 +807,14 @@ const char HTTP_SNS_NEOPOOL_STATUS_ACTIVE[] PROGMEM = "filter:invert(1)";
* 4 - Intelligent * 4 - Intelligent
* 13 - Backwash * 13 - Backwash
* *
* NPFiltrationSpeed {<speed>}
* (only available for non-standard filtration types)
* get/set manual filtration speed (speed = 1..3)
* get filtration speed if <speed> is omitted, otherwise set new speed
* 1 - low
* 2 - mid
* 3 - high
*
* NPTime {<time>} * NPTime {<time>}
* get/set system time * get/set system time
* get current time if <time> is omitted, otherwise set time according: * get current time if <time> is omitted, otherwise set time according:
@ -974,6 +983,7 @@ const char HTTP_SNS_NEOPOOL_STATUS_ACTIVE[] PROGMEM = "filter:invert(1)";
#define D_CMND_NP_BITL "BitL" #define D_CMND_NP_BITL "BitL"
#define D_CMND_NP_FILTRATION "Filtration" #define D_CMND_NP_FILTRATION "Filtration"
#define D_CMND_NP_FILTRATIONMODE "Filtrationmode" #define D_CMND_NP_FILTRATIONMODE "Filtrationmode"
#define D_CMND_NP_FILTRATIONSPEED "Filtrationspeed"
#define D_CMND_NP_TIME "Time" #define D_CMND_NP_TIME "Time"
#define D_CMND_NP_LIGHT "Light" #define D_CMND_NP_LIGHT "Light"
#define D_CMND_NP_PHMIN "pHMin" #define D_CMND_NP_PHMIN "pHMin"
@ -1002,6 +1012,7 @@ const char kNPCommands[] PROGMEM = D_PRFX_NEOPOOL "|" // Prefix
D_CMND_NP_BITL "|" D_CMND_NP_BITL "|"
D_CMND_NP_FILTRATION "|" D_CMND_NP_FILTRATION "|"
D_CMND_NP_FILTRATIONMODE "|" D_CMND_NP_FILTRATIONMODE "|"
D_CMND_NP_FILTRATIONSPEED "|"
D_CMND_NP_TIME "|" D_CMND_NP_TIME "|"
D_CMND_NP_LIGHT "|" D_CMND_NP_LIGHT "|"
D_CMND_NP_PHMIN "|" D_CMND_NP_PHMIN "|"
@ -1031,6 +1042,7 @@ void (* const NPCommand[])(void) PROGMEM = {
&CmndNeopoolBit, &CmndNeopoolBit,
&CmndNeopoolFiltration, &CmndNeopoolFiltration,
&CmndNeopoolFiltrationMode, &CmndNeopoolFiltrationMode,
&CmndNeopoolFiltrationSpeed,
&CmndNeopoolTime, &CmndNeopoolTime,
&CmndNeopoolLight, &CmndNeopoolLight,
&CmndNeopoolpHMin, &CmndNeopoolpHMin,
@ -1527,7 +1539,7 @@ void NeoPoolShow(bool json)
float f12volt = (float)NeoPoolGetData(MBF_VOLT_12)/1000; float f12volt = (float)NeoPoolGetData(MBF_VOLT_12)/1000;
float f24_36volt = (float)NeoPoolGetData(MBF_VOLT_24_36)/1000; float f24_36volt = (float)NeoPoolGetData(MBF_VOLT_24_36)/1000;
float f420mA = (float)NeoPoolGetData(MBF_AMP_4_20_MICRO)/100; float f420mA = (float)NeoPoolGetData(MBF_AMP_4_20_MICRO)/100;
ResponseAppend_P(PSTR(",\"" D_JSON_POWERUSAGE "\":{")); ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_POWERUNIT "\":{"));
if (neopool_power_module_version || if (neopool_power_module_version ||
NEOPOOL_MODBUS_OK == NeoPoolReadRegister(MBF_POWER_MODULE_VERSION, &neopool_power_module_version, 1)) { NEOPOOL_MODBUS_OK == NeoPoolReadRegister(MBF_POWER_MODULE_VERSION, &neopool_power_module_version, 1)) {
ResponseAppend_P(PSTR("\"" D_JSON_VERSION "\":\"V%d.%d\","), ResponseAppend_P(PSTR("\"" D_JSON_VERSION "\":\"V%d.%d\","),
@ -1537,14 +1549,21 @@ void NeoPoolShow(bool json)
} }
if (neopool_power_module_nodeid[0] || if (neopool_power_module_nodeid[0] ||
NEOPOOL_MODBUS_OK == NeoPoolReadRegister(MBF_POWER_MODULE_NODEID, neopool_power_module_nodeid, nitems(neopool_power_module_nodeid))) { NEOPOOL_MODBUS_OK == NeoPoolReadRegister(MBF_POWER_MODULE_NODEID, neopool_power_module_nodeid, nitems(neopool_power_module_nodeid))) {
ResponseAppend_P(PSTR("\"" D_NEOPOOL_JSON_NODE_ID "\":\"%04X %04X %04X %04X %04X %04X\","), if (Settings->flag6.neopool_outputsensitive) {
neopool_power_module_nodeid[0], ResponseAppend_P(PSTR("\"" D_NEOPOOL_JSON_NODE_ID "\":\"%04X %04X %04X %04X %04X %04X\","),
neopool_power_module_nodeid[1], neopool_power_module_nodeid[0],
neopool_power_module_nodeid[2], neopool_power_module_nodeid[1],
neopool_power_module_nodeid[3], neopool_power_module_nodeid[2],
neopool_power_module_nodeid[4], neopool_power_module_nodeid[3],
neopool_power_module_nodeid[5] neopool_power_module_nodeid[4],
); neopool_power_module_nodeid[5]
);
}
else {
ResponseAppend_P(PSTR("\"" D_NEOPOOL_JSON_NODE_ID "\":\"XXXX XXXX XXXX XXXX XXXX %04X\","),
neopool_power_module_nodeid[5]
);
}
} }
ResponseAppend_P(PSTR("\"5V\":%*_f,\"12V\":%*_f,\"24-30V\":%*_f,\"4-20mA\":%*_f}"), ResponseAppend_P(PSTR("\"5V\":%*_f,\"12V\":%*_f,\"24-30V\":%*_f,\"4-20mA\":%*_f}"),
Settings->flag2.voltage_resolution, &f5volt, Settings->flag2.voltage_resolution, &f5volt,
@ -1629,9 +1648,14 @@ void NeoPoolShow(bool json)
sunit = PSTR(D_NEOPOOL_UNIT_GPERH); sunit = PSTR(D_NEOPOOL_UNIT_GPERH);
int dec = 1; int dec = 1;
} }
ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_HYDROLYSIS "\":{"));
fvalue = (float)NeoPoolGetData(MBF_HIDRO_CURRENT)/10; fvalue = (float)NeoPoolGetData(MBF_HIDRO_CURRENT)/10;
ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_HYDROLYSIS "\":{\"" D_JSON_DATA "\":" NEOPOOL_FMT_HIDRO), dec, &fvalue); ResponseAppend_P(PSTR( "\"" D_JSON_DATA "\":" NEOPOOL_FMT_HIDRO), dec, &fvalue);
ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_UNIT "\":\"%s\""), sunit); ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_UNIT "\":\"%s\""), sunit);
fvalue = (float)NeoPoolGetData(MBF_PAR_HIDRO)/10;
ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_SETPOINT "\":" NEOPOOL_FMT_HIDRO), dec, &fvalue);
fvalue = (float)NeoPoolGetData(MBF_PAR_HIDRO_NOM)/10;
ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_MAX "\":" NEOPOOL_FMT_HIDRO), dec, &fvalue);
ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_CELL_RUNTIME "\":{")); ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_CELL_RUNTIME "\":{"));
ResponseAppend_P(PSTR( "\"" D_NEOPOOL_JSON_CELL_RUNTIME_TOTAL "\":\"%s\""), GetDuration(NeoPoolGetDataLong(MBF_CELL_RUNTIME_LOW)).c_str()); ResponseAppend_P(PSTR( "\"" D_NEOPOOL_JSON_CELL_RUNTIME_TOTAL "\":\"%s\""), GetDuration(NeoPoolGetDataLong(MBF_CELL_RUNTIME_LOW)).c_str());
@ -1760,7 +1784,14 @@ void NeoPoolShow(bool json)
} }
fvalue = (float)NeoPoolGetData(MBF_HIDRO_CURRENT)/10; fvalue = (float)NeoPoolGetData(MBF_HIDRO_CURRENT)/10;
WSContentSend_PD(HTTP_SNS_NEOPOOL_HYDROLYSIS, neopool_type, dec, &fvalue, sunit); WSContentSend_PD(HTTP_SNS_NEOPOOL_HYDROLYSIS, neopool_type, dec, &fvalue, sunit);
// S1 // S1
float fhidromax = (float)NeoPoolGetData(MBF_PAR_HIDRO)/10;
ext_snprintf_P(stemp, sizeof(stemp), PSTR(NEOPOOL_FMT_HIDRO " %s"), dec, &fhidromax, sunit);
WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_INACTIVE, stemp);
WSContentSend_PD(PSTR(" "));
// S2
if (0 == (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_MODULE_ACTIVE)) { if (0 == (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_MODULE_ACTIVE)) {
WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_NORMAL, PSTR(D_NEOPOOL_STATUS_OFF)); WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_NORMAL, PSTR(D_NEOPOOL_STATUS_OFF));
} else if (0 == (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_FL1)) { } else if (0 == (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_FL1)) {
@ -1773,14 +1804,14 @@ void NeoPoolShow(bool json)
WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_NORMAL, PSTR(D_NEOPOOL_STATUS_OFF)); WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_NORMAL, PSTR(D_NEOPOOL_STATUS_OFF));
} }
WSContentSend_PD(PSTR(" ")); WSContentSend_PD(PSTR(" "));
// S2 // S3
if (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_COVER) { if (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_COVER) {
WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_ACTIVE, PSTR(D_NEOPOOL_COVER)); WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_ACTIVE, PSTR(D_NEOPOOL_COVER));
} else { } else {
WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_DISABLED, PSTR(D_NEOPOOL_COVER)); WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_DISABLED, PSTR(D_NEOPOOL_COVER));
} }
WSContentSend_PD(PSTR(" ")); WSContentSend_PD(PSTR(" "));
// S3 // S4
if (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_SHOCK_ENABLED) { if (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_SHOCK_ENABLED) {
if ((NeoPoolGetData(MBF_CELL_BOOST) & MBMSK_CELL_BOOST_REDOX_CTL) == 0) { if ((NeoPoolGetData(MBF_CELL_BOOST) & MBMSK_CELL_BOOST_REDOX_CTL) == 0) {
WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_ACTIVE, PSTR(D_NEOPOOL_SHOCK "+" D_NEOPOOL_REDOX)); WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_ACTIVE, PSTR(D_NEOPOOL_SHOCK "+" D_NEOPOOL_REDOX));
@ -1791,7 +1822,7 @@ void NeoPoolShow(bool json)
WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_DISABLED, PSTR(D_NEOPOOL_SHOCK)); WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_DISABLED, PSTR(D_NEOPOOL_SHOCK));
} }
WSContentSend_PD(PSTR(" ")); WSContentSend_PD(PSTR(" "));
// S4 // S5
if (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_LOW) { if (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_LOW) {
WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_ACTIVE, PSTR(D_NEOPOOL_LOW)); WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_ACTIVE, PSTR(D_NEOPOOL_LOW));
} else { } else {
@ -2225,6 +2256,41 @@ void CmndNeopoolFiltrationMode(void)
} }
void CmndNeopoolFiltrationSpeed(void)
{
uint16_t speed;
uint16_t filtration_conf;
if (NEOPOOL_MODBUS_OK != NeoPoolReadRegister(MBF_PAR_FILTRATION_CONF, &filtration_conf, 1)) {
NeopoolResponseError();
return;
}
if (MBV_PAR_FILTRATION_TYPE_STANDARD == (filtration_conf & MBMSK_PAR_FILTRATION_CONF_TYPE)) {
// no speed control for standard filtration types
NeopoolCmndError();
return;
}
speed = NeoPoolGetFiltrationSpeed();
if (XdrvMailbox.data_len) {
if (XdrvMailbox.payload >= 1 && XdrvMailbox.payload <= 3) {
speed = XdrvMailbox.payload;
// Set filtration speed
if (NEOPOOL_MODBUS_OK != NeoPoolWriteRegisterWord(MBF_PAR_FILTRATION_CONF,
(filtration_conf & ~MBMSK_PAR_FILTRATION_CONF_DEF_SPEED) | ((speed - 1) << MBSHFT_PAR_FILTRATION_CONF_DEF_SPEED))) {
NeopoolResponseError();
return;
}
NeoPoolWriteRegisterWord(MBF_EXEC, 1);
} else {
NeopoolCmndError();
return;
}
}
ResponseCmndNumber(speed);
}
void CmndNeopoolTime(void) void CmndNeopoolTime(void)
{ {
uint16_t data[2]; uint16_t data[2];