diff --git a/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino b/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino index 4b568da3a..aa0d8ace2 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino @@ -128,7 +128,7 @@ // From ESP to ARM #define SSPM_FUNC_FIND 0 // 0x00 -#define SSPM_FUNC_SET_OPS 3 // 0x03 - Overload Protection +#define SSPM_FUNC_SET_OPS 3 // 0x03 - Overload Protection (OPS) #define SSPM_FUNC_GET_OPS 4 // 0x04 #define SSPM_FUNC_SET_RELAY 8 // 0x08 #define SSPM_FUNC_GET_MODULE_STATE 9 // 0x09 - State of four channels @@ -138,7 +138,7 @@ #define SSPM_FUNC_IAMHERE 13 // 0x0D #define SSPM_FUNC_INIT_SCAN 16 // 0x10 #define SSPM_FUNC_UPLOAD_HEADER 20 // 0x14 - SPI Upload header -#define SSPM_FUNC_UNITS 21 // 0x15 +#define SSPM_FUNC_GET_MAIN_VERSION 21 // 0x15 - Read main ARM firmware version #define SSPM_FUNC_GET_ENERGY_TOTAL 22 // 0x16 #define SSPM_FUNC_GET_ENERGY 24 // 0x18 #define SSPM_FUNC_GET_LOG 26 // 0x1A @@ -148,14 +148,14 @@ #define SSPM_FUNC_UPLOAD_DONE 33 // 0x21 - SPI Finish upload #define SSPM_FUNC_34 34 // 0x22 - v1.2.0 #define SSPM_FUNC_GET_OPS_DEFAULTS 35 // 0x23 - v1.2.0 - Get Overload protection defaults -#define SSPM_FUNC_SET_POS 36 // 0x24 - v1.2.0 - Save power on relay state -#define SSPM_FUNC_GET_POS 37 // 0x25 - v1.2.0 - Read power on relay state +#define SSPM_FUNC_SET_POS 36 // 0x24 - v1.2.0 - Save power on relay state (POS) +#define SSPM_FUNC_GET_POS 37 // 0x25 - v1.2.0 - Read power on relay state (POS) // From ARM to ESP #define SSPM_FUNC_ENERGY_RESULT 6 // 0x06 #define SSPM_FUNC_KEY_PRESS 7 // 0x07 #define SSPM_FUNC_SCAN_START 15 // 0x0F -#define SSPM_FUNC_SCAN_RESULT 19 // 0x13 +#define SSPM_FUNC_SCAN_RESULT 19 // 0x13 - Provide 4relay ARM firmware version, module type and OPS limits #define SSPM_FUNC_SCAN_DONE 25 // 0x19 #define SSPM_FUNC_UPLOAD_DONE_ACK 30 // 0x1E - Restart ARM @@ -177,26 +177,27 @@ #define SSPM_VERSION_1_0_0 0x00010000 #define SSPM_VERSION_1_2_0 0x00010200 +#define SSPM_VERSION_1_4_0 0x00010400 /*********************************************************************************************/ -#define SSPM_TOTAL_MODULES 32 // Max number of SPM-4RELAY units for a total of 128 relays +#define SSPM_TOTAL_MODULES 32 // Max number of SPM-4RELAY units for a total of 128 relays -enum SspmMachineStates { SPM_NONE, // Do nothing - SPM_WAIT, // Wait 100ms - SPM_RESET, // Toggle ARM reset pin - SPM_POLL_ARM, // Wait for first acknowledge from ARM after reset +enum SspmMachineStates { SPM_NONE, // Do nothing + SPM_WAIT, // Wait 100ms + SPM_RESET, // Toggle ARM reset pin + SPM_POLL_ARM, // Wait for first acknowledge from ARM after reset // Removed to accomodate v1.2.0 too -// SPM_POLL_ARM_SPI, // Wait for first acknowledge from ARM SPI after reset -// SPM_POLL_ARM_2, // Wait for second acknowledge from ARM after reset -// SPM_POLL_ARM_3, // Wait for second acknowledge from ARM after reset - SPM_SEND_FUNC_UNITS, // Get number of units - SPM_START_SCAN, // Start module scan sequence - SPM_WAIT_FOR_SCAN, // Wait for scan sequence to complete - SPM_SCAN_COMPLETE, // Scan complete - SPM_STALL_MIDNIGHT, // Stall energy totals around midnight - SPM_GET_ENERGY_TOTALS, // Init available Energy totals registers - SPM_UPDATE_CHANNELS // Update Energy for powered on channels +// SPM_POLL_ARM_SPI, // Wait for first acknowledge from ARM SPI after reset +// SPM_POLL_ARM_2, // Wait for second acknowledge from ARM after reset +// SPM_POLL_ARM_3, // Wait for second acknowledge from ARM after reset + SPM_SEND_FUNC_GET_MAIN_VERSION, // Get main ARM firmware version + SPM_START_SCAN, // Start module scan sequence + SPM_WAIT_FOR_SCAN, // Wait for scan sequence to complete + SPM_SCAN_COMPLETE, // Scan complete + SPM_STALL_MIDNIGHT, // Stall energy totals around midnight + SPM_GET_ENERGY_TOTALS, // Init available Energy totals registers + SPM_UPDATE_CHANNELS // Update Energy for powered on channels }; enum SspmDisplayModes { SPM_DISPLAY_ROTATE, SPM_DISPLAY_ROTATE_POWERED_ON, SPM_DISPLAY_TABS, SPM_DISPLAY_MAX_OPTION }; @@ -1233,7 +1234,7 @@ void SSPMHandleReceivedData(void) { AA 55 01 ff ff ff ff ff ff ff ff ff ff ff ff 80 10 00 01 00 02 e5 03 */ break; - case SSPM_FUNC_UNITS: + case SSPM_FUNC_GET_MAIN_VERSION: /* 0x15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 80 15 00 04 00 01 00 00 01 81 b1 @@ -1479,8 +1480,10 @@ void SSPMHandleReceivedData(void) { P4 - Relay4 power on state (0 = On, 1 = Off, 2 = Laststate) */ Sspm->module_selected--; - for (uint32_t i = 0; i < 4; i++) { - Sspm->poweron_state[Sspm->module_selected][i] = (!status && (expected_bytes >= 0x05)) ? SspmBuffer[20 +i] : 1; + if (!status && (expected_bytes >= 0x05)) { + for (uint32_t i = 0; i < 4; i++) { + Sspm->poweron_state[Sspm->module_selected][i] = SspmBuffer[20 +i]; + } } if (Sspm->module_selected > 0) { SSPMSendGetModuleState(Sspm->module_selected -1); @@ -1617,10 +1620,12 @@ void SSPMHandleReceivedData(void) { case SSPM_FUNC_SCAN_RESULT: /* 0x13 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 - AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 24 6b 7e 32 37 39 37 34 13 4b 35 36 37 04 00 00 00 82 01 00 00 14 00 00 0a 00 f0 00 00 00 0a 11 30 00 00 00 0a 02 8f cd - AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 24 8b 34 32 37 39 37 34 13 4b 35 36 37 04 00 00 00 82 01 00 00 14 00 00 0a 00 f0 00 00 00 0a 11 30 00 00 00 0a 02 a0 6f Marker | |Ac|Cm|Size |Module id |Ch| |Ty|FwVersio|Max I|Min I|Max U |Min U |Max P |Min P |Ix|Chksm| + AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 24 6b 7e 32 37 39 37 34 13 4b 35 36 37 04 00 00 00 82 01 00 00 14 00 00 0a 00 f0 00 00 00 0a 11 30 00 00 00 0a 02 8f cd - v1.0.0 + AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 24 8b 34 32 37 39 37 34 13 4b 35 36 37 04 00 00 00 82 01 00 00 14 00 00 0a 00 f0 00 00 00 0a 11 30 00 00 00 0a 02 a0 6f - v1.0.0 |130| 1.0.0|20.0A|0.10A| 240.00V| 0.10V|4400.00W| 0.10W| + AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 24 8B 34 32 37 39 37 34 13 4B 35 36 37 04 00 00 00 82 01 02 00 14 00 00 0A 01 08 00 00 5A 00 12 C0 00 00 00 0A 02 6B 93 - v1.2.0 + |130| 1.2.0|20.0A|0.10A| 264.00V| 90V|4800.00W| 0.10W| Ty = Type of sub-device. 130: Four-channel sub-device */ if (0x24 == expected_bytes) { @@ -1931,6 +1936,11 @@ void SSPMInit(void) { #endif #endif + for (uint32_t module = 0; module < Sspm->module_max; module++) { + for (uint32_t relay = 0; relay < 4; relay++) { + Sspm->poweron_state[module][relay] = 1; // Set default power on state to Off ( = Sonoff 1) + } + } Sspm->relay_version = 0xFFFFFFFF; // Find lowest supported relay version Sspm->overload_relay = 255; // Disable display overload settings Sspm->history_relay = 255; // Disable display energy history @@ -1964,7 +1974,7 @@ void SSPMEvery100ms(void) { } // Fix race condition if the ARM doesn't respond - if ((Sspm->mstate > SPM_NONE) && (Sspm->mstate < SPM_SEND_FUNC_UNITS)) { + if ((Sspm->mstate > SPM_NONE) && (Sspm->mstate < SPM_SEND_FUNC_GET_MAIN_VERSION)) { Sspm->counter++; if (Sspm->counter > 30) { Sspm->mstate = SPM_NONE; @@ -2003,9 +2013,9 @@ void SSPMEvery100ms(void) { // Wait for second acknowledge from ARM after reset break; */ - case SPM_SEND_FUNC_UNITS: - // Get number of units - SSPMSendCmnd(SSPM_FUNC_UNITS); + case SPM_SEND_FUNC_GET_MAIN_VERSION: + // Get main version number + SSPMSendCmnd(SSPM_FUNC_GET_MAIN_VERSION); break; case SPM_START_SCAN: // Start scan module sequence @@ -2397,7 +2407,8 @@ void CmndSpmEnergyYesterday(void) { void CmndSSPMOverload(void) { // Get / Set overload // SspmOverload 0 - Reset overload detection parameters - // SspmOverload {"Delay":0,"Set":00000,"MinPower":0.10,"MaxPower":4400.00,"MinVoltage":0.10,"MaxVoltage":240.00,"MaxCurrent":20.00} + // SspmOverload {"Delay":0,"Set":00000,"MinPower":0.10,"MaxPower":4400.00,"MinVoltage":0.10,"MaxVoltage":240.00,"MaxCurrent":20.00} - v1.0.0 + // SspmOverload {"Delay":0,"Set":00000,"MinPower":0.10,"MaxPower":4800.00,"MinVoltage":90,"MaxVoltage":264.00,"MaxCurrent":20.00} - v1.2.0 // SspmOverload ,,,, // SspmOverload 10,0.10,4400.00,0.10,240.00,20.00 // SspmOverload 10 0.10 4400.00 0.10 240.00 20.00 @@ -2590,26 +2601,29 @@ void CmndSSPMSend(void) { void CmndSSPMPowerOnState(void) { // SspmPowerOnState2 0|1|2 - Set relay2 power on state (0 = Off, 1 = On, 2 = Saved) - uint32_t max_index = Sspm->module_max *4; - if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= max_index)) { - uint32_t module = (XdrvMailbox.index -1) >>2; - uint32_t relay = (XdrvMailbox.index -1) &3; - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { - if (XdrvMailbox.payload < 2) { XdrvMailbox.payload = !XdrvMailbox.payload; } // Swap Tasmota power off (0) with Sonoff (1) - Sspm->poweron_state[module][relay] = XdrvMailbox.payload; - SSPMSendSetPowerOnState(module); - } - Response_P(PSTR("{\"%s\":["), XdrvMailbox.command); - bool more = false; - for (uint32_t module = 0; module < Sspm->module_max; module++) { - for (uint32_t relay = 0; relay < 4; relay++) { - uint32_t poweron_state = Sspm->poweron_state[module][relay]; - if (poweron_state < 2) { poweron_state = !poweron_state; } // Swap Sonoff power off (1) with Tasmota (0) - ResponseAppend_P(PSTR("%s%d"), (more)?",":"", poweron_state); - more = true; + // Needs both main and 4relay at v1.2.0 + if (Sspm->main_version > SSPM_VERSION_1_0_0) { + uint32_t max_index = Sspm->module_max *4; + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= max_index)) { + uint32_t module = (XdrvMailbox.index -1) >>2; + uint32_t relay = (XdrvMailbox.index -1) &3; + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { + if (XdrvMailbox.payload < 2) { XdrvMailbox.payload = !XdrvMailbox.payload; } // Swap Tasmota power off (0) with Sonoff (1) + Sspm->poweron_state[module][relay] = XdrvMailbox.payload; + SSPMSendSetPowerOnState(module); } + Response_P(PSTR("{\"%s\":["), XdrvMailbox.command); + bool more = false; + for (uint32_t module = 0; module < Sspm->module_max; module++) { + for (uint32_t relay = 0; relay < 4; relay++) { + uint32_t poweron_state = Sspm->poweron_state[module][relay]; + if (poweron_state < 2) { poweron_state = !poweron_state; } // Swap Sonoff power off (1) with Tasmota (0) + ResponseAppend_P(PSTR("%s%d"), (more)?",":"", poweron_state); + more = true; + } + } + ResponseAppend_P(PSTR("]}")); } - ResponseAppend_P(PSTR("]}")); } }