Add update logic and basic lan storage mechanism
parent
37d9e1ae04
commit
9691f8c6c9
|
|
@ -29,22 +29,29 @@
|
|||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "integrationpluginsenec.h"
|
||||
#include "senecdiscovery.h"
|
||||
#include "plugininfo.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonParseError>
|
||||
|
||||
#include <network/networkdevicediscovery.h>
|
||||
|
||||
IntegrationPluginSenec::IntegrationPluginSenec()
|
||||
{
|
||||
// Testing the convert methods
|
||||
|
||||
// QString rawValue = "fl_42A2E5E4"; // 81.449
|
||||
// float value = SenecStorageLan::parseFloat(rawValue);
|
||||
// qCWarning(dcSenec()) << rawValue << value;
|
||||
|
||||
// QString rawValue = "st_foobar";
|
||||
// QString rawValue = "st_foobar"; // foobar
|
||||
// QString value = SenecStorageLan::parseString(rawValue);
|
||||
// qCWarning(dcSenec()) << rawValue << value;
|
||||
|
||||
// QString rawValue = "u8_64"; // 100
|
||||
// quint8 value = SenecStorageLan::parseUInt8(rawValue);
|
||||
// qCWarning(dcSenec()) << rawValue << value;
|
||||
}
|
||||
|
||||
IntegrationPluginSenec::~IntegrationPluginSenec()
|
||||
|
|
@ -54,7 +61,7 @@ IntegrationPluginSenec::~IntegrationPluginSenec()
|
|||
|
||||
void IntegrationPluginSenec::discoverThings(ThingDiscoveryInfo *info)
|
||||
{
|
||||
if (info->thingClassId() == senecConnectionThingClassId) {
|
||||
if (info->thingClassId() == senecStorageLanThingClassId) {
|
||||
|
||||
if (!hardwareManager()->networkDeviceDiscovery()->available()) {
|
||||
qCWarning(dcSenec()) << "Failed to discover network devices. The network device discovery is not available.";
|
||||
|
|
@ -62,39 +69,39 @@ void IntegrationPluginSenec::discoverThings(ThingDiscoveryInfo *info)
|
|||
return;
|
||||
}
|
||||
|
||||
// qCInfo(dcESPSomfyRTS()) << "Starting network discovery...";
|
||||
// EspSomfyRtsDiscovery *discovery = new EspSomfyRtsDiscovery(hardwareManager()->networkManager(), hardwareManager()->networkDeviceDiscovery(), info);
|
||||
// connect(discovery, &EspSomfyRtsDiscovery::discoveryFinished, info, [=](){
|
||||
// ThingDescriptors descriptors;
|
||||
// qCInfo(dcESPSomfyRTS()) << "Discovery finished. Found" << discovery->results().count() << "devices";
|
||||
// foreach (const EspSomfyRtsDiscovery::Result &result, discovery->results()) {
|
||||
// qCInfo(dcESPSomfyRTS()) << "Discovered device on" << result.networkDeviceInfo;
|
||||
qCInfo(dcSenec()) << "Starting network discovery...";
|
||||
SenecDiscovery *discovery = new SenecDiscovery(hardwareManager()->networkManager(), hardwareManager()->networkDeviceDiscovery(), info);
|
||||
connect(discovery, &SenecDiscovery::discoveryFinished, info, [=](){
|
||||
ThingDescriptors descriptors;
|
||||
qCInfo(dcSenec()) << "Discovery finished. Found" << discovery->results().count() << "devices";
|
||||
foreach (const SenecDiscovery::Result &result, discovery->results()) {
|
||||
qCInfo(dcSenec()) << "Discovered device on" << result.networkDeviceInfo;
|
||||
|
||||
// QString title = "ESP Somfy RTS (" + result.name + ")";
|
||||
// QString description = result.networkDeviceInfo.address().toString();
|
||||
QString title = "SENEC connection (" + result.deviceId + ")";
|
||||
QString description = result.networkDeviceInfo.address().toString();
|
||||
|
||||
// ThingDescriptor descriptor(espSomfyRtsThingClassId, title, description);
|
||||
ThingDescriptor descriptor(senecStorageLanThingClassId, title, description);
|
||||
|
||||
// ParamList params;
|
||||
// params << Param(espSomfyRtsThingMacAddressParamTypeId, result.networkDeviceInfo.thingParamValueMacAddress());
|
||||
// params << Param(espSomfyRtsThingHostNameParamTypeId, result.networkDeviceInfo.thingParamValueHostName());
|
||||
// params << Param(espSomfyRtsThingAddressParamTypeId, result.networkDeviceInfo.thingParamValueAddress());
|
||||
// descriptor.setParams(params);
|
||||
ParamList params;
|
||||
params << Param(senecStorageLanThingMacAddressParamTypeId, result.networkDeviceInfo.thingParamValueMacAddress());
|
||||
params << Param(senecStorageLanThingHostNameParamTypeId, result.networkDeviceInfo.thingParamValueHostName());
|
||||
params << Param(senecStorageLanThingAddressParamTypeId, result.networkDeviceInfo.thingParamValueAddress());
|
||||
descriptor.setParams(params);
|
||||
|
||||
// // Check if we already have set up this device
|
||||
// Thing *existingThing = myThings().findByParams(params);
|
||||
// if (existingThing) {
|
||||
// qCDebug(dcESPSomfyRTS()) << "This thing already exists in the system:" << result.networkDeviceInfo;
|
||||
// descriptor.setThingId(existingThing->id());
|
||||
// }
|
||||
// Check if we already have set up this device
|
||||
Thing *existingThing = myThings().findByParams(params);
|
||||
if (existingThing) {
|
||||
qCDebug(dcSenec()) << "This thing already exists in the system:" << result.networkDeviceInfo;
|
||||
descriptor.setThingId(existingThing->id());
|
||||
}
|
||||
|
||||
// info->addThingDescriptor(descriptor);
|
||||
// }
|
||||
info->addThingDescriptor(descriptor);
|
||||
}
|
||||
|
||||
// info->finish(Thing::ThingErrorNoError);
|
||||
// });
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
|
||||
// discovery->startDiscovery();
|
||||
discovery->startDiscovery();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -182,6 +189,85 @@ void IntegrationPluginSenec::setupThing(ThingSetupInfo *info)
|
|||
|
||||
thing->setStateValue(senecAccountUserDisplayNameStateTypeId, username);
|
||||
|
||||
} if (thing->thingClassId() == senecStorageLanThingClassId) {
|
||||
|
||||
// Handle reconfigure
|
||||
if (m_monitors.contains(thing)) {
|
||||
qCDebug(dcSenec()) << "Unregister existing monitor and recreate a new one...";
|
||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
||||
}
|
||||
|
||||
NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(thing);
|
||||
m_monitors.insert(thing, monitor);
|
||||
|
||||
SenecStorageLan *storage = new SenecStorageLan(hardwareManager()->networkManager(), this);
|
||||
m_storages.insert(thing, storage);
|
||||
|
||||
storage->setAddress(monitor->networkDeviceInfo().address());
|
||||
connect(monitor, &NetworkDeviceMonitor::reachableChanged, storage, [monitor, storage](bool reachable){
|
||||
if (reachable) {
|
||||
storage->setAddress(monitor->networkDeviceInfo().address());
|
||||
}
|
||||
});
|
||||
|
||||
connect(storage, &SenecStorageLan::availableChanged, thing, [thing](bool available){
|
||||
thing->setStateValue(senecStorageLanConnectedStateTypeId, available);
|
||||
|
||||
// TODO: Update also child things
|
||||
|
||||
});
|
||||
|
||||
connect(storage, &SenecStorageLan::updatedFinished, thing, [storage, thing, this](bool success){
|
||||
|
||||
thing->setStateValue(senecStorageLanConnectedStateTypeId, storage->available());
|
||||
|
||||
// TODO: Update also child things
|
||||
|
||||
if (!success)
|
||||
return;
|
||||
|
||||
thing->setStateValue(senecStorageLanCapacityStateTypeId, storage->capacity());
|
||||
thing->setStateValue(senecStorageLanBatteryLevelStateTypeId, storage->batteryLevel());
|
||||
thing->setStateValue(senecStorageLanBatteryCriticalStateTypeId, storage->batteryLevel() < 10.0);
|
||||
thing->setStateValue(senecStorageLanCurrentPowerStateTypeId, storage->batteryPower());
|
||||
|
||||
// Check if we have a meter
|
||||
Thing *meterThing = nullptr;
|
||||
Things meterThings = myThings().filterByThingClassId(senecMeterThingClassId).filterByParentId(thing->id());
|
||||
|
||||
if (!meterThings.isEmpty())
|
||||
meterThing = meterThings.first();
|
||||
|
||||
// If so, update
|
||||
if (meterThing) {
|
||||
meterThing->setStateValue(senecMeterCurrentPowerStateTypeId, storage->gridPower());
|
||||
meterThing->setStateValue(senecMeterConnectedStateTypeId, true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
connect(thing, &Thing::settingChanged, this, [this, thing](const ParamTypeId ¶mTypeId, const QVariant &value){
|
||||
if (paramTypeId == senecStorageLanSettingsAddMeterParamTypeId) {
|
||||
|
||||
if (value.toBool()) {
|
||||
// Check if we have to add the meter
|
||||
if (myThings().filterByThingClassId(senecMeterThingClassId).filterByParentId(thing->id()).isEmpty()) {
|
||||
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
|
||||
Things existingMeters = myThings().filterByThingClassId(senecMeterThingClassId).filterByParentId(thing->id());
|
||||
if (!existingMeters.isEmpty()) {
|
||||
qCDebug(dcSenec()) << "Remove meter thing for" << thing->name();
|
||||
emit autoThingDisappeared(existingMeters.takeFirst()->id());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
|
||||
} else if (thing->thingClassId() == senecStorageThingClassId) {
|
||||
|
||||
connect(thing, &Thing::settingChanged, this, [this, thing](const ParamTypeId ¶mTypeId, const QVariant &value){
|
||||
|
|
@ -325,6 +411,7 @@ void IntegrationPluginSenec::postSetupThing(Thing *thing)
|
|||
connect(m_refreshTimer, &PluginTimer::timeout, this, [this](){
|
||||
refresh();
|
||||
});
|
||||
|
||||
m_refreshTimer->start();
|
||||
}
|
||||
}
|
||||
|
|
@ -341,6 +428,11 @@ void IntegrationPluginSenec::thingRemoved(Thing *thing)
|
|||
pluginStorage()->endGroup();
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == senecStorageLanThingClassId) {
|
||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
||||
m_storages.take(thing)->deleteLater();
|
||||
}
|
||||
|
||||
if (myThings().isEmpty()) {
|
||||
qCDebug(dcSenec()) << "Stopping refresh timer";
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer);
|
||||
|
|
@ -361,6 +453,10 @@ void IntegrationPluginSenec::refresh(Thing *thing)
|
|||
refresh(storageThing);
|
||||
}
|
||||
|
||||
foreach (Thing *storageLanThing, myThings().filterByThingClassId(senecStorageLanThingClassId)) {
|
||||
m_storages.value(storageLanThing)->update();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,10 @@ public:
|
|||
|
||||
private:
|
||||
PluginTimer *m_refreshTimer = nullptr;
|
||||
|
||||
QHash<Thing *, SenecAccount *> m_accounts;
|
||||
QHash<Thing *, NetworkDeviceMonitor *> m_monitors;
|
||||
QHash<Thing *, SenecStorageLan *> m_storages;
|
||||
|
||||
private slots:
|
||||
void refresh(Thing *thing = nullptr);
|
||||
|
|
|
|||
|
|
@ -41,12 +41,20 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"id": "ef9e9a4c-2f66-4194-adcc-23f401572399",
|
||||
"name": "senecConnection",
|
||||
"displayName": "SENEC Connection",
|
||||
"interfaces": ["gateway", "networkdevice"],
|
||||
"id": "345df3b1-d411-4db5-bbb2-3b14eb86c1ba",
|
||||
"name": "senecStorageLan",
|
||||
"displayName": "SENEC.Home storage",
|
||||
"interfaces": ["energystorage", "networkdevice"],
|
||||
"createMethods": ["Discovery", "User"],
|
||||
"providedInterfaces": ["energystorage"],
|
||||
"settingsTypes": [
|
||||
{
|
||||
"id": "239d388c-f4a2-4055-88c3-decc6dace2b8",
|
||||
"name": "addMeter",
|
||||
"displayName": "Add meter",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
}
|
||||
],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "a45cabe9-9f76-405e-b47c-0a3d00bdd44b",
|
||||
|
|
@ -76,11 +84,54 @@
|
|||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "a95292ad-08c0-405c-85f4-b47978584604",
|
||||
"id": "d3bdc64b-67fb-4d84-97ed-c5142e5db55d",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "3b00470d-11bc-4352-a885-52ab9443cee5",
|
||||
"name": "currentPower",
|
||||
"displayName": "Current power",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0.00,
|
||||
"cached": true
|
||||
},
|
||||
{
|
||||
"id": "66a3a7d2-1210-4891-a8f2-6fe4f9b8c6cc",
|
||||
"name": "batteryLevel",
|
||||
"displayName": "Battery level",
|
||||
"type": "int",
|
||||
"unit": "Percentage",
|
||||
"minValue": 0,
|
||||
"maxValue": 100,
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "a9aa13fb-3f51-40e3-9d29-ab882513a87a",
|
||||
"name": "batteryCritical",
|
||||
"displayName": "Battery critical",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "339f602f-c9f1-446d-bc96-1c7f9a7db922",
|
||||
"name": "chargingState",
|
||||
"displayName": "Charging state",
|
||||
"type": "QString",
|
||||
"possibleValues": ["idle", "charging", "discharging"],
|
||||
"defaultValue": "idle"
|
||||
},
|
||||
{
|
||||
"id": "d927e6cf-29f0-412f-b74d-7d803fd3e191",
|
||||
"name": "capacity",
|
||||
"displayName": "Capacity",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ SenecDiscovery::SenecDiscovery(NetworkAccessManager *networkManager, NetworkDevi
|
|||
|
||||
void SenecDiscovery::startDiscovery()
|
||||
{
|
||||
qCDebug(dcSenec()) << "Discovery: Searching SENEC energy storages in the network...";
|
||||
qCInfo(dcSenec()) << "Discovery: Searching SENEC energy storages in the local network...";
|
||||
m_startDateTime = QDateTime::currentDateTime();
|
||||
|
||||
NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
|
||||
|
|
@ -72,6 +72,7 @@ void SenecDiscovery::checkNetworkDevice(const QHostAddress &address)
|
|||
|
||||
connect(storage, &SenecStorageLan::initializeFinished, this, [this, storage, address](bool success){
|
||||
if (!success) {
|
||||
qCDebug(dcSenec()) << "Discovery: Failed to initialize host" << address.toString() << "Continue ...";
|
||||
cleanupStorage(storage);
|
||||
return;
|
||||
}
|
||||
|
|
@ -81,10 +82,18 @@ void SenecDiscovery::checkNetworkDevice(const QHostAddress &address)
|
|||
result.deviceId = storage->deviceId();
|
||||
result.address = address;
|
||||
m_results.append(result);
|
||||
qCInfo(dcSenec()) << "Found SENEC storage on" << address.toString() << storage->deviceId();
|
||||
|
||||
qCInfo(dcSenec()) << "Discovery: Found SENEC storage on" << address.toString() << storage->deviceId();
|
||||
cleanupStorage(storage);
|
||||
});
|
||||
|
||||
storage->initialize();
|
||||
}
|
||||
|
||||
void SenecDiscovery::cleanupStorage(SenecStorageLan *storage)
|
||||
{
|
||||
m_storages.removeAll(storage);
|
||||
storage->deleteLater();
|
||||
}
|
||||
|
||||
void SenecDiscovery::finishDiscovery()
|
||||
|
|
@ -95,7 +104,7 @@ void SenecDiscovery::finishDiscovery()
|
|||
for (int i = 0; i < m_results.count(); i++)
|
||||
m_results[i].networkDeviceInfo = m_networkDeviceInfos.get(m_results.at(i).address);
|
||||
|
||||
qCDebug(dcSenec()) << "Discovery: Finished the discovery process. Found" << m_results.count()
|
||||
qCInfo(dcSenec()) << "Discovery: Finished the discovery process. Found" << m_results.count()
|
||||
<< "SENEC devices in" << QTime::fromMSecsSinceStartOfDay(durationMilliSeconds).toString("mm:ss.zzz");
|
||||
m_gracePeriodTimer.stop();
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,11 @@ QUrl SenecStorageLan::url() const
|
|||
return m_url;
|
||||
}
|
||||
|
||||
bool SenecStorageLan::available() const
|
||||
{
|
||||
return m_available;
|
||||
}
|
||||
|
||||
QString SenecStorageLan::deviceId() const
|
||||
{
|
||||
return m_deviceId;
|
||||
|
|
@ -86,6 +91,25 @@ float SenecStorageLan::maxDischargePower() const
|
|||
return m_maxDischargePower;
|
||||
}
|
||||
|
||||
float SenecStorageLan::batteryLevel() const
|
||||
{
|
||||
return m_batteryLevel;
|
||||
}
|
||||
|
||||
float SenecStorageLan::batteryPower() const
|
||||
{
|
||||
return m_batteryPower;
|
||||
}
|
||||
|
||||
float SenecStorageLan::gridPower() const
|
||||
{
|
||||
return m_gridPower;
|
||||
}
|
||||
|
||||
float SenecStorageLan::inverterPower() const
|
||||
{
|
||||
return m_inverterPower;
|
||||
}
|
||||
|
||||
float SenecStorageLan::parseFloat(const QString &value)
|
||||
{
|
||||
|
|
@ -109,6 +133,12 @@ QString SenecStorageLan::parseString(const QString &value)
|
|||
return value.right(value.length() - 3);
|
||||
}
|
||||
|
||||
// quint8 SenecStorageLan::parseUInt8(const QString &value)
|
||||
// {
|
||||
// Q_ASSERT_X(value.left(3) == "u8_", "SenecStorageLan", "The given value does not seem to be a uint8, it is not starting with u8_");
|
||||
|
||||
// }
|
||||
|
||||
|
||||
void SenecStorageLan::initialize()
|
||||
{
|
||||
|
|
@ -211,6 +241,70 @@ void SenecStorageLan::initialize()
|
|||
});
|
||||
}
|
||||
|
||||
void SenecStorageLan::update()
|
||||
{
|
||||
if (m_url.isValid()) {
|
||||
qCDebug(dcSenec()) << "Cannot update the storage. The request URL is not valid. Maybe the IP is not known yet or invalid.";
|
||||
emit updatedFinished(false);
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap request;
|
||||
|
||||
QVariantMap energyMap;
|
||||
energyMap.insert("GUI_BAT_DATA_POWER", QString());
|
||||
energyMap.insert("GUI_INVERTER_POWER", QString());
|
||||
energyMap.insert("GUI_BAT_DATA_FUEL_CHARGE", QString());
|
||||
energyMap.insert("GUI_HOUSE_POW", QString());
|
||||
energyMap.insert("GUI_GRID_POW", QString());
|
||||
|
||||
request.insert("ENERGY", energyMap);
|
||||
|
||||
QNetworkReply *reply = m_networkManager->post(QNetworkRequest(m_url), QJsonDocument::fromVariant(request).toJson());
|
||||
connect(reply, &QNetworkReply::sslErrors, this, &SenecStorageLan::ignoreSslErrors);
|
||||
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||
connect(reply, &QNetworkReply::finished, this, [this, reply] {
|
||||
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
// Check HTTP status code
|
||||
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcSenec()) << "Update request finished with error. Status:" << status << "Error:" << reply->errorString();
|
||||
setAvailable(false);
|
||||
emit updatedFinished(false);
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray responseData = reply->readAll();
|
||||
|
||||
QJsonParseError jsonError;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData, &jsonError);
|
||||
QVariantMap responseMap = jsonDoc.toVariant().toMap();
|
||||
if (jsonError.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcSenec()) << "Update request finished successfully, but the response contains invalid JSON object:" << responseData;
|
||||
setAvailable(false);
|
||||
emit updatedFinished(false);
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcSenec()) << "Update request finished successfully" << qUtf8Printable(jsonDoc.toJson());
|
||||
|
||||
QVariantMap energyResponseMap = responseMap.value("ENERGY").toMap();
|
||||
m_batteryPower = parseFloat(energyResponseMap.value("GUI_BAT_DATA_POWER").toString());
|
||||
m_batteryLevel = parseFloat(energyResponseMap.value("GUI_BAT_DATA_FUEL_CHARGE").toString());
|
||||
m_gridPower = parseFloat(energyResponseMap.value("GUI_GRID_POW").toString());
|
||||
m_inverterPower = parseFloat(energyResponseMap.value("GUI_INVERTER_POWER").toString());
|
||||
|
||||
setAvailable(true);
|
||||
|
||||
qCDebug(dcSenec()).nospace().noquote() << "Update values: Battery power: " << m_batteryPower
|
||||
<< "W, Battery level: " << m_batteryLevel
|
||||
<< "%, Grid power: " << m_gridPower
|
||||
<< "W, Inverter power: " << m_inverterPower << "W";
|
||||
|
||||
emit updatedFinished(true);
|
||||
});
|
||||
}
|
||||
|
||||
void SenecStorageLan::updateUrl()
|
||||
{
|
||||
QUrl url;
|
||||
|
|
|
|||
|
|
@ -37,10 +37,13 @@
|
|||
|
||||
#include <network/networkaccessmanager.h>
|
||||
|
||||
// https://blog.odenthal.cc/query-the-hidden-api-of-your-senec-photovoltaik-appliance/
|
||||
|
||||
class SenecStorageLan : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
explicit SenecStorageLan(NetworkAccessManager *networkManager, QObject *parent = nullptr);
|
||||
explicit SenecStorageLan(NetworkAccessManager *networkManager, const QHostAddress &address, QObject *parent = nullptr);
|
||||
|
||||
|
|
@ -51,22 +54,32 @@ public:
|
|||
|
||||
bool available() const;
|
||||
|
||||
// Init properties
|
||||
QString deviceId() const;
|
||||
float capacity() const;
|
||||
float maxChargePower() const;
|
||||
float maxDischargePower() const;
|
||||
|
||||
// Update properties
|
||||
float batteryLevel() const;
|
||||
float batteryPower() const;
|
||||
float gridPower() const;
|
||||
float inverterPower() const;
|
||||
|
||||
static float parseFloat(const QString &value);
|
||||
static QString parseString(const QString &value);
|
||||
|
||||
static float parseFloat(const QString &value); // fl_
|
||||
static QString parseString(const QString &value); // st_
|
||||
//static quint8 parseUInt8(const QString &value); // u8_
|
||||
|
||||
|
||||
public slots:
|
||||
void initialize();
|
||||
void update();
|
||||
|
||||
signals:
|
||||
void initializeFinished(bool success);
|
||||
void availableChanged(bool available);
|
||||
void updatedFinished(bool success);
|
||||
|
||||
private:
|
||||
NetworkAccessManager *m_networkManager = nullptr;
|
||||
|
|
@ -81,10 +94,14 @@ private:
|
|||
float m_maxChargePower = 0;
|
||||
float m_maxDischargePower = 0;
|
||||
|
||||
float m_batteryLevel = 0;
|
||||
float m_batteryPower = 0;
|
||||
float m_gridPower = 0;
|
||||
float m_inverterPower = 0;
|
||||
|
||||
void updateUrl();
|
||||
void setAvailable(bool available);
|
||||
|
||||
|
||||
private slots:
|
||||
void ignoreSslErrors(const QList<QSslError> &errors);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue