Merge PR #196: Tasmota: Add Blinds support

master
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
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.

View File

@ -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";

View File

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

View File

@ -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"
}
]
}
]
}