Senec: Add senec P4 energy storage support

This commit is contained in:
Simon Stürz 2026-10-19 16:59:09 +02:00
parent 8f72d83369
commit c882572328
11 changed files with 941 additions and 121 deletions

View File

@ -678,6 +678,16 @@ Description: nymea integration plugin for HTTP commander
HTTP requests from and to nymea.
Package: nymea-plugin-senec
Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends},
Conflicts: nymea-plugins-translations (<< 1.0.1)
Description: nymea integration plugin for SENEC.home
This package contains the nymea integration plugin for the SENEC.home
energy storages.
Package: nymea-plugin-senic
Architecture: any
Depends: ${shlibs:Depends},

View File

@ -1,10 +1,20 @@
# SENEC.Home
Connects to SENEC.Home energy storages in the local network and integrates them into the system. Optionally the grid meter of the storage can be added.
Integrates SENEC.Home energy storages into the system.
Currently supported and tested models:
## Local network (SENEC.Home V2 / V3)
* SENEC.Home P4
The storage is discovered in the local network and polled directly. Optionally the grid meter of the storage can be added using the "Add meter" setting.
## SENEC.Connect (SENEC.Home 4, P4, E4)
V4 systems do not provide a local API and are integrated using the official read-only SENEC.Connect cloud API.
1. Sign in on https://developer.senec.com with your SENEC account.
2. Subscribe to the SENEC.Connect product (SENEC.Data 45000).
3. Copy the subscription key from your profile and enter it when adding the SENEC.Connect thing.
All systems registered to the account will appear automatically, each with a grid meter and a PV inverter. The data is updated once per minute due to the request limit of the API. The energy totals of the meter and the inverter are calculated from the power values.
## More

View File

