Merge PR #152: Amperfied: Add support for connect.solar and connect.business

master
jenkins 2023-12-15 10:21:42 +01:00
commit ea84b9ad51
8 changed files with 350 additions and 61 deletions

View File

@ -4,6 +4,8 @@ Connects nymea to a Amperfied/Heidelberg wallboxes. Currently supported models a
* Amperfied Energy Control
* Amperfied connect.home
* Amperfied connect.solar
* Amperfied connect.business
# Requirements
@ -15,6 +17,7 @@ The Modbus RTU must be configured with a baud rate of 19200, even parity, 8 data
In order to allow nymea to automatically discover the wallbox on the bus, the Modbus slave ID must be in the range of 1 - 20.
If a higher slave ID number is required, the manual setup is to be used.
## Amperfied connect.home
## Amperfied connect.home/solar/business
The Amperfied connect.home is a Modbus TCP device. This means it must be connected to the same network the nymea system is in.

View File

@ -247,6 +247,16 @@
"defaultValue": 0,
"access": "RO"
},
{
"id": "logisticString",
"address": 102,
"size": 32,
"type": "string",
"readSchedule": "init",
"registerType": "inputRegister",
"description": "Logistic string",
"access": "RO"
},
{
"id": "chargingCurrent",
"address": 261,
@ -268,6 +278,16 @@
"description": "Standby function control",
"defaultValue": 0,
"access": "WO"
},
{
"id": "phaseSwitchControl",
"address": 501,
"size": 1,
"type": "uint16",
"registerType": "holdingRegister",
"description": "Phase switch control",
"defaultValue": 3,
"access": "RW"
}
]
}

View File

@ -7,11 +7,11 @@ MODBUS_TOOLS_CONFIG += VERBOSE
include(../modbus.pri)
HEADERS += \
amperfiedconnectdiscovery.h \
energycontroldiscovery.h \
connecthomediscovery.h \
integrationpluginamperfied.h
SOURCES += \
amperfiedconnectdiscovery.cpp \
energycontroldiscovery.cpp \
connecthomediscovery.cpp \
integrationpluginamperfied.cpp

View File

