New Plugin: Schrack i-CHARGE CION

pull/53/head
Michael Zanetti 2022-01-27 21:52:55 +01:00
parent 98a309d434
commit c5ebc4e5bb
15 changed files with 1476 additions and 0 deletions

8
debian/control vendored
View File

@ -122,6 +122,14 @@ Description: nymea integration plugin for M-TEC heat pumps
This package contains the nymea integration plugin for M-TEC heat pumps.
Package: nymea-plugin-schrack
Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends},
Description: nymea integration plugin for Schrack wallboxes
This package contains the nymea integration plugin for Schrack wallboxes.
Package: nymea-plugin-sunspec
Architecture: any
Depends: ${shlibs:Depends},

View File

@ -0,0 +1,2 @@
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginschrack.so
schrack/translations/*qm usr/share/nymea/translations/

View File

@ -14,6 +14,7 @@ PLUGIN_DIRS = \
modbuscommander \
mtec \
mypv \
schrack \
sunspec \
unipi \
wallbe \

View File

@ -15,3 +15,5 @@ isEmpty(PLUGIN_PRI) {
# message("Using $$PLUGIN_PRI")
include($$PLUGIN_PRI)
}
top_srcdir=$${PWD}

132
schrack/cion-registers.json Normal file
View File

@ -0,0 +1,132 @@
{
"protocol": "RTU",
"endianness": "BigEndian",
"blocks": [
{
"id": "e3",
"readSchedule": "update",
"registers": [
{
"id": "currentChargingCurrentE3",
"address": 126,
"size": 1,
"type": "uint16",
"registerType": "holdingRegister",
"readSchedule": "update",
"description": "Current charging Ampere",
"unit": "A",
"defaultValue": 6,
"access": "R"
},
{
"id": "maxChargingCurrentE3",
"address": 127,
"size": 1,
"type": "uint16",
"registerType": "holdingRegister",
"readSchedule": "update",
"description": "Maximum charging current of connected cable",
"unit": "A",
"defaultValue": 32,
"access": "R"
}
]
}
],
"registers": [
{
"id": "chargingEnabled",
"address": 100,
"size": 1,
"type": "uint16",
"registerType": "holdingRegister",
"readSchedule": "update",
"description": "Charging enabled",
"defaultValue": 0,
"access": "RW"
},
{
"id": "chargingCurrentSetpoint",
"address": 101,
"size": 1,
"type": "uint16",
"registerType": "holdingRegister",
"readSchedule": "update",
"description": "Allowed charging current",
"unit": "A",
"defaultValue": 6,
"access": "RW"
},
{
"id": "statusBits",
"address": 121,
"size": 1,
"type": "uint16",
"registerType": "holdingRegister",
"readSchedule": "update",
"description": "Maximum charging current",
"defaultValue": 0,
"access": "R"
},
{
"id": "chargingDuration",
"address": 151,
"size": 2,
"type": "uint32",
"registerType": "holdingRegister",
"readSchedule": "update",
"description": "Charging duration",
"unit": "ms",
"defaultValue": 6,
"access": "R"
},
{
"id": "pluggedInDuration",
"address": 153,
"size": 2,
"type": "uint32",
"registerType": "holdingRegister",
"readSchedule": "update",
"description": "Plugged in duration",
"unit": "ms",
"defaultValue": 6,
"access": "R"
},
{
"id": "u1Voltage",
"address": 167,
"size": 1,
"type": "uint16",
"registerType": "holdingRegister",
"readSchedule": "update",
"description": "U1 voltage",
"unit": "V",
"defaultValue": 32,
"access": "R"
},
{
"id": "gridVoltage",
"address": 302,
"size": 1,
"type": "uint16",
"registerType": "holdingRegister",
"readSchedule": "update",
"description": "Voltage of the power supply grid",
"unit": "V",
"defaultValue": 0,
"access": "R"
},
{
"id": "minChargingCurrent",
"address": 507,
"size": 1,
"type": "uint16",
"registerType": "holdingRegister",
"readSchedule": "update",
"description": "Minimum charging current",
"unit": "A",
"defaultValue": 6,
"access": "R"
}
]
}

BIN
schrack/cion-registers.pdf Normal file

Binary file not shown.

View File

@ -0,0 +1,469 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This fileDescriptor 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 "cionmodbusrtuconnection.h"
#include "loggingcategories.h"
NYMEA_LOGGING_CATEGORY(dcCionModbusRtuConnection, "CionModbusRtuConnection")
CionModbusRtuConnection::CionModbusRtuConnection(ModbusRtuMaster *modbusRtuMaster, quint16 slaveId, QObject *parent) :
QObject(parent),
m_modbusRtuMaster(modbusRtuMaster),
m_slaveId(slaveId)
{
}
ModbusRtuMaster *CionModbusRtuConnection::modbusRtuMaster() const
{
return m_modbusRtuMaster;
}
quint16 CionModbusRtuConnection::slaveId() const
{
return m_slaveId;
}
quint16 CionModbusRtuConnection::chargingEnabled() const
{
return m_chargingEnabled;
}
ModbusRtuReply *CionModbusRtuConnection::setChargingEnabled(quint16 chargingEnabled)
{
QVector<quint16> values = ModbusDataUtils::convertFromUInt16(chargingEnabled);
qCDebug(dcCionModbusRtuConnection()) << "--> Write \"Charging enabled\" register:" << 100 << "size:" << 1 << values;
return m_modbusRtuMaster->writeHoldingRegisters(m_slaveId, 100, values);
}
quint16 CionModbusRtuConnection::chargingCurrentSetpoint() const
{
return m_chargingCurrentSetpoint;
}
ModbusRtuReply *CionModbusRtuConnection::setChargingCurrentSetpoint(quint16 chargingCurrentSetpoint)
{
QVector<quint16> values = ModbusDataUtils::convertFromUInt16(chargingCurrentSetpoint);
qCDebug(dcCionModbusRtuConnection()) << "--> Write \"Allowed charging current\" register:" << 101 << "size:" << 1 << values;
return m_modbusRtuMaster->writeHoldingRegisters(m_slaveId, 101, values);
}
quint16 CionModbusRtuConnection::statusBits() const
{
return m_statusBits;
}
quint32 CionModbusRtuConnection::chargingDuration() const
{
return m_chargingDuration;
}
quint32 CionModbusRtuConnection::pluggedInDuration() const
{
return m_pluggedInDuration;
}
quint16 CionModbusRtuConnection::u1Voltage() const
{
return m_u1Voltage;
}
quint16 CionModbusRtuConnection::gridVoltage() const
{
return m_gridVoltage;
}
quint16 CionModbusRtuConnection::minChargingCurrent() const
{
return m_minChargingCurrent;
}
quint16 CionModbusRtuConnection::currentChargingCurrentE3() const
{
return m_currentChargingCurrentE3;
}
quint16 CionModbusRtuConnection::maxChargingCurrentE3() const
{
return m_maxChargingCurrentE3;
}
void CionModbusRtuConnection::initialize()
{
// No init registers defined. Nothing to be done and we are finished.
emit initializationFinished();
}
void CionModbusRtuConnection::update()
{
updateChargingEnabled();
updateChargingCurrentSetpoint();
updateStatusBits();
updateChargingDuration();
updatePluggedInDuration();
updateU1Voltage();
updateGridVoltage();
updateMinChargingCurrent();
updateE3Block();
}
void CionModbusRtuConnection::updateChargingEnabled()
{
// Update registers from Charging enabled
qCDebug(dcCionModbusRtuConnection()) << "--> Read \"Charging enabled\" register:" << 100 << "size:" << 1;
ModbusRtuReply *reply = readChargingEnabled();
if (reply) {
if (!reply->isFinished()) {
connect(reply, &ModbusRtuReply::finished, this, [this, reply](){
if (reply->error() == ModbusRtuReply::NoError) {
QVector<quint16> values = reply->result();
qCDebug(dcCionModbusRtuConnection()) << "<-- Response from \"Charging enabled\" register" << 100 << "size:" << 1 << values;
quint16 receivedChargingEnabled = ModbusDataUtils::convertToUInt16(values);
if (m_chargingEnabled != receivedChargingEnabled) {
m_chargingEnabled = receivedChargingEnabled;
emit chargingEnabledChanged(m_chargingEnabled);
}
}
});
connect(reply, &ModbusRtuReply::errorOccurred, this, [reply] (ModbusRtuReply::Error error){
qCWarning(dcCionModbusRtuConnection()) << "ModbusRtu reply error occurred while updating \"Charging enabled\" registers" << error << reply->errorString();
emit reply->finished();
});
}
} else {
qCWarning(dcCionModbusRtuConnection()) << "Error occurred while reading \"Charging enabled\" registers";
}
}
void CionModbusRtuConnection::updateChargingCurrentSetpoint()
{
// Update registers from Allowed charging current
qCDebug(dcCionModbusRtuConnection()) << "--> Read \"Allowed charging current\" register:" << 101 << "size:" << 1;
ModbusRtuReply *reply = readChargingCurrentSetpoint();
if (reply) {
if (!reply->isFinished()) {
connect(reply, &ModbusRtuReply::finished, this, [this, reply](){
if (reply->error() == ModbusRtuReply::NoError) {
QVector<quint16> values = reply->result();
qCDebug(dcCionModbusRtuConnection()) << "<-- Response from \"Allowed charging current\" register" << 101 << "size:" << 1 << values;
quint16 receivedChargingCurrentSetpoint = ModbusDataUtils::convertToUInt16(values);
if (m_chargingCurrentSetpoint != receivedChargingCurrentSetpoint) {
m_chargingCurrentSetpoint = receivedChargingCurrentSetpoint;
emit chargingCurrentSetpointChanged(m_chargingCurrentSetpoint);
}
}
});
connect(reply, &ModbusRtuReply::errorOccurred, this, [reply] (ModbusRtuReply::Error error){
qCWarning(dcCionModbusRtuConnection()) << "ModbusRtu reply error occurred while updating \"Allowed charging current\" registers" << error << reply->errorString();
emit reply->finished();
});
}
} else {
qCWarning(dcCionModbusRtuConnection()) << "Error occurred while reading \"Allowed charging current\" registers";
}
}
void CionModbusRtuConnection::updateStatusBits()
{
// Update registers from Maximum charging current
qCDebug(dcCionModbusRtuConnection()) << "--> Read \"Maximum charging current\" register:" << 121 << "size:" << 1;
ModbusRtuReply *reply = readStatusBits();
if (reply) {
if (!reply->isFinished()) {
connect(reply, &ModbusRtuReply::finished, this, [this, reply](){
if (reply->error() == ModbusRtuReply::NoError) {
QVector<quint16> values = reply->result();
qCDebug(dcCionModbusRtuConnection()) << "<-- Response from \"Maximum charging current\" register" << 121 << "size:" << 1 << values;
quint16 receivedStatusBits = ModbusDataUtils::convertToUInt16(values);
if (m_statusBits != receivedStatusBits) {
m_statusBits = receivedStatusBits;
emit statusBitsChanged(m_statusBits);
}
}
});
connect(reply, &ModbusRtuReply::errorOccurred, this, [reply] (ModbusRtuReply::Error error){
qCWarning(dcCionModbusRtuConnection()) << "ModbusRtu reply error occurred while updating \"Maximum charging current\" registers" << error << reply->errorString();
emit reply->finished();
});
}
} else {
qCWarning(dcCionModbusRtuConnection()) << "Error occurred while reading \"Maximum charging current\" registers";
}
}
void CionModbusRtuConnection::updateChargingDuration()
{
// Update registers from Charging duration
qCDebug(dcCionModbusRtuConnection()) << "--> Read \"Charging duration\" register:" << 151 << "size:" << 2;
ModbusRtuReply *reply = readChargingDuration();
if (reply) {
if (!reply->isFinished()) {
connect(reply, &ModbusRtuReply::finished, this, [this, reply](){
if (reply->error() == ModbusRtuReply::NoError) {
QVector<quint16> values = reply->result();
qCDebug(dcCionModbusRtuConnection()) << "<-- Response from \"Charging duration\" register" << 151 << "size:" << 2 << values;
quint32 receivedChargingDuration = ModbusDataUtils::convertToUInt32(values, ModbusDataUtils::ByteOrderBigEndian);
if (m_chargingDuration != receivedChargingDuration) {
m_chargingDuration = receivedChargingDuration;
emit chargingDurationChanged(m_chargingDuration);
}
}
});
connect(reply, &ModbusRtuReply::errorOccurred, this, [reply] (ModbusRtuReply::Error error){
qCWarning(dcCionModbusRtuConnection()) << "ModbusRtu reply error occurred while updating \"Charging duration\" registers" << error << reply->errorString();
emit reply->finished();
});
}
} else {
qCWarning(dcCionModbusRtuConnection()) << "Error occurred while reading \"Charging duration\" registers";
}
}
void CionModbusRtuConnection::updatePluggedInDuration()
{
// Update registers from Plugged in duration
qCDebug(dcCionModbusRtuConnection()) << "--> Read \"Plugged in duration\" register:" << 153 << "size:" << 2;
ModbusRtuReply *reply = readPluggedInDuration();
if (reply) {
if (!reply->isFinished()) {
connect(reply, &ModbusRtuReply::finished, this, [this, reply](){
if (reply->error() == ModbusRtuReply::NoError) {
QVector<quint16> values = reply->result();
qCDebug(dcCionModbusRtuConnection()) << "<-- Response from \"Plugged in duration\" register" << 153 << "size:" << 2 << values;
quint32 receivedPluggedInDuration = ModbusDataUtils::convertToUInt32(values, ModbusDataUtils::ByteOrderBigEndian);
if (m_pluggedInDuration != receivedPluggedInDuration) {
m_pluggedInDuration = receivedPluggedInDuration;
emit pluggedInDurationChanged(m_pluggedInDuration);
}
}
});
connect(reply, &ModbusRtuReply::errorOccurred, this, [reply] (ModbusRtuReply::Error error){
qCWarning(dcCionModbusRtuConnection()) << "ModbusRtu reply error occurred while updating \"Plugged in duration\" registers" << error << reply->errorString();
emit reply->finished();
});
}
} else {
qCWarning(dcCionModbusRtuConnection()) << "Error occurred while reading \"Plugged in duration\" registers";
}
}
void CionModbusRtuConnection::updateU1Voltage()
{
// Update registers from U1 voltage
qCDebug(dcCionModbusRtuConnection()) << "--> Read \"U1 voltage\" register:" << 167 << "size:" << 1;
ModbusRtuReply *reply = readU1Voltage();
if (reply) {
if (!reply->isFinished()) {
connect(reply, &ModbusRtuReply::finished, this, [this, reply](){
if (reply->error() == ModbusRtuReply::NoError) {
QVector<quint16> values = reply->result();
qCDebug(dcCionModbusRtuConnection()) << "<-- Response from \"U1 voltage\" register" << 167 << "size:" << 1 << values;
quint16 receivedU1Voltage = ModbusDataUtils::convertToUInt16(values);
if (m_u1Voltage != receivedU1Voltage) {
m_u1Voltage = receivedU1Voltage;
emit u1VoltageChanged(m_u1Voltage);
}
}
});
connect(reply, &ModbusRtuReply::errorOccurred, this, [reply] (ModbusRtuReply::Error error){
qCWarning(dcCionModbusRtuConnection()) << "ModbusRtu reply error occurred while updating \"U1 voltage\" registers" << error << reply->errorString();
emit reply->finished();
});
}
} else {
qCWarning(dcCionModbusRtuConnection()) << "Error occurred while reading \"U1 voltage\" registers";
}
}
void CionModbusRtuConnection::updateGridVoltage()
{
// Update registers from Voltage of the power supply grid
qCDebug(dcCionModbusRtuConnection()) << "--> Read \"Voltage of the power supply grid\" register:" << 302 << "size:" << 1;
ModbusRtuReply *reply = readGridVoltage();
if (reply) {
if (!reply->isFinished()) {
connect(reply, &ModbusRtuReply::finished, this, [this, reply](){
if (reply->error() == ModbusRtuReply::NoError) {
QVector<quint16> values = reply->result();
qCDebug(dcCionModbusRtuConnection()) << "<-- Response from \"Voltage of the power supply grid\" register" << 302 << "size:" << 1 << values;
quint16 receivedGridVoltage = ModbusDataUtils::convertToUInt16(values);
if (m_gridVoltage != receivedGridVoltage) {
m_gridVoltage = receivedGridVoltage;
emit gridVoltageChanged(m_gridVoltage);
}
}
});
connect(reply, &ModbusRtuReply::errorOccurred, this, [reply] (ModbusRtuReply::Error error){
qCWarning(dcCionModbusRtuConnection()) << "ModbusRtu reply error occurred while updating \"Voltage of the power supply grid\" registers" << error << reply->errorString();
emit reply->finished();
});
}
} else {
qCWarning(dcCionModbusRtuConnection()) << "Error occurred while reading \"Voltage of the power supply grid\" registers";
}
}
void CionModbusRtuConnection::updateMinChargingCurrent()
{
// Update registers from Minimum charging current
qCDebug(dcCionModbusRtuConnection()) << "--> Read \"Minimum charging current\" register:" << 507 << "size:" << 1;
ModbusRtuReply *reply = readMinChargingCurrent();
if (reply) {
if (!reply->isFinished()) {
connect(reply, &ModbusRtuReply::finished, this, [this, reply](){
if (reply->error() == ModbusRtuReply::NoError) {
QVector<quint16> values = reply->result();
qCDebug(dcCionModbusRtuConnection()) << "<-- Response from \"Minimum charging current\" register" << 507 << "size:" << 1 << values;
quint16 receivedMinChargingCurrent = ModbusDataUtils::convertToUInt16(values);
if (m_minChargingCurrent != receivedMinChargingCurrent) {
m_minChargingCurrent = receivedMinChargingCurrent;
emit minChargingCurrentChanged(m_minChargingCurrent);
}
}
});
connect(reply, &ModbusRtuReply::errorOccurred, this, [reply] (ModbusRtuReply::Error error){
qCWarning(dcCionModbusRtuConnection()) << "ModbusRtu reply error occurred while updating \"Minimum charging current\" registers" << error << reply->errorString();
emit reply->finished();
});
}
} else {
qCWarning(dcCionModbusRtuConnection()) << "Error occurred while reading \"Minimum charging current\" registers";
}
}
void CionModbusRtuConnection::updateE3Block()
{
// Update register block "e3"
qCDebug(dcCionModbusRtuConnection()) << "--> Read block \"e3\" registers from:" << 126 << "size:" << 2;
ModbusRtuReply *reply = m_modbusRtuMaster->readHoldingRegister(m_slaveId, 126, 2);
if (reply) {
if (!reply->isFinished()) {
connect(reply, &ModbusRtuReply::finished, this, [this, reply](){
if (reply->error() == ModbusRtuReply::NoError) {
QVector<quint16> blockValues = reply->result();
QVector<quint16> values;
qCDebug(dcCionModbusRtuConnection()) << "<-- Response from reading block \"e3\" register" << 126 << "size:" << 2 << blockValues;
values = blockValues.mid(0, 1);
quint16 receivedCurrentChargingCurrentE3 = ModbusDataUtils::convertToUInt16(values);
if (m_currentChargingCurrentE3 != receivedCurrentChargingCurrentE3) {
m_currentChargingCurrentE3 = receivedCurrentChargingCurrentE3;
emit currentChargingCurrentE3Changed(m_currentChargingCurrentE3);
}
values = blockValues.mid(1, 1);
quint16 receivedMaxChargingCurrentE3 = ModbusDataUtils::convertToUInt16(values);
if (m_maxChargingCurrentE3 != receivedMaxChargingCurrentE3) {
m_maxChargingCurrentE3 = receivedMaxChargingCurrentE3;
emit maxChargingCurrentE3Changed(m_maxChargingCurrentE3);
}
}
});
connect(reply, &ModbusRtuReply::errorOccurred, this, [reply] (ModbusRtuReply::Error error){
qCWarning(dcCionModbusRtuConnection()) << "ModbusRtu reply error occurred while updating block \"e3\" registers" << error << reply->errorString();
emit reply->finished();
});
}
} else {
qCWarning(dcCionModbusRtuConnection()) << "Error occurred while reading block \"e3\" registers";
}
}
ModbusRtuReply *CionModbusRtuConnection::readChargingEnabled()
{
return m_modbusRtuMaster->readHoldingRegister(m_slaveId, 100, 1);
}
ModbusRtuReply *CionModbusRtuConnection::readChargingCurrentSetpoint()
{
return m_modbusRtuMaster->readHoldingRegister(m_slaveId, 101, 1);
}
ModbusRtuReply *CionModbusRtuConnection::readStatusBits()
{
return m_modbusRtuMaster->readHoldingRegister(m_slaveId, 121, 1);
}
ModbusRtuReply *CionModbusRtuConnection::readChargingDuration()
{
return m_modbusRtuMaster->readHoldingRegister(m_slaveId, 151, 2);
}
ModbusRtuReply *CionModbusRtuConnection::readPluggedInDuration()
{
return m_modbusRtuMaster->readHoldingRegister(m_slaveId, 153, 2);
}
ModbusRtuReply *CionModbusRtuConnection::readU1Voltage()
{
return m_modbusRtuMaster->readHoldingRegister(m_slaveId, 167, 1);
}
ModbusRtuReply *CionModbusRtuConnection::readGridVoltage()
{
return m_modbusRtuMaster->readHoldingRegister(m_slaveId, 302, 1);
}
ModbusRtuReply *CionModbusRtuConnection::readMinChargingCurrent()
{
return m_modbusRtuMaster->readHoldingRegister(m_slaveId, 507, 1);
}
void CionModbusRtuConnection::verifyInitFinished()
{
if (m_pendingInitReplies.isEmpty()) {
qCDebug(dcCionModbusRtuConnection()) << "Initialization finished of CionModbusRtuConnection";
emit initializationFinished();
}
}
QDebug operator<<(QDebug debug, CionModbusRtuConnection *cionModbusRtuConnection)
{
debug.nospace().noquote() << "CionModbusRtuConnection(" << cionModbusRtuConnection->modbusRtuMaster()->modbusUuid().toString() << ", " << cionModbusRtuConnection->modbusRtuMaster()->serialPort() << ", slave ID:" << cionModbusRtuConnection->slaveId() << ")" << "\n";
debug.nospace().noquote() << " - Charging enabled:" << cionModbusRtuConnection->chargingEnabled() << "\n";
debug.nospace().noquote() << " - Allowed charging current:" << cionModbusRtuConnection->chargingCurrentSetpoint() << " [A]" << "\n";
debug.nospace().noquote() << " - Maximum charging current:" << cionModbusRtuConnection->statusBits() << "\n";
debug.nospace().noquote() << " - Charging duration:" << cionModbusRtuConnection->chargingDuration() << " [ms]" << "\n";
debug.nospace().noquote() << " - Plugged in duration:" << cionModbusRtuConnection->pluggedInDuration() << " [ms]" << "\n";
debug.nospace().noquote() << " - U1 voltage:" << cionModbusRtuConnection->u1Voltage() << " [V]" << "\n";
debug.nospace().noquote() << " - Voltage of the power supply grid:" << cionModbusRtuConnection->gridVoltage() << " [V]" << "\n";
debug.nospace().noquote() << " - Minimum charging current:" << cionModbusRtuConnection->minChargingCurrent() << " [A]" << "\n";
debug.nospace().noquote() << " - Current charging Ampere:" << cionModbusRtuConnection->currentChargingCurrentE3() << " [A]" << "\n";
debug.nospace().noquote() << " - Maximum charging current of connected cable:" << cionModbusRtuConnection->maxChargingCurrentE3() << " [A]" << "\n";
return debug.quote().space();
}

View File

@ -0,0 +1,160 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2022, nymea GmbH
* Contact: contact@nymea.io
*
* This fileDescriptor 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 CIONMODBUSRTUCONNECTION_H
#define CIONMODBUSRTUCONNECTION_H
#include <QObject>
#include "../modbus/modbusdatautils.h"
#include <hardware/modbus/modbusrtumaster.h>
class CionModbusRtuConnection : public QObject
{
Q_OBJECT
public:
enum Registers {
RegisterChargingEnabled = 100,
RegisterChargingCurrentSetpoint = 101,
RegisterStatusBits = 121,
RegisterCurrentChargingCurrentE3 = 126,
RegisterMaxChargingCurrentE3 = 127,
RegisterChargingDuration = 151,
RegisterPluggedInDuration = 153,
RegisterU1Voltage = 167,
RegisterGridVoltage = 302,
RegisterMinChargingCurrent = 507
};
Q_ENUM(Registers)
explicit CionModbusRtuConnection(ModbusRtuMaster *modbusRtuMaster, quint16 slaveId, QObject *parent = nullptr);
~CionModbusRtuConnection() = default;
ModbusRtuMaster *modbusRtuMaster() const;
quint16 slaveId() const;
/* Charging enabled - Address: 100, Size: 1 */
quint16 chargingEnabled() const;
ModbusRtuReply *setChargingEnabled(quint16 chargingEnabled);
/* Allowed charging current [A] - Address: 101, Size: 1 */
quint16 chargingCurrentSetpoint() const;
ModbusRtuReply *setChargingCurrentSetpoint(quint16 chargingCurrentSetpoint);
/* Maximum charging current - Address: 121, Size: 1 */
quint16 statusBits() const;
/* Charging duration [ms] - Address: 151, Size: 2 */
quint32 chargingDuration() const;
/* Plugged in duration [ms] - Address: 153, Size: 2 */
quint32 pluggedInDuration() const;
/* U1 voltage [V] - Address: 167, Size: 1 */
quint16 u1Voltage() const;
/* Voltage of the power supply grid [V] - Address: 302, Size: 1 */
quint16 gridVoltage() const;
/* Minimum charging current [A] - Address: 507, Size: 1 */
quint16 minChargingCurrent() const;
/* Current charging Ampere [A] - Address: 126, Size: 1 */
quint16 currentChargingCurrentE3() const;
/* Maximum charging current of connected cable [A] - Address: 127, Size: 1 */
quint16 maxChargingCurrentE3() const;
/* Read block from start addess 126 with size of 2 registers containing following 2 properties:
- Current charging Ampere [A] - Address: 126, Size: 1
- Maximum charging current of connected cable [A] - Address: 127, Size: 1
*/
void updateE3Block();
void updateChargingEnabled();
void updateChargingCurrentSetpoint();
void updateStatusBits();
void updateChargingDuration();
void updatePluggedInDuration();
void updateU1Voltage();
void updateGridVoltage();
void updateMinChargingCurrent();
virtual void initialize();
virtual void update();
signals:
void initializationFinished();
void chargingEnabledChanged(quint16 chargingEnabled);
void chargingCurrentSetpointChanged(quint16 chargingCurrentSetpoint);
void statusBitsChanged(quint16 statusBits);
void chargingDurationChanged(quint32 chargingDuration);
void pluggedInDurationChanged(quint32 pluggedInDuration);
void u1VoltageChanged(quint16 u1Voltage);
void gridVoltageChanged(quint16 gridVoltage);
void minChargingCurrentChanged(quint16 minChargingCurrent);
void currentChargingCurrentE3Changed(quint16 currentChargingCurrentE3);
void maxChargingCurrentE3Changed(quint16 maxChargingCurrentE3);
protected:
ModbusRtuReply *readChargingEnabled();
ModbusRtuReply *readChargingCurrentSetpoint();
ModbusRtuReply *readStatusBits();
ModbusRtuReply *readChargingDuration();
ModbusRtuReply *readPluggedInDuration();
ModbusRtuReply *readU1Voltage();
ModbusRtuReply *readGridVoltage();
ModbusRtuReply *readMinChargingCurrent();
quint16 m_chargingEnabled = 0;
quint16 m_chargingCurrentSetpoint = 6;
quint16 m_statusBits = 0;
quint32 m_chargingDuration = 6;
quint32 m_pluggedInDuration = 6;
quint16 m_u1Voltage = 32;
quint16 m_gridVoltage = 0;
quint16 m_minChargingCurrent = 6;
quint16 m_currentChargingCurrentE3 = 6;
quint16 m_maxChargingCurrentE3 = 32;
private:
ModbusRtuMaster *m_modbusRtuMaster = nullptr;
quint16 m_slaveId = 1;
QVector<ModbusRtuReply *> m_pendingInitReplies;
void verifyInitFinished();
};
QDebug operator<<(QDebug debug, CionModbusRtuConnection *cionModbusRtuConnection);
#endif // CIONMODBUSRTUCONNECTION_H

View File

@ -0,0 +1,291 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, 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 "integrationpluginschrack.h"
#include "plugininfo.h"
IntegrationPluginSchrack::IntegrationPluginSchrack()
{
}
void IntegrationPluginSchrack::init()
{
// connect(hardwareManager()->modbusRtuResource(), &ModbusRtuHardwareResource::modbusRtuMasterRemoved, this, [=] (const QUuid &modbusUuid){
// qCDebug(dcEnergyMeters()) << "Modbus RTU master has been removed" << modbusUuid.toString();
// foreach (Thing *thing, myThings()) {
// if (m_modbusUuidParamTypeIds.contains(thing->thingClassId())) {
// if (thing->paramValue(m_modbusUuidParamTypeIds.value(thing->thingClassId())) == modbusUuid) {
// qCWarning(dcEnergyMeters()) << "Modbus RTU hardware resource removed for" << thing << ". The thing will not be functional any more until a new resource has been configured for it.";
// thing->setStateValue(m_connectionStateTypeIds[thing->thingClassId()], false);
// if (thing->thingClassId() == sdm630ThingClassId) {
// delete m_sdmConnections.take(thing);
// } else if (thing->thingClassId() == pro380ThingClassId) {
// delete m_ineproConnections.take(thing);
// }
// }
// }
// }
// });
}
void IntegrationPluginSchrack::discoverThings(ThingDiscoveryInfo *info)
{
qCDebug(dcSchrack()) << "Discovering modbus RTU resources...";
if (hardwareManager()->modbusRtuResource()->modbusRtuMasters().isEmpty()) {
info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("No Modbus RTU interface available. Please set up a Modbus RTU interface first."));
return;
}
uint slaveAddress = info->params().paramValue(cionDiscoverySlaveAddressParamTypeId).toUInt();
if (slaveAddress > 254 || slaveAddress == 0) {
info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("The Modbus slave address must be a value between 1 and 254."));
return;
}
foreach (ModbusRtuMaster *modbusMaster, hardwareManager()->modbusRtuResource()->modbusRtuMasters()) {
qCDebug(dcSchrack()) << "Found RTU master resource" << modbusMaster << "connected" << modbusMaster->connected();
if (!modbusMaster->connected())
continue;
ThingDescriptor descriptor(info->thingClassId(), "i-CHARGE CION", QString::number(slaveAddress) + " " + modbusMaster->serialPort());
ParamList params;
params << Param(cionThingSlaveAddressParamTypeId, slaveAddress);
params << Param(cionThingModbusMasterUuidParamTypeId, modbusMaster->modbusUuid());
descriptor.setParams(params);
info->addThingDescriptor(descriptor);
}
info->finish(Thing::ThingErrorNoError);
}
void IntegrationPluginSchrack::setupThing(ThingSetupInfo *info)
{
Thing *thing = info->thing();
qCDebug(dcSchrack()) << "Setup thing" << thing << thing->params();
uint address = thing->paramValue(cionThingSlaveAddressParamTypeId).toUInt();
if (address > 254 || address == 0) {
qCWarning(dcSchrack()) << "Setup failed, slave address is not valid" << address;
info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("The Modbus address not valid. It must be a value between 1 and 254."));
return;
}
QUuid uuid = thing->paramValue(cionThingModbusMasterUuidParamTypeId).toUuid();
if (!hardwareManager()->modbusRtuResource()->hasModbusRtuMaster(uuid)) {
qCWarning(dcSchrack()) << "Setup failed, hardware manager not available";
info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("The Modbus RTU resource is not available."));
return;
}
if (m_cionConnections.contains(thing)) {
qCDebug(dcSchrack()) << "Already have a CION connection for this thing. Cleaning up old connection and initializing new one...";
delete m_cionConnections.take(thing);
}
CionModbusRtuConnection *cionConnection = new CionModbusRtuConnection(hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), address, this);
connect(cionConnection->modbusRtuMaster(), &ModbusRtuMaster::connectedChanged, thing, [=](bool connected){
if (connected) {
qCDebug(dcSchrack()) << "Modbus RTU resource connected" << thing << cionConnection->modbusRtuMaster()->serialPort();
} else {
qCWarning(dcSchrack()) << "Modbus RTU resource disconnected" << thing << cionConnection->modbusRtuMaster()->serialPort();
}
});
connect(cionConnection, &CionModbusRtuConnection::chargingEnabledChanged, thing, [=](quint16 charging){
qCDebug(dcSchrack()) << "Charging enabled changed:" << charging;
thing->setStateValue(cionPowerStateTypeId, charging == 1);
thing->setStateValue(cionConnectedStateTypeId, true);
finishAction(cionPowerStateTypeId);
});
// We can write chargingCurrentSetpoint to the preferred charging we want, and the wallbox will take it,
// however, it may not necessarily *do* it, but will give us the actual value it uses in currentChargingCurrentE3
// We'll use that for setting our state, just monitoring this one on the logs
connect(cionConnection, &CionModbusRtuConnection::chargingCurrentSetpointChanged, thing, [=](quint16 chargingCurrentSetpoint){
qCDebug(dcSchrack()) << "Charging current setpoint changed:" << chargingCurrentSetpoint;
// thing->setStateValue(cionMaxChargingCurrentStateTypeId, chargingCurrentSetpoint);
// thing->setStateValue(cionConnectedStateTypeId, true);
// finishAction(cionMaxChargingCurrentStateTypeId);
});
//
connect(cionConnection, &CionModbusRtuConnection::currentChargingCurrentE3Changed, thing, [=](quint16 currentChargingCurrentE3){
qCDebug(dcSchrack()) << "Current charging current E3 current changed:" << currentChargingCurrentE3;
thing->setStateValue(cionMaxChargingCurrentStateTypeId, currentChargingCurrentE3);
thing->setStateValue(cionConnectedStateTypeId, true);
finishAction(cionMaxChargingCurrentStateTypeId);
});
// The maxChargingCurrentE3 takes into account the DIP switches and connected cable, so this is effectively
// our maximum. However, it will go to 0 when unplugged, which is odd, so we'll ignore 0 values.
connect(cionConnection, &CionModbusRtuConnection::maxChargingCurrentE3Changed, thing, [=](quint16 maxChargingCurrentE3){
qCDebug(dcSchrack()) << "Maximum charging current E3 current changed:" << maxChargingCurrentE3;
if (maxChargingCurrentE3 != 0) {
thing->setStateMaxValue(cionMaxChargingCurrentStateTypeId, maxChargingCurrentE3);
thing->setStateValue(cionConnectedStateTypeId, true);
}
});
connect(cionConnection, &CionModbusRtuConnection::statusBitsChanged, thing, [=](quint16 statusBits){
qCDebug(dcSchrack()) << "Status bits changed:" << statusBits;
thing->setStateValue(cionConnectedStateTypeId, true);
});
connect(cionConnection, &CionModbusRtuConnection::minChargingCurrentChanged, thing, [=](quint16 minChargingCurrent){
qCDebug(dcSchrack()) << "Minimum charging current changed:" << minChargingCurrent;
thing->setStateMinValue(cionMaxChargingCurrentStateTypeId, minChargingCurrent);
thing->setStateValue(cionConnectedStateTypeId, true);
});
connect(cionConnection, &CionModbusRtuConnection::gridVoltageChanged, thing, [=](quint16 gridVoltage){
qCDebug(dcSchrack()) << "Grid voltage changed:" << 1.0 * gridVoltage / 100;
thing->setStateValue(cionConnectedStateTypeId, true);
// updateCurrentPower(thing);
});
connect(cionConnection, &CionModbusRtuConnection::u1VoltageChanged, thing, [=](quint16 gridVoltage){
qCDebug(dcSchrack()) << "U1 voltage changed:" << 1.0 * gridVoltage / 100;
thing->setStateValue(cionConnectedStateTypeId, true);
updateCurrentPower(thing);
});
connect(cionConnection, &CionModbusRtuConnection::pluggedInDurationChanged, thing, [=](quint32 pluggedInDuration){
qCDebug(dcSchrack()) << "Plugged in duration changed:" << pluggedInDuration;
thing->setStateValue(cionPluggedInStateTypeId, pluggedInDuration > 0);
thing->setStateValue(cionConnectedStateTypeId, true);
});
connect(cionConnection, &CionModbusRtuConnection::chargingDurationChanged, thing, [=](quint32 chargingDuration){
qCDebug(dcSchrack()) << "Charging duration changed:" << chargingDuration;
thing->setStateValue(cionChargingStateTypeId, chargingDuration > 0);
thing->setStateValue(cionConnectedStateTypeId, true);
});
cionConnection->update();
// Initialize min/max to their defaults. If both, nymea and the wallbox are restarted simultaneously, nymea would cache the min/max while
// the wallbox would revert to its defaults, and being the default, the modbusconnection also never emits "changed" signals for them.
// To prevent running out of sync we'll "uncache" min/max values too.
thing->setStateMinMaxValues(cionMaxChargingCurrentStateTypeId, 6, 32);
m_cionConnections.insert(thing, cionConnection);
info->finish(Thing::ThingErrorNoError);
}
void IntegrationPluginSchrack::postSetupThing(Thing *thing)
{
qCDebug(dcSchrack()) << "Post setup thing" << thing->name();
if (!m_refreshTimer) {
m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(2);
connect(m_refreshTimer, &PluginTimer::timeout, this, [this] {
foreach (Thing *thing, myThings()) {
m_cionConnections.value(thing)->update();
}
});
qCDebug(dcSchrack()) << "Starting refresh timer...";
m_refreshTimer->start();
}
}
void IntegrationPluginSchrack::thingRemoved(Thing *thing)
{
qCDebug(dcSchrack()) << "Thing removed" << thing->name();
if (m_cionConnections.contains(thing))
m_cionConnections.take(thing)->deleteLater();
if (myThings().isEmpty() && m_refreshTimer) {
qCDebug(dcSchrack()) << "Stopping reconnect timer";
hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer);
m_refreshTimer = nullptr;
}
}
void IntegrationPluginSchrack::executeAction(ThingActionInfo *info)
{
CionModbusRtuConnection *cionConnection = m_cionConnections.value(info->thing());
if (info->action().actionTypeId() == cionPowerActionTypeId) {
ModbusRtuReply *reply = cionConnection->setChargingEnabled(info->action().paramValue(cionPowerActionPowerParamTypeId).toBool() ? 1 : 0);
waitForActionFinish(info, reply, cionPowerStateTypeId);
} else if (info->action().actionTypeId() == cionMaxChargingCurrentActionTypeId) {
ModbusRtuReply *reply = cionConnection->setChargingCurrentSetpoint(info->action().paramValue(cionMaxChargingCurrentActionMaxChargingCurrentParamTypeId).toUInt());
waitForActionFinish(info, reply, cionMaxChargingCurrentStateTypeId);
}
Q_ASSERT_X(false, "IntegrationPluginSchrack::executeAction", QString("Unhandled action: %1").arg(info->action().actionTypeId().toString()).toLocal8Bit());
}
void IntegrationPluginSchrack::waitForActionFinish(ThingActionInfo *info, ModbusRtuReply *reply, const StateTypeId &stateTypeId)
{
m_pendingActions.insert(info, stateTypeId);
connect(info, &ThingActionInfo::destroyed, this, [=](){
m_pendingActions.remove(info);
});
connect(reply, &ModbusRtuReply::finished, info, [=](){
if (reply->error() != ModbusRtuReply::NoError) {
info->finish(Thing::ThingErrorHardwareFailure);
}
});
}
void IntegrationPluginSchrack::finishAction(const StateTypeId &stateTypeId)
{
foreach (ThingActionInfo *info, m_pendingActions.keys(stateTypeId)) {
info->finish(Thing::ThingErrorNoError);
}
}
void IntegrationPluginSchrack::updateCurrentPower(Thing *thing)
{
CionModbusRtuConnection *cionConnection = m_cionConnections.value(thing);
QDateTime lastUpdate = thing->property("lastUpdate").toDateTime();
QDateTime now = QDateTime::currentDateTime();
if (lastUpdate.isValid()) {
double lastCurrentPower = thing->stateValue(cionCurrentPowerStateTypeId).toDouble();
double lastTotal = thing->stateValue(cionTotalEnergyConsumedStateTypeId).toDouble();
qlonglong msecsSinceLast = lastUpdate.msecsTo(now);
double wattMs = lastCurrentPower * msecsSinceLast;
double kWh = wattMs / 60 / 60;
thing->setStateValue(cionTotalEnergyConsumedStateTypeId, lastTotal + kWh);
}
thing->setProperty("lastUpdate", now);
if (cionConnection->chargingDuration() > 0) {
thing->setStateValue(cionCurrentPowerStateTypeId, 1.0 * cionConnection->u1Voltage() / 100 * cionConnection->currentChargingCurrentE3());
} else {
thing->setStateValue(cionCurrentPowerStateTypeId, 0);
}
}

