Tasmota: Add support for the gneric I/O mechanism
This commit is contained in:
parent
cdff51655f
commit
42552690a0
@ -41,6 +41,31 @@
|
|||||||
#include "network/mqtt/mqttprovider.h"
|
#include "network/mqtt/mqttprovider.h"
|
||||||
#include "network/mqtt/mqttchannel.h"
|
#include "network/mqtt/mqttchannel.h"
|
||||||
|
|
||||||
|
static QHash<QString, StateTypeId> sonoff_basicPowerStateTypeIds = {
|
||||||
|
{"POWER1", sonoff_basicPowerStateTypeId},
|
||||||
|
};
|
||||||
|
static QHash<QString, StateTypeId> sonoff_dualPowerStateTypeIds = {
|
||||||
|
{"POWER1", sonoff_dualPowerCH1StateTypeId},
|
||||||
|
{"POWER2", sonoff_dualPowerCH2StateTypeId},
|
||||||
|
};
|
||||||
|
static QHash<QString, StateTypeId> sonoff_triPowerStateTypeIds = {
|
||||||
|
{"POWER1", sonoff_triPowerCH1StateTypeId},
|
||||||
|
{"POWER2", sonoff_triPowerCH2StateTypeId},
|
||||||
|
{"POWER3", sonoff_triPowerCH3StateTypeId},
|
||||||
|
};
|
||||||
|
static QHash<QString, StateTypeId> sonoff_quadPowerStateTypeIds = {
|
||||||
|
{"POWER1", sonoff_quadPowerCH1StateTypeId},
|
||||||
|
{"POWER2", sonoff_quadPowerCH2StateTypeId},
|
||||||
|
{"POWER3", sonoff_quadPowerCH3StateTypeId},
|
||||||
|
{"POWER4", sonoff_quadPowerCH4StateTypeId},
|
||||||
|
};
|
||||||
|
static QHash<ThingClassId, QHash<QString, StateTypeId>> stateMaps = {
|
||||||
|
{sonoff_basicThingClassId, sonoff_basicPowerStateTypeIds},
|
||||||
|
{sonoff_dualThingClassId, sonoff_dualPowerStateTypeIds},
|
||||||
|
{sonoff_triThingClassId, sonoff_triPowerStateTypeIds},
|
||||||
|
{sonoff_quadThingClassId, sonoff_quadPowerStateTypeIds},
|
||||||
|
};
|
||||||
|
|
||||||
IntegrationPluginTasmota::IntegrationPluginTasmota()
|
IntegrationPluginTasmota::IntegrationPluginTasmota()
|
||||||
{
|
{
|
||||||
// Helper maps for parent devices (aka sonoff_*)
|
// Helper maps for parent devices (aka sonoff_*)
|
||||||
@ -257,6 +282,25 @@ void IntegrationPluginTasmota::executeAction(ThingActionInfo *info)
|
|||||||
Thing *thing = info->thing();
|
Thing *thing = info->thing();
|
||||||
Action action = info->action();
|
Action action = info->action();
|
||||||
|
|
||||||
|
if (thing->thingClassId() == sonoff_basicThingClassId
|
||||||
|
|| thing->thingClassId() == sonoff_dualThingClassId
|
||||||
|
|| thing->thingClassId() == sonoff_triThingClassId
|
||||||
|
|| thing->thingClassId() == sonoff_quadThingClassId) {
|
||||||
|
MqttChannel *channel = m_mqttChannels.value(thing);
|
||||||
|
if (!channel) {
|
||||||
|
qCWarning(dcTasmota()) << "No MQTT channel for this thing.";
|
||||||
|
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QString channelName = stateMaps.value(thing->thingClassId()).key(action.actionTypeId());
|
||||||
|
qCDebug(dcTasmota) << "Publishing:" << channel->topicPrefixList().first() + "/sonoff/cmnd/" + channelName << (action.paramValue(action.actionTypeId()).toBool() ? "ON" : "OFF");
|
||||||
|
channel->publish(channel->topicPrefixList().first() + "/sonoff/cmnd/" + channelName, action.paramValue(action.actionTypeId()).toBool() ? "ON" : "OFF");
|
||||||
|
thing->setStateValue(action.actionTypeId(), action.paramValue(action.actionTypeId()));
|
||||||
|
info->finish(Thing::ThingErrorNoError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy (deprecated) connected devices
|
||||||
if (m_powerStateTypeMap.contains(thing->thingClassId())) {
|
if (m_powerStateTypeMap.contains(thing->thingClassId())) {
|
||||||
Thing *parentDev = myThings().findById(thing->parentId());
|
Thing *parentDev = myThings().findById(thing->parentId());
|
||||||
MqttChannel *channel = m_mqttChannels.value(parentDev);
|
MqttChannel *channel = m_mqttChannels.value(parentDev);
|
||||||
@ -331,40 +375,43 @@ void IntegrationPluginTasmota::onPublishReceived(MqttChannel *channel, const QSt
|
|||||||
{
|
{
|
||||||
qCDebug(dcTasmota) << "Publish received from Sonoff thing:" << topic << qUtf8Printable(payload);
|
qCDebug(dcTasmota) << "Publish received from Sonoff thing:" << topic << qUtf8Printable(payload);
|
||||||
Thing *thing = m_mqttChannels.key(channel);
|
Thing *thing = m_mqttChannels.key(channel);
|
||||||
if (m_ipAddressParamTypeMap.contains(thing->thingClassId())) {
|
if (topic.startsWith(channel->topicPrefixList().first() + "/sonoff/POWER")) {
|
||||||
if (topic.startsWith(channel->topicPrefixList().first() + "/sonoff/POWER")) {
|
QString channelName = topic.split("/").last();
|
||||||
QString channelName = topic.split("/").last();
|
|
||||||
|
|
||||||
foreach (Thing *child, myThings().filterByParentId(thing->id())) {
|
thing->setStateValue(stateMaps.value(thing->thingClassId()).value(channelName), payload == "ON");
|
||||||
if (child->paramValue(m_channelParamTypeMap.value(child->thingClassId())).toString() != channelName) {
|
|
||||||
continue;
|
// Legacy (deprecated) connected things via params
|
||||||
}
|
foreach (Thing *child, myThings().filterByParentId(thing->id())) {
|
||||||
if (m_powerStateTypeMap.contains(child->thingClassId())) {
|
if (child->paramValue(m_channelParamTypeMap.value(child->thingClassId())).toString() != channelName) {
|
||||||
child->setStateValue(m_powerStateTypeMap.value(child->thingClassId()), payload == "ON");
|
continue;
|
||||||
}
|
}
|
||||||
if (child->thingClassId() == tasmotaSwitchThingClassId) {
|
if (m_powerStateTypeMap.contains(child->thingClassId())) {
|
||||||
Event event(tasmotaSwitchPressedEventTypeId, child->id());
|
child->setStateValue(m_powerStateTypeMap.value(child->thingClassId()), payload == "ON");
|
||||||
emit emitEvent(event);
|
}
|
||||||
}
|
if (child->thingClassId() == tasmotaSwitchThingClassId) {
|
||||||
|
Event event(tasmotaSwitchPressedEventTypeId, child->id());
|
||||||
|
emit emitEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (topic.startsWith(channel->topicPrefixList().first() + "/sonoff/STATE")) {
|
}
|
||||||
QJsonParseError error;
|
if (topic.startsWith(channel->topicPrefixList().first() + "/sonoff/STATE")) {
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(payload, &error);
|
QJsonParseError error;
|
||||||
if (error.error != QJsonParseError::NoError) {
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(payload, &error);
|
||||||
qCWarning(dcTasmota) << "Cannot parse JSON from Tasmota device" << error.errorString();
|
if (error.error != QJsonParseError::NoError) {
|
||||||
return;
|
qCWarning(dcTasmota) << "Cannot parse JSON from Tasmota device" << error.errorString();
|
||||||
}
|
return;
|
||||||
QVariantMap dataMap = jsonDoc.toVariant().toMap();
|
}
|
||||||
thing->setStateValue(m_signalStrengthStateTypeMap.value(thing->thingClassId()), dataMap.value("Wifi").toMap().value("RSSI").toInt());
|
QVariantMap dataMap = jsonDoc.toVariant().toMap();
|
||||||
foreach (Thing *child, myThings().filterByParentId(thing->id())) {
|
thing->setStateValue(m_signalStrengthStateTypeMap.value(thing->thingClassId()), dataMap.value("Wifi").toMap().value("RSSI").toInt());
|
||||||
if (m_powerStateTypeMap.contains(child->thingClassId())) {
|
|
||||||
QString childChannel = child->paramValue(m_channelParamTypeMap.value(child->thingClassId())).toString();
|
// Legacy (deprecated) connected things by params
|
||||||
QString valueString = jsonDoc.toVariant().toMap().value(childChannel).toString();
|
foreach (Thing *child, myThings().filterByParentId(thing->id())) {
|
||||||
child->setStateValue(m_powerStateTypeMap.value(child->thingClassId()), valueString == "ON");
|
if (m_powerStateTypeMap.contains(child->thingClassId())) {
|
||||||
}
|
QString childChannel = child->paramValue(m_channelParamTypeMap.value(child->thingClassId())).toString();
|
||||||
child->setStateValue(m_signalStrengthStateTypeMap.value(child->thingClassId()), dataMap.value("Wifi").toMap().value("RSSI").toInt());
|
QString valueString = jsonDoc.toVariant().toMap().value(childChannel).toString();
|
||||||
|
child->setStateValue(m_powerStateTypeMap.value(child->thingClassId()), valueString == "ON");
|
||||||
}
|
}
|
||||||
|
child->setStateValue(m_signalStrengthStateTypeMap.value(child->thingClassId()), dataMap.value("Wifi").toMap().value("RSSI").toInt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,6 +50,17 @@
|
|||||||
"minValue": 0,
|
"minValue": 0,
|
||||||
"maxValue": 100,
|
"maxValue": 100,
|
||||||
"defaultValue": -1
|
"defaultValue": -1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0b5a48c9-73b8-42ab-9909-71b8dc2227e3",
|
||||||
|
"name": "power",
|
||||||
|
"displayName": "Power",
|
||||||
|
"displayNameEvent": "Power changed",
|
||||||
|
"displayNameAction": "Set power",
|
||||||
|
"type": "bool",
|
||||||
|
"writable": true,
|
||||||
|
"defaultValue": false,
|
||||||
|
"ioType": "digitalOutput"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -103,6 +114,28 @@
|
|||||||
"minValue": 0,
|
"minValue": 0,
|
||||||
"maxValue": 100,
|
"maxValue": 100,
|
||||||
"defaultValue": 100
|
"defaultValue": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "b8bf3085-8061-4cd6-af1f-f76a03054f46",
|
||||||
|
"name": "powerCH1",
|
||||||
|
"displayName": "Power channel 1",
|
||||||
|
"displayNameEvent": "Power channel 1 changed",
|
||||||
|
"displayNameAction": "Set power channel 1",
|
||||||
|
"type": "bool",
|
||||||
|
"writable": true,
|
||||||
|
"defaultValue": false,
|
||||||
|
"ioType": "digitalOutput"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4fbcaeb6-9242-4aa6-b462-a214fb38bcc9",
|
||||||
|
"name": "powerCH2",
|
||||||
|
"displayName": "Power channel 2",
|
||||||
|
"displayNameEvent": "Power channel 2 changed",
|
||||||
|
"displayNameAction": "Set power channel 2",
|
||||||
|
"type": "bool",
|
||||||
|
"writable": true,
|
||||||
|
"defaultValue": false,
|
||||||
|
"ioType": "digitalOutput"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -164,6 +197,39 @@
|
|||||||
"minValue": 0,
|
"minValue": 0,
|
||||||
"maxValue": 100,
|
"maxValue": 100,
|
||||||
"defaultValue": 100
|
"defaultValue": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "27bdb42d-ef95-4905-ac3d-925bcc8a1ba1",
|
||||||
|
"name": "powerCH1",
|
||||||
|
"displayName": "Power channel 1",
|
||||||
|
"displayNameEvent": "Power channel 1 changed",
|
||||||
|
"displayNameAction": "Set power channel 1",
|
||||||
|
"type": "bool",
|
||||||
|
"writable": true,
|
||||||
|
"defaultValue": false,
|
||||||
|
"ioType": "digitalOutput"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "705d8277-896a-4d56-b9ff-0a614ecfd39c",
|
||||||
|
"name": "powerCH2",
|
||||||
|
"displayName": "Power channel 2",
|
||||||
|
"displayNameEvent": "Power channel 2 changed",
|
||||||
|
"displayNameAction": "Set power channel 2",
|
||||||
|
"type": "bool",
|
||||||
|
"writable": true,
|
||||||
|
"defaultValue": false,
|
||||||
|
"ioType": "digitalOutput"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "156f285d-e474-43d9-9a9d-17b3bcaef893",
|
||||||
|
"name": "powerCH3",
|
||||||
|
"displayName": "Power channel 3",
|
||||||
|
"displayNameEvent": "Power channel 3 changed",
|
||||||
|
"displayNameAction": "Set power channel 3",
|
||||||
|
"type": "bool",
|
||||||
|
"writable": true,
|
||||||
|
"defaultValue": false,
|
||||||
|
"ioType": "digitalOutput"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -233,6 +299,50 @@
|
|||||||
"minValue": 0,
|
"minValue": 0,
|
||||||
"maxValue": 100,
|
"maxValue": 100,
|
||||||
"defaultValue": 100
|
"defaultValue": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e8fd95c3-2323-40d8-89cf-40e0068977d8",
|
||||||
|
"name": "powerCH1",
|
||||||
|
"displayName": "Power channel 1",
|
||||||
|
"displayNameEvent": "Power channel 1 changed",
|
||||||
|
"displayNameAction": "Set power channel 1",
|
||||||
|
"type": "bool",
|
||||||
|
"writable": true,
|
||||||
|
"defaultValue": false,
|
||||||
|
"ioType": "digitalOutput"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "baf0ca62-7f09-45ea-aea1-6de34764e6cb",
|
||||||
|
"name": "powerCH2",
|
||||||
|
"displayName": "Power channel 2",
|
||||||
|
"displayNameEvent": "Power channel 2 changed",
|
||||||
|
"displayNameAction": "Set power channel 2",
|
||||||
|
"type": "bool",
|
||||||
|
"writable": true,
|
||||||
|
"defaultValue": false,
|
||||||
|
"ioType": "digitalOutput"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8b939d15-3e45-40aa-bb53-9b3fb47f3cb3",
|
||||||
|
"name": "powerCH3",
|
||||||
|
"displayName": "Power channel 3",
|
||||||
|
"displayNameEvent": "Power channel 3 changed",
|
||||||
|
"displayNameAction": "Set power channel 3",
|
||||||
|
"type": "bool",
|
||||||
|
"writable": true,
|
||||||
|
"defaultValue": false,
|
||||||
|
"ioType": "digitalOutput"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4060baa0-2b11-4905-908c-b6f1c3b6a892",
|
||||||
|
"name": "powerCH4",
|
||||||
|
"displayName": "Power channel 4",
|
||||||
|
"displayNameEvent": "Power channel 4 changed",
|
||||||
|
"displayNameAction": "Set power channel 4",
|
||||||
|
"type": "bool",
|
||||||
|
"writable": true,
|
||||||
|
"defaultValue": false,
|
||||||
|
"ioType": "digitalOutput"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user