@ -102,6 +102,49 @@ void IntegrationPluginSenec::discoverThings(ThingDiscoveryInfo *info)
}
}
void IntegrationPluginSenec::startPairing(ThingPairingInfo *info)
{
info->finish(Thing::ThingErrorNoError, QT_TR_NOOP("Please sign in on developer.senec.com with your SENEC account, subscribe to the SENEC.Connect product and enter the subscription key from your profile."));
}
void IntegrationPluginSenec::confirmPairing(ThingPairingInfo *info, const QString &username, const QString &secret)
{
Q_UNUSED(username)
QString subscriptionKey = secret.trimmed();
if (subscriptionKey.isEmpty()) {
info->finish(Thing::ThingErrorAuthenticationFailure, QT_TR_NOOP("Please enter a subscription key."));
return;
}
qCDebug(dcSenec()) << "Verifying SENEC.Connect subscription key" << subscriptionKey.left(4) + QString(subscriptionKey.length() - 4, '*');
SenecConnect *senecConnect = new SenecConnect(hardwareManager()->networkManager(), subscriptionKey, info);
QNetworkReply *reply = senecConnect->getDeviceData();
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
connect(reply, &QNetworkReply::finished, info, [this, reply, info, subscriptionKey] {
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (status == 401 || status == 403) {
qCWarning(dcSenec()) << "SENEC.Connect rejected the subscription key. Status:" << status;
info->finish(Thing::ThingErrorAuthenticationFailure, QT_TR_NOOP("The subscription key is not valid."));
return;
}
if (status != 200 || reply->error() != QNetworkReply::NoError) {
qCWarning(dcSenec()) << "SENEC.Connect request finished with error. Status:" << status << "Error:" << reply->errorString();
info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("Unable to connect to SENEC.Connect. Please try again later."));
return;
}
pluginStorage()->beginGroup(info->thingId().toString());
pluginStorage()->setValue("subscriptionKey", subscriptionKey);
pluginStorage()->endGroup();
info->finish(Thing::ThingErrorNoError);
});
}
void IntegrationPluginSenec::setupThing(ThingSetupInfo *info)
{
Thing *thing = info->thing();
@ -159,7 +202,7 @@ void IntegrationPluginSenec::setupThing(ThingSetupInfo *info)
thing->setStateValue(senecStorageLanChargingStateStateTypeId, "idle");
}
Thing *meter = meterThing(thing);
Thing *meter = childThing(thing, senecMeterThingClassId);
if (meter) {
meter->setStateValue(senecMeterCurrentPowerStateTypeId, storage->gridPower());
}
@ -170,13 +213,13 @@ void IntegrationPluginSenec::setupThing(ThingSetupInfo *info)
if (value.toBool()) {
// Check if we have to add the meter
if (!meterThing(thing)) {
if (!childThing(thing, senecMeterThingClassId)) {
qCDebug(dcSenec()) << "Add meter for" << thing->name();
emit autoThingsAppeared(ThingDescriptors() << ThingDescriptor(senecMeterThingClassId, "SENEC Meter", QString(), thing->id()));
}
} else {
// Check if we have to remove the meter
Thing *meter = meterThing(thing);
Thing *meter = childThing(thing, senecMeterThingClassId);
if (meter) {
qCDebug(dcSenec()) << "Remove meter thing for" << thing->name();
emit autoThingDisappeared(meter->id());
@ -187,10 +230,41 @@ void IntegrationPluginSenec::setupThing(ThingSetupInfo *info)
info->finish(Thing::ThingErrorNoError);
} else if (thing->thingClassId() == senecConnectThingClassId) {
pluginStorage()->beginGroup(thing->id().toString());
QString subscriptionKey = pluginStorage()->value("subscriptionKey").toString();
pluginStorage()->endGroup();
if (subscriptionKey.isEmpty()) {
info->finish(Thing::ThingErrorAuthenticationFailure, QT_TR_NOOP("The SENEC.Connect subscription key is missing. Please reconfigure the connection."));
return;
}
// Handle reconfigure
if (m_connects.contains(thing))
m_connects.take(thing)->deleteLater();
m_connects.insert(thing, new SenecConnect(hardwareManager()->networkManager(), subscriptionKey, this));
info->finish(Thing::ThingErrorNoError);
} else if (thing->thingClassId() == senecStorageCloudThingClassId) {
info->finish(Thing::ThingErrorNoError);
} else if (thing->thingClassId() == senecMeterThingClassId) {
Thing *parentThing = myThings().findById(thing->parentId());
if (parentThing) {
if (parentThing && parentThing->thingClassId() == senecStorageLanThingClassId) {
thing->setStateValue(senecMeterConnectedStateTypeId, parentThing->stateValue(senecStorageLanConnectedStateTypeId).toBool());
} else if (parentThing && parentThing->thingClassId() == senecStorageCloudThingClassId) {
thing->setStateValue(senecMeterConnectedStateTypeId, parentThing->stateValue(senecStorageCloudConnectedStateTypeId).toBool());
}
info->finish(Thing::ThingErrorNoError);
} else if (thing->thingClassId() == senecInverterThingClassId) {
Thing *parentThing = myThings().findById(thing->parentId());
if (parentThing) {
thing->setStateValue(senecInverterConnectedStateTypeId, parentThing->stateValue(senecStorageCloudConnectedStateTypeId).toBool());
}
info->finish(Thing::ThingErrorNoError);
@ -201,14 +275,37 @@ void IntegrationPluginSenec::postSetupThing(Thing *thing)
{
if (thing->thingClassId() == senecStorageLanThingClassId) {
m_storages.value(thing)->initialize();
}
// Create the refresh timer if not already set up
if (!m_refreshTimer) {
qCDebug(dcSenec()) << "Starting refresh timer ...";
m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(5);
connect(m_refreshTimer, &PluginTimer::timeout, this, &IntegrationPluginSenec::refresh);
m_refreshTimer->start();
if (!m_refreshTimer) {
qCDebug(dcSenec()) << "Starting LAN refresh timer ...";
m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(5);
connect(m_refreshTimer, &PluginTimer::timeout, this, &IntegrationPluginSenec::refresh);
m_refreshTimer->start();
}
} else if (thing->thingClassId() == senecConnectThingClassId) {
refreshCloud(thing);
// SENEC.Connect allows 45000 requests per month, which is roughly one request per minute
if (!m_cloudRefreshTimer) {
qCDebug(dcSenec()) << "Starting SENEC.Connect refresh timer ...";
m_cloudRefreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(60);
connect(m_cloudRefreshTimer, &PluginTimer::timeout, this, &IntegrationPluginSenec::refreshClouds);
m_cloudRefreshTimer->start();
}
} else if (thing->thingClassId() == senecStorageCloudThingClassId) {
ThingDescriptors descriptors;
if (!childThing(thing, senecMeterThingClassId))
descriptors.append(ThingDescriptor(senecMeterThingClassId, "SENEC Meter", thing->name(), thing->id()));
if (!childThing(thing, senecInverterThingClassId))
descriptors.append(ThingDescriptor(senecInverterThingClassId, "SENEC PV inverter", thing->name(), thing->id()));
if (!descriptors.isEmpty()) {
qCDebug(dcSenec()) << "Adding" << descriptors.count() << "child things for" << thing->name();
emit autoThingsAppeared(descriptors);
}
}
}
@ -219,27 +316,44 @@ void IntegrationPluginSenec::thingRemoved(Thing *thing)
m_storages.take(thing)->deleteLater();
}
if (myThings().isEmpty()) {
qCDebug(dcSenec()) << "Stopping refresh timer";
if (thing->thingClassId() == senecConnectThingClassId) {
if (m_connects.contains(thing))
m_connects.take(thing)->deleteLater();
pluginStorage()->beginGroup(thing->id().toString());
pluginStorage()->remove("");
pluginStorage()->endGroup();
}
m_lastEnergyUpdates.remove(thing);
if (m_refreshTimer && m_storages.isEmpty()) {
qCDebug(dcSenec()) << "Stopping LAN refresh timer";
hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer);
m_refreshTimer = nullptr;
}
if (m_cloudRefreshTimer && m_connects.isEmpty()) {
qCDebug(dcSenec()) << "Stopping SENEC.Connect refresh timer";
hardwareManager()->pluginTimerManager()->unregisterTimer(m_cloudRefreshTimer);
m_cloudRefreshTimer = nullptr;
}
}
Thing *IntegrationPluginSenec::meterThing(Thing *storageThing) const
Thing *IntegrationPluginSenec::childThing(Thing *parentThing, const ThingClassId &thingClassId) const
{
Things meterThings = myThings().filterByThingClassId(senecMeterThingClassId).filterByParentId(storageThing->id());
if (meterThings.isEmpty())
Things childThings = myThings().filterByThingClassId(thingClassId).filterByParentId(parentThing->id());
if (childThings.isEmpty())
return nullptr;
return meterThings.first();
return childThings.first();
}
void IntegrationPluginSenec::setConnected(Thing *storageThing, bool connected)
{
storageThing->setStateValue(senecStorageLanConnectedStateTypeId, connected);
Thing *meter = meterThing(storageThing);
Thing *meter = childThing(storageThing, senecMeterThingClassId);
if (meter) {
meter->setStateValue(senecMeterConnectedStateTypeId, connected);
}
@ -257,3 +371,153 @@ void IntegrationPluginSenec::refresh()
}
}
}
void IntegrationPluginSenec::refreshClouds()
{
foreach (Thing *connectThing, myThings().filterByThingClassId(senecConnectThingClassId)) {
refreshCloud(connectThing);
}
}
void IntegrationPluginSenec::refreshCloud(Thing *connectThing)
{
SenecConnect *senecConnect = m_connects.value(connectThing);
if (!senecConnect)
return;
QNetworkReply *reply = senecConnect->getDeviceData();
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
connect(reply, &QNetworkReply::finished, connectThing, [this, reply, connectThing] {
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (status == 401 || status == 403) {
qCWarning(dcSenec()) << "SENEC.Connect request has been rejected. The subscription key seems to be invalid. Status:" << status;
connectThing->setStateValue(senecConnectLoggedInStateTypeId, false);
setCloudConnected(connectThing, false);
return;
}
if (status != 200 || reply->error() != QNetworkReply::NoError) {
qCWarning(dcSenec()) << "SENEC.Connect request finished with error. Status:" << status << "Error:" << reply->errorString();
setCloudConnected(connectThing, false);
return;
}
QByteArray responseData = reply->readAll();
qCDebug(dcSenec()) << "SENEC.Connect request finished successfully" << qUtf8Printable(responseData);
bool ok = false;
QList<SenecConnect::SystemData> systems = SenecConnect::parseDeviceData(responseData, &ok);
if (!ok) {
qCWarning(dcSenec()) << "SENEC.Connect request finished successfully, but the response contains invalid data:" << responseData;
setCloudConnected(connectThing, false);
return;
}
connectThing->setStateValue(senecConnectLoggedInStateTypeId, true);
connectThing->setStateValue(senecConnectConnectedStateTypeId, true);
processCloudData(connectThing, systems);
});
}
void IntegrationPluginSenec::processCloudData(Thing *connectThing, const QList<SenecConnect::SystemData> &systems)
{
ThingDescriptors descriptors;
Things storageThings = myThings().filterByThingClassId(senecStorageCloudThingClassId).filterByParentId(connectThing->id());
foreach (const SenecConnect::SystemData &system, systems) {
Things existingThings = storageThings.filterByParam(senecStorageCloudThingSystemIdParamTypeId, system.systemId);
if (existingThings.isEmpty()) {
qCDebug(dcSenec()) << "Creating new storage for" << system.systemId << system.model;
ThingDescriptor descriptor(senecStorageCloudThingClassId, system.model.isEmpty() ? "SENEC.Home storage" : system.model, system.systemId, connectThing->id());
descriptor.setParams(ParamList() << Param(senecStorageCloudThingSystemIdParamTypeId, system.systemId)
<< Param(senecStorageCloudThingSerialNumberParamTypeId, system.serialNumber));
descriptors.append(descriptor);
continue;
}
Thing *storageThing = existingThings.first();
Thing *meter = childThing(storageThing, senecMeterThingClassId);
Thing *inverter = childThing(storageThing, senecInverterThingClassId);
storageThing->setStateValue(senecStorageCloudConnectedStateTypeId, system.active);
if (meter)
meter->setStateValue(senecMeterConnectedStateTypeId, system.active);
if (inverter)
inverter->setStateValue(senecInverterConnectedStateTypeId, system.active);
if (!system.active) {
qCDebug(dcSenec()) << "System" << system.systemId << "does not provide live data. Marking as disconnected.";
continue;
}
int batteryLevel = qRound(system.batteryLevel);
storageThing->setStateValue(senecStorageCloudCapacityStateTypeId, system.capacity);
storageThing->setStateValue(senecStorageCloudBatteryLevelStateTypeId, batteryLevel);
storageThing->setStateValue(senecStorageCloudBatteryCriticalStateTypeId, batteryLevel < 10);
storageThing->setStateValue(senecStorageCloudCurrentPowerStateTypeId, system.batteryPower);
if (system.batteryPower > 0) {
storageThing->setStateValue(senecStorageCloudChargingStateStateTypeId, "charging");
} else if (system.batteryPower < 0) {
storageThing->setStateValue(senecStorageCloudChargingStateStateTypeId, "discharging");
} else {
storageThing->setStateValue(senecStorageCloudChargingStateStateTypeId, "idle");
}
if (meter) {
updateEnergy(meter, system.gridPower, senecMeterTotalEnergyConsumedStateTypeId, senecMeterTotalEnergyProducedStateTypeId);
meter->setStateValue(senecMeterCurrentPowerStateTypeId, system.gridPower);
}
if (inverter) {
updateEnergy(inverter, -system.production, StateTypeId(), senecInverterTotalEnergyProducedStateTypeId);
inverter->setStateValue(senecInverterCurrentPowerStateTypeId, -system.production);
}
}
if (!descriptors.isEmpty()) {
qCDebug(dcSenec()) << "Adding" << descriptors.count() << "new SENEC.Home" << (descriptors.count() > 1 ? "storages" : "storage");
emit autoThingsAppeared(descriptors);
}
}
void IntegrationPluginSenec::setCloudConnected(Thing *connectThing, bool connected)
{
connectThing->setStateValue(senecConnectConnectedStateTypeId, connected);
foreach (Thing *storageThing, myThings().filterByThingClassId(senecStorageCloudThingClassId).filterByParentId(connectThing->id())) {
storageThing->setStateValue(senecStorageCloudConnectedStateTypeId, connected);
Thing *meter = childThing(storageThing, senecMeterThingClassId);
if (meter)
meter->setStateValue(senecMeterConnectedStateTypeId, connected);
Thing *inverter = childThing(storageThing, senecInverterThingClassId);
if (inverter)
inverter->setStateValue(senecInverterConnectedStateTypeId, connected);
}
}
void IntegrationPluginSenec::updateEnergy(Thing *thing, double currentPower, const StateTypeId &consumedStateTypeId, const StateTypeId &producedStateTypeId)
{
// The cloud API only provides power values, so the energy totals are integrated between two samples
QDateTime now = QDateTime::currentDateTimeUtc();
QDateTime lastUpdate = m_lastEnergyUpdates.value(thing);
m_lastEnergyUpdates.insert(thing, now);
// Skip the first sample and gaps (restart, connection loss) instead of extrapolating
if (!lastUpdate.isValid() || lastUpdate.secsTo(now) > 300)
return;
// Trapezoidal integration using the previous power value still stored in the state
double hoursPassed = lastUpdate.msecsTo(now) / 1000.0 / 3600.0;
double averagePower = (thing->stateValue("currentPower").toDouble() + currentPower) / 2.0;
double energy = qAbs(averagePower) / 1000.0 * hoursPassed;
if (averagePower > 0 && !consumedStateTypeId.isNull()) {
thing->setStateValue(consumedStateTypeId, thing->stateValue(consumedStateTypeId).toDouble() + energy);
} else if (averagePower < 0 && !producedStateTypeId.isNull()) {
thing->setStateValue(producedStateTypeId, thing->stateValue(producedStateTypeId).toDouble() + energy);
}
}