View File

@ -0,0 +1,73 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, 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 INTEGRATIONPLUGINSCHRACK_H
#define INTEGRATIONPLUGINSCHRACK_H
#include <integrations/integrationplugin.h>
#include <hardware/modbus/modbusrtuhardwareresource.h>
#include <plugintimer.h>
#include "cionmodbusrtuconnection.h"
#include "extern-plugininfo.h"
#include <QObject>
#include <QTimer>
class IntegrationPluginSchrack : public IntegrationPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginschrack.json")
Q_INTERFACES(IntegrationPlugin)
public:
explicit IntegrationPluginSchrack();
void init() override;
void discoverThings(ThingDiscoveryInfo *info) override;
void setupThing(ThingSetupInfo *info) override;
void postSetupThing(Thing *thing) override;
void thingRemoved(Thing *thing) override;
void executeAction(ThingActionInfo *info) override;
private:
void waitForActionFinish(ThingActionInfo *info, ModbusRtuReply *reply, const StateTypeId &stateTypeId);
void finishAction(const StateTypeId &stateTypeId);
void updateCurrentPower(Thing *thing);
private:
PluginTimer *m_refreshTimer = nullptr;
QHash<Thing *, CionModbusRtuConnection *> m_cionConnections;
QHash<ThingActionInfo*, StateTypeId> m_pendingActions;
};
#endif // INTEGRATIONPLUGINSCHRACK_H

