Merge PR #196: Tasmota: Add Blinds support

This commit is contained in:
Jenkins nymea 2019-12-09 10:09:02 +01:00
commit 482ed8d8dd
4 changed files with 91 additions and 19 deletions

View File

@ -15,6 +15,6 @@ will connect to the MQTT broker and appear as connected in nymea.
## Plugin properties ## Plugin properties
When adding a Tasmota device it will add a new Gateway type device representing the Tasmota device itself. In addition 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 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 device setup, the user can optionally select the type of the connected hardware, (e.g. a light, roller shutter or blind) which
plugin to create a light device in the system which also controls the switches inside the Tasmota device and nicely 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. integrates with the nymea:ux for the given device type.

View File

@ -51,10 +51,19 @@ DevicePluginTasmota::DevicePluginTasmota()
m_channelParamTypeMap[tasmotaLightDeviceClassId] = tasmotaLightDeviceChannelNameParamTypeId; m_channelParamTypeMap[tasmotaLightDeviceClassId] = tasmotaLightDeviceChannelNameParamTypeId;
m_openingChannelParamTypeMap[tasmotaShutterDeviceClassId] = tasmotaShutterDeviceOpeningChannelParamTypeId; m_openingChannelParamTypeMap[tasmotaShutterDeviceClassId] = tasmotaShutterDeviceOpeningChannelParamTypeId;
m_closingChannelParamTypeMap[tasmotaShutterDeviceClassId] = tasmotaShutterDeviceClosingChannelParamTypeId; m_closingChannelParamTypeMap[tasmotaShutterDeviceClassId] = tasmotaShutterDeviceClosingChannelParamTypeId;
m_openingChannelParamTypeMap[tasmotaBlindsDeviceClassId] = tasmotaBlindsDeviceOpeningChannelParamTypeId;
m_closingChannelParamTypeMap[tasmotaBlindsDeviceClassId] = tasmotaBlindsDeviceClosingChannelParamTypeId;
m_powerStateTypeMap[tasmotaSwitchDeviceClassId] = tasmotaSwitchPowerStateTypeId; m_powerStateTypeMap[tasmotaSwitchDeviceClassId] = tasmotaSwitchPowerStateTypeId;
m_powerStateTypeMap[tasmotaLightDeviceClassId] = tasmotaLightPowerStateTypeId; 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 // Helper maps for all devices
m_connectedStateTypeMap[sonoff_basicDeviceClassId] = sonoff_basicConnectedStateTypeId; m_connectedStateTypeMap[sonoff_basicDeviceClassId] = sonoff_basicConnectedStateTypeId;
@ -64,6 +73,7 @@ DevicePluginTasmota::DevicePluginTasmota()
m_connectedStateTypeMap[tasmotaSwitchDeviceClassId] = tasmotaSwitchConnectedStateTypeId; m_connectedStateTypeMap[tasmotaSwitchDeviceClassId] = tasmotaSwitchConnectedStateTypeId;
m_connectedStateTypeMap[tasmotaLightDeviceClassId] = tasmotaLightConnectedStateTypeId; m_connectedStateTypeMap[tasmotaLightDeviceClassId] = tasmotaLightConnectedStateTypeId;
m_connectedStateTypeMap[tasmotaShutterDeviceClassId] = tasmotaShutterConnectedStateTypeId; m_connectedStateTypeMap[tasmotaShutterDeviceClassId] = tasmotaShutterConnectedStateTypeId;
m_connectedStateTypeMap[tasmotaBlindsDeviceClassId] = tasmotaBlindsConnectedStateTypeId;
} }
DevicePluginTasmota::~DevicePluginTasmota() DevicePluginTasmota::~DevicePluginTasmota()
@ -157,6 +167,8 @@ void DevicePluginTasmota::setupDevice(DeviceSetupInfo *info)
deviceDescriptors.clear(); deviceDescriptors.clear();
int shutterUpChannel = -1; int shutterUpChannel = -1;
int shutterDownChannel = -1; int shutterDownChannel = -1;
int blindsUpChannel = -1;
int blindsDownChannel = -1;
for (int i = 0; i < m_attachedDeviceParamTypeIdMap.value(info->device()->deviceClassId()).count(); i++) { for (int i = 0; i < m_attachedDeviceParamTypeIdMap.value(info->device()->deviceClassId()).count(); i++) {
ParamTypeId attachedDeviceParamTypeId = m_attachedDeviceParamTypeIdMap.value(info->device()->deviceClassId()).at(i); ParamTypeId attachedDeviceParamTypeId = m_attachedDeviceParamTypeIdMap.value(info->device()->deviceClassId()).at(i);
QString deviceType = info->device()->paramValue(attachedDeviceParamTypeId).toString(); QString deviceType = info->device()->paramValue(attachedDeviceParamTypeId).toString();
@ -174,12 +186,12 @@ void DevicePluginTasmota::setupDevice(DeviceSetupInfo *info)
shutterUpChannel = i+1; shutterUpChannel = i+1;
} else if (deviceType == "Roller Shutter Down") { } else if (deviceType == "Roller Shutter Down") {
shutterDownChannel = i+1; 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) { if (shutterUpChannel != -1 && shutterDownChannel != -1) {
qCDebug(dcTasmota) << "Adding Shutter device"; qCDebug(dcTasmota) << "Adding Shutter device";
DeviceDescriptor descriptor(tasmotaShutterDeviceClassId, info->device()->name() + " Shutter", QString(), info->device()->id()); 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))); << Param(tasmotaShutterDeviceClosingChannelParamTypeId, "POWER" + QString::number(shutterDownChannel)));
deviceDescriptors << descriptor; 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()) { if (!deviceDescriptors.isEmpty()) {
emit autoDevicesAppeared(deviceDescriptors); emit autoDevicesAppeared(deviceDescriptors);
} }
@ -234,7 +254,7 @@ void DevicePluginTasmota::executeAction(DeviceActionInfo *info)
device->setStateValue(m_powerStateTypeMap.value(device->deviceClassId()), action.param(powerActionParamTypeId).value().toBool()); device->setStateValue(m_powerStateTypeMap.value(device->deviceClassId()), action.param(powerActionParamTypeId).value().toBool());
return info->finish(Device::DeviceErrorNoError); return info->finish(Device::DeviceErrorNoError);
} }
if (device->deviceClassId() == tasmotaShutterDeviceClassId) { if (m_closableStopActionTypeMap.contains(device->deviceClassId())) {
Device *parentDev = myDevices().findById(device->parentId()); Device *parentDev = myDevices().findById(device->parentId());
MqttChannel *channel = m_mqttChannels.value(parentDev); MqttChannel *channel = m_mqttChannels.value(parentDev);
if (!channel) { if (!channel) {
@ -243,12 +263,12 @@ void DevicePluginTasmota::executeAction(DeviceActionInfo *info)
} }
ParamTypeId openingChannelParamTypeId = m_openingChannelParamTypeMap.value(device->deviceClassId()); ParamTypeId openingChannelParamTypeId = m_openingChannelParamTypeMap.value(device->deviceClassId());
ParamTypeId closingChannelParamTypeId = m_closingChannelParamTypeMap.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"; 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"); 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"; 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"); 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"; 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"); 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"; qCDebug(dcTasmota) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + device->paramValue(closingChannelParamTypeId).toString() << "ON";