View File

@ -39,8 +39,11 @@
#include "extern-plugininfo.h"
#include "senecconnect.h"
#include "senecstoragelan.h"
#include <QDateTime>
class IntegrationPluginSenec : public IntegrationPlugin
{
Q_OBJECT
@ -54,21 +57,33 @@ public:
void discoverThings(ThingDiscoveryInfo *info) override;
void startPairing(ThingPairingInfo *info) override;
void confirmPairing(ThingPairingInfo *info, const QString &username, const QString &secret) override;
void setupThing(ThingSetupInfo *info) override;
void postSetupThing(Thing *thing) override;
void thingRemoved(Thing *thing) override;
private:
PluginTimer *m_refreshTimer = nullptr;
PluginTimer *m_cloudRefreshTimer = nullptr;
QHash<Thing *, NetworkDeviceMonitor *> m_monitors;
QHash<Thing *, SenecStorageLan *> m_storages;
QHash<Thing *, SenecConnect *> m_connects;
QHash<Thing *, QDateTime> m_lastEnergyUpdates;
Thing *meterThing(Thing *storageThing) const;
Thing *childThing(Thing *parentThing, const ThingClassId &thingClassId) const;
void setConnected(Thing *storageThing, bool connected);
void refreshCloud(Thing *connectThing);
void processCloudData(Thing *connectThing, const QList<SenecConnect::SystemData> &systems);
void setCloudConnected(Thing *connectThing, bool connected);
void updateEnergy(Thing *thing, double currentPower, const StateTypeId &consumedStateTypeId, const StateTypeId &producedStateTypeId);
private slots:
void refresh();
void refreshClouds();
};

View File