View File

@ -0,0 +1,116 @@
{
"name": "schrack",
"displayName": "Schrack",
"id": "600beeb5-5c34-49fc-b2af-8f83c1b11eab",
"paramTypes":[ ],
"vendors": [
{
"name": "schrack",
"displayName": "Schrack GmbH",
"id": "cadbbbc5-216f-4d25-a8ad-ccf653d1518f",
"thingClasses": [
{
"name": "cion",
"displayName": "i-CHARGE CION",
"id": "075d389d-3330-4d0b-9649-9f085120ca40",
"createMethods": ["discovery"],
"interfaces": ["evcharger", "connectable"],
"discoveryParamTypes": [
{
"id": "8004705f-0e13-4713-b75e-49d115cd9517",
"name": "slaveAddress",
"displayName": "Slave address",
"type": "int",
"defaultValue": 1
}
],
"paramTypes": [
{
"id": "dac10e08-734c-4e71-a5d6-0d2a1f416ca6",
"name": "slaveAddress",
"displayName": "Modbus slave address",
"type": "uint",
"defaultValue": 1
},
{
"id": "636241a9-4838-48ae-bcc8-3427ac3fc102",
"name": "modbusMasterUuid",
"displayName": "Modbus RTU master",
"type": "QUuid",
"defaultValue": "",
"readOnly": true
}
],
"stateTypes": [
{
"id": "b7aa8e49-a6c0-4b48-b65e-47259686185f",
"name": "connected",
"displayName": "Connected",
"displayNameEvent": "Connected changed",
"type": "bool",
"cached": false,
"defaultValue": false
},
{
"id": "61aea53a-bf8d-4fe6-859a-f1687e15d190",
"name": "power",
"displayName": "Charging enabled",
"displayNameEvent": "Charging enabled or disabled",
"displayNameAction": "Enable or disable charging",
"type": "bool",
"defaultValue": false,
"writable": true
},
{
"id": "221af869-a796-46c2-a5e0-27c8972a0bf2",
"name": "maxChargingCurrent",
"displayName": "Maximum charging current",
"displayNameEvent": "Maximum charging current changed",
"displayNameAction": "Set maximum charging current",
"type": "uint",
"unit": "Ampere",
"defaultValue": 6,
"minValue": 1,
"maxValue": 32,
"writable": true
},
{
"id": "db5c951f-47e0-4cdc-8b8b-285f7ed95285",
"name": "currentPower",
"displayName": "Current power consumption",
"displayNameEvent": "Current power consumption changed",
"type": "double",
"unit": "Watt",
"defaultValue": 0
},
{
"id": "8390c005-a8ba-4db6-bb94-8f765ddcc784",
"name": "totalEnergyConsumed",
"displayName": "Total consumed energy",
"displayNameEvent": "Total consumed energy changed",
"type": "double",
"unit": "KiloWattHour",
"defaultValue": 0
},
{
"id": "13423618-4314-49be-b48c-42d9415199a8",
"name": "pluggedIn",
"displayName": "Plugged in",
"displayNameEvent": "Plugged or unplugged",
"type": "bool",
"defaultValue": false
},
{
"id": "b59b4b4d-2cdb-4534-bf86-90123ae9bb1a",
"name": "charging",
"displayName": "Charging",
"displayNameEvent": "Charging started or stopped",
"type": "bool",
"defaultValue": false
}
]
}
]
}
]
}