View File

@ -60,6 +60,10 @@ private:
QHash<DeviceClassId, ParamTypeId> m_closingChannelParamTypeMap; QHash<DeviceClassId, ParamTypeId> m_closingChannelParamTypeMap;
QHash<DeviceClassId, StateTypeId> m_powerStateTypeMap; QHash<DeviceClassId, StateTypeId> m_powerStateTypeMap;
QHash<DeviceClassId, ActionTypeId> m_closableOpenActionTypeMap;
QHash<DeviceClassId, ActionTypeId> m_closableCloseActionTypeMap;
QHash<DeviceClassId, ActionTypeId> m_closableStopActionTypeMap;
// Helpers for both devices // Helpers for both devices
QHash<DeviceClassId, StateTypeId> m_connectedStateTypeMap; QHash<DeviceClassId, StateTypeId> m_connectedStateTypeMap;
}; };

View File

@ -60,7 +60,7 @@
"name": "attachedDeviceCH1", "name": "attachedDeviceCH1",
"displayName": "Connected device 1", "displayName": "Connected device 1",
"type": "QString", "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" "defaultValue": "None"
}, },
{ {
@ -68,7 +68,7 @@
"name": "attachedDeviceCH2", "name": "attachedDeviceCH2",
"displayName": "Connected device 2", "displayName": "Connected device 2",
"type": "QString", "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" "defaultValue": "None"
} }
], ],
@ -102,7 +102,7 @@
"name": "attachedDeviceCH1", "name": "attachedDeviceCH1",
"displayName": "Connected device 1", "displayName": "Connected device 1",
"type": "QString", "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" "defaultValue": "None"
}, },
{ {
@ -110,7 +110,7 @@
"name": "attachedDeviceCH2", "name": "attachedDeviceCH2",
"displayName": "Connected device 2", "displayName": "Connected device 2",
"type": "QString", "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" "defaultValue": "None"
}, },
{ {
@ -118,7 +118,7 @@
"name": "attachedDeviceCH3", "name": "attachedDeviceCH3",
"displayName": "Connected device 3", "displayName": "Connected device 3",
"type": "QString", "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" "defaultValue": "None"
} }
], ],
@ -152,7 +152,7 @@
"name": "attachedDeviceCH1", "name": "attachedDeviceCH1",
"displayName": "Connected device 1", "displayName": "Connected device 1",
"type": "QString", "type": "QString",
"allowedValues": ["None", "Light"], "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down", "Blinds Up", "Blinds Down"],
"defaultValue": "None" "defaultValue": "None"
}, },
{ {
@ -160,7 +160,7 @@
"name": "attachedDeviceCH2", "name": "attachedDeviceCH2",
"displayName": "Connected device 2", "displayName": "Connected device 2",
"type": "QString", "type": "QString",
"allowedValues": ["None", "Light"], "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down", "Blinds Up", "Blinds Down"],
"defaultValue": "None" "defaultValue": "None"
}, },
{ {
@ -168,7 +168,7 @@
"name": "attachedDeviceCH3", "name": "attachedDeviceCH3",
"displayName": "Connected device 3", "displayName": "Connected device 3",
"type": "QString", "type": "QString",
"allowedValues": ["None", "Light"], "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down", "Blinds Up", "Blinds Down"],
"defaultValue": "None" "defaultValue": "None"
}, },
{ {
@ -176,7 +176,7 @@
"name": "attachedDeviceCH4", "name": "attachedDeviceCH4",
"displayName": "Connected device 4", "displayName": "Connected device 4",
"type": "QString", "type": "QString",
"allowedValues": ["None", "Light"], "allowedValues": ["None", "Light", "Roller Shutter Up", "Roller Shutter Down", "Blinds Up", "Blinds Down"],
"defaultValue": "None" "defaultValue": "None"
} }
], ],
@ -288,7 +288,7 @@
"id": "600c00fd-6a2c-46cd-8031-2d9a1b1bc710", "id": "600c00fd-6a2c-46cd-8031-2d9a1b1bc710",
"name": "closingChannel", "name": "closingChannel",
"displayName": "Closing channel", "displayName": "Closing channel",
"type": "QString" "type": "int"
} }
], ],
"stateTypes": [ "stateTypes": [
@ -318,6 +318,54 @@
"displayName": "Stop" "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"
}
]
} }
] ]
} }