diff --git a/debian/control b/debian/control index 35e0a9e..0e628d8 100644 --- a/debian/control +++ b/debian/control @@ -29,6 +29,22 @@ Description: nymea.io plugin for Drexel & Weiss heat pumps This package will install the nymea.io plugin for Drexel & Weiss heat pumps +Package: nymea-plugin-idm +Architecture: any +Section: libs +Depends: ${shlibs:Depends}, + ${misc:Depends}, + nymea-plugins-modbus-translations, +Description: nymea.io plugin for iDM heat pumps + The nymea daemon is a plugin based IoT (Internet of Things) server. The + server works like a translator for devices, things and services and + allows them to interact. + With the powerful rule engine you are able to connect any device available + in the system and create individual scenes and behaviors for your environment. + . + This package will install the nymea.io plugin for iDM heat pumps + + Package: nymea-plugin-modbuscommander Architecture: any Section: libs diff --git a/debian/nymea-plugin-idm.install.in b/debian/nymea-plugin-idm.install.in new file mode 100644 index 0000000..5ef2f03 --- /dev/null +++ b/debian/nymea-plugin-idm.install.in @@ -0,0 +1 @@ +usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_devicepluginidm.so diff --git a/idm/README.md b/idm/README.md new file mode 100644 index 0000000..74a43f4 --- /dev/null +++ b/idm/README.md @@ -0,0 +1,15 @@ +# iDM + +## Supported Things + +## More + +https://www.idm-energie.at/en/ + +** Modbus TCP communication not working ** + * Is "Modbus TCP" selected in the "Building Management System" menu? + * Is the Modbus TCP device and the heat pump in the same network? + * Is there an IP address conflict? + * Has the heat pump set the IP address manually? IP address should be set manually, because with "DHCP" the IP address can change (e.g. after a power failure). + * Was the connection made via a switch, possibly blocking this communication? If so, integrate the Modbus TCP device directly (without a switch). + diff --git a/idm/idm.cpp b/idm/idm.cpp new file mode 100644 index 0000000..2fcbc81 --- /dev/null +++ b/idm/idm.cpp @@ -0,0 +1,43 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2020, 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 . +* +* 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" + +Idm::Idm(const QHostAddress &address, QObject *parent) : + QObject(parent), + m_hostAddress(address) +{ + m_modbusMaster = new ModbusTCPMaster(address, 502, this); +} + +void Idm::getOutsideTemperature() +{ + m_modbusMaster-> +} diff --git a/idm/idm.h b/idm/idm.h new file mode 100644 index 0000000..4c6fbd2 --- /dev/null +++ b/idm/idm.h @@ -0,0 +1,105 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2020, 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 . +* +* 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 + +#include "../modbus/modbustcpmaster.h" + +class Idm : public QObject +{ + Q_OBJECT +public: + explicit Idm(const QHostAddress &address, QObject *parent = nullptr); + void getOutsideTemperature(); + void getCurrentFaultNumber(); + + +private: + + enum IscModus { + KeineAbwarme = 0, + Heizung = 1, + Warmwasser = 4, + Warmequelle = 8, + }; + + enum RegisterList { + OutsideTemperature = 1000, + MeanOutsideTemperature = 1002, + CurrentFaultNumber = 1004, + OperationModeSystem = 1005, + SmartGridStatus = 1006, + HeatStorageTemperature = 1008, + ColdStorageTemperature = 1010, + DrinkingWaterHeaterTempBelow = 1012, + DrinkingWaterHeaterTempAbove = 1014, + HotWaterTapTemperature = 1030, + TargetHotWaterTemperature = 1032, + HeatPumpOperatingMode = 1090, + SummationFaultHeatPump = 1099, + Humiditysensor = 1392, + ExternalOutsideTemperature = 1690, + ExternalHumidity = 1692, + ExternalRequestTemperatureHeating = 1694, //Externe Anforderungstemperatur Heizen + ExternalRequestTemperatureCooling = 1695, // Externe Anforderungstemperatur Kühlen + HeatingRequirement = 1710 + CoolingRequirement = 1711, + HotWaterChargingRequirement = 1712, // Anforderung Warmwasserladung + //Wärmemenge Heizen + //Wärmemenge Kühlen, + //Wärmemenge Warmwasser, + //Wärmemenge Abtauung, + //Wärmemenge Passive Kühlung, + //Wärmemenge Solar, + //Wärmemenge Elektroheizeinsatz, + Momentanleistung + SolarKollektortemperatur + SolarKollektorrücklauftemperatur + SolarLadetemperatur + MomentanleistungSolar, + SolarOperatingMode = + ISCModus = 1874, + AcknowledgeFaultMessages = 1999, // Störmeldungen quittieren + Aktueller PV-Überschuss + Aktueller PV Produktion + Aktuelle Leistungsaufnahme Wärmepumpe + }; + + QHostAddress m_hostAddress; + ModbusTCPMaster *m_modbusMaster = nullptr; + +signals: + +}; + +#endif // IDM_H diff --git a/idm/idm.pro b/idm/idm.pro new file mode 100644 index 0000000..bc0cf39 --- /dev/null +++ b/idm/idm.pro @@ -0,0 +1,15 @@ +include(../plugins.pri) + +QT += \ + network \ + serialbus \ + +SOURCES += \ + idm.cpp \ + integrationpluginidm.cpp \ + ../modbus/modbustcpmaster.cpp \ + +HEADERS += \ + idm.h \ + integrationpluginidm.h \ + ../modbus/modbustcpmaster.h \ diff --git a/idm/integrationpluginidm.cpp b/idm/integrationpluginidm.cpp new file mode 100644 index 0000000..af78481 --- /dev/null +++ b/idm/integrationpluginidm.cpp @@ -0,0 +1,80 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2020, 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 . +* +* 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 "integrationpluginidm.h" +#include "plugininfo.h" + +void IntegrationPluginIdm::discoverThings(ThingDiscoveryInfo *info) +{ + if (info->thingClassId() == navigator2ThingClassId) { + //TODO add discovery method + } +} + +void IntegrationPluginIdm::setupThing(ThingSetupInfo *info) +{ + Thing *thing = info->thing(); + + if (thing->thingClassId() == navigator2ThingClassId) { + QHostAddress hostAddress = QHostAddress(thing->paramValue(navigator2ThingIpAddressParamTypeId).toString()); + Idm *idm = new Idm(hostAddress, this); + m_idmConnections.insert(thing, idm); + } + +} + +void IntegrationPluginIdm::postSetupThing(Thing *thing) +{ + if (thing->thingClassId() == navigator2ThingClassId) { + Idm *idm = m_idmConnections.value(thing); + + } +} + +void IntegrationPluginIdm::thingRemoved(Thing *thing) +{ + if (m_idmConnections.contains(thing)) + m_idmConnections.take(thing)->deleteLater(); +} + +void IntegrationPluginIdm::executeAction(ThingActionInfo *info) +{ + Thing *thing = info->thing(); + Action action = info->action(); + + if (thing->thingClassId() == navigator2ThingClassId) { + if (action.actionTypeId() == navigator2PowerActionTypeId) { + } else { + Q_ASSERT_X(false, "executeAction", QString("Unhandled action: %1").arg(action.actionTypeId().toString()).toUtf8()); + } + } else { + Q_ASSERT_X(false, "executeAction", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8()); + } +} diff --git a/idm/integrationpluginidm.h b/idm/integrationpluginidm.h new file mode 100644 index 0000000..58d2910 --- /dev/null +++ b/idm/integrationpluginidm.h @@ -0,0 +1,97 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2020, 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 . +* +* 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 INTEGRATIONPLUGINIDM_H +#define INTEGRATIONPLUGINIDM_H + +#include "integrations/integrationplugin.h" +#include "plugintimer.h" + +#include "idm.h" + +#include + +class IntegrationPluginIdm: public IntegrationPlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginidm.json") + Q_INTERFACES(IntegrationPlugin) + + +public: + explicit IntegrationPluginIdm(); + + 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: + + enum IdmSysMode { + IdmSysModeStandby = 0, + IdmSysModeAutomatic, + IdmSysModeAway, + IdmSysModeOnlyWarmwater, + IdmSysModeOnlyRoomHeating + }; + + enum IdmSmartGridMode { + EVUSperreKeinPVErtrag, + EVUBezugKeinPVErtrag, + KeinEVUBezugPVErtrag, + EVUSperrePVErtrag + }; + + enum IdmStatus { + Heating = 2, + Standby = 3, + Boosted = 4, + HeatFinished = 5, + Setup = 9, + ErrorOvertempFuseBlown = 201, + ErrorOvertempMeasured = 202, + ErrorOvertempElectronics = 203, + ErrorHardwareFault = 204, + ErrorTempSensor = 205 + }; + + PluginTimer *m_refreshTimer = nullptr; + QHash m_idmConnections; + QHash m_asyncActions; + +private slots: + void onRefreshTimer(); +}; + +#endif // INTEGRATIONPLUGINIDM_H + diff --git a/idm/integrationpluginidm.json b/idm/integrationpluginidm.json new file mode 100644 index 0000000..0bb2721 --- /dev/null +++ b/idm/integrationpluginidm.json @@ -0,0 +1,180 @@ +{ + "name": "Idm", + "displayName": "iDM", + "id": "3968d86d-d51a-4ad1-a185-91faa017e38f", + "vendors": [ + { + "name": "Idm", + "displayName": "iDM", + "id": "6f54e4b0-1057-4004-87a9-97fdf4581625", + "thingClasses": [ + { + "name": "navigator2", + "displayName": "Navigator 2.0", + "id": "1c95ac91-4eca-4cbf-b0f4-d60d35d069ed", + "createMethods": ["Discovery"], + "interfaces": ["heating", "temperaturesensor", "connectable"], + "paramTypes": [ + { + "id": "05714e5c-d66a-4095-bbff-a0eb96fb035b", + "name":"ipAddress", + "displayName": "IP address", + "type": "QString" + } + ], + "stateTypes":[ + { + "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", + "displayNameAction": "Change power", + "type": "bool", + "defaultValue": 0, + "writable": true + }, + { + "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 + }, + { + "id": "efae7493-68c3-4cb9-853c-81011bdf09ca", + "name": "targetTemperature", + "displayName": "Target room temperature", + "displayNameEvent": "Target room temperature changed", + "displayNameAction": "Change room target temperature", + "type": "double", + "unit": "DegreeCelsius", + "minValue": 14.00, + "maxValue": 26.00, + "defaultValue": 22.00, + "writable": true + }, + { + "id": "746244d6-dd37-4af8-b2ae-a7d8463e51e2", + "name": "targetWaterTemperature", + "displayName": "Target water temperature", + "displayNameEvent": "Target water temperature changed", + "displayNameAction": "Change water target temperature", + "type": "double", + "unit": "DegreeCelsius", + "minValue": 20.00, + "maxValue": 55.00, + "defaultValue": 46.00, + "writable": true + }, + { + "id": "e539366b-44da-4119-b11b-497bcdb1f522", + "name": "mode", + "displayName": "Mode", + "displayNameEvent": "Mode changed", + "type": "QString", + "defaultValue": "Off", + "possibleValues": [ + "Off", + "Heating", + "Cooling", + "Hot water", + "Defrost" + ] + }, + { + "id": "49fd83ee-ddf3-4477-9ee4-e01c53283b43", + "name": "error", + "displayName": "Error", + "displayNameEvent": "Error changed", + "type": "bool", + "defaultValue": false + } + ], + "actionTypes": [ + { + "id": "29b65c13-46e9-49b1-970a-68252bdfeadc", + "name": "externTemperature", + "displayName": "Extern temperature", + "paramTypes" : [ + { + "id": "d60fcb0c-19b5-4cac-9b95-a1b414518385", + "name": "temperature", + "displayName": "Temperature", + "type": "double", + "defaultValue": 0, + "unit": "DegreeCelsius" + } + ] + }, + { + "id": "046f2e72-899a-4d82-91d3-fd268c784a1c", + "name": "externHumidity", + "displayName": "Extern humidity", + "paramTypes" : [ + { + "id": "034b9a8c-1a5a-45da-8422-393273d0a159", + "name": "humidity", + "displayName": "humidity", + "type": "int", + "defaultValue": 0, + "minValue": 0, + "maxValue": 100, + "unit": "Percentage" + } + ] + }, + { + "id": "87633d1f-3826-4bf0-9a2c-46a927446eb5", + "name": "pvEnergy", + "displayName": "Set avilable PV Energy", + "paramTypes" : [ + { + "id": "84b251ab-33b5-45e5-9a5c-468e3affe821", + "name": "energy", + "displayName": "Energy", + "type": "double", + "defaultValue": 0.00, + "minValue": 0.00, + "unit": "KiloWatt" + } + ] + } + ] + } + ] + } + ] +} + + + + diff --git a/idm/meta.json b/idm/meta.json new file mode 100644 index 0000000..71b2812 --- /dev/null +++ b/idm/meta.json @@ -0,0 +1,13 @@ +{ + "title": "iDM", + "tagline": "Control iDM network enabled heat pumps.", + "icon": "idm.png", + "stability": "consumer", + "offline": true, + "technologies": [ + "network" + ], + "categories": [ + "heating" + ] +} diff --git a/nymea-plugins-modbus.pro b/nymea-plugins-modbus.pro index 694d2c8..207d8bc 100644 --- a/nymea-plugins-modbus.pro +++ b/nymea-plugins-modbus.pro @@ -6,6 +6,7 @@ PLUGIN_DIRS = \ mypv \ sunspec \ unipi \ + idm \ wallbe \ webasto \