mirror of https://github.com/arendst/Tasmota.git
As requested in issue 824# by ascillato2, implement split interlock.
=> Split interlock of SONOFF with more than 2 channel into 2 groups => This is needed for shutter and similar utilization
This commit is contained in:
parent
72bc9b8107
commit
15e4918238
|
@ -76,7 +76,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
|||
uint32_t sleep_normal : 1; // bit 10 (v6.3.0.15) - SetOption60 - Enable normal sleep instead of dynamic sleep
|
||||
uint32_t button_switch_force_local : 1;// bit 11 (v6.3.0.16) - SetOption61 - Force local operation when button/switch topic is set
|
||||
uint32_t no_pullup : 1; // bit 12 (v6.4.1.7) - SetOption62 - Force no pull-up (0 = (no)pull-up, 1 = no pull-up)
|
||||
uint32_t spare13 : 1;
|
||||
uint32_t split_interlock : 1; // bit 13 (v6.4.1.8) - SetOption63 - Split interlock on CH4
|
||||
uint32_t spare14 : 1;
|
||||
uint32_t spare15 : 1;
|
||||
uint32_t spare16 : 1;
|
||||
|
|
|
@ -319,6 +319,23 @@ void SetDevicePower(power_t rpower, int source)
|
|||
power = (1 << devices_present) -1;
|
||||
rpower = power;
|
||||
}
|
||||
if (Settings.flag3.split_interlock) {
|
||||
Settings.flag.interlock = 1; // prevent the situation where interlock is off and split-interlock is on
|
||||
uint8_t mask = 0x01;
|
||||
uint8_t count = 0;
|
||||
byte result1 = 0;
|
||||
byte result2 = 0;
|
||||
for (byte i = 0; i < devices_present; i++) {
|
||||
if (rpower & mask) {
|
||||
if (i <2) { result1++;}//increment if low part is ON
|
||||
if (i >1) { result2++;}//increment if high part is ON
|
||||
}
|
||||
mask <<= 1; // shift the bitmask one left (1,2,4,8) to find out what is on
|
||||
}
|
||||
if ((result1) >1 && (result2 >1)) {power = 0; rpower = 0;} // all 4 switch are on, something is wrong, so we turn all off
|
||||
if ((result1) >1 && (result2 <2)) {power = power & 0x0C; rpower = power;} // 1/2 are both on and 3/4 max one is on
|
||||
if ((result1) <2 && (result2 >1)) {power = power & 0x03; rpower = power;} // 1/2 max one is on and 3/4 both are on
|
||||
} else {
|
||||
if (Settings.flag.interlock) { // Allow only one or no relay set
|
||||
power_t mask = 1;
|
||||
uint8_t count = 0;
|
||||
|
@ -331,6 +348,7 @@ void SetDevicePower(power_t rpower, int source)
|
|||
rpower = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XdrvMailbox.index = rpower;
|
||||
XdrvCall(FUNC_SET_POWER); // Signal power state
|
||||
|
@ -1389,7 +1407,28 @@ void ExecuteCommandPower(byte device, byte state, int source)
|
|||
blink_mask &= (POWER_MASK ^ mask); // Clear device mask
|
||||
MqttPublishPowerBlinkState(device);
|
||||
}
|
||||
if (Settings.flag.interlock && !interlock_mutex) { // Clear all but masked relay
|
||||
if (Settings.flag3.split_interlock && !Settings.flag.interlock ) Settings.flag.interlock=1; // ensure interlock is on, in case split_interlock is on
|
||||
// check if channel 1/2 or 3/4 are to be changed
|
||||
if (device <= 2 && Settings.flag3.split_interlock ) { // channel 1/2 are changed
|
||||
if (Settings.flag3.split_interlock && !interlock_mutex) { // Clear all but masked relay, but only if we are not already doing something
|
||||
interlock_mutex = 1;
|
||||
for (byte i = 0; i < 2; i++) {
|
||||
byte imask = 0x01 << i;
|
||||
if ((power & imask) && (mask != imask)) { ExecuteCommandPower(i +1, POWER_OFF, SRC_IGNORE); delay(50); }// example, first power is ON but the pushed button is not the first, then powerOFF the first one
|
||||
}
|
||||
interlock_mutex = 0; // avoid infinite loop due to recursive requests
|
||||
}
|
||||
} else { // channel 3/4 are changed
|
||||
if (Settings.flag3.split_interlock && !interlock_mutex) { // only start if we are on interlock split and have no re-call
|
||||
interlock_mutex = 1;
|
||||
for (byte i = 2; i < devices_present; i++) {
|
||||
byte imask = 0x01 << i;
|
||||
if ((power & imask) && (mask != imask)) ExecuteCommandPower(i +1, POWER_OFF, SRC_IGNORE);
|
||||
}
|
||||
interlock_mutex = 0;
|
||||
}
|
||||
}
|
||||
if ( Settings.flag.interlock && !interlock_mutex && !Settings.flag3.split_interlock) { //execute regular interlock-mode as interlock-split is off
|
||||
interlock_mutex = 1;
|
||||
for (byte i = 0; i < devices_present; i++) {
|
||||
power_t imask = 1 << i;
|
||||
|
|
Loading…
Reference in New Issue