diff --git a/button_maps.json b/button_maps.json index 527ea133d7..e335cbc14c 100644 --- a/button_maps.json +++ b/button_maps.json @@ -146,82 +146,6 @@ } }, "maps": { - "deLightingSwitchMap": { - "vendor": "dresden elektronik", - "modelids": ["Lighting Switch"], - "doc": "Lighting Switch", - "buttons": [ - {"S_BUTTON_1": "Top Left"}, - {"S_BUTTON_2": "Bottom Left"}, - {"S_BUTTON_3": "Top Right"}, - {"S_BUTTON_4": "Bottom Right"} - ], - "map": [ - [1, "0x01", "ONOFF", "ON", "0", "S_BUTTON_1", "S_BUTTON_ACTION_SHORT_RELEASED", "On"], - [2, "0x01", "ONOFF", "ON", "0", "S_BUTTON_1", "S_BUTTON_ACTION_SHORT_RELEASED", "On"], - [3, "0x01", "ONOFF", "ON", "0", "S_BUTTON_1", "S_BUTTON_ACTION_SHORT_RELEASED", "On"], - [1, "0x01", "LEVEL_CONTROL", "MOVE", "0", "S_BUTTON_1", "S_BUTTON_ACTION_HOLD", "Dimm up"], - [2, "0x01", "LEVEL_CONTROL", "MOVE", "0", "S_BUTTON_1", "S_BUTTON_ACTION_HOLD", "Dimm up"], - [3, "0x01", "LEVEL_CONTROL", "MOVE", "0", "S_BUTTON_1", "S_BUTTON_ACTION_HOLD", "Dimm up"], - [1, "0x01", "LEVEL_CONTROL", "STOP", "0", "S_BUTTON_1", "S_BUTTON_ACTION_LONG_RELEASED", "Dimm stop"], - [2, "0x01", "LEVEL_CONTROL", "STOP", "0", "S_BUTTON_1", "S_BUTTON_ACTION_LONG_RELEASED", "Dimm stop"], - [3, "0x01", "LEVEL_CONTROL", "STOP", "0", "S_BUTTON_1", "S_BUTTON_ACTION_LONG_RELEASED", "Dimm stop"], - - [1, "0x01", "ONOFF", "OFF", "0", "S_BUTTON_2", "S_BUTTON_ACTION_SHORT_RELEASED", "Off"], - [2, "0x01", "ONOFF", "OFF", "0", "S_BUTTON_2", "S_BUTTON_ACTION_SHORT_RELEASED", "Off"], - [3, "0x01", "ONOFF", "OFF", "0", "S_BUTTON_2", "S_BUTTON_ACTION_SHORT_RELEASED", "Off"], - [1, "0x01", "LEVEL_CONTROL", "MOVE", "1", "S_BUTTON_2", "S_BUTTON_ACTION_HOLD", "Dimm down"], - [2, "0x01", "LEVEL_CONTROL", "MOVE", "1", "S_BUTTON_2", "S_BUTTON_ACTION_HOLD", "Dimm down"], - [3, "0x01", "LEVEL_CONTROL", "MOVE", "1", "S_BUTTON_2", "S_BUTTON_ACTION_HOLD", "Dimm down"], - [1, "0x01", "LEVEL_CONTROL", "STOP", "1", "S_BUTTON_2", "S_BUTTON_ACTION_LONG_RELEASED", "Dimm stop"], - [2, "0x01", "LEVEL_CONTROL", "STOP", "1", "S_BUTTON_2", "S_BUTTON_ACTION_LONG_RELEASED", "Dimm stop"], - [3, "0x01", "LEVEL_CONTROL", "STOP", "1", "S_BUTTON_2", "S_BUTTON_ACTION_LONG_RELEASED", "Dimm stop"], - - [1, "0x01", "SCENES", "RECALL_SCENE", "1", "S_BUTTON_3", "S_BUTTON_ACTION_SHORT_RELEASED", "Recall scene 1"], - [2, "0x02", "ONOFF", "ON", "0", "S_BUTTON_3", "S_BUTTON_ACTION_SHORT_RELEASED", "On"], - [3, "0x01", "COLOR_CONTROL", "MOVE_COLOR_TEMPERATURE", "0x01FE", "S_BUTTON_3", "S_BUTTON_ACTION_SHORT_RELEASED", "Color temperature move up"], - [2, "0x02", "LEVEL_CONTROL", "MOVE_WITH_ON_OFF", "0", "S_BUTTON_3", "S_BUTTON_ACTION_HOLD", "Dimm up"], - [3, "0x01", "COLOR_CONTROL", "MOVE_COLOR_TEMPERATURE", "0x0128", "S_BUTTON_3", "S_BUTTON_ACTION_HOLD", "Color temperature move up hold"], - [2, "0x02", "LEVEL_CONTROL", "STOP", "0", "S_BUTTON_3", "S_BUTTON_ACTION_LONG_RELEASED", "Dimm stop"], - [3, "0x01", "COLOR_CONTROL", "MOVE_COLOR_TEMPERATURE", "0x1028", "S_BUTTON_3", "S_BUTTON_ACTION_LONG_RELEASED", "Color temperature move up stop"], - - - [1, "0x01", "SCENES", "RECALL_SCENE", "4", "S_BUTTON_4", "S_BUTTON_ACTION_SHORT_RELEASED", "Recall scene 4"], - [2, "0x02", "ONOFF", "OFF", "0", "S_BUTTON_4", "S_BUTTON_ACTION_SHORT_RELEASED", "Off"], - [3, "0x01", "COLOR_CONTROL", "MOVE_COLOR_TEMPERATURE", "0x03FE", "S_BUTTON_4", "S_BUTTON_ACTION_SHORT_RELEASED", "Color temperature move down"], - [2, "0x02", "LEVEL_CONTROL", "MOVE", "1", "S_BUTTON_4", "S_BUTTON_ACTION_HOLD", "Dimm down"], - [3, "0x01", "COLOR_CONTROL", "MOVE_COLOR_TEMPERATURE", "0x0328", "S_BUTTON_4", "S_BUTTON_ACTION_HOLD", "Color temperature move down hold"], - [2, "0x02", "LEVEL_CONTROL", "STOP", "1", "S_BUTTON_4", "S_BUTTON_ACTION_LONG_RELEASED", "Dimm stop"], - [3, "0x01", "COLOR_CONTROL", "MOVE_COLOR_TEMPERATURE", "0x3028", "S_BUTTON_4", "S_BUTTON_ACTION_LONG_RELEASED", "Color temperature move down stop"] - ] - }, - "deSceneSwitchMap": { - "vendor": "dresden elektronik", - "modelids": ["Scene Switch"], - "doc": "Scene Switch", - "buttons": [ - {"S_BUTTON_1": "Top Left"}, - {"S_BUTTON_2": "Bottom Left"}, - {"S_BUTTON_3": "Scene 1"}, - {"S_BUTTON_4": "Scene 2"}, - {"S_BUTTON_5": "Scene 3"}, - {"S_BUTTON_6": "Scene 4"} - ], - "map": [ - [1, "0x01", "ONOFF", "ON", "0", "S_BUTTON_1", "S_BUTTON_ACTION_SHORT_RELEASED", "On"], - [1, "0x01", "LEVEL_CONTROL", "MOVE", "0", "S_BUTTON_1", "S_BUTTON_ACTION_HOLD", "Dimm up"], - [1, "0x01", "LEVEL_CONTROL", "STOP", "0", "S_BUTTON_1", "S_BUTTON_ACTION_LONG_RELEASED", "Dimm up stop"], - - [1, "0x01", "ONOFF", "OFF", "0", "S_BUTTON_2", "S_BUTTON_ACTION_SHORT_RELEASED", "Off"], - [1, "0x01", "LEVEL_CONTROL", "MOVE", "1", "S_BUTTON_2", "S_BUTTON_ACTION_HOLD", "Dimm down"], - [1, "0x01", "LEVEL_CONTROL", "STOP", "1", "S_BUTTON_2", "S_BUTTON_ACTION_LONG_RELEASED", "Dimm down stop"], - - [1, "0x01", "SCENES", "RECALL_SCENE", "1", "S_BUTTON_3", "S_BUTTON_ACTION_SHORT_RELEASED", "Recall scene 1"], - [1, "0x01", "SCENES", "RECALL_SCENE", "2", "S_BUTTON_4", "S_BUTTON_ACTION_SHORT_RELEASED", "Recall scene 2"], - [1, "0x01", "SCENES", "RECALL_SCENE", "3", "S_BUTTON_5", "S_BUTTON_ACTION_SHORT_RELEASED", "Recall scene 3"], - [1, "0x01", "SCENES", "RECALL_SCENE", "4", "S_BUTTON_6", "S_BUTTON_ACTION_SHORT_RELEASED", "Recall scene 4"] - ] - }, "deKoboldMap": { "vendor": "dresden elektronik", "modelids": ["Kobold"], diff --git a/de_web_plugin.cpp b/de_web_plugin.cpp index 0b95721ae0..0ea7d855e7 100644 --- a/de_web_plugin.cpp +++ b/de_web_plugin.cpp @@ -195,8 +195,6 @@ static const SupportedDevice supportedDevices[] = { { VENDOR_NONE, "SPW35Z", tiMacPrefix }, // RT-RK OBLO SPW35ZD0 smart plug { VENDOR_NONE, "SWO-MOS1PA", tiMacPrefix }, // Swann One Motion Sensor { VENDOR_BITRON, "902010/32", emberMacPrefix }, // Bitron: thermostat - { VENDOR_DDEL, "Lighting Switch", deMacPrefix }, - { VENDOR_DDEL, "Scene Switch", deMacPrefix }, { VENDOR_IKEA, "TRADFRI remote control", silabs1MacPrefix }, { VENDOR_IKEA, "TRADFRI remote control", silabsMacPrefix }, { VENDOR_IKEA, "TRADFRI remote control", silabs2MacPrefix }, @@ -4500,47 +4498,6 @@ void DeRestPluginPrivate::checkSensorButtonEvent(Sensor *sensor, const deCONZ::A { // DDF managed devices handle this in another place } - // DE Lighting Switch: probe for mode changes - else if (sensor->modelId() == QLatin1String("Lighting Switch") && ind.dstAddressMode() == deCONZ::ApsGroupAddress) - { - Sensor::SensorMode mode = sensor->mode(); - - if (ind.srcEndpoint() == 2 && mode != Sensor::ModeTwoGroups) - { - mode = Sensor::ModeTwoGroups; - } - else if (ind.clusterId() == SCENE_CLUSTER_ID && mode != Sensor::ModeScenes) - { - mode = Sensor::ModeScenes; - } - else if (ind.clusterId() == COLOR_CLUSTER_ID && mode != Sensor::ModeColorTemperature) - { - mode = Sensor::ModeColorTemperature; - } - - Sensor *other = getSensorNodeForAddressAndEndpoint(sensor->address(), (sensor->fingerPrint().endpoint == 2) ? 1 : 2); - - if (mode != sensor->mode()) - { - sensor->setMode(mode); - updateSensorEtag(sensor); - sensor->setNeedSaveDatabase(true); - queSaveDb(DB_SENSORS, DB_SHORT_SAVE_DELAY); - - // set changed mode for sensor endpoints 1 and 2 - if (other) - { - other->setMode(mode); - other->setNeedSaveDatabase(true); - updateSensorEtag(other); - } - } - - if (other && ind.srcEndpoint() == 2 && other->fingerPrint().endpoint == 1) - { // forward button events 300x and 400x to first endpoint sensor - checkSensorButtonEvent(other, ind, zclFrame); - } - } // Busch-Jaeger else if (sensor->modelId() == QLatin1String("RM01") || sensor->modelId() == QLatin1String("RB01")) { @@ -4661,11 +4618,6 @@ void DeRestPluginPrivate::checkSensorButtonEvent(Sensor *sensor, const deCONZ::A } else if (ind.dstAddressMode() == deCONZ::ApsGroupAddress) { - if (sensor->mode() == Sensor::ModeTwoGroups) // only supported for DE Lighting Switch - { - sensor->setMode(Sensor::ModeScenes); - updateSensorEtag(sensor); - } } else if (sensor->modelId().endsWith(QLatin1String("86opcn01"))) // Aqara Opple { @@ -4725,21 +4677,6 @@ void DeRestPluginPrivate::checkSensorButtonEvent(Sensor *sensor, const deCONZ::A quint16 groupId = ind.dstAddress().group(); - if (sensor->modelId() == QLatin1String("Lighting Switch")) - { - // adjust groupId for endpoints - // ep 1: - // ep 2: + 1 - if (sensor->fingerPrint().endpoint == 2 && ind.srcEndpoint() == 1) - { - groupId++; - } - else if (sensor->fingerPrint().endpoint == 1 && ind.srcEndpoint() == 2) - { - groupId--; - } - } - QStringList gids; const QString gid = QString::number(groupId); @@ -7715,12 +7652,6 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const SensorFi } else if (node->nodeDescriptor().manufacturerCode() == VENDOR_DDEL) { - sensorNode.setManufacturer("dresden elektronik"); - - if (modelId == QLatin1String("Lighting Switch")) - { - sensorNode.setMode(Sensor::ModeTwoGroups); // inital - } } else if ((node->nodeDescriptor().manufacturerCode() == VENDOR_OSRAM_STACK) || (node->nodeDescriptor().manufacturerCode() == VENDOR_OSRAM)) { @@ -16728,10 +16659,24 @@ void DEV_AllocateGroup(const Device *device, Resource *rsub, ResourceItem *item) if (groupList[i] != QLatin1String("auto") && groupList[i] != QLatin1String("null")) { // verify group exists - auto g = std::find_if(groups.begin(), groups.end(), [&](const Group &x) - { return x.state() == Group::StateNormal && x.id() == groupList[i]; }); + auto g = std::find_if(groups.begin(), groups.end(), [&](const Group &x) { + const ResourceItem *itemUniqueId = x.item(RAttrUniqueId); + if (x.state() == Group::StateNormal) + { + if (x.id() == groupList[i]) + { + return true; + } + + if (itemUniqueId && itemUniqueId->toString() == gUniqueId) + { + return true; + } + } + return false; + }); - if (g == groups.cend()) + if (g == groups.end()) { bool ok; uint gid = groupList[i].toUInt(&ok, 0); diff --git a/devices/dresden_elektronik/lighting_switch.json b/devices/dresden_elektronik/lighting_switch.json new file mode 100644 index 0000000000..807e11a6bc --- /dev/null +++ b/devices/dresden_elektronik/lighting_switch.json @@ -0,0 +1,332 @@ +{ + "schema": "devcap1.schema.json", + "manufacturername": "dresden elektronik", + "modelid": "Lighting Switch", + "product": "Lighting Switch", + "sleeper": true, + "status": "Gold", + "subdevices": [ + { + "type": "$TYPE_SWITCH", + "restapi": "/sensors", + "uuid": [ + "$address.ext", + "0x01", + "0x1000" + ], + "fingerprint": { + "profile": "0x0104", + "device": "0x0800", + "endpoint": "0x01", + "in": [ + "0x0000", + "0x1000" + ], + "out": [ + "0x0006", + "0x0008", + "0x0005" + ] + }, + "buttons": { + "1": { + "name": "Top Left" + }, + "2": { + "name": "Bottom Left" + }, + "3": { + "name": "Top Right" + }, + "4": { + "name": "Bottom Right" + } + }, + "buttonevents": { + "1001": { + "action": "HOLD", + "button": 1 + }, + "1002": { + "action": "SHORT_RELEASE", + "button": 1 + }, + "1003": { + "action": "LONG_RELEASE", + "button": 1 + }, + "2001": { + "action": "HOLD", + "button": 2 + }, + "2002": { + "action": "SHORT_RELEASE", + "button": 2 + }, + "2003": { + "action": "LONG_RELEASE", + "button": 2 + }, + "3001": { + "action": "HOLD", + "button": 3 + }, + "3002": { + "action": "SHORT_RELEASE", + "button": 3 + }, + "3003": { + "action": "LONG_RELEASE", + "button": 3 + }, + "4001": { + "action": "HOLD", + "button": 4 + }, + "4002": { + "action": "SHORT_RELEASE", + "button": 4 + }, + "4003": { + "action": "LONG_RELEASE", + "button": 4 + } + }, + "meta": {"group.endpoints": [1] }, + "items": [ + { + "name": "attr/id" + }, + { + "name": "attr/lastannounced" + }, + { + "name": "attr/lastseen" + }, + { + "name": "attr/manufacturername" + }, + { + "name": "attr/mode", + "default": 2 + }, + { + "name": "attr/modelid" + }, + { + "name": "attr/name" + }, + { + "name": "attr/swversion" + }, + { + "name": "attr/type" + }, + { + "name": "attr/uniqueid" + }, + { + "name": "config/group", + "default": "65535" + }, + { + "name": "config/on" + }, + { + "name": "config/reachable" + }, + { + "name": "state/buttonevent" + }, + { + "name": "state/lastupdated" + }, + { + "name": "state/on", + "public": false, + "parse": { + "fn": "zcl:cmd", + "ep": 255, + "cl": "0x0006", + "cmd": "any", + "script": "lighting_switch_on.js" + }, + "read": { + "fn": "none" + } + }, + { + "name": "state/bri", + "public": false, + "parse": { + "fn": "zcl:cmd", + "ep": 255, + "cl": "0x0008", + "cmd": "any", + "script": "lighting_switch_bri.js" + }, + "read": { + "fn": "none" + } + }, + { + "name": "state/sat", + "public": false, + "parse": { + "fn": "zcl:cmd", + "ep": 255, + "cl": "0x0005", + "cmd": "any", + "script": "lighting_switch_scenes.js" + }, + "read": { + "fn": "none" + } + }, + { + "name": "state/temperature_bis", + "public": false, + "parse": { + "fn": "zcl:cmd", + "ep": 255, + "cl": "0x0300", + "cmd": "any", + "script": "lighting_switch_ct.js" + }, + "read": { + "fn": "none" + } + } + ] + }, + { + "type": "$TYPE_SWITCH", + "restapi": "/sensors", + "uuid": [ + "$address.ext", + "0x02", + "0x1000" + ], + "fingerprint": { + "profile": "0x0104", + "device": "0x0800", + "endpoint": "0x02", + "in": [ + "0x0000", + "0x1000" + ], + "out": [ + "0x0006", + "0x0008", + "0x0005" + ] + }, + "meta": {"group.endpoints": [2] }, + "items": [ + { + "name": "attr/id" + }, + { + "name": "attr/lastannounced" + }, + { + "name": "attr/lastseen" + }, + { + "name": "attr/manufacturername" + }, + { + "name": "attr/mode", + "default": 2 + }, + { + "name": "attr/modelid" + }, + { + "name": "attr/name" + }, + { + "name": "attr/swversion" + }, + { + "name": "attr/type" + }, + { + "name": "attr/uniqueid" + }, + { + "name": "config/group", + "default": "65535" + }, + { + "name": "config/on" + }, + { + "name": "config/reachable" + }, + { + "name": "state/buttonevent" + }, + { + "name": "state/lastupdated" + }, + { + "name": "state/on", + "public": false, + "parse": { + "fn": "zcl:cmd", + "ep": 255, + "cl": "0x0006", + "cmd": "any", + "script": "lighting_switch_on.js" + }, + "read": { + "fn": "none" + } + }, + { + "name": "state/bri", + "public": false, + "parse": { + "fn": "zcl:cmd", + "ep": 255, + "cl": "0x0008", + "cmd": "any", + "script": "lighting_switch_bri.js" + }, + "read": { + "fn": "none" + } + }, + { + "name": "state/sat", + "public": false, + "parse": { + "fn": "zcl:cmd", + "ep": 255, + "cl": "0x0005", + "cmd": "any", + "script": "lighting_switch_scenes.js" + }, + "read": { + "fn": "none" + } + }, + { + "name": "state/temperature_bis", + "public": false, + "parse": { + "fn": "zcl:cmd", + "ep": 255, + "cl": "0x0300", + "cmd": "any", + "script": "lighting_switch_ct.js" + }, + "read": { + "fn": "none" + } + } + ] + } + ] +} diff --git a/devices/dresden_elektronik/lighting_switch_bri.js b/devices/dresden_elektronik/lighting_switch_bri.js new file mode 100644 index 0000000000..5a58a09418 --- /dev/null +++ b/devices/dresden_elektronik/lighting_switch_bri.js @@ -0,0 +1,10 @@ +var i = R.item("state/buttonevent"); +if (ZclFrame.cmd == 1) { + if (ZclFrame.at(0) == 0) + i.val = (SrcEp == 1) ? 1001 : 3001; + else + i.val = (SrcEp == 1) ? 2001 : 4001; +} else if (ZclFrame.cmd == 3) { + var v = i.val >> 2; + i.val = ((v << 2) / 1000) * 1000 + 3; +} diff --git a/devices/dresden_elektronik/lighting_switch_ct.js b/devices/dresden_elektronik/lighting_switch_ct.js new file mode 100644 index 0000000000..8fc926754d --- /dev/null +++ b/devices/dresden_elektronik/lighting_switch_ct.js @@ -0,0 +1,19 @@ +var i = R.item("state/buttonevent"); +if (ZclFrame.cmd == 0x4b) { + var mode = ZclFrame.at(0); + var rate = ZclFrame.at(1); + var button; + if (mode == 1) button = 3000; + else if (mode == 3) button = 4000; + else { + button = i.val >> 2; + button = ((button << 2) / 1000) * 1000; + } + + if (mode == 0) button += 3; + else if (rate == 0xfe) button += 2; + else button += 1; + + i.val = button; + R.item("attr/mode").val = 3; +} diff --git a/devices/dresden_elektronik/lighting_switch_on.js b/devices/dresden_elektronik/lighting_switch_on.js new file mode 100644 index 0000000000..1a7397df0e --- /dev/null +++ b/devices/dresden_elektronik/lighting_switch_on.js @@ -0,0 +1,9 @@ +var i = R.item("state/buttonevent"); +if (ZclFrame.cmd == 1) { + i.val = (SrcEp == 1) ? 1002 : 3002; +} else if (ZclFrame.cmd == 0) { + i.val = (SrcEp == 1) ? 2002 : 4002; +} +if (SrcEp == 2) { + R.item("attr/mode").val = 2; +} diff --git a/devices/dresden_elektronik/lighting_switch_scenes.js b/devices/dresden_elektronik/lighting_switch_scenes.js new file mode 100644 index 0000000000..0aa24ef5b2 --- /dev/null +++ b/devices/dresden_elektronik/lighting_switch_scenes.js @@ -0,0 +1,13 @@ +var i = R.item("state/buttonevent"); +if (ZclFrame.cmd == 5) { + if (ZclFrame.at(2) == 1) + i.val = 3002; + else + i.val = 4002; +} else if (ZclFrame.cmd == 4) { + if (ZclFrame.at(2) == 1) + i.val = 3003; + else + i.val = 4003; +} +R.item("attr/mode").val = 1; \ No newline at end of file diff --git a/devices/dresden_elektronik/scene_switch.json b/devices/dresden_elektronik/scene_switch.json new file mode 100644 index 0000000000..3017d5232a --- /dev/null +++ b/devices/dresden_elektronik/scene_switch.json @@ -0,0 +1,142 @@ +{ + "schema": "devcap1.schema.json", + "manufacturername": "dresden elektronik", + "modelid": "Scene Switch", + "product": "Scene Switch", + "sleeper": true, + "status": "Gold", + "subdevices": [ + { + "type": "$TYPE_SWITCH", + "restapi": "/sensors", + "uuid": [ + "$address.ext", + "0x01", + "0x1000" + ], + "fingerprint": { + "profile": "0xC05E", + "device": "0x0800", + "endpoint": "0x01", + "in": [ + "0x0000", + "0x1000" + ], + "out": [ + "0x0006", + "0x0008", + "0x0005" + ] + }, + "buttons": { + "1": { + "name": "Top Left" + }, + "2": { + "name": "Bottom Left" + }, + "3": { + "name": "Scene 1" + }, + "4": { + "name": "Scene 2" + }, + "5": { + "name": "Scene 3" + }, + "6": { + "name": "Scene 4" + } + }, + "buttonevents": { + "1001": { + "action": "HOLD", + "button": 1 + }, + "1002": { + "action": "SHORT_RELEASE", + "button": 1 + }, + "1003": { + "action": "LONG_RELEASE", + "button": 1 + }, + "2001": { + "action": "HOLD", + "button": 2 + }, + "2002": { + "action": "SHORT_RELEASE", + "button": 2 + }, + "2003": { + "action": "LONG_RELEASE", + "button": 2 + }, + "3002": { + "action": "SHORT_RELEASE", + "button": 3 + }, + "4002": { + "action": "SHORT_RELEASE", + "button": 4 + }, + "5002": { + "action": "SHORT_RELEASE", + "button": 5 + }, + "6002": { + "action": "SHORT_RELEASE", + "button": 6 + } + }, + "meta": {"group.endpoints": [1] }, + "items": [ + { + "name": "attr/id" + }, + { + "name": "attr/lastannounced" + }, + { + "name": "attr/lastseen" + }, + { + "name": "attr/manufacturername" + }, + { + "name": "attr/modelid" + }, + { + "name": "attr/name" + }, + { + "name": "attr/swversion" + }, + { + "name": "attr/type" + }, + { + "name": "attr/uniqueid" + }, + { + "name": "config/group", + "default": "65535" + }, + { + "name": "config/on" + }, + { + "name": "config/reachable" + }, + { + "name": "state/buttonevent", + "awake": true + }, + { + "name": "state/lastupdated" + } + ] + } + ] +} diff --git a/rest_sensors.cpp b/rest_sensors.cpp index ad0d9a1626..37192852e8 100644 --- a/rest_sensors.cpp +++ b/rest_sensors.cpp @@ -3950,308 +3950,7 @@ void DeRestPluginPrivate::handleIndicationSearchSensors(const deCONZ::ApsDataInd return; } - // check for dresden elektronik devices - if (existDevicesWithVendorCodeForMacPrefix(sc->address, VENDOR_DDEL)) - { - if (sc->macCapabilities & deCONZ::MacDeviceIsFFD) // end-devices only - return; - - if (ind.profileId() != HA_PROFILE_ID) - return; - - SensorCommand cmd; - cmd.cluster = ind.clusterId(); - cmd.endpoint = ind.srcEndpoint(); - cmd.dstGroup = ind.dstAddress().group(); - cmd.zclCommand = zclFrame.commandId(); - cmd.zclCommandParameter = 0; - - // filter - if (cmd.endpoint == 0x01 && cmd.cluster == ONOFF_CLUSTER_ID) - { - // on: Lighting and Scene Switch left button - DBG_Printf(DBG_INFO, "Lighting or Scene Switch left button\n"); - } - else if (cmd.endpoint == 0x02 && cmd.cluster == ONOFF_CLUSTER_ID) - { - // on: Lighting Switch right button - DBG_Printf(DBG_INFO, "Lighting Switch right button\n"); - } - else if (cmd.endpoint == 0x01 && cmd.cluster == SCENE_CLUSTER_ID && cmd.zclCommand == 0x05 - && zclFrame.payload().size() >= 3 && zclFrame.payload().at(2) == 0x04) - { - // recall scene: Scene Switch - cmd.zclCommandParameter = zclFrame.payload()[2]; // sceneId - DBG_Printf(DBG_INFO, "Scene Switch scene %u\n", cmd.zclCommandParameter); - } - else - { - return; - } - - bool found = false; - for (size_t i = 0; i < sc->rxCommands.size(); i++) - { - if (sc->rxCommands[i] == cmd) - { - found = true; - break; - } - } - - if (!found) - { - sc->rxCommands.push_back(cmd); - } - - bool isLightingSwitch = false; - bool isSceneSwitch = false; - quint16 group1 = 0; - quint16 group2 = 0; - - for (size_t i = 0; i < sc->rxCommands.size(); i++) - { - const SensorCommand &c = sc->rxCommands[i]; - if (c.cluster == SCENE_CLUSTER_ID && c.zclCommandParameter == 0x04 && c.endpoint == 0x01) - { - group1 = c.dstGroup; - isSceneSwitch = true; - DBG_Printf(DBG_INFO, "Scene Switch group1 0x%04X\n", group1); - break; - } - else if (c.cluster == ONOFF_CLUSTER_ID && c.endpoint == 0x01) - { - group1 = c.dstGroup; - } - else if (c.cluster == ONOFF_CLUSTER_ID && c.endpoint == 0x02) - { - group2 = c.dstGroup; - } - - if (!isSceneSwitch && group1 != 0 && group2 != 0) - { - if (group1 > group2) - { - std::swap(group1, group2); // reorder - } - isLightingSwitch = true; - DBG_Printf(DBG_INFO, "Lighting Switch group1 0x%04X, group2 0x%04X\n", group1, group2); - break; - } - } - - Sensor *s1 = getSensorNodeForAddressAndEndpoint(ind.srcAddress(), 0x01); - Sensor *s2 = getSensorNodeForAddressAndEndpoint(ind.srcAddress(), 0x02); - - if (isSceneSwitch || isLightingSwitch) - { - Sensor sensorNode; - SensorFingerprint &fp = sensorNode.fingerPrint(); - fp.endpoint = 0x01; - fp.deviceId = DEV_ID_ZLL_COLOR_CONTROLLER; - fp.profileId = HA_PROFILE_ID; - fp.inClusters.push_back(BASIC_CLUSTER_ID); - fp.inClusters.push_back(COMMISSIONING_CLUSTER_ID); - fp.outClusters.push_back(ONOFF_CLUSTER_ID); - fp.outClusters.push_back(LEVEL_CLUSTER_ID); - fp.outClusters.push_back(SCENE_CLUSTER_ID); - - sensorNode.setNode(0); - sensorNode.address() = sc->address; - sensorNode.setType(QLatin1String("ZHASwitch")); - sensorNode.fingerPrint() = fp; - sensorNode.setUniqueId(generateUniqueId(sensorNode.address().ext(), sensorNode.fingerPrint().endpoint, COMMISSIONING_CLUSTER_ID)); - sensorNode.setManufacturer(QLatin1String("dresden elektronik")); - - ResourceItem *item; - item = sensorNode.item(RConfigOn); - item->setValue(true); - - item = sensorNode.item(RConfigReachable); - item->setValue(true); - - sensorNode.addItem(DataTypeInt32, RStateButtonEvent); - sensorNode.updateStateTimestamp(); - - sensorNode.setNeedSaveDatabase(true); - updateSensorEtag(&sensorNode); - - bool update = false; - - if (!s1 && isSceneSwitch && searchSensorsState == SearchSensorsActive) - { - openDb(); - sensorNode.setId(QString::number(getFreeSensorId())); - closeDb(); - sensorNode.setMode(Sensor::ModeScenes); - sensorNode.setModelId(QLatin1String("Scene Switch")); - sensorNode.setName(QString("Scene Switch %1").arg(sensorNode.id())); - sensorNode.setNeedSaveDatabase(true); - sensors.push_back(sensorNode); - s1 = &sensors.back(); - updateSensorEtag(s1); - update = true; - Event e(RSensors, REventAdded, sensorNode.id()); - enqueueEvent(e); - } - else if (isLightingSwitch) - { - if (!s1 && searchSensorsState == SearchSensorsActive) - { - openDb(); - sensorNode.setId(QString::number(getFreeSensorId())); - closeDb(); - sensorNode.setMode(Sensor::ModeTwoGroups); - sensorNode.setModelId(QLatin1String("Lighting Switch")); - sensorNode.setName(QString("Lighting Switch %1").arg(sensorNode.id())); - sensorNode.setNeedSaveDatabase(true); - sensors.push_back(sensorNode); - s1 = &sensors.back(); - updateSensorEtag(s1); - update = true; - Event e(RSensors, REventAdded, sensorNode.id()); - enqueueEvent(e); - } - - if (!s2 && searchSensorsState == SearchSensorsActive) - { - openDb(); - sensorNode.setId(QString::number(getFreeSensorId())); - closeDb(); - sensorNode.setMode(Sensor::ModeTwoGroups); - sensorNode.setName(QString("Lighting Switch %1").arg(sensorNode.id())); - sensorNode.setNeedSaveDatabase(true); - sensorNode.fingerPrint().endpoint = 0x02; - sensorNode.setUniqueId(generateUniqueId(sensorNode.address().ext(), sensorNode.fingerPrint().endpoint, COMMISSIONING_CLUSTER_ID)); - sensors.push_back(sensorNode); - s2 = &sensors.back(); - updateSensorEtag(s2); - update = true; - Event e(RSensors, REventAdded, sensorNode.id()); - enqueueEvent(e); - } - } - - // check updated data - if (s1 && s1->modelId().isEmpty()) - { - if (isSceneSwitch) { s1->setModelId(QLatin1String("Scene Switch")); } - else if (isLightingSwitch) { s1->setModelId(QLatin1String("Lighting Switch")); } - s1->setNeedSaveDatabase(true); - update = true; - } - - if (s2 && s2->modelId().isEmpty()) - { - if (isLightingSwitch) { s2->setModelId(QLatin1String("Lighting Switch")); } - s2->setNeedSaveDatabase(true); - update = true; - } - - if (s1 && s1->manufacturer().isEmpty()) - { - s1->setManufacturer(QLatin1String("dresden elektronik")); - s1->setNeedSaveDatabase(true); - update = true; - } - - if (s2 && s2->manufacturer().isEmpty()) - { - s2->setManufacturer(QLatin1String("dresden elektronik")); - s2->setNeedSaveDatabase(true); - update = true; - } - - // create or update first group - Group *g = (s1 && group1 != 0) ? getGroupForId(group1) : 0; - if (!g && s1 && group1 != 0) - { - // delete older groups of this switch permanently - deleteOldGroupOfSwitch(s1, group1); - - //create new switch group - Group group; - group.setAddress(group1); - group.addDeviceMembership(s1->id()); - group.setName(QString("%1").arg(s1->name())); - updateGroupEtag(&group); - groups.push_back(group); - update = true; - } - else if (g && s1) - { - if (g->state() == Group::StateDeleted) - { - g->setState(Group::StateNormal); - } - - // check for changed device memberships - if (!g->m_deviceMemberships.empty()) - { - if (isLightingSwitch || isSceneSwitch) // only support one device member per group - { - if (g->m_deviceMemberships.size() > 1 || g->m_deviceMemberships.front() != s1->id()) - { - g->m_deviceMemberships.clear(); - } - } - } - - if (g->addDeviceMembership(s1->id())) - { - updateGroupEtag(g); - update = true; - } - } - - // create or update second group (if needed) - g = (s2 && group2 != 0) ? getGroupForId(group2) : 0; - if (!g && s2 && group2 != 0) - { - // delete older groups of this switch permanently - deleteOldGroupOfSwitch(s2, group2); - - //create new switch group - Group group; - group.setAddress(group2); - group.addDeviceMembership(s2->id()); - group.setName(QString("%1").arg(s2->name())); - updateGroupEtag(&group); - groups.push_back(group); - } - else if (g && s2) - { - if (g->state() == Group::StateDeleted) - { - g->setState(Group::StateNormal); - } - - // check for changed device memberships - if (!g->m_deviceMemberships.empty()) - { - if (isLightingSwitch || isSceneSwitch) // only support one device member per group - { - if (g->m_deviceMemberships.size() > 1 || g->m_deviceMemberships.front() != s2->id()) - { - g->m_deviceMemberships.clear(); - } - } - } - - if (g->addDeviceMembership(s2->id())) - { - updateGroupEtag(g); - update = true; - } - } - - if (update) - { - queSaveDb(DB_GROUPS | DB_SENSORS, DB_SHORT_SAVE_DELAY); - } - } - } - else if (existDevicesWithVendorCodeForMacPrefix(sc->address, VENDOR_IKEA)) + if (existDevicesWithVendorCodeForMacPrefix(sc->address, VENDOR_IKEA)) { if (sc->macCapabilities & deCONZ::MacDeviceIsFFD) // end-devices only return;