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

This commit is contained in:
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 Energy Control
* Amperfied connect.home * Amperfied connect.home
* Amperfied connect.solar
* Amperfied connect.business
# Requirements # 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. 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. 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. 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, "defaultValue": 0,
"access": "RO" "access": "RO"
}, },
{
"id": "logisticString",
"address": 102,
"size": 32,
"type": "string",
"readSchedule": "init",
"registerType": "inputRegister",
"description": "Logistic string",
"access": "RO"
},
{ {
"id": "chargingCurrent", "id": "chargingCurrent",
"address": 261, "address": 261,
@ -268,6 +278,16 @@
"description": "Standby function control", "description": "Standby function control",
"defaultValue": 0, "defaultValue": 0,
"access": "WO" "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) include(../modbus.pri)
HEADERS += \ HEADERS += \
amperfiedconnectdiscovery.h \
energycontroldiscovery.h \ energycontroldiscovery.h \
connecthomediscovery.h \
integrationpluginamperfied.h integrationpluginamperfied.h
SOURCES += \ SOURCES += \
amperfiedconnectdiscovery.cpp \
energycontroldiscovery.cpp \ energycontroldiscovery.cpp \
connecthomediscovery.cpp \
integrationpluginamperfied.cpp integrationpluginamperfied.cpp

View File

@ -28,10 +28,10 @@
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "connecthomediscovery.h" #include "amperfiedconnectdiscovery.h"
#include "extern-plugininfo.h" #include "extern-plugininfo.h"
ConnectHomeDiscovery::ConnectHomeDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent) : AmperfiedConnectDiscovery::AmperfiedConnectDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent) :
QObject{parent}, QObject{parent},
m_networkDeviceDiscovery{networkDeviceDiscovery} 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(); NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
connect(discoveryReply, &NetworkDeviceDiscoveryReply::networkDeviceInfoAdded, this, &ConnectHomeDiscovery::checkNetworkDevice); connect(discoveryReply, &NetworkDeviceDiscoveryReply::networkDeviceInfoAdded, this, &AmperfiedConnectDiscovery::checkNetworkDevice);
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){ connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){
qCDebug(dcAmperfied()) << "Discovery: Network discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "network devices"; 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; return m_discoveryResults;
} }
void ConnectHomeDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo) void AmperfiedConnectDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo)
{ {
int port = 502; int port = 502;
int slaveId = 1; int slaveId = 1;
@ -92,12 +93,20 @@ void ConnectHomeDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDe
return; 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 result;
result.firmwareVersion = connection->version(); result.firmwareVersion = connection->version();
result.modelName = connection->logisticString();
result.networkDeviceInfo = networkDeviceInfo; result.networkDeviceInfo = networkDeviceInfo;
m_discoveryResults.append(result); m_discoveryResults.append(result);
qCDebug(dcAmperfied()) << "Discovery: --> Found" qCDebug(dcAmperfied()) << "Discovery: --> Found"
<< result.modelName
<< "Version:" << result.firmwareVersion << "Version:" << result.firmwareVersion
<< result.networkDeviceInfo; << result.networkDeviceInfo;
@ -122,14 +131,14 @@ void ConnectHomeDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDe
connection->connectDevice(); connection->connectDevice();
} }
void ConnectHomeDiscovery::cleanupConnection(AmperfiedModbusTcpConnection *connection) void AmperfiedConnectDiscovery::cleanupConnection(AmperfiedModbusTcpConnection *connection)
{ {
m_connections.removeAll(connection); m_connections.removeAll(connection);
connection->disconnectDevice(); connection->disconnectDevice();
connection->deleteLater(); connection->deleteLater();
} }
void ConnectHomeDiscovery::finishDiscovery() void AmperfiedConnectDiscovery::finishDiscovery()
{ {
qint64 durationMilliSeconds = QDateTime::currentMSecsSinceEpoch() - m_startDateTime.toMSecsSinceEpoch(); qint64 durationMilliSeconds = QDateTime::currentMSecsSinceEpoch() - m_startDateTime.toMSecsSinceEpoch();

View File

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

View File

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

View File

@ -212,6 +212,226 @@
"defaultValue": 0 "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) void PhoenixDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDeviceInfo)
{ {
if (networkDeviceInfo.macAddressManufacturer() != "wallbe GmbH" && networkDeviceInfo.macAddressManufacturer() != "Phoenix") { // if (networkDeviceInfo.macAddressManufacturer() != "wallbe GmbH" && networkDeviceInfo.macAddressManufacturer() != "Phoenix") {
return; // return;
} // }
int port = 502; int port = 502;
int slaveId = 0xff; int slaveId = 0xff;