add sonoff-tasmota plugin
parent
11f56c948d
commit
e55cceca6c
|
|
@ -1,43 +1,44 @@
|
|||
TEMPLATE = subdirs
|
||||
|
||||
PLUGIN_DIRS = \
|
||||
elro \
|
||||
intertechno \
|
||||
networkdetector \
|
||||
conrad \
|
||||
openweathermap \
|
||||
wakeonlan \
|
||||
mailnotification \
|
||||
philipshue \
|
||||
eq-3 \
|
||||
wemo \
|
||||
lgsmarttv \
|
||||
datetime \
|
||||
genericelements \
|
||||
commandlauncher \
|
||||
unitec \
|
||||
leynew \
|
||||
udpcommander \
|
||||
tcpcommander \
|
||||
httpcommander \
|
||||
kodi \
|
||||
elgato \
|
||||
senic \
|
||||
awattar \
|
||||
netatmo \
|
||||
plantcare \
|
||||
osdomotics \
|
||||
ws2812 \
|
||||
orderbutton \
|
||||
denon \
|
||||
avahimonitor \
|
||||
gpio \
|
||||
snapd \
|
||||
simulation \
|
||||
keba \
|
||||
remotessh \
|
||||
awattar \
|
||||
commandlauncher \
|
||||
conrad \
|
||||
datetime \
|
||||
denon \
|
||||
dweetio \
|
||||
elgato \
|
||||
elro \
|
||||
eq-3 \
|
||||
flowercare \
|
||||
genericelements \
|
||||
gpio \
|
||||
httpcommander \
|
||||
intertechno \
|
||||
keba \
|
||||
kodi \
|
||||
leynew \
|
||||
lgsmarttv \
|
||||
mailnotification \
|
||||
netatmo \
|
||||
networkdetector \
|
||||
openweathermap \
|
||||
orderbutton \
|
||||
osdomotics \
|
||||
philipshue \
|
||||
plantcare \
|
||||
remotessh \
|
||||
senic \
|
||||
simulation \
|
||||
snapd \
|
||||
tasmota \
|
||||
tcpcommander \
|
||||
udpcommander \
|
||||
unitec \
|
||||
wakeonlan \
|
||||
wemo \
|
||||
ws2812 \
|
||||
|
||||
CONFIG+=all
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,231 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2018 Michael Zanetti <michael.zanetti@nymea.io> *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
* nymea is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 2 of the License. *
|
||||
* *
|
||||
* nymea is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with nymea. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "deviceplugintasmota.h"
|
||||
#include "plugininfo.h"
|
||||
|
||||
#include <QUrlQuery>
|
||||
#include <QNetworkReply>
|
||||
#include <QHostAddress>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "hardwaremanager.h"
|
||||
#include "network/networkaccessmanager.h"
|
||||
#include "network/mqtt/mqttprovider.h"
|
||||
#include "network/mqtt/mqttchannel.h"
|
||||
|
||||
DevicePluginTasmota::DevicePluginTasmota()
|
||||
{
|
||||
// Helper maps for parent devices (aka sonoff_*)
|
||||
m_ipAddressParamTypeMap[sonoff_basicDeviceClassId] = sonoff_basicDeviceIpAddressParamTypeId;
|
||||
m_ipAddressParamTypeMap[sonoff_dualDeviceClassId] = sonoff_dualDeviceIpAddressParamTypeId;
|
||||
m_ipAddressParamTypeMap[sonoff_quadDeviceClassId] = sonoff_quadDeviceIpAddressParamTypeId;
|
||||
|
||||
m_attachedDeviceParamTypeIdMap[sonoff_basicDeviceClassId] << sonoff_basicDeviceAttachedDeviceCH1ParamTypeId;
|
||||
m_attachedDeviceParamTypeIdMap[sonoff_dualDeviceClassId] << sonoff_dualDeviceAttachedDeviceCH1ParamTypeId << sonoff_dualDeviceAttachedDeviceCH2ParamTypeId;
|
||||
m_attachedDeviceParamTypeIdMap[sonoff_quadDeviceClassId] << sonoff_quadDeviceAttachedDeviceCH1ParamTypeId << sonoff_quadDeviceAttachedDeviceCH2ParamTypeId << sonoff_quadDeviceAttachedDeviceCH3ParamTypeId << sonoff_quadDeviceAttachedDeviceCH4ParamTypeId;
|
||||
|
||||
// Helper maps for virtual childs (aka tasmota*)
|
||||
m_channelParamTypeMap[tasmotaSwitchDeviceClassId] = tasmotaSwitchDeviceChannelNameParamTypeId;
|
||||
m_channelParamTypeMap[tasmotaLightDeviceClassId] = tasmotaLightDeviceChannelNameParamTypeId;
|
||||
|
||||
m_powerStateTypeMap[tasmotaSwitchDeviceClassId] = tasmotaSwitchPowerStateTypeId;
|
||||
m_powerStateTypeMap[tasmotaLightDeviceClassId] = tasmotaLightPowerStateTypeId;
|
||||
|
||||
// Helper maps for all devices
|
||||
m_connectedStateTypeMap[sonoff_basicDeviceClassId] = sonoff_basicConnectedStateTypeId;
|
||||
m_connectedStateTypeMap[sonoff_dualDeviceClassId] = sonoff_dualConnectedStateTypeId;
|
||||
m_connectedStateTypeMap[sonoff_quadDeviceClassId] = sonoff_quadConnectedStateTypeId;
|
||||
m_connectedStateTypeMap[tasmotaSwitchDeviceClassId] = tasmotaSwitchConnectedStateTypeId;
|
||||
m_connectedStateTypeMap[tasmotaLightDeviceClassId] = tasmotaLightConnectedStateTypeId;
|
||||
}
|
||||
|
||||
DevicePluginTasmota::~DevicePluginTasmota()
|
||||
{
|
||||
}
|
||||
|
||||
void DevicePluginTasmota::init()
|
||||
{
|
||||
}
|
||||
|
||||
DeviceManager::DeviceSetupStatus DevicePluginTasmota::setupDevice(Device *device)
|
||||
{
|
||||
if (m_ipAddressParamTypeMap.contains(device->deviceClassId())) {
|
||||
ParamTypeId ipAddressParamTypeId = m_ipAddressParamTypeMap.value(device->deviceClassId());
|
||||
|
||||
QHostAddress deviceAddress = QHostAddress(device->paramValue(ipAddressParamTypeId).toString());
|
||||
if (deviceAddress.isNull()) {
|
||||
qCWarning(dcTasmota) << "Not a valid IP address given for IP address parameter";
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
}
|
||||
MqttChannel *channel = hardwareManager()->mqttProvider()->createChannel(device->id(), deviceAddress);
|
||||
|
||||
Q_UNUSED(device)
|
||||
QUrl url("http://10.10.10.90/sv");
|
||||
QUrlQuery query;
|
||||
query.addQueryItem("w", "2%2C1");
|
||||
query.addQueryItem("mh", channel->serverAddress().toString());
|
||||
query.addQueryItem("ml", QString::number(channel->serverPort()));
|
||||
query.addQueryItem("mc", channel->clientId());
|
||||
query.addQueryItem("mu", channel->username());
|
||||
query.addQueryItem("mp", channel->password());
|
||||
query.addQueryItem("mt", "sonoff");
|
||||
query.addQueryItem("mf", channel->topicPrefix() + "/%topic%/");
|
||||
url.setQuery(query);
|
||||
QNetworkRequest request(url);
|
||||
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
|
||||
connect(reply, &QNetworkReply::finished, this, [this, device, channel, reply](){
|
||||
reply->deleteLater();
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qCDebug(dcTasmota) << "Sonoff device setup call failed:" << reply->error() << reply->errorString() << reply->readAll();
|
||||
hardwareManager()->mqttProvider()->releaseChannel(channel);
|
||||
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure);
|
||||
return;
|
||||
}
|
||||
m_mqttChannels.insert(device, channel);
|
||||
connect(channel, &MqttChannel::clientConnected, this, &DevicePluginTasmota::onClientConnected);
|
||||
connect(channel, &MqttChannel::clientDisconnected, this, &DevicePluginTasmota::onClientDisconnected);
|
||||
connect(channel, &MqttChannel::publishReceived, this, &DevicePluginTasmota::onPublishReceived);
|
||||
|
||||
qCDebug(dcTasmota) << "Sonoff setup complete";
|
||||
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusSuccess);
|
||||
|
||||
foreach (Device *child, myDevices()) {
|
||||
if (child->parentId() == device->id()) {
|
||||
// Already have child devices... We're done here
|
||||
return;
|
||||
}
|
||||
}
|
||||
qCDebug(dcTasmota) << "Adding Tasmota Switch devices";
|
||||
QList<DeviceDescriptor> deviceDescriptors;
|
||||
for (int i = 0; i < m_attachedDeviceParamTypeIdMap.value(device->deviceClassId()).count(); i++) {
|
||||
DeviceDescriptor descriptor(tasmotaSwitchDeviceClassId, device->name() + " CH" + QString::number(i+1), QString(), device->id());
|
||||
if (m_attachedDeviceParamTypeIdMap.value(device->deviceClassId()).count() == 1) {
|
||||
descriptor.setParams(ParamList() << Param(tasmotaSwitchDeviceChannelNameParamTypeId, "POWER"));
|
||||
} else {
|
||||
descriptor.setParams(ParamList() << Param(tasmotaSwitchDeviceChannelNameParamTypeId, "POWER" + QString::number(i+1)));
|
||||
}
|
||||
deviceDescriptors << descriptor;
|
||||
}
|
||||
emit autoDevicesAppeared(tasmotaSwitchDeviceClassId, deviceDescriptors);
|
||||
|
||||
qCDebug(dcTasmota) << "Adding Tasmota connected devices";
|
||||
deviceDescriptors.clear();
|
||||
for (int i = 0; i < m_attachedDeviceParamTypeIdMap.value(device->deviceClassId()).count(); i++) {
|
||||
ParamTypeId attachedDeviceParamTypeId = m_attachedDeviceParamTypeIdMap.value(device->deviceClassId()).at(i);
|
||||
if (device->paramValue(attachedDeviceParamTypeId).toString() == "Light") {
|
||||
DeviceDescriptor descriptor1(tasmotaLightDeviceClassId, device->name() + " CH" + QString::number(i+1), QString(), device->id());
|
||||
if (m_attachedDeviceParamTypeIdMap.value(device->deviceClassId()).count() == 1) {
|
||||
descriptor1.setParams(ParamList() << Param(tasmotaLightDeviceChannelNameParamTypeId, "POWER"));
|
||||
} else {
|
||||
descriptor1.setParams(ParamList() << Param(tasmotaLightDeviceChannelNameParamTypeId, "POWER" + QString::number(i+1)));
|
||||
}
|
||||
deviceDescriptors << descriptor1;
|
||||
}
|
||||
}
|
||||
if (!deviceDescriptors.isEmpty()) {
|
||||
emit autoDevicesAppeared(tasmotaLightDeviceClassId, deviceDescriptors);
|
||||
}
|
||||
});
|
||||
return DeviceManager::DeviceSetupStatusAsync;
|
||||
}
|
||||
|
||||
if (m_connectedStateTypeMap.contains(device->deviceClassId())) {
|
||||
Device* parentDevice = myDevices().findById(device->parentId());
|
||||
StateTypeId connectedStateTypeId = m_connectedStateTypeMap.value(device->deviceClassId());
|
||||
device->setStateValue(m_connectedStateTypeMap.value(device->deviceClassId()), parentDevice->stateValue(connectedStateTypeId));
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
}
|
||||
|
||||
qCWarning(dcTasmota) << "Unhandled DeviceClass in setupDevice" << device->deviceClassId();
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
}
|
||||
|
||||
void DevicePluginTasmota::deviceRemoved(Device *device)
|
||||
{
|
||||
qCDebug(dcTasmota) << "Device removed" << device->name();
|
||||
if (m_mqttChannels.contains(device)) {
|
||||
qCDebug(dcTasmota) << "Releasing MQTT channel";
|
||||
MqttChannel* channel = m_mqttChannels.take(device);
|
||||
hardwareManager()->mqttProvider()->releaseChannel(channel);
|
||||
}
|
||||
}
|
||||
|
||||
DeviceManager::DeviceError DevicePluginTasmota::executeAction(Device *device, const Action &action)
|
||||
{
|
||||
if (m_powerStateTypeMap.contains(device->deviceClassId())) {
|
||||
Device *parentDev = myDevices().findById(device->parentId());
|
||||
MqttChannel *channel = m_mqttChannels.value(parentDev);
|
||||
ParamTypeId channelParamTypeId = m_channelParamTypeMap.value(device->deviceClassId());
|
||||
ParamTypeId powerActionParamTypeId = ParamTypeId(m_powerStateTypeMap.value(device->deviceClassId()).toString());
|
||||
qCDebug(dcTasmota) << "Publishing:" << channel->topicPrefix() + "/sonoff/cmnd/" + device->paramValue(channelParamTypeId).toString() << (action.param(powerActionParamTypeId).value().toBool() ? "ON" : "OFF");
|
||||
channel->publish(channel->topicPrefix() + "/sonoff/cmnd/" + device->paramValue(channelParamTypeId).toString().toLower(), action.param(powerActionParamTypeId).value().toBool() ? "ON" : "OFF");
|
||||
}
|
||||
return DeviceManager::DeviceErrorActionTypeNotFound;
|
||||
}
|
||||
|
||||
void DevicePluginTasmota::onClientConnected(MqttChannel *channel)
|
||||
{
|
||||
qCDebug(dcTasmota) << "Sonoff device connected!";
|
||||
Device *dev = m_mqttChannels.key(channel);
|
||||
dev->setStateValue(m_connectedStateTypeMap.value(dev->deviceClassId()), true);
|
||||
|
||||
foreach (Device *child, myDevices()) {
|
||||
if (child->parentId() == dev->id()) {
|
||||
child->setStateValue(m_connectedStateTypeMap.value(child->deviceClassId()), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginTasmota::onClientDisconnected(MqttChannel *channel)
|
||||
{
|
||||
qCDebug(dcTasmota) << "Sonoff device disconnected!";
|
||||
Device *dev = m_mqttChannels.key(channel);
|
||||
dev->setStateValue(m_connectedStateTypeMap.value(dev->deviceClassId()), false);
|
||||
|
||||
foreach (Device *child, myDevices()) {
|
||||
if (child->parentId() == dev->id()) {
|
||||
child->setStateValue(m_connectedStateTypeMap.value(dev->deviceClassId()), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginTasmota::onPublishReceived(MqttChannel *channel, const QString &topic, const QByteArray &payload)
|
||||
{
|
||||
qCDebug(dcTasmota) << "Publish received from Sonoff device:" << topic << payload;
|
||||
Device *dev = m_mqttChannels.key(channel);
|
||||
if (m_ipAddressParamTypeMap.contains(dev->deviceClassId())) {
|
||||
if (!topic.startsWith(channel->topicPrefix() + "/sonoff/POWER")) {
|
||||
return;
|
||||
}
|
||||
QString channelName = topic.split("/").last();
|
||||
|
||||
foreach (Device *child, myDevices()) {
|
||||
if (child->parentId() != dev->id()) {
|
||||
continue;
|
||||
}
|
||||
if (child->paramValue(m_channelParamTypeMap.value(child->deviceClassId())).toString() != channelName) {
|
||||
continue;
|
||||
}
|
||||
child->setStateValue(m_powerStateTypeMap.value(child->deviceClassId()), payload == "ON");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2018 Michael Zanetti <michael.zanetti@nymea.io> *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
* nymea is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 2 of the License. *
|
||||
* *
|
||||
* nymea is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with nymea. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef DEVICEPLUGINTASMOTA_H
|
||||
#define DEVICEPLUGINTASMOTA_H
|
||||
|
||||
#include "plugin/deviceplugin.h"
|
||||
#include "devicemanager.h"
|
||||
|
||||
class MqttChannel;
|
||||
|
||||
class DevicePluginTasmota: public DevicePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "deviceplugintasmota.json")
|
||||
Q_INTERFACES(DevicePlugin)
|
||||
|
||||
|
||||
public:
|
||||
explicit DevicePluginTasmota();
|
||||
~DevicePluginTasmota();
|
||||
|
||||
void init() override;
|
||||
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
|
||||
void deviceRemoved(Device *device) override;
|
||||
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
|
||||
|
||||
private slots:
|
||||
void onClientConnected(MqttChannel *channel);
|
||||
void onClientDisconnected(MqttChannel *channel);
|
||||
void onPublishReceived(MqttChannel *channel, const QString &topic, const QByteArray &payload);
|
||||
|
||||
private:
|
||||
QHash<Device*, MqttChannel*> m_mqttChannels;
|
||||
|
||||
// Helpers for parent devices (the ones starting with sonoff)
|
||||
QHash<DeviceClassId, ParamTypeId> m_ipAddressParamTypeMap;
|
||||
QHash<DeviceClassId, QList<ParamTypeId> > m_attachedDeviceParamTypeIdMap;
|
||||
|
||||
// Helpers for child devices (virtual ones, starting with tasmota)
|
||||
QHash<DeviceClassId, ParamTypeId> m_channelParamTypeMap;
|
||||
QHash<DeviceClassId, StateTypeId> m_powerStateTypeMap;
|
||||
|
||||
// Helpers for both devices
|
||||
QHash<DeviceClassId, StateTypeId> m_connectedStateTypeMap;
|
||||
};
|
||||
|
||||
#endif // DEVICEPLUGINTASMOTA_H
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
{
|
||||
"name": "tasmota",
|
||||
"displayName": "Sonoff-Tasmota",
|
||||
"id": "d136e0c0-0cbf-4731-aabb-b2201088d6cb",
|
||||
"vendors": [
|
||||
{
|
||||
"name": "tasmota",
|
||||
"displayName": "Sonoff-Tasmota",
|
||||
"id": "789e6173-3de3-44ef-8664-9492c9d15d44",
|
||||
"deviceClasses": [
|
||||
{
|
||||
"id": "f39fdfa8-73e0-4cf4-8d05-dc237ced7a57",
|
||||
"name": "sonoff_basic",
|
||||
"displayName": "Sonoff switch (Basic, RF, Touch...)",
|
||||
"createMethods": ["user"],
|
||||
"interfaces": [ "gateway" ],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "cdead654-a765-488c-9fe6-ce6afb550d8b",
|
||||
"name":"ipAddress",
|
||||
"displayName": "IP address",
|
||||
"type": "QString"
|
||||
},
|
||||
{
|
||||
"id": "f210d0c0-dda1-442d-a0cc-2f2e48c24984",
|
||||
"name": "attachedDeviceCH1",
|
||||
"displayName": "Connected device",
|
||||
"type": "QString",
|
||||
"allowedValues": ["None", "Light"],
|
||||
"defaultValue": "None"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "9cde6321-2abf-4a58-a1d6-c7418edb9747",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connected changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"cached": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "425ab191-833c-4618-8ac8-aff02370b99d",
|
||||
"name": "sonoff_dual",
|
||||
"displayName": "Sonoff dual switch (Dual, T1 2CH...)",
|
||||
"createMethods": ["user"],
|
||||
"interfaces": [ "gateway" ],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "7fe081a4-b9ec-4ca5-b583-50e992a24f4d",
|
||||
"name":"ipAddress",
|
||||
"displayName": "IP address",
|
||||
"type": "QString"
|
||||
},
|
||||
{
|
||||
"id": "5101ad0d-c887-44b8-998d-021948184ccd",
|
||||
"name": "attachedDeviceCH1",
|
||||
"displayName": "Connected device",
|
||||
"type": "QString",
|
||||
"allowedValues": ["None", "Light"],
|
||||
"defaultValue": "None"
|
||||
},
|
||||
{
|
||||
"id": "530edfb0-930d-4885-b1c0-3bf51a7671f1",
|
||||
"name": "attachedDeviceCH2",
|
||||
"displayName": "Connected device",
|
||||
"type": "QString",
|
||||
"allowedValues": ["None", "Light"],
|
||||
"defaultValue": "None"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "e2f55332-e706-412e-beb6-abf76b3bcff3",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connected changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"cached": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "ae845ec9-be61-4bdf-9015-4c156f937da7",
|
||||
"name": "sonoff_quad",
|
||||
"displayName": "Sonoff 4 channel switch (4CH, T1 4CH...)",
|
||||
"createMethods": ["user"],
|
||||
"interfaces": [ "gateway" ],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "dbc3f3b3-2d17-40e9-8f6e-dde0b26952bc",
|
||||
"name":"ipAddress",
|
||||
"displayName": "IP address",
|
||||
"type": "QString"
|
||||
},
|
||||
{
|
||||
"id": "d6520a7a-d340-4f42-a8c4-b2da8434f40f",
|
||||
"name": "attachedDeviceCH1",
|
||||
"displayName": "Connected device 1",
|
||||
"type": "QString",
|
||||
"allowedValues": ["None", "Light"],
|
||||
"defaultValue": "None"
|
||||
},
|
||||
{
|
||||
"id": "b27a1ad0-4455-4264-81a1-d625e312c330",
|
||||
"name": "attachedDeviceCH2",
|
||||
"displayName": "Connected device 2",
|
||||
"type": "QString",
|
||||
"allowedValues": ["None", "Light"],
|
||||
"defaultValue": "None"
|
||||
},
|
||||
{
|
||||
"id": "ee2509fb-7690-47f7-af74-05635b460be7",
|
||||
"name": "attachedDeviceCH3",
|
||||
"displayName": "Connected device 3",
|
||||
"type": "QString",
|
||||
"allowedValues": ["None", "Light"],
|
||||
"defaultValue": "None"
|
||||
},
|
||||
{
|
||||
"id": "a5bdb44f-9789-4e0a-8274-ec7866e8f148",
|
||||
"name": "attachedDeviceCH4",
|
||||
"displayName": "Connected device 4",
|
||||
"type": "QString",
|
||||
"allowedValues": ["None", "Light"],
|
||||
"defaultValue": "None"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "5b422d28-9f60-4ea9-ab23-42a0ec605b9e",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connected changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"cached": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "8a5e69c0-14ad-4ae8-9ff9-10055de6ffdf",
|
||||
"name": "tasmotaSwitch",
|
||||
"displayName": "Tasmota power switch",
|
||||
"createMethods": ["auto"],
|
||||
"interfaces": ["power", "connectable"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "564cf6c6-86eb-41a5-9b87-fb32f1b6fcd6",
|
||||
"name": "channelName",
|
||||
"displayName": "Channel name",
|
||||
"type": "QString"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "b4607e5d-70c4-4e76-9d9a-c6de7c50377e",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connected changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "413503d7-fc9f-417a-95fa-5c350a6f69f9",
|
||||
"name": "power",
|
||||
"displayName": "Power",
|
||||
"displayNameEvent": "Power changed",
|
||||
"displayNameAction": "Set power",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "83e5d9e6-5ac8-4e41-9717-481415048d49",
|
||||
"name": "tasmotaLight",
|
||||
"displayName": "Tasmota light",
|
||||
"createMethods": ["auto"],
|
||||
"interfaces": ["light", "connectable"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "1f792ae4-cf39-4e12-99ca-c593bd020fcb",
|
||||
"name": "channelName",
|
||||
"displayName": "Channel name",
|
||||
"type": "QString"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "72050de9-c318-4e53-93e5-36f7c2fc7cab",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connected changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "88dbdf8e-45ff-466f-8352-8654a6b5fe68",
|
||||
"name": "power",
|
||||
"displayName": "Power",
|
||||
"displayNameEvent": "Power changed",
|
||||
"displayNameAction": "Set power",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
include(../plugins.pri)
|
||||
|
||||
QT += network
|
||||
|
||||
TARGET = $$qtLibraryTarget(nymea_deviceplugintasmota)
|
||||
|
||||
SOURCES += \
|
||||
deviceplugintasmota.cpp \
|
||||
|
||||
HEADERS += \
|
||||
deviceplugintasmota.h \
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1">
|
||||
</TS>
|
||||
Loading…
Reference in New Issue