abbterra: restaure pilotage (cpp+json upstream) + registers.json sans readSchedule vide (compat generateur 1.15)

This commit is contained in:
Patrick Schurig 2026-06-01 09:09:22 +02:00
parent 47257a6a29
commit 09dd698cf6
3 changed files with 153 additions and 176 deletions

View File

@ -12,184 +12,35 @@
"id": "deviceInfo", "id": "deviceInfo",
"readSchedule": "init", "readSchedule": "init",
"registers": [ "registers": [
{ { "id": "serialNumber", "address": 16384, "size": 4, "type": "uint64", "registerType": "holdingRegister", "description": "Product serial number", "defaultValue": "0", "access": "RO" },
"id": "serialNumber", { "id": "firmwareVersionRaw", "address": 16388, "size": 2, "type": "uint32", "registerType": "holdingRegister", "description": "Firmware version", "defaultValue": "0", "access": "RO" },
"address": 16384, { "id": "userSettableMaxCurrent", "address": 16390, "size": 2, "type": "uint32", "unit": "mA", "registerType": "holdingRegister", "description": "Maximum user settable charging current", "defaultValue": "32000", "access": "RO" }
"size": 4,
"type": "uint64",
"registerType": "holdingRegister",
"description": "Product serial number",
"defaultValue": "0",
"access": "RO"
},
{
"id": "firmwareVersionRaw",
"address": 16388,
"size": 2,
"type": "uint32",
"registerType": "holdingRegister",
"description": "Firmware version",
"defaultValue": "0",
"access": "RO"
},
{
"id": "userSettableMaxCurrent",
"address": 16390,
"size": 2,
"type": "uint32",
"unit": "mA",
"registerType": "holdingRegister",
"description": "Maximum user settable charging current",
"defaultValue": "32000",
"access": "RO"
}
] ]
}, },
{ {
"id": "status", "id": "status",
"readSchedule": "update", "readSchedule": "update",
"registers": [ "registers": [
{ { "id": "errorCode", "address": 16392, "size": 2, "type": "uint32", "registerType": "holdingRegister", "description": "Last error code", "defaultValue": "0", "access": "RO" },
"id": "errorCode", { "id": "socketLockState", "address": 16394, "size": 2, "type": "uint32", "registerType": "holdingRegister", "description": "Socket and cable lock state", "defaultValue": "0", "access": "RO" },
"address": 16392, { "id": "chargingStateRaw", "address": 16396, "size": 2, "type": "uint32", "registerType": "holdingRegister", "description": "Charging state", "defaultValue": "0", "access": "RO" },
"size": 2, { "id": "chargingCurrentLimit", "address": 16398, "size": 2, "type": "uint32", "unit": "mA", "registerType": "holdingRegister", "description": "Current charging current limit", "defaultValue": "6000", "access": "RO" },
"type": "uint32", { "id": "currentL1", "address": 16400, "size": 2, "type": "uint32", "unit": "mA", "registerType": "holdingRegister", "description": "Current L1", "defaultValue": "0", "access": "RO" },
"registerType": "holdingRegister", { "id": "currentL2", "address": 16402, "size": 2, "type": "uint32", "unit": "mA", "registerType": "holdingRegister", "description": "Current L2", "defaultValue": "0", "access": "RO" },
"description": "Last error code", { "id": "currentL3", "address": 16404, "size": 2, "type": "uint32", "unit": "mA", "registerType": "holdingRegister", "description": "Current L3", "defaultValue": "0", "access": "RO" },
"defaultValue": "0", { "id": "voltageL1", "address": 16406, "size": 2, "type": "uint32", "unit": "0.1V", "registerType": "holdingRegister", "description": "Voltage L1", "defaultValue": "0", "access": "RO" },
"access": "RO" { "id": "voltageL2", "address": 16408, "size": 2, "type": "uint32", "unit": "0.1V", "registerType": "holdingRegister", "description": "Voltage L2", "defaultValue": "0", "access": "RO" },
}, { "id": "voltageL3", "address": 16410, "size": 2, "type": "uint32", "unit": "0.1V", "registerType": "holdingRegister", "description": "Voltage L3", "defaultValue": "0", "access": "RO" },
{ { "id": "activePower", "address": 16412, "size": 2, "type": "uint32", "unit": "W", "registerType": "holdingRegister", "description": "Measured active power", "defaultValue": "0", "access": "RO" },
"id": "socketLockState", { "id": "sessionEnergy", "address": 16414, "size": 2, "type": "uint32", "unit": "Wh", "registerType": "holdingRegister", "description": "Delivered energy of the current session", "defaultValue": "0", "access": "RO" },
"address": 16394, { "id": "communicationTimeoutReadback", "address": 16416, "size": 1, "type": "uint16", "unit": "s", "registerType": "holdingRegister", "description": "Communication timeout", "defaultValue": "60", "access": "RO" }
"size": 2,
"type": "uint32",
"registerType": "holdingRegister",
"description": "Socket and cable lock state",
"defaultValue": "0",
"access": "RO"
},
{
"id": "chargingStateRaw",
"address": 16396,
"size": 2,
"type": "uint32",
"registerType": "holdingRegister",
"description": "Charging state",
"defaultValue": "0",
"access": "RO"
},
{
"id": "chargingCurrentLimit",
"address": 16398,
"size": 2,
"type": "uint32",
"unit": "mA",
"registerType": "holdingRegister",
"description": "Current charging current limit",
"defaultValue": "6000",
"access": "RO"
},
{
"id": "currentL1",
"address": 16400,
"size": 2,
"type": "uint32",
"unit": "mA",
"registerType": "holdingRegister",
"description": "Current L1",
"defaultValue": "0",
"access": "RO"
},
{
"id": "currentL2",
"address": 16402,
"size": 2,
"type": "uint32",
"unit": "mA",
"registerType": "holdingRegister",
"description": "Current L2",
"defaultValue": "0",
"access": "RO"
},
{
"id": "currentL3",
"address": 16404,
"size": 2,
"type": "uint32",
"unit": "mA",
"registerType": "holdingRegister",
"description": "Current L3",
"defaultValue": "0",
"access": "RO"
},
{
"id": "voltageL1",
"address": 16406,
"size": 2,
"type": "uint32",
"unit": "0.1V",
"registerType": "holdingRegister",
"description": "Voltage L1",
"defaultValue": "0",
"access": "RO"
},
{
"id": "voltageL2",
"address": 16408,
"size": 2,
"type": "uint32",
"unit": "0.1V",
"registerType": "holdingRegister",
"description": "Voltage L2",
"defaultValue": "0",
"access": "RO"
},
{
"id": "voltageL3",
"address": 16410,
"size": 2,
"type": "uint32",
"unit": "0.1V",
"registerType": "holdingRegister",
"description": "Voltage L3",
"defaultValue": "0",
"access": "RO"
},
{
"id": "activePower",
"address": 16412,
"size": 2,
"type": "uint32",
"unit": "W",
"registerType": "holdingRegister",
"description": "Measured active power",
"defaultValue": "0",
"access": "RO"
},
{
"id": "sessionEnergy",
"address": 16414,
"size": 2,
"type": "uint32",
"unit": "Wh",
"registerType": "holdingRegister",
"description": "Delivered energy of the current session",
"defaultValue": "0",
"access": "RO"
},
{
"id": "communicationTimeoutReadback",
"address": 16416,
"size": 1,
"type": "uint16",
"unit": "s",
"registerType": "holdingRegister",
"description": "Communication timeout",
"defaultValue": "60",
"access": "RO"
}
] ]
} }
],
"registers": [
{ "id": "chargingCurrentLimitCommand", "address": 16640, "size": 2, "type": "uint32", "unit": "mA", "registerType": "holdingRegister", "description": "Set charging current limit", "defaultValue": "6000", "access": "WO" },
{ "id": "socketLockCommand", "address": 16642, "size": 1, "type": "uint16", "registerType": "holdingRegister", "description": "Socket lock control", "defaultValue": "0", "access": "WO" },
{ "id": "startStopChargingSession", "address": 16645, "size": 1, "type": "uint16", "registerType": "holdingRegister", "description": "Start or stop charging session", "defaultValue": "0", "access": "WO" },
{ "id": "communicationTimeoutCommand", "address": 16646, "size": 1, "type": "uint16", "unit": "s", "registerType": "holdingRegister", "description": "Set communication timeout", "defaultValue": "60", "access": "WO" }
] ]
} }

