From f3776b129cf8fb1360c426ce1a6c8b6b0f44b8ea Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Tue, 26 Nov 2019 23:37:55 +0100 Subject: [PATCH 1/2] Tasmota: Add Blinds connected device and bring 4CH device up to par with others --- tasmota/deviceplugintasmota.cpp | 34 ++++++++++++---- tasmota/deviceplugintasmota.h | 4 ++ tasmota/deviceplugintasmota.json | 68 +++++++++++++++++++++++++++----- 3 files changed, 89 insertions(+), 17 deletions(-) diff --git a/tasmota/deviceplugintasmota.cpp b/tasmota/deviceplugintasmota.cpp index a87f7267..094e1c1b 100644 --- a/tasmota/deviceplugintasmota.cpp +++ b/tasmota/deviceplugintasmota.cpp @@ -51,10 +51,19 @@ DevicePluginTasmota::DevicePluginTasmota() m_channelParamTypeMap[tasmotaLightDeviceClassId] = tasmotaLightDeviceChannelNameParamTypeId; m_openingChannelParamTypeMap[tasmotaShutterDeviceClassId] = tasmotaShutterDeviceOpeningChannelParamTypeId; m_closingChannelParamTypeMap[tasmotaShutterDeviceClassId] = tasmotaShutterDeviceClosingChannelParamTypeId; + m_openingChannelParamTypeMap[tasmotaBlindsDeviceClassId] = tasmotaBlindsDeviceOpeningChannelParamTypeId; + m_closingChannelParamTypeMap[tasmotaBlindsDeviceClassId] = tasmotaBlindsDeviceClosingChannelParamTypeId; m_powerStateTypeMap[tasmotaSwitchDeviceClassId] = tasmotaSwitchPowerStateTypeId; m_powerStateTypeMap[tasmotaLightDeviceClassId] = tasmotaLightPowerStateTypeId; + m_closableOpenActionTypeMap[tasmotaShutterDeviceClassId] = tasmotaShutterOpenActionTypeId; + m_closableCloseActionTypeMap[tasmotaShutterDeviceClassId] = tasmotaShutterCloseActionTypeId; + m_closableStopActionTypeMap[tasmotaShutterDeviceClassId] = tasmotaShutterStopActionTypeId; + + m_closableOpenActionTypeMap[tasmotaBlindsDeviceClassId] = tasmotaBlindsOpenActionTypeId; + m_closableCloseActionTypeMap[tasmotaBlindsDeviceClassId] = tasmotaBlindsCloseActionTypeId; + m_closableStopActionTypeMap[tasmotaBlindsDeviceClassId] = tasmotaBlindsStopActionTypeId; // Helper maps for all devices m_connectedStateTypeMap[sonoff_basicDeviceClassId] = sonoff_basicConnectedStateTypeId; @@ -64,6 +73,7 @@ DevicePluginTasmota::DevicePluginTasmota() m_connectedStateTypeMap[tasmotaSwitchDeviceClassId] = tasmotaSwitchConnectedStateTypeId; m_connectedStateTypeMap[tasmotaLightDeviceClassId] = tasmotaLightConnectedStateTypeId; m_connectedStateTypeMap[tasmotaShutterDeviceClassId] = tasmotaShutterConnectedStateTypeId; + m_connectedStateTypeMap[tasmotaBlindsDeviceClassId] = tasmotaBlindsConnectedStateTypeId; } DevicePluginTasmota::~DevicePluginTasmota() @@ -157,6 +167,8 @@ void DevicePluginTasmota::setupDevice(DeviceSetupInfo *info) deviceDescriptors.clear(); int shutterUpChannel = -1; int shutterDownChannel = -1; + int blindsUpChannel = -1; + int blindsDownChannel = -1; for (int i = 0; i < m_attachedDeviceParamTypeIdMap.value(info->device()->deviceClassId()).count(); i++) { ParamTypeId attachedDeviceParamTypeId = m_attachedDeviceParamTypeIdMap.value(info->device()->deviceClassId()).at(i); QString deviceType = info->device()->paramValue(attachedDeviceParamTypeId).toString(); @@ -174,12 +186,12 @@ void DevicePluginTasmota::setupDevice(DeviceSetupInfo *info) shutterUpChannel = i+1; } else if (deviceType == "Roller Shutter Down") { shutterDownChannel = i+1; + } else if (deviceType == "Blinds Up") { + blindsUpChannel = i+1; + } else if (deviceType == "Blinds Down") { + blindsDownChannel = i+1; } } - if (!deviceDescriptors.isEmpty()) { - emit autoDevicesAppeared(deviceDescriptors); - } - deviceDescriptors.clear(); if (shutterUpChannel != -1 && shutterDownChannel != -1) { qCDebug(dcTasmota) << "Adding Shutter device"; DeviceDescriptor descriptor(tasmotaShutterDeviceClassId, info->device()->name() + " Shutter", QString(), info->device()->id()); @@ -188,6 +200,14 @@ void DevicePluginTasmota::setupDevice(DeviceSetupInfo *info) << Param(tasmotaShutterDeviceClosingChannelParamTypeId, "POWER" + QString::number(shutterDownChannel))); deviceDescriptors << descriptor; } + if (blindsUpChannel != -1 && blindsDownChannel != -1) { + qCDebug(dcTasmota) << "Adding Blinds device"; + DeviceDescriptor descriptor(tasmotaBlindsDeviceClassId, info->device()->name() + " Blinds", QString(), info->device()->id()); + descriptor.setParams(ParamList() + << Param(tasmotaBlindsDeviceOpeningChannelParamTypeId, "POWER" + QString::number(blindsUpChannel)) + << Param(tasmotaBlindsDeviceClosingChannelParamTypeId, "POWER" + QString::number(blindsDownChannel))); + deviceDescriptors << descriptor; + } if (!deviceDescriptors.isEmpty()) { emit autoDevicesAppeared(deviceDescriptors); } @@ -234,7 +254,7 @@ void DevicePluginTasmota::executeAction(DeviceActionInfo *info) device->setStateValue(m_powerStateTypeMap.value(device->deviceClassId()), action.param(powerActionParamTypeId).value().toBool()); return info->finish(Device::DeviceErrorNoError); } - if (device->deviceClassId() == tasmotaShutterDeviceClassId) { + if (m_closableStopActionTypeMap.contains(device->deviceClassId())) { Device *parentDev = myDevices().findById(device->parentId()); MqttChannel *channel = m_mqttChannels.value(parentDev); if (!channel) { @@ -243,12 +263,12 @@ void DevicePluginTasmota::executeAction(DeviceActionInfo *info) } ParamTypeId openingChannelParamTypeId = m_openingChannelParamTypeMap.value(device->deviceClassId()); ParamTypeId closingChannelParamTypeId = m_closingChannelParamTypeMap.value(device->deviceClassId()); - if (action.actionTypeId() == tasmotaShutterOpenActionTypeId) { + if (action.actionTypeId() == m_closableOpenActionTypeMap.value(device->deviceClassId())) { qCDebug(dcTasmota) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + device->paramValue(closingChannelParamTypeId).toString() << "OFF"; channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + device->paramValue(closingChannelParamTypeId).toString().toLower(), "OFF"); qCDebug(dcTasmota) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + device->paramValue(openingChannelParamTypeId).toString() << "ON"; channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + device->paramValue(openingChannelParamTypeId).toString().toLower(), "ON"); - } else if (action.actionTypeId() == tasmotaShutterCloseActionTypeId) { + } else if (action.actionTypeId() == m_closableCloseActionTypeMap.value(device->deviceClassId())) { qCDebug(dcTasmota) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + device->paramValue(openingChannelParamTypeId).toString() << "OFF"; channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + device->paramValue(openingChannelParamTypeId).toString().toLower(), "OFF"); qCDebug(dcTasmota) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + device->paramValue(closingChannelParamTypeId).toString() << "ON"; diff --git a/tasmota/deviceplugintasmota.h b/tasmota/deviceplugintasmota.h index 21449add..ceee2329 100644 --- a/tasmota/deviceplugintasmota.h +++ b/tasmota/deviceplugintasmota.h @@ -60,6 +60,10 @@ private: QHash m_closingChannelParamTypeMap; QHash m_powerStateTypeMap; + QHash m_closableOpenActionTypeMap; + QHash m_closableCloseActionTypeMap; + QHash m_closableStopActionTypeMap; + // Helpers for both devices QHash m_connectedStateTypeMap; }; diff --git a/tasmota/deviceplugintasmota.json b/tasmota/deviceplugintasmota.json index f6427b81..e330490c 100644 --- a/tasmota/deviceplugintasmota.json +++ b/tasmota/deviceplugintasmota.json @@ -60,7 +60,7 @@ "name": "attachedDeviceCH1", "displayName": "Connected device 1", "type": "QString", - "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down"], + "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down", "Blinds Up", "Blinds Down"], "defaultValue": "None" }, { @@ -68,7 +68,7 @@ "name": "attachedDeviceCH2", "displayName": "Connected device 2", "type": "QString", - "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down"], + "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down", "Blinds Up", "Blinds Down"], "defaultValue": "None" } ], @@ -102,7 +102,7 @@ "name": "attachedDeviceCH1", "displayName": "Connected device 1", "type": "QString", - "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down"], + "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down", "Blinds Up", "Blinds Down"], "defaultValue": "None" }, { @@ -110,7 +110,7 @@ "name": "attachedDeviceCH2", "displayName": "Connected device 2", "type": "QString", - "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down"], + "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down", "Blinds Up", "Blinds Down"], "defaultValue": "None" }, { @@ -118,7 +118,7 @@ "name": "attachedDeviceCH3", "displayName": "Connected device 3", "type": "QString", - "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down"], + "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down", "Blinds Up", "Blinds Down"], "defaultValue": "None" } ], @@ -152,7 +152,7 @@ "name": "attachedDeviceCH1", "displayName": "Connected device 1", "type": "QString", - "allowedValues": ["None", "Light"], + "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down", "Blinds Up", "Blinds Down"], "defaultValue": "None" }, { @@ -160,7 +160,7 @@ "name": "attachedDeviceCH2", "displayName": "Connected device 2", "type": "QString", - "allowedValues": ["None", "Light"], + "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down", "Blinds Up", "Blinds Down"], "defaultValue": "None" }, { @@ -168,7 +168,7 @@ "name": "attachedDeviceCH3", "displayName": "Connected device 3", "type": "QString", - "allowedValues": ["None", "Light"], + "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down", "Blinds Up", "Blinds Down"], "defaultValue": "None" }, { @@ -176,7 +176,7 @@ "name": "attachedDeviceCH4", "displayName": "Connected device 4", "type": "QString", - "allowedValues": ["None", "Light"], + "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down", "Blinds Up", "Blinds Down"], "defaultValue": "None" } ], @@ -288,7 +288,7 @@ "id": "600c00fd-6a2c-46cd-8031-2d9a1b1bc710", "name": "closingChannel", "displayName": "Closing channel", - "type": "QString" + "type": "int" } ], "stateTypes": [ @@ -318,6 +318,54 @@ "displayName": "Stop" } ] + }, + { + "id": "70ae35db-68bf-42d7-872a-85582d27d128", + "name": "tasmotaBlinds", + "displayName": "Tasmota blinds", + "createMethods": ["auto"], + "interfaces": ["blind", "closable", "connectable"], + "paramTypes": [ + { + "id": "d8f26857-6a6c-4aba-8301-dbd3ba68bc28", + "name": "openingChannel", + "displayName": "Opening channel", + "type": "int" + }, + { + "id": "32d0a914-e4df-4cac-bf70-304d7130f5f6", + "name": "closingChannel", + "displayName": "Closing channel", + "type": "int" + } + ], + "stateTypes": [ + { + "id": "686ad054-0ee5-4135-8f2d-dda993532262", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "type": "bool", + "defaultValue": false + } + ], + "actionTypes": [ + { + "id": "df8025a0-3553-413b-9986-61248d7a8440", + "name": "open", + "displayName": "Open" + }, + { + "id": "b548fde8-1fdc-4605-9507-964076437ffb", + "name": "close", + "displayName": "Close" + }, + { + "id": "f985c1ce-3ddd-415d-a10b-060fc0fa995c", + "name": "stop", + "displayName": "Stop" + } + ] } ] } From 15d8cc3cffca5e6dfa409f00006a5a1b3bfd6213 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Tue, 26 Nov 2019 23:40:32 +0100 Subject: [PATCH 2/2] update docs --- tasmota/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/README.md b/tasmota/README.md index cd89004a..489a680b 100644 --- a/tasmota/README.md +++ b/tasmota/README.md @@ -15,6 +15,6 @@ will connect to the MQTT broker and appear as connected in nymea. ## Plugin properties When adding a Tasmota device it will add a new Gateway type device representing the Tasmota device itself. In addition to that a power switch device will appear which can be used to control the switches in the Tasmota device. Upon -device setup, the user can optionally select the type of the connected hardware, (e.g. a light) which causes this -plugin to create a light device in the system which also controls the switches inside the Tasmota device and nicely +device setup, the user can optionally select the type of the connected hardware, (e.g. a light, roller shutter or blind) which +causes this plugin to create an additional device in the system which also controls the switches inside the Tasmota device and nicely integrates with the nymea:ux for the given device type.