@ -28,10 +28,10 @@
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "connecthomediscovery.h"
#include "amperfiedconnectdiscovery.h"
#include "extern-plugininfo.h"
ConnectHomeDiscovery::ConnectHomeDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent) :
AmperfiedConnectDiscovery::AmperfiedConnectDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent) :
QObject{parent},
m_networkDeviceDiscovery{networkDeviceDiscovery}
{
@ -43,12 +43,13 @@ ConnectHomeDiscovery::ConnectHomeDiscovery(NetworkDeviceDiscovery *networkDevice
});
}
void ConnectHomeDiscovery::startDiscovery()
void AmperfiedConnectDiscovery::startDiscovery(const QString &nameFilter)
{
qCInfo(dcAmperfied()) << "Discovery: Searching for Amperfied wallboxes in the network...";
qCInfo(dcAmperfied()) << "Discovery: Searching for Amperfied" << nameFilter << "wallboxes in the network...";
m_nameFilter = nameFilter;
NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
connect(discoveryReply, &NetworkDeviceDiscoveryReply::networkDeviceInfoAdded, this, &ConnectHomeDiscovery::checkNetworkDevice);
connect(discoveryReply, &NetworkDeviceDiscoveryReply::networkDeviceInfoAdded, this, &AmperfiedConnectDiscovery::checkNetworkDevice);
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){
qCDebug(dcAmperfied()) << "Discovery: Network discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "network devices";
@ -57,12 +58,12 @@ void ConnectHomeDiscovery::startDiscovery()
});
}
QList<ConnectHomeDiscovery::Result> ConnectHomeDiscovery::discoveryResults() const
QList<AmperfiedConnectDiscovery::Result> AmperfiedConnectDiscovery::discoveryResults() const
{
return m_discoveryResults;
}
void ConnectHomeDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo)
void AmperfiedConnectDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo)
{
int port = 502;
int slaveId = 1;
@ -92,12 +93,20 @@ void ConnectHomeDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDe
return;
}
if (!m_nameFilter.isEmpty() && connection->logisticString() != m_nameFilter) {
qCInfo(dcAmperfied()) << "Skipping" << connection->modbusTcpMaster()->hostAddress().toString() << "as name" << connection->logisticString() << "does not match filter" << m_nameFilter;
cleanupConnection(connection);
return;
}
Result result;
result.firmwareVersion = connection->version();
result.modelName = connection->logisticString();
result.networkDeviceInfo = networkDeviceInfo;
m_discoveryResults.append(result);
qCDebug(dcAmperfied()) << "Discovery: --> Found"
<< result.modelName
<< "Version:" << result.firmwareVersion
<< result.networkDeviceInfo;
@ -122,14 +131,14 @@ void ConnectHomeDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDe
connection->connectDevice();
}
void ConnectHomeDiscovery::cleanupConnection(AmperfiedModbusTcpConnection *connection)
void AmperfiedConnectDiscovery::cleanupConnection(AmperfiedModbusTcpConnection *connection)
{
m_connections.removeAll(connection);
connection->disconnectDevice();
connection->deleteLater();
}
void ConnectHomeDiscovery::finishDiscovery()
void AmperfiedConnectDiscovery::finishDiscovery()
{
qint64 durationMilliSeconds = QDateTime::currentMSecsSinceEpoch() - m_startDateTime.toMSecsSinceEpoch();

View File

@ -28,8 +28,8 @@
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef CONNECTHOMEDISCOVERY_H
#define CONNECTHOMEDISCOVERY_H
#ifndef AMPERFIEDCONNECTDISCOVERY_H
#define AMPERFIEDCONNECTDISCOVERY_H
#include <QObject>
#include <QTimer>
@ -38,18 +38,19 @@
#include "amperfiedmodbustcpconnection.h"
class ConnectHomeDiscovery : public QObject
class AmperfiedConnectDiscovery : public QObject
{
Q_OBJECT
public:
explicit ConnectHomeDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent = nullptr);
explicit AmperfiedConnectDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent = nullptr);
struct Result {
quint16 firmwareVersion;
quint16 slaveId;
QString modelName;
NetworkDeviceInfo networkDeviceInfo;
};
void startDiscovery();
void startDiscovery(const QString &nameFilter);
QList<Result> discoveryResults() const;
@ -61,6 +62,7 @@ private:
QTimer m_gracePeriodTimer;
QDateTime m_startDateTime;
QString m_nameFilter;
QList<AmperfiedModbusTcpConnection *> m_connections;
@ -72,4 +74,4 @@ private:
void finishDiscovery();
};
#endif // CONNECTHOMEDISCOVERY_H
#endif // AMPERFIEDCONNECTDISCOVERY_H

View File

