Hi cosmic gate,
I've made some changes to the code, so it will send the state to the controller.
I haven't been able to test it, as my sonoff duals are all in use.
There are also a few side effects which I can't eliminate at the moment. The attached binary doesn't have these side effects (see below).
When you change the switch from domoticz, it will be switched on/off twice (as you can see in the domoticz log).
When you change the switch from a url, it will be switched on/off twice (as you can see in the esp log).
Code: Select all
//#######################################################################################################
//################################# Plugin 101: SONOFF Dual Switch ######################################
//#######################################################################################################
#define PLUGIN_101
#define PLUGIN_ID_101 101
#define PLUGIN_NAME_101 "Sonoff dual"
#define PLUGIN_VALUENAME1_101 "SonoffDual"
int switchstate,senddata;
boolean Plugin_101(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_101;
Device[deviceCount].Type = DEVICE_TYPE_DUMMY;
Device[deviceCount].VType = SENSOR_TYPE_SWITCH;
Device[deviceCount].Ports = 0;
Device[deviceCount].ValueCount = 0;
Device[deviceCount].SendDataOption = false;
Device[deviceCount].GlobalSyncOption = true;
break;
}
case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_101);
break;
}
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_101));
break;
}
case PLUGIN_WEBFORM_LOAD:
{
addFormNumericBox(string, F("Sonoff Dual IDX1"), F("IDX1"), ExtraTaskSettings.TaskDevicePluginConfigLong[0]);
addFormNumericBox(string, F("Sonoff Dual IDX2"), F("IDX2"), ExtraTaskSettings.TaskDevicePluginConfigLong[1]);
addFormCheckBox(string, F("Send to controller"),F("plugin_101_sendtocontroller"),
Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
success = true;
break;
}
case PLUGIN_WEBFORM_SAVE:
{
ExtraTaskSettings.TaskDevicePluginConfigLong[0] = getFormItemInt(F("IDX1"));
ExtraTaskSettings.TaskDevicePluginConfigLong[1] = getFormItemInt(F("IDX2"));
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = isFormItemChecked(F("plugin_101_sendtocontroller"));
success = true;
break;
}
case PLUGIN_INIT:
{
UserVar[event->BaseVarIndex] = 0;
switchstate = 0;
senddata=0;
success = true;
break;
}
case PLUGIN_WRITE:
{
String log = "";
String command = parseString(string, 1);
if (command == F("sonoff1"))
{
success = true;
if (event->Par1 >= 0 && event->Par1 <= 1)
{
Serial.begin(19200);
Serial.write(0xA0);
Serial.write(0x04);
if (event->Par1 == 0)
{
switch (switchstate)
{
case 0:
{
Serial.write(0x00);
switchstate = 0;
break;
}
case 1:
{
Serial.write(0x00);
UserVar[event->BaseVarIndex]= 0;
switchstate = 0;
senddata=1;
break;
}
case 2:
{
Serial.write(0x02);
switchstate = 2;
break;
}
case 3:
{
Serial.write(0x02);
UserVar[event->BaseVarIndex]= 0;
switchstate = 2;
senddata=1;
break;
}
}
}
if (event->Par1 == 1)
{
switch (switchstate)
{
case 0:
{
Serial.write(0x01);
UserVar[event->BaseVarIndex]= 1;
switchstate = 1;
senddata=1;
break;
}
case 1:
{
Serial.write(0x01);
switchstate = 1;
break;
}
case 2:
{
Serial.write(0x03);
UserVar[event->BaseVarIndex]= 1;
switchstate = 3;
senddata=1;
break;
}
case 3:
{
Serial.write(0x03);
UserVar[event->BaseVarIndex]= 1;
switchstate = 3;
break;
}
}
}
Serial.write(0xA1);
Serial.flush();
log = String(F("SW : Sonoff 1 Set to ")) + String(event->Par1) + String(F(" switchstate Set to ")) + String(switchstate);
addLog(LOG_LEVEL_INFO, log);
printToWebJSON = true;
String reply = String(F("{\"log\": \"Sonoff Switch 1 state = ")) + String(event->Par1) + String(F("\",\"plugin\": 101,\"switch\": 1,\"mode\": \"output\",\"state\": ")) + String(event->Par1) + String(F(" }"));
SendStatus(event->Source, reply);
Settings.TaskDeviceID[0][event->TaskIndex] = ExtraTaskSettings.TaskDevicePluginConfigLong[0];
event->sensorType = SENSOR_TYPE_SWITCH;
if (senddata && Settings.TaskDevicePluginConfig[event->TaskIndex][0]){
Settings.TaskDeviceSendData[0][event->TaskIndex] = 1;
Settings.TaskDeviceSendData[1][event->TaskIndex] = 1;
Settings.TaskDeviceSendData[2][event->TaskIndex] = 1;
sendData(event);
senddata=0;
}
}
}
if (command == F("sonoff2"))
{
success = true;
if (event->Par1 >= 0 && event->Par1 <= 1)
{
Serial.begin(19200);
Serial.write(0xA0);
Serial.write(0x04);
if (event->Par1 == 0)
{
switch (switchstate)
{
case 0:
{
Serial.write(0x00);
switchstate = 0;
break;
}
case 1:
{
Serial.write(0x01);
switchstate = 1;
break;
}
case 2:
{
Serial.write(0x00);
UserVar[event->BaseVarIndex]= 0;
switchstate = 0;
senddata=1;
break;
}
case 3:
{
Serial.write(0x01);
UserVar[event->BaseVarIndex]= 0;
switchstate = 1;
senddata=1;
break;
}
}
}
if (event->Par1 == 1)
{
switch (switchstate)
{
case 0:
{
Serial.write(0x02);
UserVar[event->BaseVarIndex]= 1;
switchstate = 2;
senddata=1;
break;
}
case 1:
{
Serial.write(0x03);
UserVar[event->BaseVarIndex]= 1;
switchstate = 3;
senddata=1;
break;
}
case 2:
{
Serial.write(0x02);
switchstate = 2;
break;
}
case 3:
{
Serial.write(0x03);
switchstate = 3;
break;
}
}
}
Serial.write(0xA1);
Serial.flush();
log = String(F("SW : Sonoff 2 Set to ")) + String(event->Par1) + String(F(" switchstate Set to ")) + String(switchstate);
addLog(LOG_LEVEL_INFO, log);
printToWebJSON = true;
String reply = String(F("{\"log\": \"Sonoff Switch 2 state = ")) + String(event->Par1) + String(F("\",\"plugin\": 102,\"switch\": 2,\"mode\": \"output\",\"state\": ")) + String(event->Par1) + String(F(" }"));
SendStatus(event->Source, reply);
Settings.TaskDeviceID[0][event->TaskIndex] = ExtraTaskSettings.TaskDevicePluginConfigLong[1];
event->sensorType = SENSOR_TYPE_SWITCH;
if (senddata && Settings.TaskDevicePluginConfig[event->TaskIndex][0]){
Settings.TaskDeviceSendData[0][event->TaskIndex] = 1;
Settings.TaskDeviceSendData[1][event->TaskIndex] = 1;
Settings.TaskDeviceSendData[2][event->TaskIndex] = 1;
sendData(event);
senddata=0;
}
}
}
break;
}
}
return success;
}
I think it is the best I can do at the moment without changing the esp code (only the plugin).
To reset the state in domoticz after reboot, use rules (and change the idx and ip address):
On System#Boot do
timerSet,1,10
endon
On Rules#Timer=1 do
SendToHTTP 192.168.0.xxx,8080,/json.htm?type=command¶m=udevice&idx=11&nvalue=0
SendToHTTP 192.168.0.xxx,8080,/json.htm?type=command¶m=udevice&idx=12&nvalue=0
endon
Turn off serial on the advanced menu.
The attached binary does have a slightly adjusted core code. This binary does not have the side effects that the switch is changed twice.
Compiled with source from github.
If you want to compile yourself, here are the changed files:
Regards,
Bryan