@ -8,6 +8,32 @@
"name": "senec",
"id": "1be922b9-4439-42cf-9caa-67f2ac7cc425",
"thingClasses": [
{
"id": "d064f111-1332-4096-b5de-529d44f72963",
"name": "senecConnect",
"displayName": "SENEC.Connect",
"interfaces": ["account"],
"createMethods": ["User"],
"setupMethod": "EnterPin",
"providedInterfaces": ["energystorage", "energymeter", "solarinverter"],
"stateTypes": [
{
"id": "ed8ef7d7-bf20-4780-870d-cf7171440952",
"name": "connected",
"displayName": "Connected",
"type": "bool",
"defaultValue": false,
"cached": false
},
{
"id": "73c4da2a-2167-4b68-8fbf-d03f5b7920a5",
"name": "loggedIn",
"displayName": "Logged in",
"type": "bool",
"defaultValue": false
}
]
},
{
"id": "345df3b1-d411-4db5-bbb2-3b14eb86c1ba",
"name": "senecStorageLan",
@ -103,6 +129,83 @@
}
]
},
{
"id": "8de0eeca-a698-4aee-bc67-a586c8f10652",
"name": "senecStorageCloud",
"displayName": "SENEC.Home storage (SENEC.Connect)",
"interfaces": ["energystorage", "connectable"],
"createMethods": ["Auto"],
"paramTypes": [
{
"id": "9172116e-e513-429b-b9a0-c73d7587bfa8",
"name": "systemId",
"displayName": "System ID",
"type": "QString",
"readOnly": true,
"defaultValue": ""
},
{
"id": "5d1d61dd-a419-4ba5-992a-91e9a3f34d31",
"name": "serialNumber",
"displayName": "Serial number",
"type": "QString",
"readOnly": true,
"defaultValue": ""
}
],
"stateTypes": [
{
"id": "cd7d8a3c-44b4-4517-8aa0-25288d03f19a",
"name": "connected",
"displayName": "Connected",
"type": "bool",
"defaultValue": false,
"cached": false
},
{
"id": "eccdfa19-b033-445c-b196-ab41bb2e449f",
"name": "currentPower",
"displayName": "Current power",
"type": "double",
"unit": "Watt",
"defaultValue": 0.00,
"cached": true
},
{
"id": "500b0df2-61d0-4895-91c7-c8f2616dd93d",
"name": "batteryLevel",
"displayName": "Battery level",
"type": "int",
"unit": "Percentage",
"minValue": 0,
"maxValue": 100,
"defaultValue": 0
},
{
"id": "8805be49-b88b-48b6-a0e3-7b6b251d3299",
"name": "batteryCritical",
"displayName": "Battery critical",
"type": "bool",
"defaultValue": false
},
{
"id": "8db60ec4-06cd-4fc3-a66e-ced915bf5c11",
"name": "chargingState",
"displayName": "Charging state",
"type": "QString",
"possibleValues": ["idle", "charging", "discharging"],
"defaultValue": "idle"
},
{
"id": "f282b051-a68c-4739-88c7-e5819d8424f9",
"name": "capacity",
"displayName": "Capacity",
"type": "double",
"unit": "KiloWattHour",
"defaultValue": 0
}
]
},
{
"name": "senecMeter",
"displayName": "SENEC Meter",
@ -225,6 +328,40 @@
"cached": false
}
]
},
{
"id": "12a613fb-f33c-48b1-a9a4-caaee1041d25",
"name": "senecInverter",
"displayName": "SENEC PV inverter",
"interfaces": ["solarinverter", "connectable"],
"createMethods": ["Auto"],
"stateTypes": [
{
"id": "67c15e22-2503-41e3-8318-2ccb973760c4",
"name": "connected",
"displayName": "Connected",
"type": "bool",
"defaultValue": false,
"cached": false
},
{
"id": "11e72bac-a531-4622-bbd0-da5b638e3257",
"name": "currentPower",
"displayName": "Current power",
"type": "double",
"unit": "Watt",
"defaultValue": 0,
"cached": false
},
{
"id": "e5a22d6c-573a-46df-ba92-3d33bd0ad754",
"name": "totalEnergyProduced",
"displayName": "Total energy produced",
"type": "double",
"unit": "KiloWattHour",
"defaultValue": 0
}
]
}
]
}

View File