13
schrack/meta.json Normal file
View File

@ -0,0 +1,13 @@
{
"title": "Schrack",
"tagline": "Integrate the Schrack i-CHARGE CION wallbox with nymea.",
"icon": "schrack.jpg",
"stability": "consumer",
"offline": true,
"technologies": [
"modbus"
],
"categories": [
"energy"
]
}

BIN
schrack/schrack.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

20
schrack/schrack.pro Normal file
View File

@ -0,0 +1,20 @@
include(../plugins.pri)
QT += serialport serialbus
SOURCES += \
integrationpluginschrack.cpp \
cionmodbusrtuconnection.cpp \
../modbus/modbusdatautils.cpp
HEADERS += \
integrationpluginschrack.h \
cionmodbusrtuconnection.h \
../modbus/modbusdatautils.h
OTHER_FILES += cion-registers.json
modbusconnection.commands = python $${top_srcdir}/modbus/tools/generate-connection.py -j $${_PRO_FILE_PWD_}/cion-registers.json -o $${_PRO_FILE_PWD_} -c CionModbusRtuConnection
QMAKE_EXTRA_TARGETS += modbusconnection
#target.depends += modbusconnection

View File

@ -0,0 +1,189 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1">
<context>
<name>IntegrationPluginSchrack</name>
<message>
<location filename="../integrationpluginschrack.cpp" line="64"/>
<source>No Modbus RTU interface available. Please set up a Modbus RTU interface first.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../integrationpluginschrack.cpp" line="70"/>
<source>The Modbus slave address must be a value between 1 and 254.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../integrationpluginschrack.cpp" line="99"/>
<source>The Modbus address not valid. It must be a value between 1 and 254.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../integrationpluginschrack.cpp" line="106"/>
<source>The Modbus RTU resource is not available.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>schrack</name>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="56"/>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="59"/>
<source>Charging</source>
<extracomment>The name of the ParamType (ThingClass: cion, EventType: charging, ID: {b59b4b4d-2cdb-4534-bf86-90123ae9bb1a})
----------
The name of the StateType ({b59b4b4d-2cdb-4534-bf86-90123ae9bb1a}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="62"/>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="65"/>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="68"/>
<source>Charging enabled</source>
<extracomment>The name of the ParamType (ThingClass: cion, ActionType: power, ID: {61aea53a-bf8d-4fe6-859a-f1687e15d190})
----------
The name of the ParamType (ThingClass: cion, EventType: power, ID: {61aea53a-bf8d-4fe6-859a-f1687e15d190})
----------
The name of the StateType ({61aea53a-bf8d-4fe6-859a-f1687e15d190}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="71"/>
<source>Charging enabled or disabled</source>
<extracomment>The name of the EventType ({61aea53a-bf8d-4fe6-859a-f1687e15d190}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="74"/>
<source>Charging started or stopped</source>
<extracomment>The name of the EventType ({b59b4b4d-2cdb-4534-bf86-90123ae9bb1a}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="77"/>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="80"/>
<source>Connected</source>
<extracomment>The name of the ParamType (ThingClass: cion, EventType: connected, ID: {b7aa8e49-a6c0-4b48-b65e-47259686185f})
----------
The name of the StateType ({b7aa8e49-a6c0-4b48-b65e-47259686185f}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="83"/>
<source>Connected changed</source>
<extracomment>The name of the EventType ({b7aa8e49-a6c0-4b48-b65e-47259686185f}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="86"/>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="89"/>
<source>Current power consumption</source>
<extracomment>The name of the ParamType (ThingClass: cion, EventType: currentPower, ID: {db5c951f-47e0-4cdc-8b8b-285f7ed95285})
----------
The name of the StateType ({db5c951f-47e0-4cdc-8b8b-285f7ed95285}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="92"/>
<source>Current power consumption changed</source>
<extracomment>The name of the EventType ({db5c951f-47e0-4cdc-8b8b-285f7ed95285}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="95"/>
<source>Enable or disable charging</source>
<extracomment>The name of the ActionType ({61aea53a-bf8d-4fe6-859a-f1687e15d190}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="98"/>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="101"/>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="104"/>
<source>Maximum charging current</source>
<extracomment>The name of the ParamType (ThingClass: cion, ActionType: maxChargingCurrent, ID: {221af869-a796-46c2-a5e0-27c8972a0bf2})
----------
The name of the ParamType (ThingClass: cion, EventType: maxChargingCurrent, ID: {221af869-a796-46c2-a5e0-27c8972a0bf2})
----------
The name of the StateType ({221af869-a796-46c2-a5e0-27c8972a0bf2}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="107"/>
<source>Maximum charging current changed</source>
<extracomment>The name of the EventType ({221af869-a796-46c2-a5e0-27c8972a0bf2}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="110"/>
<source>Modbus RTU master</source>
<extracomment>The name of the ParamType (ThingClass: cion, Type: thing, ID: {636241a9-4838-48ae-bcc8-3427ac3fc102})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="113"/>
<source>Modbus slave address</source>
<extracomment>The name of the ParamType (ThingClass: cion, Type: thing, ID: {dac10e08-734c-4e71-a5d6-0d2a1f416ca6})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="116"/>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="119"/>
<source>Plugged in</source>
<extracomment>The name of the ParamType (ThingClass: cion, EventType: pluggedIn, ID: {13423618-4314-49be-b48c-42d9415199a8})
----------
The name of the StateType ({13423618-4314-49be-b48c-42d9415199a8}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="122"/>
<source>Plugged or unplugged</source>
<extracomment>The name of the EventType ({13423618-4314-49be-b48c-42d9415199a8}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="125"/>
<source>Schrack</source>
<extracomment>The name of the plugin schrack ({600beeb5-5c34-49fc-b2af-8f83c1b11eab})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="128"/>
<source>Schrack GmbH</source>
<extracomment>The name of the vendor ({cadbbbc5-216f-4d25-a8ad-ccf653d1518f})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="131"/>
<source>Set maximum charging current</source>
<extracomment>The name of the ActionType ({221af869-a796-46c2-a5e0-27c8972a0bf2}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="134"/>
<source>Slave address</source>
<extracomment>The name of the ParamType (ThingClass: cion, Type: discovery, ID: {8004705f-0e13-4713-b75e-49d115cd9517})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="137"/>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="140"/>
<source>Total consumed energy</source>
<extracomment>The name of the ParamType (ThingClass: cion, EventType: totalEnergyConsumed, ID: {8390c005-a8ba-4db6-bb94-8f765ddcc784})
----------
The name of the StateType ({8390c005-a8ba-4db6-bb94-8f765ddcc784}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="143"/>
<source>Total consumed energy changed</source>
<extracomment>The name of the EventType ({8390c005-a8ba-4db6-bb94-8f765ddcc784}) of ThingClass cion</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build/nymea-plugins-modbus-Desktop-Debug/schrack/plugininfo.h" line="146"/>
<source>i-CHARGE CION</source>
<extracomment>The name of the ThingClass ({075d389d-3330-4d0b-9649-9f085120ca40})</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>