Add support for Sonoff Zigbee Bridge Pro

- Add support for Sonoff Zigbee Bridge Pro by Stephan Hadinger (#15701)
- Add command ``SspmDisplay 2`` to display Sonoff SPM energy data in GUI for user tab-selected relay modules (#13447)
This commit is contained in:
Theo Arends 2022-05-27 16:08:27 +02:00
parent 66ef338681
commit a43c194db6
3 changed files with 48 additions and 14 deletions

View File

@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file.
## [11.1.0.3] ## [11.1.0.3]
### Added ### Added
- Support for Sonoff SPM v1.2.0 - Support for Sonoff SPM v1.2.0
- Support for Sonoff Zigbee Bridge Pro by Stephan Hadinger (#15701)
- Command ``SspmDisplay 2`` to display Sonoff SPM energy data in GUI for user tab-selected relay modules (#13447)
### Changed ### Changed

View File

@ -110,10 +110,12 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Command ``SetOption140 0/1`` to switch between MQTT Clean Session (0) or Persistent Session (1) [#15530](https://github.com/arendst/Tasmota/issues/15530) - Command ``SetOption140 0/1`` to switch between MQTT Clean Session (0) or Persistent Session (1) [#15530](https://github.com/arendst/Tasmota/issues/15530)
- Command ``EnergyExportActive<phase>`` to (p)reset energy export active for supported devices. Currently ADE7880 only [#13515](https://github.com/arendst/Tasmota/issues/13515) - Command ``EnergyExportActive<phase>`` to (p)reset energy export active for supported devices. Currently ADE7880 only [#13515](https://github.com/arendst/Tasmota/issues/13515)
- Command ``IfxRp ""|<policy>`` adds optional InfluxDb Retention Policy [#15513](https://github.com/arendst/Tasmota/issues/15513) - Command ``IfxRp ""|<policy>`` adds optional InfluxDb Retention Policy [#15513](https://github.com/arendst/Tasmota/issues/15513)
- Command ``SspmDisplay 2`` to display Sonoff SPM energy data in GUI for user tab-selected relay modules [#13447](https://github.com/arendst/Tasmota/issues/13447)
- Support for Sonoff MS01 soil moisture sensor [#15335](https://github.com/arendst/Tasmota/issues/15335) - Support for Sonoff MS01 soil moisture sensor [#15335](https://github.com/arendst/Tasmota/issues/15335)
- Support for daisy chaining MAX7219 displays [#15345](https://github.com/arendst/Tasmota/issues/15345) - Support for daisy chaining MAX7219 displays [#15345](https://github.com/arendst/Tasmota/issues/15345)
- Sonoff SPM delayed SetPowerOnState [#13447](https://github.com/arendst/Tasmota/issues/13447) - Sonoff SPM delayed SetPowerOnState [#13447](https://github.com/arendst/Tasmota/issues/13447)
- Support for Sonoff SPM v1.2.0 - Support for Sonoff SPM v1.2.0
- Support for Sonoff Zigbee Bridge Pro by Stephan Hadinger [#15701](https://github.com/arendst/Tasmota/issues/15701)
- Support for flowrate meters like YF-DN50 and similary [#15474](https://github.com/arendst/Tasmota/issues/15474) - Support for flowrate meters like YF-DN50 and similary [#15474](https://github.com/arendst/Tasmota/issues/15474)
- ESP32 Command ``Restart 3`` to switch between SafeBoot and Production - ESP32 Command ``Restart 3`` to switch between SafeBoot and Production

View File

@ -49,7 +49,7 @@
* - Yellow led blinks 2 seconds if an ARM-ESP comms CRC error is detected. * - Yellow led blinks 2 seconds if an ARM-ESP comms CRC error is detected.
* - Persistence for module mapping, total energy and energy yesterday * - Persistence for module mapping, total energy and energy yesterday
* - Supported commands: * - Supported commands:
* SspmDisplay 0|1 - Select alternative GUI rotating display either all (0) or powered on only (1) * SspmDisplay 0|1|2 - Select alternative GUI rotating display either all (0), powered on only (1) or user selected (2)
* SspmDump 0|1 - Select shortenend (0) or full (1) serial receive buffer dumps * SspmDump 0|1 - Select shortenend (0) or full (1) serial receive buffer dumps
* SspmEnergyTotal<relay> - (p)reset total energy without today's energy * SspmEnergyTotal<relay> - (p)reset total energy without today's energy
* SspmEnergyYesterday<relay> - (p)reset energy yesterday * SspmEnergyYesterday<relay> - (p)reset energy yesterday
@ -210,9 +210,8 @@ TasmotaSerial *SspmSerial;
typedef union { typedef union {
uint16_t data; uint16_t data;
struct { struct {
uint16_t dump : 1; // bit 0 (v10.1.0.6) - SSPMDump - Short receive dump (0) or full receive dump (1) uint16_t dump : 1; // bit 0 (v10.1.0.6) - SSPMDump - Short receive dump (0) or full receive dump (1)
uint16_t display : 1; // bit 1 (v10.1.0.6) - SSPMDisplay - GUI display all relays (0) or only powered on relays (1) uint16_t display : 2; // bit 1,2 (v10.1.0.6) - SSPMDisplay - GUI display all relays (0), only powered on relays (1) or user selected relays (2)
uint16_t spare02 : 1; // bit 2
uint16_t spare03 : 1; // bit 3 uint16_t spare03 : 1; // bit 3
uint16_t spare04 : 1; // bit 4 uint16_t spare04 : 1; // bit 4
uint16_t spare05 : 1; // bit 5 uint16_t spare05 : 1; // bit 5
@ -2103,7 +2102,8 @@ void SSPMEnergyShow(bool json) {
power_t power = TasmotaGlobal.power; power_t power = TasmotaGlobal.power;
for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) { for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) {
if ((0 == Sspm->Settings.flag.display) || if ((0 == Sspm->Settings.flag.display) ||
((1 == Sspm->Settings.flag.display) && (power >> i) &1)) { ((1 == Sspm->Settings.flag.display) && (power >> i) &1) ||
(2 == Sspm->Settings.flag.display)) {
relay[index] = i +1; relay[index] = i +1;
indirect[index] = i; indirect[index] = i;
index++; index++;
@ -2111,23 +2111,40 @@ void SSPMEnergyShow(bool json) {
} }
if (index) { if (index) {
if (index > 4) { if (Sspm->Settings.flag.display != 2) {
Sspm->rotate++; if (index > 4) {
} else { Sspm->rotate++;
Sspm->rotate = 0; } else {
Sspm->rotate = 0;
}
} }
if (Sspm->rotate > ((index -1) | 0x3)) { // Always test in case index has changed due to use of SspmDisplay command if (Sspm->rotate > ((index -1) | 0x3)) { // Always test in case index has changed due to use of SspmDisplay command
Sspm->rotate = 0; Sspm->rotate = 0;
} }
uint32_t offset = (Sspm->rotate >> 2) * 4; uint32_t offset = (Sspm->rotate >> 2) * 4;
uint32_t count = index - offset; uint32_t count = index - offset;
if (count > 4) { count = 4; } if (count > 4) { count = 4; }
if (2 == Sspm->Settings.flag.display) {
uint32_t modules = index / 4;
if (modules > 1) {
WSContentSend_P(PSTR("</table><hr/>{t}<tr>"));
uint32_t cols_width = 100 / modules;
uint32_t current_module = Sspm->rotate >> 2;
for (uint32_t idx = 0; idx < modules; idx++) {
WSContentSend_P(PSTR("<td style='width:%d%%'><button style='border-radius:0;background:#%06X' onclick='la(\"&k86=%d\");'>%d</button></td>"), // &k86 is related to WebGetArg("k", tmp, sizeof(tmp));
cols_width, (current_module == idx) ? WebColor(COL_BACKGROUND) : WebColor(COL_TIMER_TAB_BACKGROUND), idx, idx +1);
}
WSContentSend_P(PSTR("</tr></table>"));
}
} else {
WSContentSend_P(PSTR("</table><hr/>"));
}
// {s}</th><th></th><th>Head1</th><th></th><td>{e} // {s}</th><th></th><th>Head1</th><th></th><td>{e}
// {s}</th><th></th><th>Head1</th><th></th><th>Head2</th><th></th><td>{e} // {s}</th><th></th><th>Head1</th><th></th><th>Head2</th><th></th><td>{e}
// {s}</th><th></th><th>Head1</th><th></th><th>Head2</th><th></th><th>Head3</th><th></th><td>{e} // {s}</th><th></th><th>Head1</th><th></th><th>Head2</th><th></th><th>Head3</th><th></th><td>{e}
// {s}</th><th></th><th>Head1</th><th></th><th>Head2</th><th></th><th>Head3</th><th></th><th>Head4</th><th></th><td>{e} // {s}</th><th></th><th>Head1</th><th></th><th>Head2</th><th></th><th>Head3</th><th></th><th>Head4</th><th></th><td>{e}
WSContentSend_P(PSTR("{t}{s}</th><th></th>")); // First column is empty ({t} = <table style='width:100%'>, {s} = <tr><th>)
char value_chr[SSPM_SIZE]; char value_chr[SSPM_SIZE];
WSContentSend_P(PSTR("</table><hr/>{t}{s}</th><th></th>")); // First column is empty ({t} = <table style='width:100%'>, {s} = <tr><th>)
bool no_label = false; bool no_label = false;
for (uint32_t i = 0; i < count; i++) { for (uint32_t i = 0; i < count; i++) {
WSContentSend_P(PSTR("<th style='text-align:center'>%s%s<th></th>"), (no_label)?"":"L", (no_label)?"":itoa(relay[offset +i], value_chr, 10)); WSContentSend_P(PSTR("<th style='text-align:center'>%s%s<th></th>"), (no_label)?"":"L", (no_label)?"":itoa(relay[offset +i], value_chr, 10));
@ -2150,6 +2167,16 @@ void SSPMEnergyShow(bool json) {
} }
} }
#ifdef USE_WEBSERVER
void SSPMWebGetArg(void) {
char tmp[8]; // WebGetArg numbers only
WebGetArg(PSTR("k86"), tmp, sizeof(tmp)); // 1 - 8 relay modules
if (strlen(tmp)) { Sspm->rotate = atoi(tmp) *4; }
}
#endif // USE_WEBSERVER
/*********************************************************************************************\ /*********************************************************************************************\
* Commands * Commands
\*********************************************************************************************/ \*********************************************************************************************/
@ -2167,9 +2194,9 @@ void (* const SSPMCommand[])(void) PROGMEM = {
&CmndSpmEnergyTotal, &CmndSpmEnergyYesterday, &CmndSSPMSend }; &CmndSpmEnergyTotal, &CmndSpmEnergyYesterday, &CmndSSPMSend };
void CmndSSPMDisplay(void) { void CmndSSPMDisplay(void) {
// Select either all relays or only powered on relays // Select either all relays, only powered on relays or user selected relay module
// SspmDisplay 0 or SspmDisplay 1 // SspmDisplay 0, SspmDisplay 1 or SspmDisplay 2
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) {
Sspm->Settings.flag.display = XdrvMailbox.payload; Sspm->Settings.flag.display = XdrvMailbox.payload;
} }
ResponseCmndNumber(Sspm->Settings.flag.display); ResponseCmndNumber(Sspm->Settings.flag.display);
@ -2440,6 +2467,9 @@ bool Xdrv86(uint8_t function) {
case FUNC_WEB_SENSOR: case FUNC_WEB_SENSOR:
SSPMEnergyShow(false); SSPMEnergyShow(false);
break; break;
case FUNC_WEB_GET_ARG:
SSPMWebGetArg();
break;
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
case FUNC_COMMAND: case FUNC_COMMAND:
result = DecodeCommand(kSSPMCommands, SSPMCommand); result = DecodeCommand(kSSPMCommands, SSPMCommand);