Merge PR #301: New PlugIn: SMA
This commit is contained in:
commit
e3cfd9c539
17
debian/control
vendored
17
debian/control
vendored
@ -1035,6 +1035,22 @@ Description: nymea.io plugin to send and receive strings over a serial port
|
||||
.
|
||||
This package will install the nymea.io plugin for serial ports
|
||||
|
||||
|
||||
Package: nymea-plugin-sma
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
nymea-plugins-translations,
|
||||
Description: nymea.io plugin for SMA PV-Inverter
|
||||
The nymea daemon is a plugin based IoT (Internet of Things) server. The
|
||||
server works like a translator for devices, things and services and
|
||||
allows them to interact.
|
||||
With the powerful rule engine you are able to connect any device available
|
||||
in the system and create individual scenes and behaviors for your environment.
|
||||
.
|
||||
This package will install the nymea.io plugin for SMA PV-Inverter
|
||||
|
||||
|
||||
Package: nymea-plugin-systemmonitor
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
@ -1231,6 +1247,7 @@ Depends: nymea-plugin-anel,
|
||||
nymea-plugin-shelly,
|
||||
nymea-plugin-senic,
|
||||
nymea-plugin-somfytahoma,
|
||||
nymea-plugin-sma,
|
||||
nymea-plugin-sonos,
|
||||
nymea-plugin-solarlog,
|
||||
nymea-plugin-tado,
|
||||
|
||||
1
debian/nymea-plugin-sma.install.in
vendored
Normal file
1
debian/nymea-plugin-sma.install.in
vendored
Normal file
@ -0,0 +1 @@
|
||||
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginsma.so
|
||||
@ -53,6 +53,7 @@ PLUGIN_DIRS = \
|
||||
senic \
|
||||
serialportcommander \
|
||||
simulation \
|
||||
sma \
|
||||
somfytahoma \
|
||||
sonos \
|
||||
sunposition \
|
||||
|
||||
14
sma/README.md
Normal file
14
sma/README.md
Normal file
@ -0,0 +1,14 @@
|
||||
# SMA
|
||||
|
||||
nymea plug-in for SMA solar equipment.
|
||||
|
||||
## Supported Things
|
||||
|
||||
* Sunny WebBox
|
||||
|
||||
## Requirements
|
||||
|
||||
* The package "nymea-plugin-sma" must be installed.
|
||||
|
||||
## More
|
||||
https://www.sma.de/en/
|
||||
194
sma/integrationpluginsma.cpp
Normal file
194
sma/integrationpluginsma.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; version 3. This project 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "integrationpluginsma.h"
|
||||
#include "plugininfo.h"
|
||||
|
||||
#include "network/networkdevicediscovery.h"
|
||||
|
||||
IntegrationPluginSma::IntegrationPluginSma()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void IntegrationPluginSma::discoverThings(ThingDiscoveryInfo *info)
|
||||
{
|
||||
if (!hardwareManager()->networkDeviceDiscovery()->available()) {
|
||||
qCWarning(dcSma()) << "Failed to discover network devices. The network device discovery is not available.";
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("Unable to discover devices in your network."));
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcSma()) << "Starting network discovery...";
|
||||
NetworkDeviceDiscoveryReply *discoveryReply = hardwareManager()->networkDeviceDiscovery()->discover();
|
||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){
|
||||
ThingDescriptors descriptors;
|
||||
qCDebug(dcSma()) << "Discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "devices";
|
||||
foreach (const NetworkDeviceInfo &networkDeviceInfo, discoveryReply->networkDeviceInfos()) {
|
||||
// Filter for sma hosts
|
||||
if (!networkDeviceInfo.hostName().toLower().contains("sma"))
|
||||
continue;
|
||||
|
||||
QString title = networkDeviceInfo.hostName() + " (" + networkDeviceInfo.address().toString() + ")";
|
||||
QString description;
|
||||
if (networkDeviceInfo.macAddressManufacturer().isEmpty()) {
|
||||
description = networkDeviceInfo.macAddress();
|
||||
} else {
|
||||
description = networkDeviceInfo.macAddress() + " (" + networkDeviceInfo.macAddressManufacturer() + ")";
|
||||
}
|
||||
|
||||
ThingDescriptor descriptor(sunnyWebBoxThingClassId, title, description);
|
||||
|
||||
// Check for reconfiguration
|
||||
foreach (Thing *existingThing, myThings()) {
|
||||
if (existingThing->paramValue(sunnyWebBoxThingMacAddressParamTypeId).toString() == networkDeviceInfo.macAddress()) {
|
||||
descriptor.setThingId(existingThing->id());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ParamList params;
|
||||
params << Param(sunnyWebBoxThingHostParamTypeId, networkDeviceInfo.address().toString());
|
||||
params << Param(sunnyWebBoxThingMacAddressParamTypeId, networkDeviceInfo.macAddress());
|
||||
descriptor.setParams(params);
|
||||
descriptors.append(descriptor);
|
||||
}
|
||||
info->addThingDescriptors(descriptors);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void IntegrationPluginSma::setupThing(ThingSetupInfo *info)
|
||||
{
|
||||
Thing *thing = info->thing();
|
||||
qCDebug(dcSma()) << "Setup thing" << thing << thing->params();
|
||||
|
||||
if (thing->thingClassId() == sunnyWebBoxThingClassId) {
|
||||
// Check if a Sunny WebBox is already added with this mac address
|
||||
foreach (SunnyWebBox *sunnyWebBox, m_sunnyWebBoxes.values()) {
|
||||
if (sunnyWebBox->macAddress() == thing->paramValue(sunnyWebBoxThingMacAddressParamTypeId).toString()){
|
||||
qCWarning(dcSma()) << "Thing with mac address" << thing->paramValue(sunnyWebBoxThingMacAddressParamTypeId).toString() << " already added!";
|
||||
info->finish(Thing::ThingErrorThingInUse);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_sunnyWebBoxes.contains(thing)) {
|
||||
qCDebug(dcSma()) << "Setup after reconfiguration, cleaning up...";
|
||||
m_sunnyWebBoxes.take(thing)->deleteLater();
|
||||
}
|
||||
|
||||
SunnyWebBox *sunnyWebBox = new SunnyWebBox(hardwareManager()->networkManager(), QHostAddress(thing->paramValue(sunnyWebBoxThingHostParamTypeId).toString()), this);
|
||||
sunnyWebBox->setMacAddress(thing->paramValue(sunnyWebBoxThingMacAddressParamTypeId).toString());
|
||||
|
||||
connect(info, &ThingSetupInfo::aborted, sunnyWebBox, &SunnyWebBox::deleteLater);
|
||||
connect(sunnyWebBox, &SunnyWebBox::destroyed, this, [thing, this] { m_sunnyWebBoxes.remove(thing);});
|
||||
|
||||
QString requestId = sunnyWebBox->getPlantOverview();
|
||||
connect(sunnyWebBox, &SunnyWebBox::plantOverviewReceived, info, [=] (const QString &messageId, SunnyWebBox::Overview overview) {
|
||||
qCDebug(dcSma()) << "Received plant overview" << messageId << "Finish setup";
|
||||
Q_UNUSED(overview)
|
||||
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
connect(sunnyWebBox, &SunnyWebBox::connectedChanged, this, &IntegrationPluginSma::onConnectedChanged);
|
||||
connect(sunnyWebBox, &SunnyWebBox::plantOverviewReceived, this, &IntegrationPluginSma::onPlantOverviewReceived);
|
||||
m_sunnyWebBoxes.insert(info->thing(), sunnyWebBox);
|
||||
|
||||
if (!m_refreshTimer) {
|
||||
qCDebug(dcSma()) << "Starting refresh timer";
|
||||
m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(1);
|
||||
connect(m_refreshTimer, &PluginTimer::timeout, this, &IntegrationPluginSma::onRefreshTimer);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Q_ASSERT_X(false, "setupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginSma::postSetupThing(Thing *thing)
|
||||
{
|
||||
qCDebug(dcSma()) << "Post setup thing" << thing->name();
|
||||
if (thing->thingClassId() == sunnyWebBoxThingClassId) {
|
||||
SunnyWebBox *sunnyWebBox = m_sunnyWebBoxes.value(thing);
|
||||
if (!sunnyWebBox)
|
||||
return;
|
||||
sunnyWebBox->getPlantOverview();
|
||||
thing->setStateValue(sunnyWebBoxConnectedStateTypeId, true);
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginSma::thingRemoved(Thing *thing)
|
||||
{
|
||||
if (thing->thingClassId() == sunnyWebBoxThingClassId) {
|
||||
m_sunnyWebBoxes.take(thing)->deleteLater();
|
||||
}
|
||||
|
||||
if (myThings().isEmpty()) {
|
||||
qCDebug(dcSma()) << "Stopping timer";
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer);
|
||||
m_refreshTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginSma::onRefreshTimer()
|
||||
{
|
||||
Q_FOREACH(Thing *thing, myThings().filterByThingClassId(sunnyWebBoxThingClassId)) {
|
||||
SunnyWebBox *sunnyWebBox = m_sunnyWebBoxes.value(thing);
|
||||
sunnyWebBox->getPlantOverview();
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginSma::onConnectedChanged(bool connected)
|
||||
{
|
||||
Thing *thing = m_sunnyWebBoxes.key(static_cast<SunnyWebBox *>(sender()));
|
||||
if (!thing)
|
||||
return;
|
||||
thing->setStateValue(sunnyWebBoxConnectedStateTypeId, connected);
|
||||
}
|
||||
|
||||
void IntegrationPluginSma::onPlantOverviewReceived(const QString &messageId, SunnyWebBox::Overview overview)
|
||||
{
|
||||
Q_UNUSED(messageId)
|
||||
|
||||
qCDebug(dcSma()) << "Plant overview received" << overview.status;
|
||||
Thing *thing = m_sunnyWebBoxes.key(static_cast<SunnyWebBox *>(sender()));
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
thing->setStateValue(sunnyWebBoxCurrentPowerStateTypeId, overview.power);
|
||||
thing->setStateValue(sunnyWebBoxDayEnergyProducedStateTypeId, overview.dailyYield);
|
||||
thing->setStateValue(sunnyWebBoxTotalEnergyProducedStateTypeId, overview.totalYield);
|
||||
thing->setStateValue(sunnyWebBoxModeStateTypeId, overview.status);
|
||||
if (!overview.error.isEmpty()){
|
||||
qCDebug(dcSma()) << "Received error" << overview.error;
|
||||
thing->setStateValue(sunnyWebBoxErrorStateTypeId, overview.error);
|
||||
}
|
||||
}
|
||||
64
sma/integrationpluginsma.h
Normal file
64
sma/integrationpluginsma.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; version 3. This project 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef INTEGRATIONPLUGINSMA_H
|
||||
#define INTEGRATIONPLUGINSMA_H
|
||||
|
||||
#include "integrations/integrationplugin.h"
|
||||
#include "plugintimer.h"
|
||||
#include "sunnywebbox.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
class IntegrationPluginSma: public IntegrationPlugin {
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginsma.json")
|
||||
Q_INTERFACES(IntegrationPlugin)
|
||||
|
||||
public:
|
||||
explicit IntegrationPluginSma();
|
||||
|
||||
void discoverThings(ThingDiscoveryInfo *info) override;
|
||||
void setupThing(ThingSetupInfo *info) override;
|
||||
void postSetupThing(Thing *thing) override;
|
||||
void thingRemoved(Thing *thing) override;
|
||||
|
||||
private slots:
|
||||
void onRefreshTimer();
|
||||
|
||||
void onConnectedChanged(bool connected);
|
||||
void onPlantOverviewReceived(const QString &messageId, SunnyWebBox::Overview overview);
|
||||
|
||||
private:
|
||||
PluginTimer *m_refreshTimer = nullptr;
|
||||
QHash<Thing *, SunnyWebBox *> m_sunnyWebBoxes;
|
||||
};
|
||||
|
||||
#endif // INTEGRATIONPLUGINSMA_H
|
||||
93
sma/integrationpluginsma.json
Normal file
93
sma/integrationpluginsma.json
Normal file
@ -0,0 +1,93 @@
|
||||
{
|
||||
"id": "b8442bbf-9d3f-4aa2-9443-b3a31ae09bac",
|
||||
"name": "sma",
|
||||
"displayName": "SMA",
|
||||
"vendors": [
|
||||
{
|
||||
"id": "16d5a4a3-36d5-46c0-b7dd-df166ddf5981",
|
||||
"name": "Sma",
|
||||
"displayName": "SMA",
|
||||
"thingClasses": [
|
||||
{
|
||||
"id": "49304127-ce9b-45dd-8511-05030a4ac003",
|
||||
"name": "sunnyWebBox",
|
||||
"displayName": "Sunny WebBox",
|
||||
"createMethods": ["user", "discovery"],
|
||||
"interfaces": ["smartmeterproducer"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "864d4162-e3ce-48b8-b8ac-c1b971b52d42",
|
||||
"name": "host",
|
||||
"displayName": "Host address",
|
||||
"type": "QString",
|
||||
"inputType": "IPv4Address",
|
||||
"defaultValue": "192.168.0.168"
|
||||
},
|
||||
{
|
||||
"id": "03f32361-4e13-4597-a346-af8d16a986b3",
|
||||
"name": "macAddress",
|
||||
"displayName": "hardware address",
|
||||
"type": "QString",
|
||||
"inputType": "TextLine",
|
||||
"readOnly": true
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "c05e6a1a-252c-4f2b-8b31-09cf113d01c1",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connected changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "ff4ff872-2f0f-4ca4-9fe2-220eeaf16cc2",
|
||||
"name": "currentPower",
|
||||
"displayName": "Current power",
|
||||
"displayNameEvent": "Current power changed",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "16f34c5c-8dbb-4dcc-9faa-4b782d57226c",
|
||||
"name": "dayEnergyProduced",
|
||||
"displayName": "Day energy produced",
|
||||
"displayNameEvent": "Day energy produced changed",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "0bb4e227-7e38-49ca-9b32-ce4621c9305b",
|
||||
"name": "totalEnergyProduced",
|
||||
"displayName": "Total energy produced",
|
||||
"displayNameEvent": "Total energy produced changed",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "1974550b-6059-4b0e-83f4-70177e20dac3",
|
||||
"name": "mode",
|
||||
"displayName": "Mode",
|
||||
"displayNameEvent": "Mode changed",
|
||||
"type": "QString",
|
||||
"defaultValue": "MPP"
|
||||
},
|
||||
{
|
||||
"id": "4e64f9ca-7e5a-4897-8035-6f2ae88fde89",
|
||||
"name": "error",
|
||||
"displayName": "Error",
|
||||
"displayNameEvent": "Error changed",
|
||||
"type": "QString",
|
||||
"defaultValue": "None"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
13
sma/meta.json
Normal file
13
sma/meta.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"title": "SMA",
|
||||
"tagline": "Connect to SMA solar equipment.",
|
||||
"icon": "sma.png",
|
||||
"stability": "consumer",
|
||||
"offline": true,
|
||||
"technologies": [
|
||||
"network"
|
||||
],
|
||||
"categories": [
|
||||
|
||||
]
|
||||
}
|
||||
BIN
sma/sma.png
Normal file
BIN
sma/sma.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
11
sma/sma.pro
Normal file
11
sma/sma.pro
Normal file
@ -0,0 +1,11 @@
|
||||
include(../plugins.pri)
|
||||
|
||||
QT += network
|
||||
|
||||
SOURCES += \
|
||||
integrationpluginsma.cpp \
|
||||
sunnywebbox.cpp
|
||||
|
||||
HEADERS += \
|
||||
integrationpluginsma.h \
|
||||
sunnywebbox.h
|
||||
332
sma/sunnywebbox.cpp
Normal file
332
sma/sunnywebbox.cpp
Normal file
@ -0,0 +1,332 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; version 3. This project 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "sunnywebbox.h"
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
#include "QJsonDocument"
|
||||
#include "QJsonObject"
|
||||
#include "QJsonArray"
|
||||
|
||||
SunnyWebBox::SunnyWebBox(NetworkAccessManager *networkAccessManager, const QHostAddress &hostAddress, QObject *parrent) :
|
||||
QObject(parrent),
|
||||
m_hostAddresss(hostAddress),
|
||||
m_networkManager(networkAccessManager)
|
||||
{
|
||||
qCDebug(dcSma()) << "SunnyWebBox: Creating Sunny Web Box connection";
|
||||
}
|
||||
|
||||
SunnyWebBox::~SunnyWebBox()
|
||||
{
|
||||
qCDebug(dcSma()) << "SunnyWebBox: Deleting Sunny Web Box connection";
|
||||
}
|
||||
|
||||
QString SunnyWebBox::getPlantOverview()
|
||||
{
|
||||
return sendMessage(m_hostAddresss, "GetPlantOverview");
|
||||
}
|
||||
|
||||
QString SunnyWebBox::getDevices()
|
||||
{
|
||||
return sendMessage(m_hostAddresss, "GetDevices");
|
||||
}
|
||||
|
||||
QString SunnyWebBox::getProcessDataChannels(const QString &deviceId)
|
||||
{
|
||||
QJsonObject params;
|
||||
params["device"] = deviceId;
|
||||
return sendMessage(m_hostAddresss, "GetProcessDataChannels", params);
|
||||
}
|
||||
|
||||
QString SunnyWebBox::getProcessData(const QStringList &deviceKeys)
|
||||
{
|
||||
QJsonObject paramsObj;
|
||||
QJsonArray devicesArray;
|
||||
Q_FOREACH(QString key, deviceKeys) {
|
||||
QJsonObject deviceObj;
|
||||
deviceObj["key"] = key;
|
||||
devicesArray.append(deviceObj);
|
||||
}
|
||||
paramsObj["devices"] = devicesArray;
|
||||
return sendMessage(m_hostAddresss, "GetProcessData", paramsObj);
|
||||
}
|
||||
|
||||
QString SunnyWebBox::getParameterChannels(const QString &deviceKey)
|
||||
{
|
||||
QJsonObject paramsObj;
|
||||
QJsonArray devicesArray;
|
||||
QJsonObject deviceObj;
|
||||
deviceObj["key"] = deviceKey;
|
||||
devicesArray.append(deviceObj);
|
||||
paramsObj["devices"] = devicesArray;
|
||||
return sendMessage(m_hostAddresss, "GetParameterChannels", paramsObj);
|
||||
}
|
||||
|
||||
QString SunnyWebBox::getParameters(const QStringList &deviceKeys)
|
||||
{
|
||||
QJsonObject paramsObj;
|
||||
QJsonArray devicesArray;
|
||||
Q_FOREACH(QString key, deviceKeys) {
|
||||
QJsonObject deviceObj;
|
||||
deviceObj["key"] = key;
|
||||
devicesArray.append(deviceObj);
|
||||
}
|
||||
paramsObj["devices"] = devicesArray;
|
||||
return sendMessage(m_hostAddresss, "GetParameter", paramsObj);
|
||||
}
|
||||
|
||||
QString SunnyWebBox::setParameters(const QString &deviceKey, const QHash<QString, QVariant> &channels)
|
||||
{
|
||||
QJsonObject paramsObj;
|
||||
QJsonArray devicesArray;
|
||||
QJsonObject deviceObj;
|
||||
deviceObj["key"] = deviceKey;
|
||||
QJsonArray channelsArray;
|
||||
Q_FOREACH(QString key, channels.keys()) {
|
||||
QJsonObject channelObj;
|
||||
channelObj["meta"] = key;
|
||||
channelObj["value"] = channels.value(key).toString();
|
||||
channelsArray.append(channelObj);
|
||||
}
|
||||
deviceObj["channels"] = channelsArray;
|
||||
devicesArray.append(deviceObj);
|
||||
paramsObj["devices"] = devicesArray;
|
||||
return sendMessage(m_hostAddresss, "SetParameter", paramsObj);
|
||||
}
|
||||
|
||||
QHostAddress SunnyWebBox::hostAddress() const
|
||||
{
|
||||
return m_hostAddresss;
|
||||
}
|
||||
|
||||
void SunnyWebBox::setHostAddress(const QHostAddress &address)
|
||||
{
|
||||
qCDebug(dcSma()) << "SunnyWebBox: Setting host address to" << address.toString();
|
||||
m_hostAddresss = address;
|
||||
}
|
||||
|
||||
QString SunnyWebBox::macAddress() const
|
||||
{
|
||||
return m_macAddress;
|
||||
}
|
||||
|
||||
void SunnyWebBox::setMacAddress(const QString &macAddress)
|
||||
{
|
||||
m_macAddress = macAddress;
|
||||
}
|
||||
|
||||
void SunnyWebBox::parseMessage(const QString &messageId, const QString &messageType, const QVariantMap &result)
|
||||
{
|
||||
if (messageType == "GetPlantOverview") {
|
||||
Overview overview;
|
||||
QVariantList overviewList = result.value("overview").toList();
|
||||
qCDebug(dcSma()) << "SunnyWebBox: GetPlantOverview";
|
||||
Q_FOREACH(QVariant value, overviewList) {
|
||||
QVariantMap map = value.toMap();
|
||||
|
||||
if (map["meta"].toString() == "GriPwr") {
|
||||
overview.power = map["value"].toString().toInt();
|
||||
QString unit = map["unit"].toString();
|
||||
qCDebug(dcSma()) << "SunnyWebBox: - Power" << overview.power << unit;
|
||||
} else if (map["meta"].toString() == "GriEgyTdy") {
|
||||
overview.dailyYield = map["value"].toString().toDouble();
|
||||
QString unit = map["unit"].toString();
|
||||
qCDebug(dcSma()) << "SunnyWebBox: - Daily yield" << overview.dailyYield << unit;
|
||||
} else if (map["meta"].toString() == "GriEgyTot") {
|
||||
overview.totalYield = map["value"].toString().toDouble();
|
||||
QString unit = map["unit"].toString();
|
||||
qCDebug(dcSma()) << "SunnyWebBox: - Total yield" << overview.totalYield << unit;
|
||||
} else if (map["meta"].toString() == "OpStt") {
|
||||
overview.status = map["value"].toString();
|
||||
qCDebug(dcSma()) << "SunnyWebBox: - Status" << overview.status;
|
||||
} else if (map["meta"].toString() == "Msg") {
|
||||
overview.error = map["value"].toString();
|
||||
qCDebug(dcSma()) << "SunnyWebBox: - Error" << overview.error;
|
||||
}
|
||||
}
|
||||
emit plantOverviewReceived(messageId, overview);
|
||||
|
||||
} else if (messageType == "GetDevices") {
|
||||
QList<Device> devices;
|
||||
QVariantList deviceList = result.value("devices").toList();
|
||||
qCDebug(dcSma()) << "SunnyWebBox: GetDevices" << result.value("totalDevicesReturned").toInt();
|
||||
Q_FOREACH(QVariant value, deviceList) {
|
||||
Device device;
|
||||
QVariantMap map = value.toMap();
|
||||
device.name = map["name"].toString();
|
||||
qCDebug(dcSma()) << "SunnyWebBox: - Name" << device.name;
|
||||
device.key = map["key"].toString();
|
||||
qCDebug(dcSma()) << "SunnyWebBox: - Key" << device.key;
|
||||
QVariantList childrenList = map["children"].toList();
|
||||
Q_FOREACH(QVariant childValue, childrenList) {
|
||||
Device child;
|
||||
QVariantMap childMap = childValue.toMap();
|
||||
device.name = childMap["name"].toString();
|
||||
device.key = childMap["key"].toString();
|
||||
device.childrens.append(child);
|
||||
}
|
||||
devices.append(device);
|
||||
}
|
||||
if (!devices.isEmpty())
|
||||
emit devicesReceived(messageId, devices);
|
||||
} else if (messageType == "GetProcessDataChannels" ||
|
||||
messageType == "GetProDataChannels") {
|
||||
Q_FOREACH(QString deviceKey, result.keys()) {
|
||||
QStringList processDataChannels = result.value(deviceKey).toStringList();
|
||||
if (!processDataChannels.isEmpty())
|
||||
emit processDataChannelsReceived(messageId, deviceKey, processDataChannels);
|
||||
}
|
||||
} else if (messageType == "GetProcessData") {
|
||||
QList<Device> devices;
|
||||
QVariantList devicesList = result.value("devices").toList();
|
||||
qCDebug(dcSma()) << "SunnyWebBox: GetProcessData response received";
|
||||
Q_FOREACH(QVariant value, devicesList) {
|
||||
|
||||
QString key = value.toMap().value("key").toString();
|
||||
QVariantList channelsList = value.toMap().value("channels").toList();
|
||||
QHash<QString, QVariant> channels;
|
||||
Q_FOREACH(QVariant channel, channelsList) {
|
||||
channels.insert(channel.toMap().value("meta").toString(), channel.toMap().value("value"));
|
||||
}
|
||||
emit processDataReceived(messageId, key, channels);
|
||||
}
|
||||
} else if (messageType == "GetParameterChannels") {
|
||||
Q_FOREACH(QString deviceKey, result.keys()) {
|
||||
QStringList parameterChannels = result.value(deviceKey).toStringList();
|
||||
if (!parameterChannels.isEmpty())
|
||||
emit parameterChannelsReceived(messageId, deviceKey, parameterChannels);
|
||||
}
|
||||
} else if (messageType == "GetParameter"|| messageType == "SetParameter") {
|
||||
QList<Device> devices;
|
||||
QVariantList devicesList = result.value("devices").toList();
|
||||
Q_FOREACH(QVariant value, devicesList) {
|
||||
|
||||
QString key = value.toMap().value("key").toString();
|
||||
QVariantList channelsList = value.toMap().value("channels").toList();
|
||||
QList<Parameter> parameters;
|
||||
Q_FOREACH(QVariant channel, channelsList) {
|
||||
Parameter parameter;
|
||||
parameter.meta = channel.toMap().value("meta").toString();
|
||||
parameter.name = channel.toMap().value("name").toString();
|
||||
parameter.unit = channel.toMap().value("unit").toString();
|
||||
parameter.min = channel.toMap().value("min").toDouble();
|
||||
parameter.max = channel.toMap().value("max").toDouble();
|
||||
parameter.value = channel.toMap().value("value").toDouble();
|
||||
parameters.append(parameter);
|
||||
}
|
||||
emit parametersReceived(messageId, key, parameters);
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcSma()) << "SunnyWebBox: Unknown message type" << messageType;
|
||||
}
|
||||
}
|
||||
|
||||
void SunnyWebBox::setConnectionStatus(bool connected)
|
||||
{
|
||||
if (m_connected != connected) {
|
||||
qCDebug(dcSma()) << "SunnyWebBox: Connection status changed" << connected;
|
||||
m_connected = connected;
|
||||
emit connectedChanged(m_connected);
|
||||
}
|
||||
}
|
||||
|
||||
QString SunnyWebBox::sendMessage(const QHostAddress &address, const QString &procedure)
|
||||
{
|
||||
return sendMessage(address, procedure, QJsonObject());
|
||||
}
|
||||
|
||||
QString SunnyWebBox::sendMessage(const QHostAddress &address, const QString &procedure, const QJsonObject ¶ms)
|
||||
{
|
||||
qCDebug(dcSma()) << "SunnyWebBox: Send message to" << address.toString() << "Procedure:" << procedure << "Params:" << params;
|
||||
QString requestId = QUuid::createUuid().toString().remove('{').remove('-').left(14);
|
||||
|
||||
QJsonDocument doc;
|
||||
QJsonObject obj;
|
||||
obj["format"] = "JSON";
|
||||
obj["id"] = requestId;
|
||||
obj["proc"] = procedure;
|
||||
obj["version"] = "1.0";
|
||||
|
||||
if (!params.isEmpty()) {
|
||||
obj.insert("params", params);
|
||||
}
|
||||
doc.setObject(obj);
|
||||
|
||||
QUrl url;
|
||||
url.setHost(address.toString());
|
||||
url.setPath("/rpc");
|
||||
url.setPort(80);
|
||||
url.setScheme("http");
|
||||
QNetworkRequest request(url);
|
||||
request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json");
|
||||
QByteArray data = doc.toJson(QJsonDocument::JsonFormat::Compact);
|
||||
data.prepend("RPC=");
|
||||
QNetworkReply *reply = m_networkManager->post(request, data);
|
||||
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||
connect(reply, &QNetworkReply::finished, this, [this, address, requestId, reply]{
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
setConnectionStatus(false);
|
||||
return;
|
||||
}
|
||||
setConnectionStatus(true);
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
qCDebug(dcSma()) << "SunnyWebBox: Received reply" << data;
|
||||
|
||||
QJsonParseError error;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(data, &error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcSma()) << "SunnyWebBox: Could not parse JSON" << error.errorString();
|
||||
return;
|
||||
}
|
||||
if (!doc.isObject()) {
|
||||
qCWarning(dcSma()) << "SunnyWebBox: JSON is not an Object";
|
||||
return;
|
||||
}
|
||||
QVariantMap map = doc.toVariant().toMap();
|
||||
if (map["version"] != "1.0") {
|
||||
qCWarning(dcSma()) << "SunnyWebBox: API version not supported" << map["version"];
|
||||
return;
|
||||
}
|
||||
|
||||
if (map.contains("proc") && map.contains("result")) {
|
||||
QString requestType = map["proc"].toString();
|
||||
QString requestId = map["id"].toString();
|
||||
QVariantMap result = map.value("result").toMap();
|
||||
parseMessage(requestId, requestType, result);
|
||||
} else if (map.contains("proc") && map.contains("error")) {
|
||||
} else {
|
||||
qCWarning(dcSma()) << "SunnyWebBox: Missing proc or result value";
|
||||
}
|
||||
});
|
||||
return requestId;
|
||||
}
|
||||
|
||||
115
sma/sunnywebbox.h
Normal file
115
sma/sunnywebbox.h
Normal file
@ -0,0 +1,115 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; version 3. This project 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef SUNNYWEBBOX_H
|
||||
#define SUNNYWEBBOX_H
|
||||
|
||||
#include "integrations/thing.h"
|
||||
#include "network/networkaccessmanager.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
#include <QUdpSocket>
|
||||
|
||||
class SunnyWebBox : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
struct Overview {
|
||||
int power;
|
||||
double dailyYield;
|
||||
int totalYield;
|
||||
QString status;
|
||||
QString error;
|
||||
};
|
||||
|
||||
struct Device {
|
||||
QString key;
|
||||
QString name;
|
||||
QList<Device> childrens;
|
||||
};
|
||||
|
||||
struct Channel {
|
||||
QString meta;
|
||||
QString name;
|
||||
QVariant value;
|
||||
QString unit;
|
||||
};
|
||||
|
||||
struct Parameter {
|
||||
QString meta;
|
||||
QString name;
|
||||
QString unit;
|
||||
double min;
|
||||
double max;
|
||||
double value;
|
||||
};
|
||||
|
||||
explicit SunnyWebBox(NetworkAccessManager *networkAccessManager, const QHostAddress &hostAddress, QObject *parrent = 0);
|
||||
~SunnyWebBox();
|
||||
|
||||
QString getPlantOverview(); // Returns an object with the following plant data: PAC, E-TODAY, E-TOTAL, MODE, ERROR
|
||||
QString getDevices(); // Returns a hierarchical list of all detected plant devices.
|
||||
QString getProcessDataChannels(const QString &deviceKey); //Returns a list with the meta names of the available process data channels for a particular device type.
|
||||
QString getProcessData(const QStringList &deviceKeys); //Returns process data for up to 5 devices per request.
|
||||
QString getParameterChannels(const QString &deviceKey); //Returns a list with the meta names of the available parameter channels for a particular device type
|
||||
QString getParameters(const QStringList &deviceKeys); //Returns the parameter values of up to 5 devices
|
||||
QString setParameters(const QString &deviceKeys, const QHash<QString, QVariant> &channels); //Sets parameter values
|
||||
|
||||
QHostAddress hostAddress() const;
|
||||
void setHostAddress(const QHostAddress &address);
|
||||
|
||||
QString macAddress() const;
|
||||
void setMacAddress(const QString &macAddress);
|
||||
|
||||
private:
|
||||
bool m_connected = false;
|
||||
QHostAddress m_hostAddresss;
|
||||
QString m_macAddress;
|
||||
NetworkAccessManager *m_networkManager = nullptr;
|
||||
|
||||
QString sendMessage(const QHostAddress &address, const QString &procedure);
|
||||
QString sendMessage(const QHostAddress &address, const QString &procedure, const QJsonObject ¶ms);
|
||||
void parseMessage(const QString &messageId, const QString &messageType, const QVariantMap &result);
|
||||
void setConnectionStatus(bool connected);
|
||||
|
||||
signals:
|
||||
void connectedChanged(bool connected);
|
||||
|
||||
void plantOverviewReceived(const QString &messageId, Overview overview);
|
||||
void devicesReceived(const QString &messageId, QList<Device> devices);
|
||||
void processDataChannelsReceived(const QString &messageId, const QString &deviceKey, QStringList processDataChanels);
|
||||
void processDataReceived(const QString &messageId, const QString &deviceKey, const QHash<QString, QVariant> &channels);
|
||||
void parameterChannelsReceived(const QString &messageId, const QString &deviceKey, QStringList parameterChannels);
|
||||
void parametersReceived(const QString &messageId, const QString &deviceKey, const QList<Parameter> ¶meters);
|
||||
};
|
||||
|
||||
#endif // SUNNYWEBBOX_H
|
||||
132
sma/translations/b8442bbf-9d3f-4aa2-9443-b3a31ae09bac-en_US.ts
Normal file
132
sma/translations/b8442bbf-9d3f-4aa2-9443-b3a31ae09bac-en_US.ts
Normal file
@ -0,0 +1,132 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1">
|
||||
<context>
|
||||
<name>IntegrationPluginSma</name>
|
||||
<message>
|
||||
<location filename="../integrationpluginsma.cpp" line="45"/>
|
||||
<source>Unable to discover devices in your network.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>sma</name>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="48"/>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="51"/>
|
||||
<source>Connected</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: sunnyWebBox, EventType: connected, ID: {c05e6a1a-252c-4f2b-8b31-09cf113d01c1})
|
||||
----------
|
||||
The name of the StateType ({c05e6a1a-252c-4f2b-8b31-09cf113d01c1}) of ThingClass sunnyWebBox</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="54"/>
|
||||
<source>Connected changed</source>
|
||||
<extracomment>The name of the EventType ({c05e6a1a-252c-4f2b-8b31-09cf113d01c1}) of ThingClass sunnyWebBox</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="57"/>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="60"/>
|
||||
<source>Current power</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: sunnyWebBox, EventType: currentPower, ID: {ff4ff872-2f0f-4ca4-9fe2-220eeaf16cc2})
|
||||
----------
|
||||
The name of the StateType ({ff4ff872-2f0f-4ca4-9fe2-220eeaf16cc2}) of ThingClass sunnyWebBox</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="63"/>
|
||||
<source>Current power changed</source>
|
||||
<extracomment>The name of the EventType ({ff4ff872-2f0f-4ca4-9fe2-220eeaf16cc2}) of ThingClass sunnyWebBox</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="66"/>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="69"/>
|
||||
<source>Day energy produced</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: sunnyWebBox, EventType: dayEnergyProduced, ID: {16f34c5c-8dbb-4dcc-9faa-4b782d57226c})
|
||||
----------
|
||||
The name of the StateType ({16f34c5c-8dbb-4dcc-9faa-4b782d57226c}) of ThingClass sunnyWebBox</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="72"/>
|
||||
<source>Day energy produced changed</source>
|
||||
<extracomment>The name of the EventType ({16f34c5c-8dbb-4dcc-9faa-4b782d57226c}) of ThingClass sunnyWebBox</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="75"/>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="78"/>
|
||||
<source>Error</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: sunnyWebBox, EventType: error, ID: {4e64f9ca-7e5a-4897-8035-6f2ae88fde89})
|
||||
----------
|
||||
The name of the StateType ({4e64f9ca-7e5a-4897-8035-6f2ae88fde89}) of ThingClass sunnyWebBox</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="81"/>
|
||||
<source>Error changed</source>
|
||||
<extracomment>The name of the EventType ({4e64f9ca-7e5a-4897-8035-6f2ae88fde89}) of ThingClass sunnyWebBox</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="84"/>
|
||||
<source>Host address</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: sunnyWebBox, Type: thing, ID: {864d4162-e3ce-48b8-b8ac-c1b971b52d42})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="87"/>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="90"/>
|
||||
<source>Mode</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: sunnyWebBox, EventType: mode, ID: {1974550b-6059-4b0e-83f4-70177e20dac3})
|
||||
----------
|
||||
The name of the StateType ({1974550b-6059-4b0e-83f4-70177e20dac3}) of ThingClass sunnyWebBox</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="93"/>
|
||||
<source>Mode changed</source>
|
||||
<extracomment>The name of the EventType ({1974550b-6059-4b0e-83f4-70177e20dac3}) of ThingClass sunnyWebBox</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="96"/>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="99"/>
|
||||
<source>SMA</source>
|
||||
<extracomment>The name of the vendor ({16d5a4a3-36d5-46c0-b7dd-df166ddf5981})
|
||||
----------
|
||||
The name of the plugin sma ({b8442bbf-9d3f-4aa2-9443-b3a31ae09bac})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="105"/>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="108"/>
|
||||
<source>Total energy produced</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: sunnyWebBox, EventType: totalEnergyProduced, ID: {0bb4e227-7e38-49ca-9b32-ce4621c9305b})
|
||||
----------
|
||||
The name of the StateType ({0bb4e227-7e38-49ca-9b32-ce4621c9305b}) of ThingClass sunnyWebBox</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="111"/>
|
||||
<source>Total energy produced changed</source>
|
||||
<extracomment>The name of the EventType ({0bb4e227-7e38-49ca-9b32-ce4621c9305b}) of ThingClass sunnyWebBox</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="102"/>
|
||||
<source>Sunny WebBox</source>
|
||||
<extracomment>The name of the ThingClass ({49304127-ce9b-45dd-8511-05030a4ac003})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/sma/plugininfo.h" line="114"/>
|
||||
<source>hardware address</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: sunnyWebBox, Type: thing, ID: {03f32361-4e13-4597-a346-af8d16a986b3})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
Loading…
x
Reference in New Issue
Block a user