Add Neopool cmnd NPReadLSB/NPReadMSB, NWriteLSB/NPWriteMSB (#24083)
* Add NeoPool display backlight register description * Add NeoPool cmnd `NPReadLSB/MSB`, `NWriteLSB/MSB`
This commit is contained in:
parent
fcf0809d8d
commit
524c95bac1
@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file.
|
||||
- Scripter array transfer via UFS (#24060)
|
||||
- ESP8266 GPIOViewer memory map if enabled with `#define GV_USE_ESPINFO`
|
||||
- Berry `tcp.write()` add `offset` and `len` (#24076)
|
||||
- NeoPool command `NPReadLSB`, `NPReadMSB`, `NPWriteLSB`, `NWriteMSB` for directly read/write LSB/MSB of 16-bit register
|
||||
|
||||
### Breaking Changed
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
xsns_83_neopool.ino - Sugar Valley NeoPool Control System Modbus support for Tasmota
|
||||
|
||||
Copyright (C) 2023 Norbert Richter
|
||||
Copyright (C) 2025 Norbert Richter
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -50,7 +50,6 @@
|
||||
* Only one Modbus client (master) can be connected to the Modbus connector
|
||||
* of the same name. It is not possible to operate several clients on
|
||||
* connectors with the same name.
|
||||
*
|
||||
* The differently labelled Modbus connectors are completely independent
|
||||
* physical Modbus interfaces. Data traffic on one of the connector is
|
||||
* invisible on the other connectors. One exception is the DISPLAY connector,
|
||||
@ -58,9 +57,7 @@
|
||||
* Since only one Modbus client can operate one Modbus server at a time, the
|
||||
* DISPLAY connector is useless for our purposes as long as the internal LCD
|
||||
* is connected to one of the two DISPLAY connectors at the same time.
|
||||
*
|
||||
* Conclusion:
|
||||
* Use the WIFI or EXTERNAL connector only.
|
||||
* Conclusion: Use the WIFI or EXTERNAL connector only.
|
||||
\****************************************************************************/
|
||||
|
||||
#define XSNS_83 83
|
||||
@ -290,7 +287,7 @@ enum NeoPoolRegister {
|
||||
// Contains the configuration parameters for the screen controllers (language, colours, sound, etc).
|
||||
MBF_PAR_UICFG_MACHINE = 0x0600, // 0x0600* Machine type (see MBV_PAR_MACH_* and kNeoPoolMachineNames[])
|
||||
MBF_PAR_UICFG_LANGUAGE, // 0x0601* Selected language (see MBV_PAR_LANG_*)
|
||||
MBF_PAR_UICFG_BACKLIGHT, // 0x0602* Display backlight function (see MBV_PAR_BACKLIGHT_*)
|
||||
MBF_PAR_UICFG_BACKLIGHT, // 0x0602* Display backlight brightness (in %, upper part (8-bit MSB)=0-100) and function (lower part 8-bit LSB, see MBV_PAR_BACKLIGHT_*)
|
||||
MBF_PAR_UICFG_SOUND, // 0x0603* mask Audible alerts (see MBMSK_PAR_SOUND_*)
|
||||
MBF_PAR_UICFG_PASSWORD, // 0x0604* System password encoded in BCD
|
||||
MBF_PAR_UICFG_VISUAL_OPTIONS, // 0x0605* mask Stores the different display options for the user interface menus (bitmask). Some bits allow you to hide options that are normally visible (bits 0 to 3) while other bits allow you to show options that are normally hidden (bits 9 to 15)
|
||||
@ -517,7 +514,7 @@ enum NeoPoolConstAndBitMask {
|
||||
MBV_PAR_LANG_HUNGARIAN = 10,
|
||||
MBV_PAR_LANG_RUSSIAN = 11,
|
||||
|
||||
// MBF_PAR_UICFG_BACKLIGHT
|
||||
// MBF_PAR_UICFG_BACKLIGHT (LSB)
|
||||
MBV_PAR_BACKLIGHT_15SEC = 0, // Backlight off after 15 sec
|
||||
MBV_PAR_BACKLIGHT_30SEC = 1, // Backlight off after 30 sec
|
||||
MBV_PAR_BACKLIGHT_60SEC = 2, // Backlight off after 60 sec
|
||||
@ -1174,15 +1171,23 @@ const char HTTP_SNS_NEOPOOL_STATUS_ACTIVE[] PROGMEM = "filter:invert(1)";
|
||||
*
|
||||
* NPRead <addr> {<cnt>}
|
||||
* NPReadL <addr> {<cnt>}
|
||||
* read 16/32-bit register (cnt = 1..30|1..15), cnt = 1 if omitted
|
||||
* NPRead read 16-bit register
|
||||
* NPReadL read 32-bit register
|
||||
* NPReadLSB <addr> {<cnt>}
|
||||
* NPReadMSB <addr> {<cnt>}
|
||||
* read 16|32-bit register (cnt = 1..30|1..15), cnt = 1 if omitted
|
||||
* NPRead read 16-bit register
|
||||
* NPReadL read 32-bit register
|
||||
* NPReadLSB read 16-bit register LSB only (like NPRead, but only reads the least significant byte (LSB) of 16-bit register)
|
||||
* NPReadMSB read 16-bit register MSB only (like NPRead, but only reads the most significant byte (MSB) of 16-bit register)
|
||||
*
|
||||
* NPWrite <addr> <data> {<data>...}
|
||||
* NPWriteL <addr> <data> {<data>...}
|
||||
* NPWrite write 16-bit register (data = 0..65535)
|
||||
* NPWriteL write 32-bit register (data = 0..4294967295)
|
||||
* The max. number of <data> parameters is 10
|
||||
* NPWriteLSB <addr> <data> {<data>...}
|
||||
* NPWriteMSB <addr> <data> {<data>...}
|
||||
* write 16|32-bit register (the max. number of <data> parameters is 20|10)
|
||||
* NPWrite write 16-bit register (data = 0..65535)
|
||||
* NPWriteL write 32-bit register (data = 0..4294967295)
|
||||
* NPWriteLSB write 16-bit register LSB only (data = 0..255, like NPWrite, but only writes the least significant byte (LSB) of 16-bit register)
|
||||
* NPWriteMSB write 16-bit register MSB only (data = 0..255, like NPWrite, but only writes the most significant byte (LSB) of 16-bit register)
|
||||
*
|
||||
* NPBit <addr> <bit> {<data>}
|
||||
* NPBitL <addr> <bit> {<data>}
|
||||
@ -1253,8 +1258,12 @@ const char HTTP_SNS_NEOPOOL_STATUS_ACTIVE[] PROGMEM = "filter:invert(1)";
|
||||
#define D_CMND_NP_RESULT "Result"
|
||||
#define D_CMND_NP_READ "Read"
|
||||
#define D_CMND_NP_READL "ReadL"
|
||||
#define D_CMND_NP_READLSB D_CMND_NP_READ "LSB"
|
||||
#define D_CMND_NP_READMSB D_CMND_NP_READ "MSB"
|
||||
#define D_CMND_NP_WRITE "Write"
|
||||
#define D_CMND_NP_WRITEL "WriteL"
|
||||
#define D_CMND_NP_WRITELSB D_CMND_NP_WRITE "LSB"
|
||||
#define D_CMND_NP_WRITEMSB D_CMND_NP_WRITE "MSB"
|
||||
#define D_CMND_NP_BIT "Bit"
|
||||
#define D_CMND_NP_BITL "BitL"
|
||||
#define D_CMND_NP_FILTRATION "Filtration"
|
||||
@ -1289,8 +1298,12 @@ const char kNPCommands[] PROGMEM = D_PRFX_NEOPOOL "|" // Prefix
|
||||
D_CMND_NP_RESULT "|"
|
||||
D_CMND_NP_READ "|"
|
||||
D_CMND_NP_READL "|"
|
||||
D_CMND_NP_READLSB "|"
|
||||
D_CMND_NP_READMSB "|"
|
||||
D_CMND_NP_WRITE "|"
|
||||
D_CMND_NP_WRITEL "|"
|
||||
D_CMND_NP_WRITELSB "|"
|
||||
D_CMND_NP_WRITEMSB "|"
|
||||
D_CMND_NP_BIT "|"
|
||||
D_CMND_NP_BITL "|"
|
||||
D_CMND_NP_FILTRATION "|"
|
||||
@ -1326,6 +1339,10 @@ void (* const NPCommand[])(void) PROGMEM = {
|
||||
&CmndNeopoolResult,
|
||||
&CmndNeopoolReadReg,
|
||||
&CmndNeopoolReadReg,
|
||||
&CmndNeopoolReadReg,
|
||||
&CmndNeopoolReadReg,
|
||||
&CmndNeopoolWriteReg,
|
||||
&CmndNeopoolWriteReg,
|
||||
&CmndNeopoolWriteReg,
|
||||
&CmndNeopoolWriteReg,
|
||||
&CmndNeopoolBit,
|
||||
@ -2520,7 +2537,7 @@ void NeoPoolShow(bool json)
|
||||
* Command implementation
|
||||
\****************************************************************************/
|
||||
|
||||
void NeopoolReadWriteResponse(uint16_t addr, uint16_t *data, uint16_t cnt, bool fbits32, int16_t bit)
|
||||
void NeopoolReadWriteResponse(uint16_t addr, uint16_t *data, uint16_t cnt, bool fbits32, bool flsb, bool fmsb, int16_t bit)
|
||||
{
|
||||
const char *data_fmt;
|
||||
uint32_t ldata;
|
||||
@ -2531,27 +2548,32 @@ void NeopoolReadWriteResponse(uint16_t addr, uint16_t *data, uint16_t cnt, bool
|
||||
|
||||
data_fmt = PSTR("%ld");
|
||||
if (NEOPOOL_RESULT_HEX == NeoPoolSettings.result) {
|
||||
data_fmt = fbits32 ? PSTR("\"0x%08X\"") : PSTR("\"0x%04X\"");
|
||||
data_fmt = fbits32 ? PSTR("\"0x%08X\"") : (!flsb && !fmsb) ? PSTR("\"0x%04X\"") : PSTR("\"0x%02X\"");
|
||||
}
|
||||
ldata = (uint32_t)data[0];
|
||||
if (fbits32) {
|
||||
ldata |= (uint32_t)data[1] << 16;
|
||||
char sdel[2] = {0};
|
||||
if ( cnt > 1 ) {
|
||||
ResponseAppend_P(PSTR("["));
|
||||
}
|
||||
for(uint16_t i=0; i<cnt; i++) {
|
||||
if ( cnt > 1 ) {
|
||||
ResponseAppend_P(PSTR("%s"), sdel);
|
||||
}
|
||||
ldata = (uint32_t)data[(fbits32+1)*i];
|
||||
if (fbits32) {
|
||||
ldata |= (uint32_t)data[(fbits32+1)*i+1] << 16;
|
||||
}
|
||||
else if (flsb) {
|
||||
ldata &= 0xff;
|
||||
}
|
||||
else if (fmsb) {
|
||||
ldata >>= 8;
|
||||
ldata &= 0xff;
|
||||
}
|
||||
ResponseAppend_P(data_fmt, ldata);
|
||||
*sdel = ',';
|
||||
}
|
||||
if ( cnt > 1 ) {
|
||||
char sdel[2] = {0};
|
||||
ResponseAppend_P(PSTR("["));
|
||||
for(uint16_t i=0; i<cnt; i++) {
|
||||
ResponseAppend_P(PSTR("%s"), sdel);
|
||||
ldata = (uint32_t)data[(fbits32+1)*i];
|
||||
if (fbits32) {
|
||||
ldata |= (uint32_t)data[(fbits32+1)*i+1] << 16;
|
||||
}
|
||||
ResponseAppend_P(data_fmt, ldata);
|
||||
*sdel = ',';
|
||||
}
|
||||
ResponseAppend_P(PSTR("]"));
|
||||
} else {
|
||||
ResponseAppend_P(data_fmt, ldata);
|
||||
}
|
||||
if (bit >= 0) {
|
||||
ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_BIT "%d\":%ld"), bit, (ldata>>bit) & 1);
|
||||
@ -2587,6 +2609,8 @@ void CmndNeopoolReadReg(void)
|
||||
uint32_t value[2] = { 0 };
|
||||
uint32_t params_cnt = ParseParameters(nitems(value), value);
|
||||
bool fbits32 = !strcasecmp_P(XdrvMailbox.command, PSTR(D_PRFX_NEOPOOL D_CMND_NP_READL));
|
||||
bool flsb = !strcasecmp_P(XdrvMailbox.command, PSTR(D_PRFX_NEOPOOL D_CMND_NP_READLSB));
|
||||
bool fmsb = !strcasecmp_P(XdrvMailbox.command, PSTR(D_PRFX_NEOPOOL D_CMND_NP_READMSB));
|
||||
|
||||
cnt = 1;
|
||||
if (2 == params_cnt) {
|
||||
@ -2599,7 +2623,7 @@ void CmndNeopoolReadReg(void)
|
||||
return;
|
||||
}
|
||||
}
|
||||
NeopoolReadWriteResponse(addr, data, cnt, fbits32, -1);
|
||||
NeopoolReadWriteResponse(addr, data, cnt, fbits32, flsb, fmsb, -1);
|
||||
}
|
||||
|
||||
|
||||
@ -2609,16 +2633,34 @@ void CmndNeopoolWriteReg(void)
|
||||
uint32_t value[(nitems(data)/2)+1] = { 0 };
|
||||
uint32_t params_cnt = ParseParameters(nitems(value), value);
|
||||
bool fbits32 = !strcasecmp_P(XdrvMailbox.command, PSTR(D_PRFX_NEOPOOL D_CMND_NP_WRITEL));
|
||||
bool flsb = !strcasecmp_P(XdrvMailbox.command, PSTR(D_PRFX_NEOPOOL D_CMND_NP_WRITELSB));
|
||||
bool fmsb = !strcasecmp_P(XdrvMailbox.command, PSTR(D_PRFX_NEOPOOL D_CMND_NP_WRITEMSB));
|
||||
|
||||
if (params_cnt > 1) {
|
||||
cnt = params_cnt-1;
|
||||
if (params_cnt > 1 && cnt < (fbits32 ? (nitems(data)/2) : nitems(data))) {
|
||||
addr = value[0];
|
||||
cnt = params_cnt-1;
|
||||
if (flsb || fmsb) {
|
||||
if (NEOPOOL_MODBUS_OK != NeoPoolReadRegister(addr, data, fbits32 ? (cnt*2) : cnt)) {
|
||||
NeopoolResponseError();
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < cnt; i++) {
|
||||
if (fbits32) {
|
||||
data[i*2] = value[i+1]; // LSB
|
||||
data[i*2+1] = value[i+1]>>16; // MSB
|
||||
} else {
|
||||
data[i] = value[i+1];
|
||||
if (flsb) {
|
||||
data[i] &= 0xff00;
|
||||
data[i] |= (value[i+1] & 0xff);
|
||||
}
|
||||
else if (fmsb) {
|
||||
data[i] &= 0x00ff;
|
||||
data[i] |= (value[i+1] & 0xff)<<8;
|
||||
}
|
||||
else {
|
||||
data[i] = value[i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NEOPOOL_MODBUS_OK != NeoPoolWriteRegister(addr, data, fbits32 ? cnt*2 : cnt)) {
|
||||
@ -2630,7 +2672,7 @@ void CmndNeopoolWriteReg(void)
|
||||
NeopoolResponseError();
|
||||
return;
|
||||
}
|
||||
NeopoolReadWriteResponse(addr, data, cnt, fbits32, -1);
|
||||
NeopoolReadWriteResponse(addr, data, cnt, fbits32, flsb, fmsb, -1);
|
||||
}
|
||||
|
||||
|
||||
@ -2674,7 +2716,7 @@ void CmndNeopoolBit(void)
|
||||
NeopoolResponseError();
|
||||
return;
|
||||
}
|
||||
NeopoolReadWriteResponse(addr, &data, 1, fbits32, bit);
|
||||
NeopoolReadWriteResponse(addr, &data, 1, fbits32, false, false, bit);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user