View File

@ -133,7 +133,93 @@ void IntegrationPluginAbbterra::thingRemoved(Thing *thing)
void IntegrationPluginAbbterra::executeAction(ThingActionInfo *info) void IntegrationPluginAbbterra::executeAction(ThingActionInfo *info)
{ {
// Read-only mode: WO registers removed for compatibility with libnymea-modbus 1.15 Thing *thing = info->thing();
if (thing->thingClassId() == terraAcTcpThingClassId) {
AbbTerraModbusTcpConnection *connection = m_tcpConnections.value(thing);
if (!connection || !connection->reachable()) {
info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("The charging station is not reachable."));
return;
}
if (info->action().actionTypeId() == terraAcTcpPowerActionTypeId) {
const bool power = info->action().paramValue(terraAcTcpPowerActionPowerParamTypeId).toBool();
const quint32 currentMilliAmps = power ? static_cast<quint32>(qRound(thing->stateValue(terraAcTcpMaxChargingCurrentStateTypeId).toDouble() * 1000.0)) : 0;
QModbusReply *reply = connection->setChargingCurrentLimitCommand(currentMilliAmps);
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
connect(reply, &QModbusReply::finished, info, [info, thing, connection, reply, power]() {
if (reply->error() == QModbusDevice::NoError) {
thing->setStateValue(terraAcTcpPowerStateTypeId, power);
connection->update();
info->finish(Thing::ThingErrorNoError);
} else {
info->finish(Thing::ThingErrorHardwareFailure);
}
});
return;
}
if (info->action().actionTypeId() == terraAcTcpMaxChargingCurrentActionTypeId) {
const double current = info->action().paramValue(terraAcTcpMaxChargingCurrentActionMaxChargingCurrentParamTypeId).toDouble();
QModbusReply *reply = connection->setChargingCurrentLimitCommand(static_cast<quint32>(qRound(current * 1000.0)));
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
connect(reply, &QModbusReply::finished, info, [info, thing, connection, reply, current]() {
if (reply->error() == QModbusDevice::NoError) {
thing->setStateValue(terraAcTcpMaxChargingCurrentStateTypeId, current);
thing->setStateValue(terraAcTcpPowerStateTypeId, current >= 6.0);
connection->update();
info->finish(Thing::ThingErrorNoError);
} else {
info->finish(Thing::ThingErrorHardwareFailure);
}
});
return;
}
info->finish(Thing::ThingErrorUnsupportedFeature);
return;
}
if (thing->thingClassId() == terraAcRtuThingClassId) {
AbbTerraModbusRtuConnection *connection = m_rtuConnections.value(thing);
if (!connection || !connection->reachable()) {
info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("The charging station is not reachable."));
return;
}
if (info->action().actionTypeId() == terraAcRtuPowerActionTypeId) {
const bool power = info->action().paramValue(terraAcRtuPowerActionPowerParamTypeId).toBool();
const quint32 currentMilliAmps = power ? static_cast<quint32>(qRound(thing->stateValue(terraAcRtuMaxChargingCurrentStateTypeId).toDouble() * 1000.0)) : 0;
ModbusRtuReply *reply = connection->setChargingCurrentLimitCommand(currentMilliAmps);
connect(reply, &ModbusRtuReply::finished, info, [info, thing, connection, reply, power]() {
if (reply->error() == ModbusRtuReply::NoError) {
thing->setStateValue(terraAcRtuPowerStateTypeId, power);
connection->update();
info->finish(Thing::ThingErrorNoError);
} else {
info->finish(Thing::ThingErrorHardwareFailure);
}
});
return;
}
if (info->action().actionTypeId() == terraAcRtuMaxChargingCurrentActionTypeId) {
const double current = info->action().paramValue(terraAcRtuMaxChargingCurrentActionMaxChargingCurrentParamTypeId).toDouble();
ModbusRtuReply *reply = connection->setChargingCurrentLimitCommand(static_cast<quint32>(qRound(current * 1000.0)));
connect(reply, &ModbusRtuReply::finished, info, [info, thing, connection, reply, current]() {
if (reply->error() == ModbusRtuReply::NoError) {
thing->setStateValue(terraAcRtuMaxChargingCurrentStateTypeId, current);
thing->setStateValue(terraAcRtuPowerStateTypeId, current >= 6.0);
connection->update();
info->finish(Thing::ThingErrorNoError);
} else {
info->finish(Thing::ThingErrorHardwareFailure);
}
});
return;
}
}
info->finish(Thing::ThingErrorUnsupportedFeature); info->finish(Thing::ThingErrorUnsupportedFeature);
} }
@ -194,6 +280,7 @@ void IntegrationPluginAbbterra::setupTcpThing(ThingSetupInfo *info)
thing->setStateValue(terraAcTcpFirmwareVersionStateTypeId, deviceInfo.firmwareVersion); thing->setStateValue(terraAcTcpFirmwareVersionStateTypeId, deviceInfo.firmwareVersion);
thing->setStateValue(terraAcTcpSerialNumberStateTypeId, deviceInfo.serialNumber); thing->setStateValue(terraAcTcpSerialNumberStateTypeId, deviceInfo.serialNumber);
thing->setStateMinMaxValues(terraAcTcpMaxChargingCurrentStateTypeId, 6.0, deviceInfo.maxChargingCurrent); thing->setStateMinMaxValues(terraAcTcpMaxChargingCurrentStateTypeId, 6.0, deviceInfo.maxChargingCurrent);
applyTimeoutSetting(thing, connection);
}); });
connect(connection, &AbbTerraModbusTcpConnection::initializationFinished, info, [this, info, thing, connection](bool success) { connect(connection, &AbbTerraModbusTcpConnection::initializationFinished, info, [this, info, thing, connection](bool success) {
@ -221,6 +308,11 @@ void IntegrationPluginAbbterra::setupTcpThing(ThingSetupInfo *info)
updateThing(thing, connection); updateThing(thing, connection);
}); });
connect(thing, &Thing::settingChanged, connection, [this, thing, connection](const ParamTypeId &paramTypeId, const QVariant &) {
if (paramTypeId == terraAcTcpSettingsCommunicationTimeoutParamTypeId) {
applyTimeoutSetting(thing, connection);
}
});
} }
void IntegrationPluginAbbterra::setupRtuThing(ThingSetupInfo *info) void IntegrationPluginAbbterra::setupRtuThing(ThingSetupInfo *info)
@ -264,6 +356,7 @@ void IntegrationPluginAbbterra::setupRtuThing(ThingSetupInfo *info)
thing->setStateValue(terraAcRtuFirmwareVersionStateTypeId, deviceInfo.firmwareVersion); thing->setStateValue(terraAcRtuFirmwareVersionStateTypeId, deviceInfo.firmwareVersion);
thing->setStateValue(terraAcRtuSerialNumberStateTypeId, deviceInfo.serialNumber); thing->setStateValue(terraAcRtuSerialNumberStateTypeId, deviceInfo.serialNumber);
thing->setStateMinMaxValues(terraAcRtuMaxChargingCurrentStateTypeId, 6.0, deviceInfo.maxChargingCurrent); thing->setStateMinMaxValues(terraAcRtuMaxChargingCurrentStateTypeId, 6.0, deviceInfo.maxChargingCurrent);
applyTimeoutSetting(thing, connection);
}); });
connect(connection, &AbbTerraModbusRtuConnection::initializationFinished, info, [this, info, thing, connection](bool success) { connect(connection, &AbbTerraModbusRtuConnection::initializationFinished, info, [this, info, thing, connection](bool success) {
@ -291,8 +384,33 @@ void IntegrationPluginAbbterra::setupRtuThing(ThingSetupInfo *info)
updateThing(thing, connection); updateThing(thing, connection);
}); });
connect(thing, &Thing::settingChanged, connection, [this, thing, connection](const ParamTypeId &paramTypeId, const QVariant &) {
if (paramTypeId == terraAcRtuSettingsCommunicationTimeoutParamTypeId) {
applyTimeoutSetting(thing, connection);
}
});
} }
void IntegrationPluginAbbterra::applyTimeoutSetting(Thing *thing, AbbTerraModbusTcpConnection *connection)
{
QModbusReply *reply = connection->setCommunicationTimeoutCommand(static_cast<quint16>(thing->setting(terraAcTcpSettingsCommunicationTimeoutParamTypeId).toUInt()));
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
connect(reply, &QModbusReply::finished, connection, [connection, reply]() {
if (reply->error() != QModbusDevice::NoError && connection->reachable()) {
connection->updateCommunicationTimeoutReadback();
}
});
}
void IntegrationPluginAbbterra::applyTimeoutSetting(Thing *thing, AbbTerraModbusRtuConnection *connection)
{
ModbusRtuReply *reply = connection->setCommunicationTimeoutCommand(static_cast<quint16>(thing->setting(terraAcRtuSettingsCommunicationTimeoutParamTypeId).toUInt()));
connect(reply, &ModbusRtuReply::finished, connection, [connection, reply]() {
if (reply->error() != ModbusRtuReply::NoError && connection->reachable()) {
connection->updateCommunicationTimeoutReadback();
}
});
}
void IntegrationPluginAbbterra::updateThing(Thing *thing, AbbTerraModbusTcpConnection *connection) void IntegrationPluginAbbterra::updateThing(Thing *thing, AbbTerraModbusTcpConnection *connection)
{ {

View File

@ -107,19 +107,23 @@
"id": "207e2074-0147-4617-9a8b-3f326dcd6a0b", "id": "207e2074-0147-4617-9a8b-3f326dcd6a0b",
"name": "power", "name": "power",
"displayName": "Charging enabled", "displayName": "Charging enabled",
"displayNameAction": "Set charging enabled",
"type": "bool", "type": "bool",
"defaultValue": true "defaultValue": true,
"writable": true
}, },
{ {
"id": "e3d27f8a-73d0-493a-b99a-29e7dc184485", "id": "e3d27f8a-73d0-493a-b99a-29e7dc184485",
"name": "maxChargingCurrent", "name": "maxChargingCurrent",
"displayName": "Maximum charging current", "displayName": "Maximum charging current",
"displayNameAction": "Set maximum charging current",
"type": "double", "type": "double",
"unit": "Ampere", "unit": "Ampere",
"minValue": 6, "minValue": 6,
"maxValue": 32, "maxValue": 32,
"stepSize": 0.1, "stepSize": 0.1,
"defaultValue": 6 "defaultValue": 6,
"writable": true
}, },
{ {
"id": "0764bce9-fd26-4da8-8d92-f6a5ce73e81e", "id": "0764bce9-fd26-4da8-8d92-f6a5ce73e81e",
@ -290,19 +294,23 @@
"id": "e35fd4fa-bf5a-45a1-8a39-f0d3d9efa4c6", "id": "e35fd4fa-bf5a-45a1-8a39-f0d3d9efa4c6",
"name": "power", "name": "power",
"displayName": "Charging enabled", "displayName": "Charging enabled",
"displayNameAction": "Set charging enabled",
"type": "bool", "type": "bool",
"defaultValue": true "defaultValue": true,
"writable": true
}, },
{ {
"id": "ea933a77-a098-4303-bbdb-15c72dfd3634", "id": "ea933a77-a098-4303-bbdb-15c72dfd3634",
"name": "maxChargingCurrent", "name": "maxChargingCurrent",
"displayName": "Maximum charging current", "displayName": "Maximum charging current",
"displayNameAction": "Set maximum charging current",
"type": "double", "type": "double",
"unit": "Ampere", "unit": "Ampere",
"minValue": 6, "minValue": 6,
"maxValue": 32, "maxValue": 32,
"stepSize": 0.1, "stepSize": 0.1,
"defaultValue": 6 "defaultValue": 6,
"writable": true
}, },
{ {
"id": "cd1add95-18d9-46b5-a3d5-f0f29d5160c9", "id": "cd1add95-18d9-46b5-a3d5-f0f29d5160c9",