@ -31,7 +31,7 @@
#include "integrationpluginamperfied.h"
#include "plugininfo.h"
#include "energycontroldiscovery.h"
#include "connecthomediscovery.h"
#include "amperfiedconnectdiscovery.h"
#include <network/networkdevicediscovery.h>
#include <hardwaremanager.h>
@ -79,16 +79,17 @@ void IntegrationPluginAmperfied::discoverThings(ThingDiscoveryInfo *info)
return;
}
if (info->thingClassId() == connectHomeThingClassId) {
ConnectHomeDiscovery *discovery = new ConnectHomeDiscovery(hardwareManager()->networkDeviceDiscovery(), info);
connect(discovery, &ConnectHomeDiscovery::discoveryFinished, info, [this, info, discovery](){
if (info->thingClassId() == connectHomeThingClassId || info->thingClassId() == connectBusinessThingClassId || info->thingClassId() == connectSolarThingClassId) {
AmperfiedConnectDiscovery *discovery = new AmperfiedConnectDiscovery(hardwareManager()->networkDeviceDiscovery(), info);
connect(discovery, &AmperfiedConnectDiscovery::discoveryFinished, info, [this, info, discovery](){
qCInfo(dcAmperfied()) << "Discovery results:" << discovery->discoveryResults().count();
foreach (const ConnectHomeDiscovery::Result &result, discovery->discoveryResults()) {
ThingDescriptor descriptor(connectHomeThingClassId, "Amperfied connect.home", QString("MAC: %1").arg(result.networkDeviceInfo.macAddress()));
foreach (const AmperfiedConnectDiscovery::Result &result, discovery->discoveryResults()) {
ThingDescriptor descriptor(info->thingClassId(), "Amperfied " + result.modelName, QString("MAC: %1").arg(result.networkDeviceInfo.macAddress()));
ParamTypeId macAddressParamTypeId = thingClass(info->thingClassId()).paramTypes().findByName("macAddress").id();
ParamList params{
{connectHomeThingMacAddressParamTypeId, result.networkDeviceInfo.macAddress()}
{macAddressParamTypeId, result.networkDeviceInfo.macAddress()}
};
descriptor.setParams(params);
@ -102,7 +103,12 @@ void IntegrationPluginAmperfied::discoverThings(ThingDiscoveryInfo *info)
info->finish(Thing::ThingErrorNoError);
});
discovery->startDiscovery();
QHash<ThingClassId, QString> map = {
{connectHomeThingClassId, "connect.home"},
{connectBusinessThingClassId, "connect.business"},
{connectSolarThingClassId, "connect.solar"}
};
discovery->startDiscovery(map.value(info->thingClassId()));
}
}
@ -123,14 +129,16 @@ void IntegrationPluginAmperfied::setupThing(ThingSetupInfo *info)
}
if (info->thing()->thingClassId() == connectHomeThingClassId) {
if (info->thing()->thingClassId() == connectHomeThingClassId
|| info->thing()->thingClassId() == connectSolarThingClassId
|| info->thing()->thingClassId() == connectBusinessThingClassId) {
if (m_tcpConnections.contains(info->thing())) {
delete m_tcpConnections.take(info->thing());
}
NetworkDeviceMonitor *monitor = m_monitors.value(info->thing());
if (!monitor) {
monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(MacAddress(thing->paramValue(connectHomeThingMacAddressParamTypeId).toString()));
monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(MacAddress(thing->paramValue("macAddress").toString()));
m_monitors.insert(thing, monitor);
}
@ -141,7 +149,7 @@ void IntegrationPluginAmperfied::setupThing(ThingSetupInfo *info)
}
});
qCDebug(dcAmperfied()) << "Monitor reachable" << monitor->reachable() << thing->paramValue(connectHomeThingMacAddressParamTypeId).toString();
qCDebug(dcAmperfied()) << "Monitor reachable" << monitor->reachable() << thing->paramValue("macAddress").toString();
if (monitor->reachable()) {
setupTcpConnection(info);
} else {
@ -212,36 +220,54 @@ void IntegrationPluginAmperfied::executeAction(ThingActionInfo *info)
}
if (info->thing()->thingClassId() == connectHomeThingClassId) {
if (info->thing()->thingClassId() == connectHomeThingClassId
|| info->thing()->thingClassId() == connectBusinessThingClassId
|| info->thing()->thingClassId() == connectSolarThingClassId) {
AmperfiedModbusTcpConnection *connection = m_tcpConnections.value(info->thing());
if (info->action().actionTypeId() == connectHomePowerActionTypeId) {
bool power = info->action().paramValue(connectHomePowerActionPowerParamTypeId).toBool();
QModbusReply *reply = connection->setChargingCurrent(power ? info->thing()->stateValue(connectHomeMaxChargingCurrentStateTypeId).toUInt() * 10 : 0);
ActionType actionType = info->thing()->thingClass().actionTypes().findById(info->action().actionTypeId());
if (actionType.name() == "power") {
bool power = info->action().paramValue(actionType.paramTypes().findByName("power").id()).toBool();
uint max = info->thing()->stateValue("maxChargingCurrent").toUInt();
QModbusReply *reply = connection->setChargingCurrent(power ? max * 10 : 0);
connect(reply, &QModbusReply::finished, info, [info, reply, power](){
if (reply->error() == QModbusDevice::NoError) {
info->thing()->setStateValue(connectHomePowerStateTypeId, power);
info->thing()->setStateValue("power", power);
info->finish(Thing::ThingErrorNoError);
} else {
qCWarning(dcAmperfied()) << "Error setting power:" << reply->error() << reply->errorString();
info->finish(Thing::ThingErrorHardwareFailure);
}
});
}
if (info->action().actionTypeId() == connectHomeMaxChargingCurrentActionTypeId) {
bool power = info->thing()->stateValue(connectHomePowerStateTypeId).toBool();
uint max = info->action().paramValue(connectHomeMaxChargingCurrentActionMaxChargingCurrentParamTypeId).toUInt() * 10;
QModbusReply *reply = connection->setChargingCurrent(power ? max : 0);
} else if (actionType.name() == "maxChargingCurrent") {
bool power = info->thing()->stateValue("power").toBool();
uint max = info->action().paramValue(actionType.paramTypes().findByName("maxChargingCurrent").id()).toUInt();
QModbusReply *reply = connection->setChargingCurrent(power ? max * 10 : 0);
connect(reply, &QModbusReply::finished, info, [info, reply, max](){
if (reply->error() == QModbusDevice::NoError) {
info->thing()->setStateValue(connectHomeMaxChargingCurrentStateTypeId, max / 10);
info->thing()->setStateValue("maxChargingCurrent", max / 10);
info->finish(Thing::ThingErrorNoError);
} else {
qCWarning(dcAmperfied()) << "Error setting power:" << reply->error() << reply->errorString();
info->finish(Thing::ThingErrorHardwareFailure);
}
});
} else if (actionType.name() == "desiredPhaseCount") {
uint desiredPhaseCount = info->thing()->stateValue("desiredPhaseCount").toBool();
QModbusReply *reply = connection->setPhaseSwitchControl(desiredPhaseCount);
connect(reply, &QModbusReply::finished, info, [info, reply, desiredPhaseCount](){
if (reply->error() == QModbusDevice::NoError) {
info->thing()->setStateValue("desiredPhaseCount", desiredPhaseCount);
info->finish(Thing::ThingErrorNoError);
} else {
qCWarning(dcAmperfied()) << "Error setting desired phase count:" << reply->error() << reply->errorString();
info->finish(Thing::ThingErrorHardwareFailure);
}
});
} else {
info->finish(Thing::ThingErrorUnsupportedFeature);
}
}
@ -254,7 +280,9 @@ void IntegrationPluginAmperfied::thingRemoved(Thing *thing)
delete m_rtuConnections.take(thing);
}
if (thing->thingClassId() == connectHomeThingClassId) {
if (thing->thingClassId() == connectHomeThingClassId
|| thing->thingClassId() == connectBusinessThingClassId
|| thing->thingClassId() == connectSolarThingClassId) {
delete m_tcpConnections.take(thing);
}
@ -337,7 +365,9 @@ void IntegrationPluginAmperfied::setupRtuConnection(ThingSetupInfo *info)
case AmperfiedModbusRtuConnection::ChargingStateE:
case AmperfiedModbusRtuConnection::ChargingStateError:
case AmperfiedModbusRtuConnection::ChargingStateF:
qCWarning(dcAmperfied()) << "Unhandled charging state:" << connection->chargingState();
qCWarning(dcAmperfied()) << "Erraneous charging state:" << connection->chargingState();
thing->setStateValue(energyControlPluggedInStateTypeId, false);
break;
}
int phaseCount = 0;
@ -371,8 +401,8 @@ void IntegrationPluginAmperfied::setupTcpConnection(ThingSetupInfo *info)
if (reachable) {
connection->initialize();
} else {
thing->setStateValue(connectHomeCurrentPowerStateTypeId, 0);
thing->setStateValue(connectHomeConnectedStateTypeId, false);
thing->setStateValue("currentPower", 0);
thing->setStateValue("connected", false);
}
});
@ -396,35 +426,41 @@ void IntegrationPluginAmperfied::setupTcpConnection(ThingSetupInfo *info)
connect(connection, &AmperfiedModbusTcpConnection::updateFinished, thing, [connection, thing](){
qCDebug(dcAmperfied()) << "Updated:" << connection;
thing->setStateValue(connectHomeConnectedStateTypeId, true);
thing->setStateValue("connected", true);
if (connection->chargingCurrent() == 0) {
thing->setStateValue(connectHomePowerStateTypeId, false);
thing->setStateValue("power", false);
} else {
thing->setStateValue(connectHomePowerStateTypeId, true);
thing->setStateValue(connectHomeMaxChargingCurrentStateTypeId, connection->chargingCurrent() / 10);
thing->setStateValue("power", true);
thing->setStateValue("maxChargingCurrent", connection->chargingCurrent() / 10);
}
thing->setStateMinMaxValues(connectHomeMaxChargingCurrentStateTypeId, connection->minChargingCurrent(), connection->maxChargingCurrent());
thing->setStateValue(connectHomeCurrentPowerStateTypeId, connection->currentPower());
thing->setStateValue(connectHomeTotalEnergyConsumedStateTypeId, connection->totalEnergy() / 1000.0);
thing->setStateValue(connectHomeSessionEnergyStateTypeId, connection->sessionEnergy() / 1000.0);
thing->setStateMinMaxValues("maxChargingCurrent", connection->minChargingCurrent(), connection->maxChargingCurrent());
thing->setStateValue("currentPower", connection->currentPower());
thing->setStateValue("totalEnergyConsumed", connection->totalEnergy() / 1000.0);
thing->setStateValue("sessionEnergy", connection->sessionEnergy() / 1000.0);
switch (connection->chargingState()) {
case AmperfiedModbusTcpConnection::ChargingStateUndefined:
case AmperfiedModbusTcpConnection::ChargingStateA1:
case AmperfiedModbusTcpConnection::ChargingStateA2:
thing->setStateValue(connectHomePluggedInStateTypeId, false);
thing->setStateValue("pluggedIn", false);
thing->setStateValue("charging", false);
break;
case AmperfiedModbusTcpConnection::ChargingStateB1:
case AmperfiedModbusTcpConnection::ChargingStateB2:
thing->setStateValue("pluggedIn", true);
thing->setStateValue("charging", false);
break;
case AmperfiedModbusTcpConnection::ChargingStateC1:
case AmperfiedModbusTcpConnection::ChargingStateC2:
thing->setStateValue(connectHomePluggedInStateTypeId, true);
thing->setStateValue("pluggedIn", true);
thing->setStateValue("charging", true);
break;
case AmperfiedModbusTcpConnection::ChargingStateDerating:
case AmperfiedModbusTcpConnection::ChargingStateE:
case AmperfiedModbusTcpConnection::ChargingStateError:
case AmperfiedModbusTcpConnection::ChargingStateF:
qCWarning(dcAmperfied()) << "Unhandled charging state:" << connection->chargingState();
qCWarning(dcAmperfied()) << "Erraneous CP signal state:" << connection->chargingState();
thing->setStateValue("charging", false);
}
int phaseCount = 0;
@ -438,9 +474,8 @@ void IntegrationPluginAmperfied::setupTcpConnection(ThingSetupInfo *info)
phaseCount++;
}
if (phaseCount > 0) {
thing->setStateValue(connectHomePhaseCountStateTypeId, phaseCount);
thing->setStateValue("phaseCount", phaseCount);
}
thing->setStateValue(connectHomeChargingStateTypeId, phaseCount > 0);
});
connection->connectDevice();

