Merge PR #98: iDM: Update to modbus tools and latest interfaces
This commit is contained in:
commit
4a353ddf66
247
idm/idm-registers.json
Normal file
247
idm/idm-registers.json
Normal file
@ -0,0 +1,247 @@
|
||||
{
|
||||
"className": "Idm",
|
||||
"protocol": "TCP",
|
||||
"endianness": "LittleEndian",
|
||||
"errorLimitUntilNotReachable": 20,
|
||||
"checkReachableRegister": "outdoorTemperature",
|
||||
"enums": [
|
||||
{
|
||||
"name": "SystemOperationMode",
|
||||
"values": [
|
||||
{
|
||||
"key": "Standby",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"key": "Automatic",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"key": "Absent",
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"key": "WarmWaterOnly",
|
||||
"value": 4
|
||||
},
|
||||
{
|
||||
"key": "HeatingCoolingOnly",
|
||||
"value": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "HeatPumpOperationMode",
|
||||
"values": [
|
||||
{
|
||||
"key": "Off",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"key": "Heating",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"key": "Cooling",
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"key": "HotWater",
|
||||
"value": 4
|
||||
},
|
||||
{
|
||||
"key": "Defrost",
|
||||
"value": 8
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"blocks": [
|
||||
{
|
||||
"id": "status",
|
||||
"readSchedule": "update",
|
||||
"registers": [
|
||||
{
|
||||
"id": "currentFaultNumber",
|
||||
"address": 1004,
|
||||
"size": 1,
|
||||
"type": "uint16",
|
||||
"registerType": "holdingRegister",
|
||||
"description": "Current fault number",
|
||||
"defaultValue": "0",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "systemOperationMode",
|
||||
"address": 1005,
|
||||
"size": 1,
|
||||
"type": "uint16",
|
||||
"registerType": "holdingRegister",
|
||||
"description": "Operation mode",
|
||||
"enum": "SystemOperationMode",
|
||||
"defaultValue": "SystemOperationModeStandby",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "smartGridStatus",
|
||||
"address": 1006,
|
||||
"size": 1,
|
||||
"type": "uint16",
|
||||
"registerType": "holdingRegister",
|
||||
"description": "Smart grid status",
|
||||
"defaultValue": "0",
|
||||
"access": "RO"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "energyProduced",
|
||||
"readSchedule": "update",
|
||||
"registers": [
|
||||
{
|
||||
"id": "energyHeating",
|
||||
"address": 1750,
|
||||
"size": 2,
|
||||
"type": "float",
|
||||
"registerType": "holdingRegister",
|
||||
"description": "Energy heating",
|
||||
"unit": "kWh",
|
||||
"defaultValue": "0",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "energyCooling",
|
||||
"address": 1752,
|
||||
"size": 2,
|
||||
"type": "float",
|
||||
"registerType": "holdingRegister",
|
||||
"description": "Energy cooling",
|
||||
"unit": "kWh",
|
||||
"defaultValue": "0",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "energyHotWater",
|
||||
"address": 1754,
|
||||
"size": 2,
|
||||
"type": "float",
|
||||
"registerType": "holdingRegister",
|
||||
"description": "Energy hot water",
|
||||
"unit": "kWh",
|
||||
"defaultValue": "0",
|
||||
"access": "RO"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"registers": [
|
||||
{
|
||||
"id": "currentPvSurplus",
|
||||
"address": 74,
|
||||
"size": 2,
|
||||
"type": "float",
|
||||
"registerType": "holdingRegister",
|
||||
"readSchedule": "update",
|
||||
"description": "Current PV surplus ",
|
||||
"unit": "kW",
|
||||
"defaultValue": "0",
|
||||
"access": "RW"
|
||||
},
|
||||
{
|
||||
"id": "currentPvProduction",
|
||||
"address": 78,
|
||||
"size": 2,
|
||||
"type": "float",
|
||||
"registerType": "holdingRegister",
|
||||
"readSchedule": "update",
|
||||
"description": "Current PV production ",
|
||||
"unit": "kW",
|
||||
"defaultValue": "0",
|
||||
"access": "RW"
|
||||
},
|
||||
{
|
||||
"id": "outdoorTemperature",
|
||||
"address": 1000,
|
||||
"size": 2,
|
||||
"type": "float",
|
||||
"readSchedule": "update",
|
||||
"registerType": "holdingRegister",
|
||||
"description": "Outdoor temperature",
|
||||
"unit": "°C",
|
||||
"defaultValue": "0",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "heatStorageTemperature",
|
||||
"address": 1008,
|
||||
"size": 2,
|
||||
"type": "float",
|
||||
"registerType": "holdingRegister",
|
||||
"readSchedule": "update",
|
||||
"description": "Heat storage temperature",
|
||||
"defaultValue": "0",
|
||||
"unit": "°C",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "targetHotWaterTemperature",
|
||||
"address": 1032,
|
||||
"size": 1,
|
||||
"type": "uint16",
|
||||
"registerType": "holdingRegister",
|
||||
"readSchedule": "update",
|
||||
"description": "Target hot water temperature",
|
||||
"defaultValue": "0",
|
||||
"unit": "°C",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "roomTemperature",
|
||||
"address": 1364,
|
||||
"size": 2,
|
||||
"type": "float",
|
||||
"readSchedule": "update",
|
||||
"registerType": "holdingRegister",
|
||||
"description": "Room temperature",
|
||||
"defaultValue": "0",
|
||||
"unit": "°C",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "roomTemperatureTargetHeatingEco",
|
||||
"address": 1415,
|
||||
"size": 2,
|
||||
"type": "float",
|
||||
"readSchedule": "update",
|
||||
"registerType": "holdingRegister",
|
||||
"description": "Room target temperature",
|
||||
"defaultValue": "0",
|
||||
"unit": "°C",
|
||||
"access": "RW"
|
||||
},
|
||||
{
|
||||
"id": "heatPumpOperatingMode",
|
||||
"address": 1090,
|
||||
"size": 1,
|
||||
"type": "uint16",
|
||||
"registerType": "holdingRegister",
|
||||
"readSchedule": "update",
|
||||
"description": "Heat pump operation mode",
|
||||
"enum": "HeatPumpOperationMode",
|
||||
"defaultValue": "HeatPumpOperationModeOff",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "currentPowerConsumption",
|
||||
"address": 4122,
|
||||
"size": 2,
|
||||
"type": "float",
|
||||
"readSchedule": "update",
|
||||
"registerType": "holdingRegister",
|
||||
"description": "Current power consumption",
|
||||
"unit": "kW",
|
||||
"defaultValue": "0",
|
||||
"access": "RO"
|
||||
}
|
||||
]
|
||||
}
|
||||
194
idm/idm.cpp
194
idm/idm.cpp
@ -1,194 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 "idm.h"
|
||||
#include "extern-plugininfo.h"
|
||||
#include "modbushelpers.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
Idm::Idm(const QHostAddress &address, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_hostAddress(address)
|
||||
{
|
||||
qCDebug(dcIdm()) << "iDM: Creating iDM connection" << m_hostAddress.toString();
|
||||
m_modbusMaster = new ModbusTCPMaster(address, 502, this);
|
||||
connect(m_modbusMaster, &ModbusTCPMaster::receivedHoldingRegister, this, &Idm::onReceivedHoldingRegister);
|
||||
connect(m_modbusMaster, &ModbusTCPMaster::readRequestError, this, &Idm::onModbusError);
|
||||
connect(m_modbusMaster, &ModbusTCPMaster::writeRequestError, this, &Idm::onModbusError);
|
||||
connect(m_modbusMaster, &ModbusTCPMaster::writeRequestExecuted, this, &Idm::writeRequestExecuted);
|
||||
}
|
||||
|
||||
Idm::~Idm()
|
||||
{
|
||||
qCDebug(dcIdm()) << "iDM: Deleting iDM connection" << m_hostAddress.toString();
|
||||
}
|
||||
|
||||
bool Idm::connectDevice()
|
||||
{
|
||||
qCDebug(dcIdm()) << "iDM: Connecting device";
|
||||
return m_modbusMaster->connectDevice();
|
||||
}
|
||||
|
||||
QHostAddress Idm::address() const
|
||||
{
|
||||
return m_hostAddress;
|
||||
}
|
||||
|
||||
void Idm::getStatus()
|
||||
{
|
||||
// This request starts an update cycle
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::OutsideTemperature, 2);
|
||||
}
|
||||
|
||||
QUuid Idm::setTargetTemperature(double targetTemperature)
|
||||
{
|
||||
QVector<uint16_t> value = ModbusHelpers::convertFloatToRegister(targetTemperature);
|
||||
return m_modbusMaster->writeHoldingRegisters(Idm::modbusUnitID, Idm::RegisterList::RoomTemperatureTargetHeatingEcoHKA, value);
|
||||
}
|
||||
|
||||
void Idm::onReceivedHoldingRegister(int slaveAddress, int modbusRegister, const QVector<quint16> &value)
|
||||
{
|
||||
Q_UNUSED(slaveAddress);
|
||||
/* qCDebug(dcIdm()) << "receivedHoldingRegister " << modbusRegister << "(length: " << value.length() << ")"; */
|
||||
|
||||
switch (modbusRegister) {
|
||||
case Idm::OutsideTemperature:
|
||||
/* qCDebug(dcIdm()) << "received outside temperature"; */
|
||||
if (value.length() == 2) {
|
||||
m_idmInfo.outsideTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::OutsideTemperature - modbusRegister]);
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::CurrentFaultNumber, 1);
|
||||
});
|
||||
break;
|
||||
case Idm::CurrentFaultNumber:
|
||||
/* qCDebug(dcIdm()) << "current fault number"; */
|
||||
if (value.length() == 1) {
|
||||
if (value[0] > 0) {
|
||||
m_idmInfo.error = true;
|
||||
} else {
|
||||
m_idmInfo.error = false;
|
||||
}
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::HeatStorageTemperature, 2);
|
||||
});
|
||||
break;
|
||||
case Idm::HeatStorageTemperature:
|
||||
/* qCDebug(dcIdm()) << "received storage temperature"; */
|
||||
if (value.length() == 2) {
|
||||
m_idmInfo.waterTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::HeatStorageTemperature - modbusRegister]);
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::TargetHotWaterTemperature, 1);
|
||||
});
|
||||
break;
|
||||
case Idm::TargetHotWaterTemperature:
|
||||
/* qCDebug(dcIdm()) << "received target hot water temperature"; */
|
||||
if (value.length() == 1) {
|
||||
/* The hot water target temperature is stored as UCHAR (manual p. 13) */
|
||||
m_idmInfo.targetWaterTemperature = (double)value[RegisterList::TargetHotWaterTemperature - modbusRegister];
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::HeatPumpOperatingMode, 1);
|
||||
});
|
||||
break;
|
||||
case Idm::HeatPumpOperatingMode:
|
||||
/* qCDebug(dcIdm()) << "received heat pump operating mode"; */
|
||||
if (value.length() == 1) {
|
||||
m_idmInfo.mode = heatPumpOperationModeToString((Idm::IdmHeatPumpMode)value[RegisterList::HeatPumpOperatingMode-modbusRegister]);
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::RoomTemperatureHKA, 2);
|
||||
});
|
||||
break;
|
||||
case Idm::RoomTemperatureHKA:
|
||||
/* qCDebug(dcIdm()) << "received room temperature hka"; */
|
||||
if (value.length() == 2) {
|
||||
m_idmInfo.roomTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::RoomTemperatureHKA - modbusRegister]);
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::RoomTemperatureTargetHeatingEcoHKA, 2);
|
||||
});
|
||||
break;
|
||||
case Idm::RoomTemperatureTargetHeatingEcoHKA:
|
||||
/* qCDebug(dcIdm()) << "received room temprature hka eco"; */
|
||||
if (value.length() == 2) {
|
||||
m_idmInfo.targetRoomTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::RoomTemperatureTargetHeatingEcoHKA - modbusRegister]);
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::CurrentPowerConsumptionHeatPump, 2);
|
||||
});
|
||||
break;
|
||||
case Idm::CurrentPowerConsumptionHeatPump:
|
||||
/* qCDebug(dcIdm()) << "received power consumption heat pump"; */
|
||||
if (value.length() == 2) {
|
||||
m_idmInfo.powerConsumptionHeatPump = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::CurrentPowerConsumptionHeatPump - modbusRegister]);
|
||||
}
|
||||
|
||||
/* Everything read without an error
|
||||
* -> set connected to true */
|
||||
m_idmInfo.connected = true;
|
||||
emit statusUpdated(m_idmInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Idm::onModbusError()
|
||||
{
|
||||
qCDebug(dcIdm()) << "iDM: Received modbus error" << m_modbusMaster->errorString();
|
||||
m_idmInfo.connected = false;
|
||||
emit statusUpdated(m_idmInfo);
|
||||
}
|
||||
|
||||
QString Idm::heatPumpOperationModeToString(IdmHeatPumpMode mode)
|
||||
{
|
||||
QString result{};
|
||||
/* Operation modes according to table of manual p. 14 */
|
||||
switch (mode) {
|
||||
case IdmHeatPumpModeOff:
|
||||
result = "Off";
|
||||
break;
|
||||
case IdmHeatPumpModeHeating:
|
||||
result = "Heating";
|
||||
break;
|
||||
case IdmHeatPumpModeCooling:
|
||||
result = "Cooling";
|
||||
break;
|
||||
case IdmHeatPumpModeHotWater:
|
||||
result = "Hot water";
|
||||
break;
|
||||
case IdmHeatPumpModeDefrost:
|
||||
result = "Defrost";
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
183
idm/idm.h
183
idm/idm.h
@ -1,183 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 IDM_H
|
||||
#define IDM_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <modbustcpmaster.h>
|
||||
|
||||
#include "idminfo.h"
|
||||
|
||||
/*
|
||||
* Functionality:
|
||||
* The current version allows read access to selected
|
||||
* modbus registers:
|
||||
* + Room temperature (HK A)
|
||||
* + Water temperature
|
||||
* + Outside air temperature
|
||||
* + Target room temperature eco mode (HK A)
|
||||
* + Target water temperature
|
||||
* + Current power consumption
|
||||
* + Operation mode
|
||||
* + Error
|
||||
*
|
||||
* At present there is no write access for target
|
||||
* room temperature and target water temperature. These
|
||||
* result in an "invalid data access" error from the
|
||||
* device.
|
||||
*/
|
||||
|
||||
/* Note: It would be desirable to read the modbus registers
|
||||
* of the Idm heat pump in groups to minimize the number
|
||||
* of read requests. However, a maximum of 6 registers
|
||||
* can be read simultaneously. With the given set of
|
||||
* addresses it is not possible to reasonably group the
|
||||
* registers, therefore they are read individually.
|
||||
*/
|
||||
|
||||
class Idm : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Idm(const QHostAddress &address, QObject *parent = nullptr);
|
||||
~Idm();
|
||||
|
||||
bool connectDevice();
|
||||
QHostAddress address() const;
|
||||
QUuid setTargetTemperature(double targetTemperature);
|
||||
void getStatus();
|
||||
|
||||
private:
|
||||
/** Modbus Unit ID of Idm device */
|
||||
static const quint16 modbusUnitID = 1;
|
||||
|
||||
enum IscModus {
|
||||
KeineAbwarme = 0,
|
||||
Heizung = 1,
|
||||
Warmwasser = 4,
|
||||
Warmequelle = 8,
|
||||
};
|
||||
|
||||
/** System operation modes according to manual p. 13 */
|
||||
enum IdmSysMode {
|
||||
IdmSysModeStandby = 0,
|
||||
IdmSysModeAutomatic = 1,
|
||||
IdmSysModeAway = 2,
|
||||
IdmSysModeOnlyHotwater = 4,
|
||||
IdmSysModeOnlyRoomHeating = 5
|
||||
};
|
||||
|
||||
/** Heat pump operation modes according to manual p. 14 */
|
||||
enum IdmHeatPumpMode {
|
||||
IdmHeatPumpModeOff = 0,
|
||||
IdmHeatPumpModeHeating = 1,
|
||||
IdmHeatPumpModeCooling = 2,
|
||||
IdmHeatPumpModeHotWater = 4,
|
||||
IdmHeatPumpModeDefrost = 8
|
||||
};
|
||||
|
||||
/** The following modbus addresses are according to the manual
|
||||
* Modbus TCP Navigatorregelung 2.0 pages 13-31.
|
||||
* Comments at the end of each line give their original name
|
||||
* in the German manual. */
|
||||
enum RegisterList {
|
||||
OutsideTemperature = 1000, // Außentemperatur (B31)
|
||||
MeanOutsideTemperature = 1002, // Gemittelte Außentemperature
|
||||
CurrentFaultNumber = 1004, // Aktuelle Störungsnummer
|
||||
OperationModeSystem = 1005, // Betriebsart System
|
||||
SmartGridStatus = 1006, // Smart Grid Status
|
||||
HeatStorageTemperature = 1008, // Wärmespeichertemperatur (B38)
|
||||
ColdStorageTemperature = 1010, // Kältespeichertemperatur (B40)
|
||||
DrinkingWaterHeaterTempBottom = 1012, // Trinkwassererwärmertmp. unten (B41)
|
||||
DrinkingWaterHeaterTempTop = 1014, // Trinkwassererwärmertmp. oben (B48)
|
||||
HotWaterTapTemperature = 1030, // Warmwasserzapftemperatur (B42)
|
||||
TargetHotWaterTemperature = 1032, // Warmwasser-Solltemperatur
|
||||
HeatPumpOperatingMode = 1090, // Betriebsart Wärmepumpe
|
||||
SummationFaultHeatPump = 1099, // Summenstörung Wärepumpe
|
||||
RoomTemperatureHKA = 1364, // Heizkreis A Raumtemperature (B61)
|
||||
HumiditySensor = 1392, // Feuchtesensor
|
||||
RoomTemperatureTargetHeatingHKA = 1401, // Raumsolltemperatur Heizen Normal HK A
|
||||
RoomTemperatureTargetHeatingEcoHKA = 1415, // Raumsolltemperatur Heizen Eco HK A
|
||||
ExternalOutsideTemperature = 1690, // Externe Außentemperatur
|
||||
ExternalHumidity = 1692, // Externe Feuchte
|
||||
ExternalRequestTemperatureHeating = 1694, // Externe Anforderungstemperatur Heizen
|
||||
ExternalRequestTemperatureCooling = 1695, // Externe Anforderungstemperatur Kühlen
|
||||
HeatingRequirement = 1710, // Anforderung Heizen
|
||||
CoolingRequirement = 1711, // Anforderung Kühlen
|
||||
HotWaterChargingRequirement = 1712, // Anforderung Warmwasserladung
|
||||
HeatQuantityHeating = 1750, // Wärmemenge Heizen
|
||||
HeatQuantityCooling = 1752, // Wärmemenge Kühlen
|
||||
HeatQuantityHotWater = 1754, // Wärmemenge Warmwasser
|
||||
HeatQuantityDefrosting = 1756, // Wärmemenge Abtauung
|
||||
HeatQuantityPassiveCooling = 1758, // Wärmemenge Passive Kühlung,
|
||||
HeatQuantityPhotovolatics = 1760, // Wärmemenge Solar
|
||||
HeatQuantityHeatingElemetn = 1762, // Wärmemenge Elektroheizeinsatz,
|
||||
CurrentPower = 1790, // Momentanleistung
|
||||
CurrentPowerSolar = 1792, // MomentanleistungSolar
|
||||
SolarCollectorTemperature = 1850, // SolarKollektortemperatur (B73)
|
||||
SolarCollectorReturnTemperature = 1852, // SolarKollektorruecklauftemperatur (B75)
|
||||
SolarChargeTemperature = 1854, // SolarLadetemperatur (B74)
|
||||
SolarOperatingMode = 1856, // Betriebsart Solar
|
||||
ISCMode = 1875, // ISCModus
|
||||
AcknowledgeFaultMessages = 1999, // Störmeldungen quittieren
|
||||
TargetRoomTemperatureZ1R1 = 2004, // Zonenmodul 1 Raumsolltemperatur Raum 1
|
||||
CurrentPhotovoltaicsSurplus = 74, // Aktueller PV-Überschuss
|
||||
CurrentPhotovoltaicsProduction = 78, // Aktueller PV Produktion
|
||||
CurrentPowerConsumptionHeatPump = 4122, // Aktuelle Leistungsaufnahme Wärmepumpe
|
||||
};
|
||||
|
||||
/* Note: This class only requires one IP address and one
|
||||
* TCP Modbus connection. Multiple devices are managed
|
||||
* within the IntegrationPluginIdm class. */
|
||||
QHostAddress m_hostAddress;
|
||||
|
||||
/** Pointer to ModbusTCPMaster object, responsible for low-level communicaiton */
|
||||
ModbusTCPMaster *m_modbusMaster = nullptr;
|
||||
|
||||
/** This structure is allocated within onRequestStatus and filled
|
||||
* by the receivedStatusGroupx functions */
|
||||
IdmInfo m_idmInfo;
|
||||
|
||||
/** Converts a heat pump operation mode code to a string (according to manual p. 14) */
|
||||
QString heatPumpOperationModeToString(IdmHeatPumpMode mode);
|
||||
|
||||
signals:
|
||||
void statusUpdated(const IdmInfo &info);
|
||||
void targetRoomTemperatureChanged();
|
||||
void writeRequestExecuted(const QUuid &requestId, bool success);
|
||||
|
||||
private slots:
|
||||
void onModbusError();
|
||||
void onReceivedHoldingRegister(int slaveAddress, int modbusRegister, const QVector<quint16> &value);
|
||||
};
|
||||
|
||||
#endif // IDM_H
|
||||
14
idm/idm.pro
14
idm/idm.pro
@ -1,14 +1,12 @@
|
||||
include(../plugins.pri)
|
||||
|
||||
# Generate modbus connection
|
||||
MODBUS_CONNECTIONS += idm-registers.json
|
||||
#MODBUS_TOOLS_CONFIG += VERBOSE
|
||||
include(../modbus.pri)
|
||||
|
||||
SOURCES += \
|
||||
idm.cpp \
|
||||
integrationpluginidm.cpp \
|
||||
modbushelpers.cpp
|
||||
integrationpluginidm.cpp
|
||||
|
||||
HEADERS += \
|
||||
idm.h \
|
||||
idminfo.h \
|
||||
integrationpluginidm.h \
|
||||
modbushelpers.h
|
||||
|
||||
integrationpluginidm.h
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 IDMINFO_H
|
||||
#define IDMINFO_H
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QString>
|
||||
|
||||
/** This struct holds the status information that is read from the IDM device
|
||||
* and passed to the nymea framework within this plugin.
|
||||
*/
|
||||
struct IdmInfo {
|
||||
/** Set to true, if register values can be read,
|
||||
* false in case of communication problems */
|
||||
bool connected;
|
||||
|
||||
bool power;
|
||||
|
||||
/** RegisterList::OutsideTemperature */
|
||||
double roomTemperature;
|
||||
|
||||
/** RegisterList::ExternalOutsideTemperature */
|
||||
double outsideTemperature;
|
||||
|
||||
/** RegisterList::HeatStorageTemperature */
|
||||
double waterTemperature;
|
||||
|
||||
/** RegisterList::TargetRoomTemperatureZ1R1 (zone 1, room 1) */
|
||||
double targetRoomTemperature;
|
||||
|
||||
/** RegisterList::TargetHotWaterTemperature */
|
||||
double targetWaterTemperature;
|
||||
|
||||
/** RegisterList::HumiditySensor */
|
||||
double humidity;
|
||||
|
||||
/** RegisterList::CurrentPowerConsumptionHeatPump */
|
||||
double powerConsumptionHeatPump;
|
||||
|
||||
/** RegisterList::OperationModeSystem */
|
||||
QString mode;
|
||||
|
||||
/** True if there is an error code set
|
||||
* (RegisterList::CurrentFaultNumber != 0) */
|
||||
bool error;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(IdmInfo);
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2021, nymea GmbH
|
||||
* Copyright 2013 - 2022, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
@ -32,6 +32,7 @@
|
||||
#include "plugininfo.h"
|
||||
|
||||
#include <network/networkdevicediscovery.h>
|
||||
#include <hardwaremanager.h>
|
||||
|
||||
IntegrationPluginIdm::IntegrationPluginIdm()
|
||||
{
|
||||
@ -79,7 +80,6 @@ void IntegrationPluginIdm::discoverThings(ThingDiscoveryInfo *info)
|
||||
|
||||
ParamList params;
|
||||
params << Param(navigator2ThingMacAddressParamTypeId, networkDeviceInfo.macAddress());
|
||||
params << Param(navigator2ThingIpAddressParamTypeId, networkDeviceInfo.address().toString());
|
||||
descriptor.setParams(params);
|
||||
info->addThingDescriptor(descriptor);
|
||||
}
|
||||
@ -90,77 +90,80 @@ void IntegrationPluginIdm::discoverThings(ThingDiscoveryInfo *info)
|
||||
void IntegrationPluginIdm::setupThing(ThingSetupInfo *info)
|
||||
{
|
||||
Thing *thing = info->thing();
|
||||
qCDebug(dcIdm()) << "setupThing called" << thing->name();
|
||||
qCDebug(dcIdm()) << "Setup" << thing << thing->params();
|
||||
|
||||
// Inverter (connection)
|
||||
if (thing->thingClassId() == navigator2ThingClassId) {
|
||||
QHostAddress hostAddress = QHostAddress(thing->paramValue(navigator2ThingIpAddressParamTypeId).toString());
|
||||
if (hostAddress.isNull()) {
|
||||
qCWarning(dcIdm()) << "Setup failed, IP address not valid";
|
||||
info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("No IP address given"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_idmConnections.contains(thing)) {
|
||||
qCDebug(dcIdm()) << "Cleaning up after reconfiguration";
|
||||
m_idmConnections.take(thing)->deleteLater();
|
||||
}
|
||||
// Handle reconfigure
|
||||
if (m_connections.contains(thing)) {
|
||||
qCDebug(dcIdm()) << "Reconfiguring existing thing" << thing->name();
|
||||
m_connections.take(thing)->deleteLater();
|
||||
|
||||
qCDebug(dcIdm()) << "User entered address: " << hostAddress.toString();
|
||||
|
||||
/* Check, if address is already in use for another device */
|
||||
foreach (Idm *idm, m_idmConnections) {
|
||||
if (hostAddress.isEqual(idm->address())) {
|
||||
qCWarning(dcIdm()) << "Address already in use";
|
||||
info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("IP address already in use"));
|
||||
return;
|
||||
if (m_monitors.contains(thing)) {
|
||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
||||
}
|
||||
}
|
||||
|
||||
qCDebug(dcIdm()) << "Creating Idm object";
|
||||
/* Create new Idm object and store it in hash table */
|
||||
Idm *idm = new Idm(hostAddress, this);
|
||||
if (idm->connectDevice()) {
|
||||
qCWarning(dcIdm()) << "Could not connect to thing";
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
MacAddress macAddress = MacAddress(thing->paramValue(navigator2ThingMacAddressParamTypeId).toString());
|
||||
if (!macAddress.isValid()) {
|
||||
qCWarning(dcIdm()) << "The configured mac address is not valid" << thing->params();
|
||||
info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("The MAC address is not known. Please reconfigure the thing."));
|
||||
return;
|
||||
}
|
||||
|
||||
connect(idm, &Idm::statusUpdated, info, [info, thing, idm, this] (const IdmInfo &idmInfo) {
|
||||
if (idmInfo.connected) {
|
||||
m_idmConnections.insert(thing, idm);
|
||||
connect(idm, &Idm::statusUpdated, this, &IntegrationPluginIdm::onStatusUpdated);
|
||||
connect(idm, &Idm::writeRequestExecuted, this, &IntegrationPluginIdm::onWriteRequestExecuted);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
// Create the monitor
|
||||
NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(macAddress);
|
||||
m_monitors.insert(thing, monitor);
|
||||
|
||||
QHostAddress address = monitor->networkDeviceInfo().address();
|
||||
if (address.isNull()) {
|
||||
qCWarning(dcIdm()) << "Cannot set up thing. The host address is not known yet. Maybe it will be available in the next run...";
|
||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
||||
info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("The host address is not known yet. Trying later again."));
|
||||
return;
|
||||
}
|
||||
|
||||
// Clean up in case the setup gets aborted
|
||||
connect(info, &ThingSetupInfo::aborted, monitor, [=](){
|
||||
if (m_monitors.contains(thing)) {
|
||||
qCDebug(dcIdm()) << "Unregister monitor because setup has been aborted.";
|
||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
||||
}
|
||||
});
|
||||
connect(idm, &Idm::destroyed, this, [thing, this] {m_idmConnections.remove(thing);});
|
||||
connect(info, &ThingSetupInfo::aborted, idm, &Idm::deleteLater);
|
||||
|
||||
// Wait for the monitor to be ready
|
||||
if (monitor->reachable()) {
|
||||
// Thing already reachable...let's continue with the setup
|
||||
setupConnection(info);
|
||||
} else {
|
||||
qCDebug(dcIdm()) << "Waiting for the network monitor to get reachable before continue to set up the connection" << thing->name() << address.toString() << "...";
|
||||
connect(monitor, &NetworkDeviceMonitor::reachableChanged, info, [=](bool reachable){
|
||||
if (reachable) {
|
||||
qCDebug(dcIdm()) << "The monitor for thing setup" << thing->name() << "is now reachable. Continue setup...";
|
||||
setupConnection(info);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
Q_ASSERT_X(false, "setupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginIdm::postSetupThing(Thing *thing)
|
||||
{
|
||||
qCDebug(dcIdm()) << "postSetupThing called" << thing->name();
|
||||
Q_UNUSED(thing)
|
||||
|
||||
if (!m_refreshTimer) {
|
||||
qCDebug(dcIdm()) << "Starting refresh timer";
|
||||
m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
|
||||
connect(m_refreshTimer, &PluginTimer::timeout, this, &IntegrationPluginIdm::onRefreshTimer);
|
||||
}
|
||||
connect(m_refreshTimer, &PluginTimer::timeout, this, [this](){
|
||||
foreach (IdmModbusTcpConnection *connection, m_connections) {
|
||||
connection->update();
|
||||
}
|
||||
});
|
||||
|
||||
if (thing->thingClassId() == navigator2ThingClassId) {
|
||||
Idm *idm = m_idmConnections.value(thing);
|
||||
if (!idm) {
|
||||
qCWarning(dcIdm()) << "Could not find any iDM connection for" << thing->name();
|
||||
return;
|
||||
}
|
||||
|
||||
thing->setStateValue(navigator2ConnectedStateTypeId, true);
|
||||
update(thing);
|
||||
m_refreshTimer->start();
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,11 +172,15 @@ void IntegrationPluginIdm::thingRemoved(Thing *thing)
|
||||
qCDebug(dcIdm()) << "thingRemoved called" << thing->name();
|
||||
|
||||
if (thing->thingClassId() == navigator2ThingClassId) {
|
||||
if (m_idmConnections.contains(thing)) {
|
||||
m_idmConnections.take(thing)->deleteLater();
|
||||
if (m_connections.contains(thing)) {
|
||||
m_connections.take(thing)->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
// Unregister related hardware resources
|
||||
if (m_monitors.contains(thing))
|
||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
||||
|
||||
if (myThings().isEmpty()) {
|
||||
qCDebug(dcIdm()) << "Stopping refresh timer";
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer);
|
||||
@ -187,15 +194,37 @@ void IntegrationPluginIdm::executeAction(ThingActionInfo *info)
|
||||
Action action = info->action();
|
||||
|
||||
if (thing->thingClassId() == navigator2ThingClassId) {
|
||||
Idm *idm = m_idmConnections.value(thing);
|
||||
if (!idm) {
|
||||
return info->finish(Thing::ThingErrorHardwareFailure);
|
||||
IdmModbusTcpConnection *connection = m_connections.value(thing);
|
||||
if (!connection) {
|
||||
qCWarning(dcIdm()) << "Failed to execute action. Could not find connection for" << thing;
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!connection->connected())
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
|
||||
|
||||
if (action.actionTypeId() == navigator2TargetTemperatureActionTypeId) {
|
||||
double targetTemperature = thing->stateValue(navigator2TargetTemperatureStateTypeId).toDouble();
|
||||
QUuid requestId = idm->setTargetTemperature(targetTemperature);
|
||||
m_asyncActions.insert(requestId, info);
|
||||
connect(info, &ThingActionInfo::aborted, [requestId, this] (){ m_asyncActions.remove(requestId); });
|
||||
float targetTemperature = action.paramValue(navigator2TargetTemperatureActionTargetTemperatureParamTypeId).toDouble();
|
||||
qCDebug(dcIdm()) << "Setting room target temperature to" << targetTemperature << "°C";
|
||||
QModbusReply *reply = connection->setRoomTemperatureTargetHeatingEco(targetTemperature);
|
||||
if (!reply) {
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, info, [info, reply, thing, targetTemperature]{
|
||||
if (reply->error() != QModbusDevice::NoError) {
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcIdm()) << "Room target temperature set successfully to" << targetTemperature << "°C";
|
||||
thing->setStateValue(navigator2TargetTemperatureStateTypeId, targetTemperature);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
} else {
|
||||
Q_ASSERT_X(false, "executeAction", QString("Unhandled action: %1").arg(action.actionTypeId().toString()).toUtf8());
|
||||
}
|
||||
@ -204,55 +233,144 @@ void IntegrationPluginIdm::executeAction(ThingActionInfo *info)
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginIdm::update(Thing *thing)
|
||||
void IntegrationPluginIdm::setupConnection(ThingSetupInfo *info)
|
||||
{
|
||||
if (thing->thingClassId() == navigator2ThingClassId) {
|
||||
qCDebug(dcIdm()) << "Updating thing" << thing->name();
|
||||
Idm *idm = m_idmConnections.value(thing);
|
||||
if (!idm) { return; };
|
||||
idm->getStatus();
|
||||
}
|
||||
}
|
||||
Thing *thing = info->thing();
|
||||
|
||||
void IntegrationPluginIdm::onStatusUpdated(const IdmInfo &info)
|
||||
{
|
||||
qCDebug(dcIdm()) << "Received status from heat pump";
|
||||
Idm *idm = qobject_cast<Idm *>(sender());
|
||||
Thing *thing = m_idmConnections.key(idm);
|
||||
QHostAddress address = m_monitors.value(thing)->networkDeviceInfo().address();
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
qCDebug(dcIdm()) << "Setting up IDM on" << address.toString() << 502 << "unit ID:" << 1;
|
||||
IdmModbusTcpConnection *connection = new IdmModbusTcpConnection(address, 502, 1, this);
|
||||
connect(info, &ThingSetupInfo::aborted, connection, &IdmModbusTcpConnection::deleteLater);
|
||||
|
||||
/* Received a structure holding the status info of the
|
||||
* heat pump. Update the thing states with the individual fields. */
|
||||
thing->setStateValue(navigator2ConnectedStateTypeId, info.connected);
|
||||
thing->setStateValue(navigator2PowerStateTypeId, info.power);
|
||||
thing->setStateValue(navigator2TemperatureStateTypeId, info.roomTemperature);
|
||||
thing->setStateValue(navigator2OutsideAirTemperatureStateTypeId, info.outsideTemperature);
|
||||
thing->setStateValue(navigator2WaterTemperatureStateTypeId, info.waterTemperature);
|
||||
thing->setStateValue(navigator2TargetTemperatureStateTypeId, info.targetRoomTemperature);
|
||||
thing->setStateValue(navigator2TargetWaterTemperatureStateTypeId, info.targetWaterTemperature);
|
||||
thing->setStateValue(navigator2CurrentPowerConsumptionHeatPumpStateTypeId, info.powerConsumptionHeatPump);
|
||||
thing->setStateValue(navigator2ModeStateTypeId, info.mode);
|
||||
thing->setStateValue(navigator2ErrorStateTypeId, info.error);
|
||||
}
|
||||
// Reconnect on monitor reachable changed
|
||||
NetworkDeviceMonitor *monitor = m_monitors.value(thing);
|
||||
connect(monitor, &NetworkDeviceMonitor::reachableChanged, thing, [=](bool reachable){
|
||||
qCDebug(dcIdm()) << "Network device monitor reachable changed for" << thing->name() << reachable;
|
||||
if (!thing->setupComplete())
|
||||
return;
|
||||
|
||||
void IntegrationPluginIdm::onWriteRequestExecuted(const QUuid &requestId, bool success)
|
||||
{
|
||||
if (m_asyncActions.contains(requestId)) {
|
||||
ThingActionInfo *info = m_asyncActions.value(requestId);
|
||||
if (success) {
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
} else {
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
if (reachable && !thing->stateValue("connected").toBool()) {
|
||||
connection->setHostAddress(monitor->networkDeviceInfo().address());
|
||||
connection->connectDevice();
|
||||
} else if (!reachable) {
|
||||
// Note: We disable autoreconnect explicitly and we will
|
||||
// connect the device once the monitor says it is reachable again
|
||||
connection->disconnectDevice();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(connection, &IdmModbusTcpConnection::reachableChanged, thing, [this, thing, connection](bool reachable){
|
||||
qCDebug(dcIdm()) << "Reachable changed to" << reachable << "for" << thing;
|
||||
if (reachable) {
|
||||
// Connected true will be set after successfull init
|
||||
connection->initialize();
|
||||
} else {
|
||||
thing->setStateValue("connected", false);
|
||||
foreach (Thing *childThing, myThings().filterByParentId(thing->id())) {
|
||||
childThing->setStateValue("connected", false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(connection, &IdmModbusTcpConnection::initializationFinished, thing, [=](bool success){
|
||||
if (!thing->setupComplete())
|
||||
return;
|
||||
|
||||
thing->setStateValue("connected", success);
|
||||
foreach (Thing *childThing, myThings().filterByParentId(thing->id())) {
|
||||
childThing->setStateValue("connected", success);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
// Try once to reconnect the device
|
||||
connection->reconnectDevice();
|
||||
}
|
||||
});
|
||||
|
||||
connect(connection, &IdmModbusTcpConnection::initializationFinished, info, [=](bool success){
|
||||
if (!success) {
|
||||
qCWarning(dcIdm()) << "Connection init finished with errors" << thing->name() << connection->hostAddress().toString();
|
||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(monitor);
|
||||
connection->deleteLater();
|
||||
info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Could not initialize the communication with the device."));
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcIdm()) << "Connection init finished successfully" << connection;
|
||||
m_connections.insert(thing, connection);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
|
||||
// Set connected true
|
||||
thing->setStateValue("connected", true);
|
||||
foreach (Thing *childThing, myThings().filterByParentId(thing->id())) {
|
||||
childThing->setStateValue("connected", true);
|
||||
}
|
||||
|
||||
|
||||
connect(connection, &IdmModbusTcpConnection::updateFinished, thing, [=](){
|
||||
qCDebug(dcIdm()) << "Updated" << connection;
|
||||
|
||||
thing->setStateValue(navigator2ConnectedStateTypeId, connection->reachable());
|
||||
thing->setStateValue(navigator2TemperatureStateTypeId, connection->roomTemperature());
|
||||
thing->setStateValue(navigator2OutsideTemperatureStateTypeId, connection->outdoorTemperature());
|
||||
thing->setStateValue(navigator2WaterTemperatureStateTypeId, connection->heatStorageTemperature());
|
||||
thing->setStateValue(navigator2TargetTemperatureStateTypeId, connection->roomTemperatureTargetHeatingEco());
|
||||
thing->setStateValue(navigator2TargetWaterTemperatureStateTypeId, connection->targetHotWaterTemperature());
|
||||
thing->setStateValue(navigator2CurrentPowerStateTypeId, connection->currentPowerConsumption() * 1000.0);
|
||||
thing->setStateValue(navigator2EnergyProducedHeatingStateTypeId, connection->energyHeating());
|
||||
thing->setStateValue(navigator2EnergyProducedCoolingStateTypeId, connection->energyCooling());
|
||||
thing->setStateValue(navigator2EnergyProducedHotWaterStateTypeId, connection->energyHotWater());
|
||||
|
||||
switch (connection->heatPumpOperatingMode()) {
|
||||
case IdmModbusTcpConnection::HeatPumpOperationModeOff:
|
||||
thing->setStateValue(navigator2ModeStateTypeId, "Off");
|
||||
break;
|
||||
case IdmModbusTcpConnection::HeatPumpOperationModeHeating:
|
||||
thing->setStateValue(navigator2ModeStateTypeId, "Heating");
|
||||
break;
|
||||
case IdmModbusTcpConnection::HeatPumpOperationModeCooling:
|
||||
thing->setStateValue(navigator2ModeStateTypeId, "Cooling");
|
||||
break;
|
||||
case IdmModbusTcpConnection::HeatPumpOperationModeHotWater:
|
||||
thing->setStateValue(navigator2ModeStateTypeId, "Hot water");
|
||||
break;
|
||||
case IdmModbusTcpConnection::HeatPumpOperationModeDefrost:
|
||||
thing->setStateValue(navigator2ModeStateTypeId, "Defrost");
|
||||
break;
|
||||
}
|
||||
|
||||
thing->setStateValue(navigator2HeatingOnStateTypeId, connection->heatPumpOperatingMode() == IdmModbusTcpConnection::HeatPumpOperationModeHeating);
|
||||
thing->setStateValue(navigator2CoolingOnStateTypeId, connection->heatPumpOperatingMode() == IdmModbusTcpConnection::HeatPumpOperationModeCooling);
|
||||
|
||||
switch (connection->systemOperationMode()) {
|
||||
case IdmModbusTcpConnection::SystemOperationModeStandby:
|
||||
thing->setStateValue(navigator2OperationModeStateTypeId, "Standby");
|
||||
break;
|
||||
case IdmModbusTcpConnection::SystemOperationModeAutomatic:
|
||||
thing->setStateValue(navigator2OperationModeStateTypeId, "Automatic");
|
||||
break;
|
||||
case IdmModbusTcpConnection::SystemOperationModeAbsent:
|
||||
thing->setStateValue(navigator2OperationModeStateTypeId, "Absent");
|
||||
break;
|
||||
case IdmModbusTcpConnection::SystemOperationModeWarmWaterOnly:
|
||||
thing->setStateValue(navigator2OperationModeStateTypeId, "Hot water only");
|
||||
break;
|
||||
case IdmModbusTcpConnection::SystemOperationModeHeatingCoolingOnly:
|
||||
thing->setStateValue(navigator2OperationModeStateTypeId, "Heating cooling only");
|
||||
break;
|
||||
}
|
||||
|
||||
thing->setStateValue(navigator2ErrorStateTypeId, connection->currentFaultNumber());
|
||||
|
||||
});
|
||||
|
||||
// Update registers
|
||||
connection->update();
|
||||
});
|
||||
|
||||
connection->connectDevice();
|
||||
}
|
||||
|
||||
void IntegrationPluginIdm::onRefreshTimer()
|
||||
{
|
||||
foreach (Thing *thing, myThings().filterByThingClassId(navigator2ThingClassId)) {
|
||||
update(thing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Copyright 2013 - 2022, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
@ -32,11 +32,10 @@
|
||||
#define INTEGRATIONPLUGINIDM_H
|
||||
|
||||
#include <integrations/integrationplugin.h>
|
||||
#include <network/networkdevicemonitor.h>
|
||||
#include <plugintimer.h>
|
||||
|
||||
#include "idm.h"
|
||||
|
||||
#include <QUuid>
|
||||
#include "idmmodbustcpconnection.h"
|
||||
|
||||
class IntegrationPluginIdm: public IntegrationPlugin
|
||||
{
|
||||
@ -56,16 +55,10 @@ public:
|
||||
|
||||
private:
|
||||
PluginTimer *m_refreshTimer = nullptr;
|
||||
QHash<Thing *, Idm *> m_idmConnections;
|
||||
QHash<QUuid, ThingActionInfo *> m_asyncActions;
|
||||
|
||||
void update(Thing *thing);
|
||||
void onRefreshTimer();
|
||||
|
||||
private slots:
|
||||
void onStatusUpdated(const IdmInfo &info);
|
||||
void onWriteRequestExecuted(const QUuid &requestId, bool success);
|
||||
QHash<Thing *, IdmModbusTcpConnection *> m_connections;
|
||||
QHash<Thing *, NetworkDeviceMonitor *> m_monitors;
|
||||
|
||||
void setupConnection(ThingSetupInfo *info);
|
||||
};
|
||||
|
||||
#endif // INTEGRATIONPLUGINIDM_H
|
||||
|
||||
@ -13,16 +13,8 @@
|
||||
"displayName": "Navigator 2.0",
|
||||
"id": "1c95ac91-4eca-4cbf-b0f4-d60d35d069ed",
|
||||
"createMethods": ["user", "discovery"],
|
||||
"interfaces": ["thermostat", "connectable"],
|
||||
"interfaces": ["thermostat", "smartmeterconsumer", "connectable" ],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "05714e5c-d66a-4095-bbff-a0eb96fb035b",
|
||||
"name":"ipAddress",
|
||||
"displayName": "IP address",
|
||||
"inputType": "IPv4Address",
|
||||
"type": "QString",
|
||||
"defaultValue": "0.0.0.0"
|
||||
},
|
||||
{
|
||||
"id": "d178ca29-41a1-4f56-82ec-76a833c1de50",
|
||||
"name": "macAddress",
|
||||
@ -36,42 +28,14 @@
|
||||
"id": "cfd71e64-b666-45ef-8db0-8213acd82c5f",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connected changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "33c27167-8e24-4cc5-943c-d17cd03e0f68",
|
||||
"name": "power",
|
||||
"displayName": "Power",
|
||||
"displayNameEvent": "Power changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "f0f596bf-7e45-43ea-b3d4-767b82dd422a",
|
||||
"name": "temperature",
|
||||
"displayName": "Room temperature",
|
||||
"displayNameEvent": "Room temperature changed",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "fcf8e97f-a672-407f-94ae-30df15b310f4",
|
||||
"name": "waterTemperature",
|
||||
"displayName": "Water temperature",
|
||||
"displayNameEvent": "Water temperature changed",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "9f3462c2-7c42-4eeb-afc4-092e1e41a25d",
|
||||
"name": "outsideAirTemperature",
|
||||
"displayName": "Outside air temperature",
|
||||
"displayNameEvent": "Outside air temperature changed",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": 0
|
||||
@ -81,39 +45,99 @@
|
||||
"name": "targetTemperature",
|
||||
"displayName": "Target room temperature",
|
||||
"displayNameAction": "Set target room temperature",
|
||||
"displayNameEvent": "Target room temperature changed",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"minValue": "18",
|
||||
"maxValue": "28",
|
||||
"defaultValue": 22.00,
|
||||
"defaultValue": 21.00,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "fcf8e97f-a672-407f-94ae-30df15b310f4",
|
||||
"name": "waterTemperature",
|
||||
"displayName": "Water temperature",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "22543424-6f4f-4200-9f90-111df28d50c9",
|
||||
"name": "heatingOn",
|
||||
"displayName": "Heating",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "5719b9f6-6581-4ea8-b000-4ae6a852bb2d",
|
||||
"name": "coolingOn",
|
||||
"displayName": "Heating",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "9f3462c2-7c42-4eeb-afc4-092e1e41a25d",
|
||||
"name": "outsideTemperature",
|
||||
"displayName": "Outside temperature",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": 0,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "746244d6-dd37-4af8-b2ae-a7d8463e51e2",
|
||||
"name": "targetWaterTemperature",
|
||||
"displayName": "Target water temperature",
|
||||
"displayNameEvent": "Target water temperature changed",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
|
||||
"id": "b98fb325-100d-4eae-bf8d-97e8f7e1eb00",
|
||||
"name": "currentPowerConsumptionHeatPump",
|
||||
"displayName": "Current power consumption",
|
||||
"displayNameEvent": "Current power consumption heat pump changed",
|
||||
"displayNameAction": "Change current power consumption het pump",
|
||||
"name": "currentPower",
|
||||
"displayName": "Current power",
|
||||
"type": "double",
|
||||
"unit": "KiloWatt",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0.00,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "b457dc5a-920a-4c92-9956-a703e69f6084",
|
||||
"name": "totalEnergyConsumed",
|
||||
"displayName": "Total energy consumed",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
"id": "bfad9bbe-063d-497e-b13e-5de0f4738c91",
|
||||
"name": "energyProducedHeating",
|
||||
"displayName": "Total heating energy",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
"id": "9bef3a6c-4a6b-4023-a82e-c5263765310d",
|
||||
"name": "energyProducedCooling",
|
||||
"displayName": "Total cooling energy",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
"id": "0b5114ec-295f-42e6-a058-3e61f6da46b0",
|
||||
"name": "energyProducedHotWater",
|
||||
"displayName": "Total hot water energy",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
"id": "e539366b-44da-4119-b11b-497bcdb1f522",
|
||||
"name": "mode",
|
||||
"displayName": "Mode",
|
||||
"displayNameEvent": "Mode changed",
|
||||
"type": "QString",
|
||||
"defaultValue": "Off",
|
||||
"possibleValues": [
|
||||
@ -124,13 +148,27 @@
|
||||
"Defrost"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fb71c8f1-2b77-403d-b2ad-f3cba9baf237",
|
||||
"name": "operationMode",
|
||||
"displayName": "Operation mode",
|
||||
"type": "QString",
|
||||
"defaultValue": "Automatic",
|
||||
"possibleValues": [
|
||||
"Standby",
|
||||
"Automatic",
|
||||
"Absent",
|
||||
"Hot water only",
|
||||
"Heating cooling only"
|
||||
],
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "49fd83ee-ddf3-4477-9ee4-e01c53283b43",
|
||||
"name": "error",
|
||||
"displayName": "Error",
|
||||
"displayNameEvent": "Error changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
"type": "int",
|
||||
"defaultValue": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,61 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 "modbushelpers.h"
|
||||
|
||||
float ModbusHelpers::convertRegisterToFloat(const quint16 *reg) {
|
||||
|
||||
float result = 0.0;
|
||||
|
||||
if (reg != nullptr) {
|
||||
/* low-order byte is sent first, so swap order */
|
||||
quint32 tmp = 0;
|
||||
|
||||
tmp |= ((quint32)(reg[1]) << 16) & 0xFFFF0000;
|
||||
tmp |= reg[0];
|
||||
|
||||
/* copy value over to float variable without any conversion */
|
||||
/* needs to be done with char * to avoid pedantic compiler errors */
|
||||
memcpy((char *)&result, (char *)&tmp, sizeof(result));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QVector<quint16> ModbusHelpers::convertFloatToRegister(float value)
|
||||
{
|
||||
quint32 tmp = 0;
|
||||
memcpy((char *)&tmp, (char *)&value, sizeof(value));
|
||||
|
||||
QVector<quint16> reg;
|
||||
reg.append((quint16)(tmp));
|
||||
reg.append((quint16)((tmp & 0xFFFF0000) >> 16));
|
||||
return reg;
|
||||
}
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 MODBUSHELPERS_H
|
||||
#define MODBUSHELPERS_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QVector>
|
||||
|
||||
class ModbusHelpers {
|
||||
public:
|
||||
static float convertRegisterToFloat(const quint16 *reg);
|
||||
static QVector<quint16> convertFloatToRegister(float value);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -2,198 +2,151 @@
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1">
|
||||
<context>
|
||||
<name>Idm</name>
|
||||
<name>IntegrationPluginIdm</name>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="61"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="64"/>
|
||||
<location filename="../integrationpluginidm.cpp" line="46"/>
|
||||
<source>The discovery is not available.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../integrationpluginidm.cpp" line="111"/>
|
||||
<source>The MAC address is not known. Please reconfigure the thing.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../integrationpluginidm.cpp" line="123"/>
|
||||
<source>The host address is not known yet. Trying later again.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../integrationpluginidm.cpp" line="296"/>
|
||||
<source>Could not initialize the communication with the device.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>idm</name>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="47"/>
|
||||
<source>Connected</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: navigator2, EventType: connected, ID: {cfd71e64-b666-45ef-8db0-8213acd82c5f})
|
||||
----------
|
||||
The name of the StateType ({cfd71e64-b666-45ef-8db0-8213acd82c5f}) of ThingClass navigator2</extracomment>
|
||||
<extracomment>The name of the StateType ({cfd71e64-b666-45ef-8db0-8213acd82c5f}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="67"/>
|
||||
<source>Connected changed</source>
|
||||
<extracomment>The name of the EventType ({cfd71e64-b666-45ef-8db0-8213acd82c5f}) of ThingClass navigator2</extracomment>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="50"/>
|
||||
<source>Current power</source>
|
||||
<extracomment>The name of the StateType ({b98fb325-100d-4eae-bf8d-97e8f7e1eb00}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="70"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="73"/>
|
||||
<source>Current power consumption</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: navigator2, EventType: currentPowerConsumptionHeatPump, ID: {b98fb325-100d-4eae-bf8d-97e8f7e1eb00})
|
||||
----------
|
||||
The name of the StateType ({b98fb325-100d-4eae-bf8d-97e8f7e1eb00}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="76"/>
|
||||
<source>Current power consumption heat pump changed</source>
|
||||
<extracomment>The name of the EventType ({b98fb325-100d-4eae-bf8d-97e8f7e1eb00}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="79"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="82"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="53"/>
|
||||
<source>Error</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: navigator2, EventType: error, ID: {49fd83ee-ddf3-4477-9ee4-e01c53283b43})
|
||||
<extracomment>The name of the StateType ({49fd83ee-ddf3-4477-9ee4-e01c53283b43}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="56"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="59"/>
|
||||
<source>Heating</source>
|
||||
<extracomment>The name of the StateType ({5719b9f6-6581-4ea8-b000-4ae6a852bb2d}) of ThingClass navigator2
|
||||
----------
|
||||
The name of the StateType ({49fd83ee-ddf3-4477-9ee4-e01c53283b43}) of ThingClass navigator2</extracomment>
|
||||
The name of the StateType ({22543424-6f4f-4200-9f90-111df28d50c9}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="85"/>
|
||||
<source>Error changed</source>
|
||||
<extracomment>The name of the EventType ({49fd83ee-ddf3-4477-9ee4-e01c53283b43}) of ThingClass navigator2</extracomment>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="62"/>
|
||||
<source>MAC address</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: navigator2, Type: thing, ID: {d178ca29-41a1-4f56-82ec-76a833c1de50})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="88"/>
|
||||
<source>IP address</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: navigator2, Type: thing, ID: {05714e5c-d66a-4095-bbff-a0eb96fb035b})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="91"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="94"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="65"/>
|
||||
<source>Mode</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: navigator2, EventType: mode, ID: {e539366b-44da-4119-b11b-497bcdb1f522})
|
||||
----------
|
||||
The name of the StateType ({e539366b-44da-4119-b11b-497bcdb1f522}) of ThingClass navigator2</extracomment>
|
||||
<extracomment>The name of the StateType ({e539366b-44da-4119-b11b-497bcdb1f522}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="97"/>
|
||||
<source>Mode changed</source>
|
||||
<extracomment>The name of the EventType ({e539366b-44da-4119-b11b-497bcdb1f522}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="100"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="68"/>
|
||||
<source>Navigator 2.0</source>
|
||||
<extracomment>The name of the ThingClass ({1c95ac91-4eca-4cbf-b0f4-d60d35d069ed})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="103"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="106"/>
|
||||
<source>Outside air temperature</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: navigator2, EventType: outsideAirTemperature, ID: {9f3462c2-7c42-4eeb-afc4-092e1e41a25d})
|
||||
----------
|
||||
The name of the StateType ({9f3462c2-7c42-4eeb-afc4-092e1e41a25d}) of ThingClass navigator2</extracomment>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="71"/>
|
||||
<source>Operation mode</source>
|
||||
<extracomment>The name of the StateType ({fb71c8f1-2b77-403d-b2ad-f3cba9baf237}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="109"/>
|
||||
<source>Outside air temperature changed</source>
|
||||
<extracomment>The name of the EventType ({9f3462c2-7c42-4eeb-afc4-092e1e41a25d}) of ThingClass navigator2</extracomment>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="74"/>
|
||||
<source>Outside temperature</source>
|
||||
<extracomment>The name of the StateType ({9f3462c2-7c42-4eeb-afc4-092e1e41a25d}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="112"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="115"/>
|
||||
<source>Power</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: navigator2, EventType: power, ID: {33c27167-8e24-4cc5-943c-d17cd03e0f68})
|
||||
----------
|
||||
The name of the StateType ({33c27167-8e24-4cc5-943c-d17cd03e0f68}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="118"/>
|
||||
<source>Power changed</source>
|
||||
<extracomment>The name of the EventType ({33c27167-8e24-4cc5-943c-d17cd03e0f68}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="121"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="124"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="77"/>
|
||||
<source>Room temperature</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: navigator2, EventType: temperature, ID: {f0f596bf-7e45-43ea-b3d4-767b82dd422a})
|
||||
----------
|
||||
The name of the StateType ({f0f596bf-7e45-43ea-b3d4-767b82dd422a}) of ThingClass navigator2</extracomment>
|
||||
<extracomment>The name of the StateType ({f0f596bf-7e45-43ea-b3d4-767b82dd422a}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="127"/>
|
||||
<source>Room temperature changed</source>
|
||||
<extracomment>The name of the EventType ({f0f596bf-7e45-43ea-b3d4-767b82dd422a}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="130"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="80"/>
|
||||
<source>Set target room temperature</source>
|
||||
<extracomment>The name of the ActionType ({efae7493-68c3-4cb9-853c-81011bdf09ca}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="133"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="136"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="139"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="83"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="86"/>
|
||||
<source>Target room temperature</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: navigator2, ActionType: targetTemperature, ID: {efae7493-68c3-4cb9-853c-81011bdf09ca})
|
||||
----------
|
||||
The name of the ParamType (ThingClass: navigator2, EventType: targetTemperature, ID: {efae7493-68c3-4cb9-853c-81011bdf09ca})
|
||||
----------
|
||||
The name of the StateType ({efae7493-68c3-4cb9-853c-81011bdf09ca}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="142"/>
|
||||
<source>Target room temperature changed</source>
|
||||
<extracomment>The name of the EventType ({efae7493-68c3-4cb9-853c-81011bdf09ca}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="145"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="148"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="89"/>
|
||||
<source>Target water temperature</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: navigator2, EventType: targetWaterTemperature, ID: {746244d6-dd37-4af8-b2ae-a7d8463e51e2})
|
||||
----------
|
||||
The name of the StateType ({746244d6-dd37-4af8-b2ae-a7d8463e51e2}) of ThingClass navigator2</extracomment>
|
||||
<extracomment>The name of the StateType ({746244d6-dd37-4af8-b2ae-a7d8463e51e2}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="151"/>
|
||||
<source>Target water temperature changed</source>
|
||||
<extracomment>The name of the EventType ({746244d6-dd37-4af8-b2ae-a7d8463e51e2}) of ThingClass navigator2</extracomment>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="92"/>
|
||||
<source>Total cooling energy</source>
|
||||
<extracomment>The name of the StateType ({9bef3a6c-4a6b-4023-a82e-c5263765310d}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="154"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="157"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="95"/>
|
||||
<source>Total energy consumed</source>
|
||||
<extracomment>The name of the StateType ({b457dc5a-920a-4c92-9956-a703e69f6084}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="98"/>
|
||||
<source>Total heating energy</source>
|
||||
<extracomment>The name of the StateType ({bfad9bbe-063d-497e-b13e-5de0f4738c91}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="101"/>
|
||||
<source>Total hot water energy</source>
|
||||
<extracomment>The name of the StateType ({0b5114ec-295f-42e6-a058-3e61f6da46b0}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="104"/>
|
||||
<source>Water temperature</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: navigator2, EventType: waterTemperature, ID: {fcf8e97f-a672-407f-94ae-30df15b310f4})
|
||||
----------
|
||||
The name of the StateType ({fcf8e97f-a672-407f-94ae-30df15b310f4}) of ThingClass navigator2</extracomment>
|
||||
<extracomment>The name of the StateType ({fcf8e97f-a672-407f-94ae-30df15b310f4}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="160"/>
|
||||
<source>Water temperature changed</source>
|
||||
<extracomment>The name of the EventType ({fcf8e97f-a672-407f-94ae-30df15b310f4}) of ThingClass navigator2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="163"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="166"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="107"/>
|
||||
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/idm/plugininfo.h" line="110"/>
|
||||
<source>iDM</source>
|
||||
<extracomment>The name of the vendor ({6f54e4b0-1057-4004-87a9-97fdf4581625})
|
||||
----------
|
||||
The name of the plugin Idm ({3968d86d-d51a-4ad1-a185-91faa017e38f})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>IntegrationPluginIdm</name>
|
||||
<message>
|
||||
<location filename="../integrationpluginidm.cpp" line="50"/>
|
||||
<source>No IP address given</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../integrationpluginidm.cpp" line="65"/>
|
||||
<source>IP address already in use</source>
|
||||
The name of the plugin idm ({3968d86d-d51a-4ad1-a185-91faa017e38f})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
|
||||
Reference in New Issue
Block a user