@ -1,11 +1,12 @@
{
"title": "SENEC",
"tagline": "Integrate SENEC.Home energy storages from the local network.",
"tagline": "Integrate SENEC.Home energy storages from the local network or via SENEC.Connect.",
"icon": "senec.svg",
"stability": "community",
"offline": true,
"offline": false,
"technologies": [
"network"
"network",
"cloud"
],
"categories": [
"energy"

View File

@ -4,11 +4,13 @@ QT+= network
SOURCES += \
integrationpluginsenec.cpp \
senecconnect.cpp \
senecdiscovery.cpp \
senecstoragelan.cpp
HEADERS += \
integrationpluginsenec.h \
senecconnect.h \
senecdiscovery.h \
senecstoragelan.h

104
senec/senecconnect.cpp Normal file
View File

@ -0,0 +1,104 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2025, 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 "senecconnect.h"
#include "extern-plugininfo.h"
#include <QUrlQuery>
#include <QJsonDocument>
#include <QJsonParseError>
SenecConnect::SenecConnect(NetworkAccessManager *networkManager, const QString &subscriptionKey, QObject *parent)
: QObject{parent},
m_networkManager{networkManager},
m_subscriptionKey{subscriptionKey}
{
}
QUrl SenecConnect::deviceDataUrl()
{
QUrl url("https://apim-eds-gwc-prod.azure-api.net/senec-connect/v1/systems/device-data/general");
QUrlQuery query;
query.addQueryItem("include", "battery,meter,bessNameplate");
url.setQuery(query);
return url;
}
QList<SenecConnect::SystemData> SenecConnect::parseDeviceData(const QByteArray &data, bool *ok)
{
QList<SystemData> systems;
QJsonParseError jsonError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
if (jsonError.error != QJsonParseError::NoError || !jsonDoc.isArray()) {
if (ok)
*ok = false;
return systems;
}
foreach (const QVariant &systemVariant, jsonDoc.toVariant().toList()) {
QVariantMap systemMap = systemVariant.toMap();
QVariantMap batteryMap = systemMap.value("battery").toMap();
QVariantMap meterMap = systemMap.value("meter").toMap();
QVariantMap nameplateMap = systemMap.value("bessNameplate").toMap();
SystemData system;
system.systemId = nameplateMap.value("system_id").toString();
if (system.systemId.isEmpty())
continue;
system.serialNumber = nameplateMap.value("serial_number").toString();
system.model = nameplateMap.value("model").toString();
system.capacity = nameplateMap.value("design_capacity").toFloat() / 1000.0;
system.batteryPower = batteryMap.value("power").toFloat();
system.batteryLevel = batteryMap.value("state_of_charge").toFloat();
system.gridPower = meterMap.value("grid_power").toFloat();
system.production = meterMap.value("production").toFloat();
// Stale systems are still listed, but without live battery measurements
system.active = batteryMap.contains("voltage") || batteryMap.contains("current");
systems.append(system);
}
if (ok)
*ok = true;
return systems;
}
QNetworkReply *SenecConnect::getDeviceData()
{
QNetworkRequest request(deviceDataUrl());
request.setRawHeader("Ocp-Apim-Subscription-Key", m_subscriptionKey.toUtf8());
request.setRawHeader("Accept", "application/json");
qCDebug(dcSenec()) << "Get" << request.url().toString();
return m_networkManager->get(request);
}

71
senec/senecconnect.h Normal file
View File

@ -0,0 +1,71 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2025, 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 SENECCONNECT_H
#define SENECCONNECT_H
#include <QUrl>
#include <QObject>
#include <QNetworkReply>
#include <network/networkaccessmanager.h>
// Official read-only SENEC cloud API (V4 systems only): https://developer.senec.com
class SenecConnect : public QObject
{
Q_OBJECT
public:
struct SystemData {
QString systemId;
QString serialNumber;
QString model;
float capacity = 0; // kWh
float batteryPower = 0; // W, positive charging
float batteryLevel = 0; // %
float gridPower = 0; // W, positive import
float production = 0; // W
bool active = false;
};
explicit SenecConnect(NetworkAccessManager *networkManager, const QString &subscriptionKey, QObject *parent = nullptr);
static QUrl deviceDataUrl();
static QList<SystemData> parseDeviceData(const QByteArray &data, bool *ok = nullptr);
QNetworkReply *getDeviceData();
private:
NetworkAccessManager *m_networkManager = nullptr;
QString m_subscriptionKey;
};
#endif // SENECCONNECT_H

View File

@ -8,153 +8,247 @@
<source>Unable to discover devices in your network.</source>
<translation>Geräte im Netzwerk können nicht gesucht werden.</translation>
</message>
<message>
<location filename="../integrationpluginsenec.cpp" line="107"/>
<source>Please sign in on developer.senec.com with your SENEC account, subscribe to the SENEC.Connect product and enter the subscription key from your profile.</source>
<translation>Bitte melden Sie sich auf developer.senec.com mit Ihrem SENEC-Konto an, abonnieren Sie das Produkt SENEC.Connect und geben Sie den Abonnementschlüssel aus Ihrem Profil ein.</translation>
</message>
<message>
<location filename="../integrationpluginsenec.cpp" line="116"/>
<source>Please enter a subscription key.</source>
<translation>Bitte geben Sie einen Abonnementschlüssel ein.</translation>
</message>
<message>
<location filename="../integrationpluginsenec.cpp" line="130"/>
<source>The subscription key is not valid.</source>
<translation>Der Abonnementschlüssel ist ungültig.</translation>
</message>
<message>
<location filename="../integrationpluginsenec.cpp" line="136"/>
<source>Unable to connect to SENEC.Connect. Please try again later.</source>
<translation>Verbindung zu SENEC.Connect nicht möglich. Bitte versuchen Sie es später erneut.</translation>
</message>
<message>
<location filename="../integrationpluginsenec.cpp" line="240"/>
<source>The SENEC.Connect subscription key is missing. Please reconfigure the connection.</source>
<translation>Der SENEC.Connect-Abonnementschlüssel fehlt. Bitte konfigurieren Sie die Verbindung neu.</translation>
</message>
</context>
<context>
<name>Senec</name>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="52"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="68"/>
<source>Add meter</source>
<extracomment>The name of the ParamType (ThingClass: senecStorageLan, Type: settings, ID: {239d388c-f4a2-4055-88c3-decc6dace2b8})</extracomment>
<translation>Zähler hinzufügen</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="55"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="71"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="74"/>
<source>Battery critical</source>
<extracomment>The name of the StateType ({a9aa13fb-3f51-40e3-9d29-ab882513a87a}) of ThingClass senecStorageLan</extracomment>
<extracomment>The name of the StateType ({8805be49-b88b-48b6-a0e3-7b6b251d3299}) of ThingClass senecStorageCloud
----------
The name of the StateType ({a9aa13fb-3f51-40e3-9d29-ab882513a87a}) of ThingClass senecStorageLan</extracomment>
<translation>Batterieladung kritisch</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="58"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="77"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="80"/>
<source>Battery level</source>
<extracomment>The name of the StateType ({66a3a7d2-1210-4891-a8f2-6fe4f9b8c6cc}) of ThingClass senecStorageLan</extracomment>
<extracomment>The name of the StateType ({500b0df2-61d0-4895-91c7-c8f2616dd93d}) of ThingClass senecStorageCloud
----------
The name of the StateType ({66a3a7d2-1210-4891-a8f2-6fe4f9b8c6cc}) of ThingClass senecStorageLan</extracomment>
<translation>Ladestand</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="61"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="83"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="86"/>
<source>Capacity</source>
<extracomment>The name of the StateType ({d927e6cf-29f0-412f-b74d-7d803fd3e191}) of ThingClass senecStorageLan</extracomment>
<extracomment>The name of the StateType ({f282b051-a68c-4739-88c7-e5819d8424f9}) of ThingClass senecStorageCloud
----------
The name of the StateType ({d927e6cf-29f0-412f-b74d-7d803fd3e191}) of ThingClass senecStorageLan</extracomment>
<translation>Kapazität</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="64"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="89"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="92"/>
<source>Charging state</source>
<extracomment>The name of the StateType ({339f602f-c9f1-446d-bc96-1c7f9a7db922}) of ThingClass senecStorageLan</extracomment>
<extracomment>The name of the StateType ({8db60ec4-06cd-4fc3-a66e-ced915bf5c11}) of ThingClass senecStorageCloud
----------
The name of the StateType ({339f602f-c9f1-446d-bc96-1c7f9a7db922}) of ThingClass senecStorageLan</extracomment>
<translation>Ladezustand</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="67"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="70"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="95"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="98"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="101"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="104"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="107"/>
<source>Connected</source>
<extracomment>The name of the StateType ({9aa4dbfb-255b-408b-b148-8fb145ba8c98}) of ThingClass senecMeter
<extracomment>The name of the StateType ({67c15e22-2503-41e3-8318-2ccb973760c4}) of ThingClass senecInverter
----------
The name of the StateType ({d3bdc64b-67fb-4d84-97ed-c5142e5db55d}) of ThingClass senecStorageLan</extracomment>
The name of the StateType ({9aa4dbfb-255b-408b-b148-8fb145ba8c98}) of ThingClass senecMeter
----------
The name of the StateType ({cd7d8a3c-44b4-4517-8aa0-25288d03f19a}) of ThingClass senecStorageCloud
----------
The name of the StateType ({d3bdc64b-67fb-4d84-97ed-c5142e5db55d}) of ThingClass senecStorageLan
----------
The name of the StateType ({ed8ef7d7-bf20-4780-870d-cf7171440952}) of ThingClass senecConnect</extracomment>
<translation>Verbunden</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="73"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="110"/>
<source>Current phase A</source>
<extracomment>The name of the StateType ({1923f7b0-5b54-46d8-a7e9-9364b7c9eeb8}) of ThingClass senecMeter</extracomment>
<translation>Strom Phase A</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="76"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="113"/>
<source>Current phase B</source>
<extracomment>The name of the StateType ({4908abf8-f655-4e14-a007-3eefeda7088e}) of ThingClass senecMeter</extracomment>
<translation>Strom Phase B</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="79"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="116"/>
<source>Current phase C</source>
<extracomment>The name of the StateType ({e8415152-0fac-4cd9-98ac-b0e7c006d637}) of ThingClass senecMeter</extracomment>
<translation>Strom Phase C</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="82"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="119"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="122"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="125"/>
<source>Current power</source>
<extracomment>The name of the StateType ({3b00470d-11bc-4352-a885-52ab9443cee5}) of ThingClass senecStorageLan</extracomment>
<extracomment>The name of the StateType ({11e72bac-a531-4622-bbd0-da5b638e3257}) of ThingClass senecInverter
----------
The name of the StateType ({eccdfa19-b033-445c-b196-ab41bb2e449f}) of ThingClass senecStorageCloud
----------
The name of the StateType ({3b00470d-11bc-4352-a885-52ab9443cee5}) of ThingClass senecStorageLan</extracomment>
<translation>Aktuelle Leistung</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="85"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="128"/>
<source>Current power phase A</source>
<extracomment>The name of the StateType ({385df15e-4f1d-4842-a10a-597d087bdac0}) of ThingClass senecMeter</extracomment>
<translation>Leistung Phase A</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="88"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="131"/>
<source>Current power phase B</source>
<extracomment>The name of the StateType ({3bab2b05-99d7-4b3a-b903-054d269a3527}) of ThingClass senecMeter</extracomment>
<translation>Leistung Phase B</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="91"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="134"/>
<source>Current power phase C</source>
<extracomment>The name of the StateType ({01a63c94-b635-4e98-8037-d5d69fe0dd7c}) of ThingClass senecMeter</extracomment>
<translation>Leistung Phase C</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="94"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="137"/>
<source>Current power usage</source>
<extracomment>The name of the StateType ({56e58d03-782d-40bb-8d32-fad396ffefdc}) of ThingClass senecMeter</extracomment>
<translation>Aktuelle Leistung</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="97"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="140"/>
<source>Energy consumed</source>
<extracomment>The name of the StateType ({21728bf0-a566-4eb0-a163-5f108f34bb9b}) of ThingClass senecMeter</extracomment>
<translation>Bezogene Energie</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="100"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="143"/>
<source>Energy returned</source>
<extracomment>The name of the StateType ({f9920cfa-26a0-4247-ad50-b4fca91596f0}) of ThingClass senecMeter</extracomment>
<translation>Eingespeiste Energie</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="103"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="146"/>
<source>Host address</source>
<extracomment>The name of the ParamType (ThingClass: senecStorageLan, Type: thing, ID: {a45cabe9-9f76-405e-b47c-0a3d00bdd44b})</extracomment>
<translation>IP-Adresse</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="106"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="149"/>
<source>Host name</source>
<extracomment>The name of the ParamType (ThingClass: senecStorageLan, Type: thing, ID: {51a1bbc0-28a5-43ac-9021-896acbf9413f})</extracomment>
<translation>Hostname</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="109"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="152"/>
<source>Logged in</source>
<extracomment>The name of the StateType ({73c4da2a-2167-4b68-8fbf-d03f5b7920a5}) of ThingClass senecConnect</extracomment>
<translation>Angemeldet</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="155"/>
<source>MAC address</source>
<extracomment>The name of the ParamType (ThingClass: senecStorageLan, Type: thing, ID: {0790e1b1-c8c9-488f-9cda-2a0bbf14b4af})</extracomment>
<translation>MAC-Adresse</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="118"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="164"/>
<source>SENEC Meter</source>
<extracomment>The name of the ThingClass ({303f454d-93b7-4f8f-b295-a4c22e09be6d})</extracomment>
<translation>SENEC Zähler</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="124"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="167"/>
<source>SENEC PV inverter</source>
<extracomment>The name of the ThingClass ({12a613fb-f33c-48b1-a9a4-caaee1041d25})</extracomment>
<translation>SENEC PV-Wechselrichter</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="170"/>
<source>SENEC.Connect</source>
<extracomment>The name of the ThingClass ({d064f111-1332-4096-b5de-529d44f72963})</extracomment>
<translation>SENEC.Connect</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="176"/>
<source>SENEC.Home storage (SENEC.Connect)</source>
<extracomment>The name of the ThingClass ({8de0eeca-a698-4aee-bc67-a586c8f10652})</extracomment>
<translation>SENEC.Home Speicher (SENEC.Connect)</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="179"/>
<source>Serial number</source>
<extracomment>The name of the ParamType (ThingClass: senecStorageCloud, Type: thing, ID: {5d1d61dd-a419-4ba5-992a-91e9a3f34d31})</extracomment>
<translation>Seriennummer</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="182"/>
<source>System ID</source>
<extracomment>The name of the ParamType (ThingClass: senecStorageCloud, Type: thing, ID: {9172116e-e513-429b-b9a0-c73d7587bfa8})</extracomment>
<translation>System-ID</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="185"/>
<source>Total energy produced</source>
<extracomment>The name of the StateType ({e5a22d6c-573a-46df-ba92-3d33bd0ad754}) of ThingClass senecInverter</extracomment>
<translation>Gesamte erzeugte Energie</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="188"/>
<source>Voltage phase A</source>
<extracomment>The name of the StateType ({db469573-bb11-48d2-84ba-2b8ff4b13413}) of ThingClass senecMeter</extracomment>
<translation>Spannung Phase A</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="127"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="191"/>
<source>Voltage phase B</source>
<extracomment>The name of the StateType ({176d5a01-220d-44da-b875-9a40aaa9c85a}) of ThingClass senecMeter</extracomment>
<translation>Spannung Phase B</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="130"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="194"/>
<source>Voltage phase C</source>
<extracomment>The name of the StateType ({e7ab02d3-016a-44ca-8da1-5d7ac9acbc6d}) of ThingClass senecMeter</extracomment>
<translation>Spannung Phase C</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="112"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="115"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="158"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="161"/>
<source>SENEC</source>
<extracomment>The name of the vendor ({1be922b9-4439-42cf-9caa-67f2ac7cc425})
----------
@ -162,27 +256,36 @@ The name of the plugin Senec ({3f055ea5-a883-445d-9556-675f5eda6c9a})</extracomm
<translation>SENEC</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="121"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="173"/>
<source>SENEC.Home storage</source>
<extracomment>The name of the ThingClass ({345df3b1-d411-4db5-bbb2-3b14eb86c1ba})</extracomment>
<translation>SENEC.Home Speicher</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="133"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="197"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="200"/>
<source>charging</source>
<extracomment>The name of a possible value of StateType {339f602f-c9f1-446d-bc96-1c7f9a7db922} of ThingClass senecStorageLan</extracomment>
<extracomment>The name of a possible value of StateType {8db60ec4-06cd-4fc3-a66e-ced915bf5c11} of ThingClass senecStorageCloud
----------
The name of a possible value of StateType {339f602f-c9f1-446d-bc96-1c7f9a7db922} of ThingClass senecStorageLan</extracomment>
<translation>lade</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="136"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="203"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="206"/>
<source>discharging</source>
<extracomment>The name of a possible value of StateType {339f602f-c9f1-446d-bc96-1c7f9a7db922} of ThingClass senecStorageLan</extracomment>
<extracomment>The name of a possible value of StateType {8db60ec4-06cd-4fc3-a66e-ced915bf5c11} of ThingClass senecStorageCloud
----------
The name of a possible value of StateType {339f602f-c9f1-446d-bc96-1c7f9a7db922} of ThingClass senecStorageLan</extracomment>
<translation>entlade</translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="139"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="209"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="212"/>
<source>idle</source>
<extracomment>The name of a possible value of StateType {339f602f-c9f1-446d-bc96-1c7f9a7db922} of ThingClass senecStorageLan</extracomment>
<extracomment>The name of a possible value of StateType {8db60ec4-06cd-4fc3-a66e-ced915bf5c11} of ThingClass senecStorageCloud
----------
The name of a possible value of StateType {339f602f-c9f1-446d-bc96-1c7f9a7db922} of ThingClass senecStorageLan</extracomment>
<translation>leerlauf</translation>
</message>
</context>

View File

@ -8,153 +8,247 @@
<source>Unable to discover devices in your network.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../integrationpluginsenec.cpp" line="107"/>
<source>Please sign in on developer.senec.com with your SENEC account, subscribe to the SENEC.Connect product and enter the subscription key from your profile.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../integrationpluginsenec.cpp" line="116"/>
<source>Please enter a subscription key.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../integrationpluginsenec.cpp" line="130"/>
<source>The subscription key is not valid.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../integrationpluginsenec.cpp" line="136"/>
<source>Unable to connect to SENEC.Connect. Please try again later.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../integrationpluginsenec.cpp" line="240"/>
<source>The SENEC.Connect subscription key is missing. Please reconfigure the connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Senec</name>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="52"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="68"/>
<source>Add meter</source>
<extracomment>The name of the ParamType (ThingClass: senecStorageLan, Type: settings, ID: {239d388c-f4a2-4055-88c3-decc6dace2b8})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="55"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="71"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="74"/>
<source>Battery critical</source>
<extracomment>The name of the StateType ({a9aa13fb-3f51-40e3-9d29-ab882513a87a}) of ThingClass senecStorageLan</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="58"/>
<source>Battery level</source>
<extracomment>The name of the StateType ({66a3a7d2-1210-4891-a8f2-6fe4f9b8c6cc}) of ThingClass senecStorageLan</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="61"/>
<source>Capacity</source>
<extracomment>The name of the StateType ({d927e6cf-29f0-412f-b74d-7d803fd3e191}) of ThingClass senecStorageLan</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="64"/>
<source>Charging state</source>
<extracomment>The name of the StateType ({339f602f-c9f1-446d-bc96-1c7f9a7db922}) of ThingClass senecStorageLan</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="67"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="70"/>
<source>Connected</source>
<extracomment>The name of the StateType ({9aa4dbfb-255b-408b-b148-8fb145ba8c98}) of ThingClass senecMeter
<extracomment>The name of the StateType ({8805be49-b88b-48b6-a0e3-7b6b251d3299}) of ThingClass senecStorageCloud
----------
The name of the StateType ({d3bdc64b-67fb-4d84-97ed-c5142e5db55d}) of ThingClass senecStorageLan</extracomment>
The name of the StateType ({a9aa13fb-3f51-40e3-9d29-ab882513a87a}) of ThingClass senecStorageLan</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="73"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="77"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="80"/>
<source>Battery level</source>
<extracomment>The name of the StateType ({500b0df2-61d0-4895-91c7-c8f2616dd93d}) of ThingClass senecStorageCloud
----------
The name of the StateType ({66a3a7d2-1210-4891-a8f2-6fe4f9b8c6cc}) of ThingClass senecStorageLan</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="83"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="86"/>
<source>Capacity</source>
<extracomment>The name of the StateType ({f282b051-a68c-4739-88c7-e5819d8424f9}) of ThingClass senecStorageCloud
----------
The name of the StateType ({d927e6cf-29f0-412f-b74d-7d803fd3e191}) of ThingClass senecStorageLan</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="89"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="92"/>
<source>Charging state</source>
<extracomment>The name of the StateType ({8db60ec4-06cd-4fc3-a66e-ced915bf5c11}) of ThingClass senecStorageCloud
----------
The name of the StateType ({339f602f-c9f1-446d-bc96-1c7f9a7db922}) of ThingClass senecStorageLan</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="95"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="98"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="101"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="104"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="107"/>
<source>Connected</source>
<extracomment>The name of the StateType ({67c15e22-2503-41e3-8318-2ccb973760c4}) of ThingClass senecInverter
----------
The name of the StateType ({9aa4dbfb-255b-408b-b148-8fb145ba8c98}) of ThingClass senecMeter
----------
The name of the StateType ({cd7d8a3c-44b4-4517-8aa0-25288d03f19a}) of ThingClass senecStorageCloud
----------
The name of the StateType ({d3bdc64b-67fb-4d84-97ed-c5142e5db55d}) of ThingClass senecStorageLan
----------
The name of the StateType ({ed8ef7d7-bf20-4780-870d-cf7171440952}) of ThingClass senecConnect</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="110"/>
<source>Current phase A</source>
<extracomment>The name of the StateType ({1923f7b0-5b54-46d8-a7e9-9364b7c9eeb8}) of ThingClass senecMeter</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="76"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="113"/>
<source>Current phase B</source>
<extracomment>The name of the StateType ({4908abf8-f655-4e14-a007-3eefeda7088e}) of ThingClass senecMeter</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="79"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="116"/>
<source>Current phase C</source>
<extracomment>The name of the StateType ({e8415152-0fac-4cd9-98ac-b0e7c006d637}) of ThingClass senecMeter</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="82"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="119"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="122"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="125"/>
<source>Current power</source>
<extracomment>The name of the StateType ({3b00470d-11bc-4352-a885-52ab9443cee5}) of ThingClass senecStorageLan</extracomment>
<extracomment>The name of the StateType ({11e72bac-a531-4622-bbd0-da5b638e3257}) of ThingClass senecInverter
----------
The name of the StateType ({eccdfa19-b033-445c-b196-ab41bb2e449f}) of ThingClass senecStorageCloud
----------
The name of the StateType ({3b00470d-11bc-4352-a885-52ab9443cee5}) of ThingClass senecStorageLan</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="85"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="128"/>
<source>Current power phase A</source>
<extracomment>The name of the StateType ({385df15e-4f1d-4842-a10a-597d087bdac0}) of ThingClass senecMeter</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="88"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="131"/>
<source>Current power phase B</source>
<extracomment>The name of the StateType ({3bab2b05-99d7-4b3a-b903-054d269a3527}) of ThingClass senecMeter</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="91"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="134"/>
<source>Current power phase C</source>
<extracomment>The name of the StateType ({01a63c94-b635-4e98-8037-d5d69fe0dd7c}) of ThingClass senecMeter</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="94"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="137"/>
<source>Current power usage</source>
<extracomment>The name of the StateType ({56e58d03-782d-40bb-8d32-fad396ffefdc}) of ThingClass senecMeter</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="97"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="140"/>
<source>Energy consumed</source>
<extracomment>The name of the StateType ({21728bf0-a566-4eb0-a163-5f108f34bb9b}) of ThingClass senecMeter</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="100"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="143"/>
<source>Energy returned</source>
<extracomment>The name of the StateType ({f9920cfa-26a0-4247-ad50-b4fca91596f0}) of ThingClass senecMeter</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="103"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="146"/>
<source>Host address</source>
<extracomment>The name of the ParamType (ThingClass: senecStorageLan, Type: thing, ID: {a45cabe9-9f76-405e-b47c-0a3d00bdd44b})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="106"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="149"/>
<source>Host name</source>
<extracomment>The name of the ParamType (ThingClass: senecStorageLan, Type: thing, ID: {51a1bbc0-28a5-43ac-9021-896acbf9413f})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="109"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="152"/>
<source>Logged in</source>
<extracomment>The name of the StateType ({73c4da2a-2167-4b68-8fbf-d03f5b7920a5}) of ThingClass senecConnect</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="155"/>
<source>MAC address</source>
<extracomment>The name of the ParamType (ThingClass: senecStorageLan, Type: thing, ID: {0790e1b1-c8c9-488f-9cda-2a0bbf14b4af})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="118"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="164"/>
<source>SENEC Meter</source>
<extracomment>The name of the ThingClass ({303f454d-93b7-4f8f-b295-a4c22e09be6d})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="124"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="167"/>
<source>SENEC PV inverter</source>
<extracomment>The name of the ThingClass ({12a613fb-f33c-48b1-a9a4-caaee1041d25})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="170"/>
<source>SENEC.Connect</source>
<extracomment>The name of the ThingClass ({d064f111-1332-4096-b5de-529d44f72963})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="176"/>
<source>SENEC.Home storage (SENEC.Connect)</source>
<extracomment>The name of the ThingClass ({8de0eeca-a698-4aee-bc67-a586c8f10652})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="179"/>
<source>Serial number</source>
<extracomment>The name of the ParamType (ThingClass: senecStorageCloud, Type: thing, ID: {5d1d61dd-a419-4ba5-992a-91e9a3f34d31})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="182"/>
<source>System ID</source>
<extracomment>The name of the ParamType (ThingClass: senecStorageCloud, Type: thing, ID: {9172116e-e513-429b-b9a0-c73d7587bfa8})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="185"/>
<source>Total energy produced</source>
<extracomment>The name of the StateType ({e5a22d6c-573a-46df-ba92-3d33bd0ad754}) of ThingClass senecInverter</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="188"/>
<source>Voltage phase A</source>
<extracomment>The name of the StateType ({db469573-bb11-48d2-84ba-2b8ff4b13413}) of ThingClass senecMeter</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="127"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="191"/>
<source>Voltage phase B</source>
<extracomment>The name of the StateType ({176d5a01-220d-44da-b875-9a40aaa9c85a}) of ThingClass senecMeter</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="130"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="194"/>
<source>Voltage phase C</source>
<extracomment>The name of the StateType ({e7ab02d3-016a-44ca-8da1-5d7ac9acbc6d}) of ThingClass senecMeter</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="112"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="115"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="158"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="161"/>
<source>SENEC</source>
<extracomment>The name of the vendor ({1be922b9-4439-42cf-9caa-67f2ac7cc425})
----------
@ -162,27 +256,36 @@ The name of the plugin Senec ({3f055ea5-a883-445d-9556-675f5eda6c9a})</extracomm
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="121"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="173"/>
<source>SENEC.Home storage</source>
<extracomment>The name of the ThingClass ({345df3b1-d411-4db5-bbb2-3b14eb86c1ba})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="133"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="197"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="200"/>
<source>charging</source>
<extracomment>The name of a possible value of StateType {339f602f-c9f1-446d-bc96-1c7f9a7db922} of ThingClass senecStorageLan</extracomment>
<extracomment>The name of a possible value of StateType {8db60ec4-06cd-4fc3-a66e-ced915bf5c11} of ThingClass senecStorageCloud
----------
The name of a possible value of StateType {339f602f-c9f1-446d-bc96-1c7f9a7db922} of ThingClass senecStorageLan</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="136"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="203"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="206"/>
<source>discharging</source>
<extracomment>The name of a possible value of StateType {339f602f-c9f1-446d-bc96-1c7f9a7db922} of ThingClass senecStorageLan</extracomment>
<extracomment>The name of a possible value of StateType {8db60ec4-06cd-4fc3-a66e-ced915bf5c11} of ThingClass senecStorageCloud
----------
The name of a possible value of StateType {339f602f-c9f1-446d-bc96-1c7f9a7db922} of ThingClass senecStorageLan</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="139"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="209"/>
<location filename="../../build/Desktop_Qt_6_11_1_Debug/senec/plugininfo.h" line="212"/>
<source>idle</source>
<extracomment>The name of a possible value of StateType {339f602f-c9f1-446d-bc96-1c7f9a7db922} of ThingClass senecStorageLan</extracomment>
<extracomment>The name of a possible value of StateType {8db60ec4-06cd-4fc3-a66e-ced915bf5c11} of ThingClass senecStorageCloud
----------
The name of a possible value of StateType {339f602f-c9f1-446d-bc96-1c7f9a7db922} of ThingClass senecStorageLan</extracomment>
<translation type="unfinished"></translation>
</message>
</context>