View File

@ -212,6 +212,226 @@
"defaultValue": 0
}
]
},
{
"name": "connectBusiness",
"displayName": "connect.business",
"id": "18e6d077-7cb5-4409-8c4b-b14ce7ddac9f",
"createMethods": ["discovery", "user"],
"interfaces": ["evcharger", "smartmeterconsumer", "connectable"],
"paramTypes": [
{
"id": "d8545dfe-65c7-44bc-9ab7-642bfdccf540",
"name":"macAddress",
"displayName": "MAC address",
"type": "QString",
"defaultValue": ""
}
],
"stateTypes": [
{
"id": "53022593-0b40-4cfb-b0d4-e374b0109b31",
"name": "connected",
"displayName": "Connected",
"type": "bool",
"defaultValue": false,
"cached": false
},
{
"id": "e5e194db-2d0a-4238-82f5-3c74a9f3ad6d",
"name": "pluggedIn",
"displayName": "Plugged in",
"type": "bool",
"defaultValue": false,
"cached": false
},
{
"id": "2b1538fa-387a-4ed0-ac11-4b7f1f62057c",
"name": "charging",
"displayName": "Charging",
"type": "bool",
"defaultValue": false,
"cached": false
},
{
"id": "96302ee0-151e-4476-b5f8-01d4e2680dd9",
"name": "phaseCount",
"displayName": "Connected phases",
"type": "uint",
"minValue": 1,
"maxValue": 3,
"defaultValue": 1
},
{
"id": "040b919c-455a-4289-b14c-33e59c48da01",
"name": "desiredPhaseCount",
"displayName": "Desired phase count",
"displayNameAction": "Set desired phase count",
"type": "uint",
"minValue": 1,
"maxValue": 3,
"possibleValues": [1,3],
"defaultValue": 3,
"writable": true
},
{
"id": "7d8732fe-2ec3-4f82-86a8-bcc1c98f7023",
"name": "currentPower",
"displayName": "Active power",
"type": "double",
"unit": "Watt",
"defaultValue": 0,
"cached": false
},
{
"id": "0f3049ef-9713-414f-a2c9-e7bdbdaf002d",
"name": "totalEnergyConsumed",
"displayName": "Total consumed energy",
"type": "double",
"unit": "KiloWattHour",
"defaultValue": 0.0,
"cached": true
},
{
"id": "f38b3054-a20f-4680-96e9-d4657942839b",
"name": "power",
"displayName": "Charging enabled",
"displayNameAction": "Set charging enabled",
"type": "bool",
"defaultValue": false,
"writable": true
},
{
"id": "9ff00928-2f9c-41da-8d7d-8887ff948999",
"name": "maxChargingCurrent",
"displayName": "Maximum charging current",
"displayNameAction": "Set maximum charging current",
"type": "uint",
"unit": "Ampere",
"minValue": 6,
"maxValue": 32,
"defaultValue": 6,
"writable": true
},
{
"id": "55fe77bf-db76-40e2-955b-8afc62cfe19a",
"name": "sessionEnergy",
"displayName": "Session energy",
"type": "double",
"unit": "KiloWattHour",
"defaultValue": 0
}
]
},
{
"name": "connectSolar",
"displayName": "connect.solar",
"id": "0bfdf18d-5a5e-4c5d-aab1-139e96a5fec0",
"createMethods": ["discovery", "user"],
"interfaces": ["evcharger", "smartmeterconsumer", "connectable"],
"paramTypes": [
{
"id": "72f82b3a-0bb0-476f-a2f9-9cde4de0ef6f",
"name":"macAddress",
"displayName": "MAC address",
"type": "QString",
"defaultValue": ""
}
],
"stateTypes": [
{
"id": "32f835ca-fe09-406a-94a6-9a7f90999310",
"name": "connected",
"displayName": "Connected",
"type": "bool",
"defaultValue": false,
"cached": false
},
{
"id": "eaa4532e-a3c2-4f33-a73d-2af1e61c2db4",
"name": "pluggedIn",
"displayName": "Plugged in",
"type": "bool",
"defaultValue": false,
"cached": false
},
{
"id": "8d05e9eb-7c7b-4db6-a59a-e5a236fba9e8",
"name": "charging",
"displayName": "Charging",
"type": "bool",
"defaultValue": false,
"cached": false
},
{
"id": "0375c5a9-f9a4-4cb1-a3e4-7ab76fdf4161",
"name": "phaseCount",
"displayName": "Connected phases",
"type": "uint",
"minValue": 1,
"maxValue": 3,
"defaultValue": 1
},
{
"id": "8096f537-748e-4040-a146-022a3aba05e1",
"name": "desiredPhaseCount",
"displayName": "Desired phase count",
"displayNameAction": "Set desired phase count",
"type": "uint",
"minValue": 1,
"maxValue": 3,
"possibleValues": [1,3],
"defaultValue": 3,
"writable": true
},
{
"id": "8ec50b7f-7a9c-47c0-91c1-9ae871fffeb7",
"name": "currentPower",
"displayName": "Active power",
"type": "double",
"unit": "Watt",
"defaultValue": 0,
"cached": false
},
{
"id": "7791c72e-4588-4985-8220-d3b67d5aacbe",
"name": "totalEnergyConsumed",
"displayName": "Total consumed energy",
"type": "double",
"unit": "KiloWattHour",
"defaultValue": 0.0,
"cached": true
},
{
"id": "eda3e61b-1f46-4b68-88b8-318efdaf94f3",
"name": "power",
"displayName": "Charging enabled",
"displayNameAction": "Set charging enabled",
"type": "bool",
"defaultValue": false,
"writable": true
},
{
"id": "8dea5017-ceec-46e3-8182-8641c49a110d",
"name": "maxChargingCurrent",
"displayName": "Maximum charging current",
"displayNameAction": "Set maximum charging current",
"type": "uint",
"unit": "Ampere",
"minValue": 6,
"maxValue": 32,
"defaultValue": 6,
"writable": true
},
{
"id": "4098c11e-e085-4a92-97f2-f5116a2011f2",
"name": "sessionEnergy",
"displayName": "Session energy",
"type": "double",
"unit": "KiloWattHour",
"defaultValue": 0
}
]
}
]
}

View File

@ -64,9 +64,9 @@ QList<PhoenixDiscovery::Result> PhoenixDiscovery::discoveryResults() const
void PhoenixDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo)
{
if (networkDeviceInfo.macAddressManufacturer() != "wallbe GmbH" && networkDeviceInfo.macAddressManufacturer() != "Phoenix") {
return;
}
// if (networkDeviceInfo.macAddressManufacturer() != "wallbe GmbH" && networkDeviceInfo.macAddressManufacturer() != "Phoenix") {
// return;
// }
int port = 502;
int slaveId = 0xff;