From 11d40425bec1131d896e7ea7f44b804a0c7a8cf5 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Thu, 27 Jan 2022 15:06:05 +0100 Subject: [PATCH] Split energymeters plugin into separate inepro and bgetech plugins --- bgetech/README.md | 9 + bgetech/bg-etech.jpg | Bin 0 -> 5535 bytes .../energymeters.pro => bgetech/bgetech.pro | 6 +- bgetech/integrationpluginbgetech.cpp | 227 +++++++ .../integrationpluginbgetech.h | 24 +- bgetech/integrationpluginbgetech.json | 230 +++++++ {energymeters => bgetech}/meta.json | 6 +- .../sdm630-registers.json | 0 .../sdm630modbusrtuconnection.cpp | 0 .../sdm630modbusrtuconnection.h | 0 ...e373f492-4527-4d5f-aa48-34d38c55b0d6-de.ts | 363 +++++++++++ ...3f492-4527-4d5f-aa48-34d38c55b0d6-en_US.ts | 363 +++++++++++ debian/control | 18 +- debian/nymea-plugin-bgetech.install.in | 2 + debian/nymea-plugin-energymeters.install.in | 2 - debian/nymea-plugin-inepro.install.in | 2 + energymeters/README.md | 21 - .../integrationpluginenergymeters.cpp | 354 ----------- .../integrationpluginenergymeters.json | 452 -------------- ...56e95111-fb6b-4f63-9a0a-a5ee001e89ed-de.ts | 577 ------------------ ...95111-fb6b-4f63-9a0a-a5ee001e89ed-en_US.ts | 577 ------------------ inepro/README.md | 9 + inepro/inepro.jpg | Bin 0 -> 181361 bytes inepro/inepro.pro | 14 + inepro/integrationplugininepro.cpp | 229 +++++++ inepro/integrationplugininepro.h | 66 ++ inepro/integrationplugininepro.json | 230 +++++++ inepro/meta.json | 13 + .../pro380-registers.json | 0 .../pro380modbusrtuconnection.cpp | 0 .../pro380modbusrtuconnection.h | 0 ...9bc19f8c-ff9e-4036-95a4-c79038709656-de.ts | 363 +++++++++++ ...19f8c-ff9e-4036-95a4-c79038709656-en_US.ts | 363 +++++++++++ nymea-plugins-modbus.pro | 5 +- 34 files changed, 2515 insertions(+), 2010 deletions(-) create mode 100644 bgetech/README.md create mode 100644 bgetech/bg-etech.jpg rename energymeters/energymeters.pro => bgetech/bgetech.pro (59%) create mode 100644 bgetech/integrationpluginbgetech.cpp rename energymeters/integrationpluginenergymeters.h => bgetech/integrationpluginbgetech.h (76%) create mode 100644 bgetech/integrationpluginbgetech.json rename {energymeters => bgetech}/meta.json (57%) rename {energymeters => bgetech}/sdm630-registers.json (100%) rename {energymeters => bgetech}/sdm630modbusrtuconnection.cpp (100%) rename {energymeters => bgetech}/sdm630modbusrtuconnection.h (100%) create mode 100644 bgetech/translations/e373f492-4527-4d5f-aa48-34d38c55b0d6-de.ts create mode 100644 bgetech/translations/e373f492-4527-4d5f-aa48-34d38c55b0d6-en_US.ts create mode 100644 debian/nymea-plugin-bgetech.install.in delete mode 100644 debian/nymea-plugin-energymeters.install.in create mode 100644 debian/nymea-plugin-inepro.install.in delete mode 100644 energymeters/README.md delete mode 100644 energymeters/integrationpluginenergymeters.cpp delete mode 100644 energymeters/integrationpluginenergymeters.json delete mode 100644 energymeters/translations/56e95111-fb6b-4f63-9a0a-a5ee001e89ed-de.ts delete mode 100644 energymeters/translations/56e95111-fb6b-4f63-9a0a-a5ee001e89ed-en_US.ts create mode 100644 inepro/README.md create mode 100644 inepro/inepro.jpg create mode 100644 inepro/inepro.pro create mode 100644 inepro/integrationplugininepro.cpp create mode 100644 inepro/integrationplugininepro.h create mode 100644 inepro/integrationplugininepro.json create mode 100644 inepro/meta.json rename {energymeters => inepro}/pro380-registers.json (100%) rename {energymeters => inepro}/pro380modbusrtuconnection.cpp (100%) rename {energymeters => inepro}/pro380modbusrtuconnection.h (100%) create mode 100644 inepro/translations/9bc19f8c-ff9e-4036-95a4-c79038709656-de.ts create mode 100644 inepro/translations/9bc19f8c-ff9e-4036-95a4-c79038709656-en_US.ts diff --git a/bgetech/README.md b/bgetech/README.md new file mode 100644 index 0000000..0fd1664 --- /dev/null +++ b/bgetech/README.md @@ -0,0 +1,9 @@ +# B+G E-Tech + +This plugin adds support for the B+G E-Tech SDM630 energy meter connected via Modbus RTU. + +# Setup instructions +First, set up a Modbus RTU resource using the configured settings of your meter. Once +that's set up, the SDM630 can be set up like any other thing. During discovery, nymea will +offer the configured Modbus resources as possible connections. Select the one that +you've set up previously. diff --git a/bgetech/bg-etech.jpg b/bgetech/bg-etech.jpg new file mode 100644 index 0000000000000000000000000000000000000000..917bc0d533ed2d4f6ff3bd3d95971bfbbed7cd68 GIT binary patch literal 5535 zcmeHLX;f3mwmy*|7!{WTttR2j{*V$2|*Gd$+-u;{hs!ZyI#My`q#UaRVQm#o$RV_?{Dv2 z6|ff^1-4sR9J2smFaUr-9{>~pCWr0JzqiNQ9a8o6((*s+?W-EGUt3odbuP>=$XE54 zm8GiHPv(}Y5eM`%_Nj)PJ9Wk{JX-ZzRbyQQH~<_5M1@5}MTA8~MMU9nQ8C1J1Y+}M zgtWNC*6niA^73-hva*UQ>PSVUUCOeus{2%T?b)lLsiA<>($zxgs-rYe8%khsI2<8{ zkU}7&P>QmOsK4C6=YXUb&X4D3(1Bq3azgoTBK;TyPM zn-3DXotPNCzh$=bu4m!+ga#1EOGJGw2_5(wfNmJ?KVbjx^JmYd4{r{7ur%)xeLuMR@q;P8 z=E%yPVi5SQb%X~eGD{~`VnN_$ULgoDG(ce4w(PEHAPa863>+$;J<71zJ^OZV>h>U5 zQz&|p{o_i7lXzw<$iaz+L$vG*;kn+_w5|>iIB%SQEQmmgn11Uwj@jWdFpIkB z;@ZfNkP5#Q{2fsWZxz+lSPj1%I6u)f8P#vjZ=*;C8SfYZN@E7hauGFW@0@pIpHH)t zc>VOUr2|@Q~`lH+HGiLdJMZd33+VP7zD%4f#*8CCj?xOg59Fy*YCHqmT&S6?JkI$9}l8Za=r0sS;m?4G#h@xL*g4f zXbIQ|5B)y4@2bFj+X(@kxMEIDcAYSar_{P|u+=t)+bKDtgj7+t{6OQ?+LD%fmZ-LT z^_?@{ipOFxTv67`m#J2E)b=~X{~Kh?{D)4#CFBSQ0N=)8rpb-UM z?Y&Pwi<9<9Tt1i)hL$BS4-6F5w7Q~;^Vgr{Cu9<>vcDoVnTO`{j)L946?jgy zf3P_rxRgQXii5zI<(DB;Mp^jSY8|}I?3qr^ih9L5?iI=Gbj&ybWOvIk0{J5#|a)vKQv2}~sA{wdh*6ZGX&#=3oOS6sYax^oV=O6s#YVMUR z{J2@tgp!I{yQOt^7P>35hI_eG*V2O!Fj#YP+!cv{^G24S!U~n{Fe1$^3^l!Z&_o zwM#Xr@h83dyO%jU9Snllt_30gWL7uK6|w>88c~s|WqU80(mcLy*KmmVyQ;-S-8J?} zr!$M+H10G{*N0 z6usM{L{~t-ODn_=-cMe@m3Fi!s9Yoag=p`|iLz@L8xn4OJ-T8_gnL>8CogeHoKUV?*yAItZ zWL+<-O4Fi9Vf8G9vAdHwp7w(y1?Gv%5|@Mo+NDV#5D3+PT&rbPRNB=%y9!=0-4&hL zsQlJ;;VdV@DB^-yU$B7*ZShWAr01N&+z8P>EREU3uO-fFGBu}Pg|s7oiQm~cI5PES zwsR%y^uId*px^3$I(RIn^sNi5;z=Oj2GyVr3tBSEGNH!g?%;R1JFDY|kKw{SjwUT2 zFB-Bj&*#={Fyq>!b44c)2LwH~&h$;Ql|x;i5)_L4X|QeuukLdaTilN(Q5C0LqpeZ` z>lxF^Hdn)5=O3&)u1xohEzFC{SjerujT!Uc!UdNr@Ef7Wvq3T+#|VMI_pUlnK@{vE zk>W8Q_YmJv6}X-tVCO5a#wCA@G2*S0`7z0>g+oe}m42mBdJEGpGak+7_6gd~7FTKX zTUsqiTz1!Hmd1@Ts0pC) zqk+kW)Z|tCZ4a7T*@c}g>Irq-1#3vQG=WxP<;nzatw-1?C>~N!tHQ~ zvQ33!vcdsUJ))(%CTz6Lzon(U1-bCJ(aTEFEg@U}3-*YbGDFGA^ zc%~ldS?usCWO?p~?BAphhK~r8vqBy2c7IraB0Vl?6uE}zBW@H%mI1M@fhoZkIYZwl zjohr*Sa}fW%7l2|q{BULA zb!j1-O9;5g&oP|eWz8%t5HEQ+vl2=jp8R#g6H0Qw?UxyGvtbTTMelu@T_@Fs)~~r) zTdptFvO8<_H->nww~Irbk?is$2*e*c-O33mKk_G%rf{8xVNlg4XF$g+5Rk&QzeKLx z!YsL@a4SBuHhlx^KH%7aCMk_xneuM)$O9xv zQ_=MF*)?kVWP$^|V`QDaz}Uv33%1j_hj9YQGOnfB$O@&s*Oa91ql5|j4R?vr^>e7H zndg;Xf{js?w6%fe$ztcu?7qRZIf1OvMdEw3Hwau@1cCZ498uC#xF-WqO-`RmNF#n$ z-eQkCVr;S%V$jCPPnaJ{xY%JX^Rdm@>77{(gZ}QC8?jfCxO}wi#@y_;!S!of>2U8S zNiLm=>~#gtCD|FH#ii$cl?U5mp5oDUltL>*{yl&8g`B9u->nrRdA~qOZ0;clymwex zyk>Y(-=foL)nuKX^}=e1g)jZ)O@t<_{fK~_%bLy z2?I67rDNgEE1vE|xv@z{GW^w`!(uD_2WBY8%j-`x{8KW)V73xxe*}RRe|=_?;C?$V zy)1i;rX(Qr2xyjAgY`W6*V*Q&PQ2WTBB_xmeQ{<-cOh06=vLX2&2I}2BK^hgMxidYMNjVjs|ot zHC_MEw=7WPh~4J~2q*2680EgR7*uiZvm$xAr8MFbs`oQ%hg0%~3qF3FUDamBv?wBL z+2IFg8qTm^A3sogC|q|QJ^L>1!_MPcPgSnIc(9pSe#B?JM5vrN5@?IOMuQ>QGEY9& z)Ny}gyqvBxPvxywbyd8)piQT3R~(YS4|tc~Q&aOytuS-^v0lkuC2Q+*-C13~&(xU~ zGAzfxVq{PJl?kj^fFil}*OVfccB1y8hODezuW+u_uXQxT(&wlCh?Ldm9bI^X=mxJd)myNvB86~<%c=Rm*@cL`S+`?k6# zqa;O~=UtNUm=|4lFEO0LoMSTuQZbi_g_W?9%_he&i z@;hkO#A)Lq{I7oR`PV<+x1rX YbAA89#DAFjFMt1k{;whtB?R{U6GJy=9RL6T literal 0 HcmV?d00001 diff --git a/energymeters/energymeters.pro b/bgetech/bgetech.pro similarity index 59% rename from energymeters/energymeters.pro rename to bgetech/bgetech.pro index 9dd6c12..080685d 100644 --- a/energymeters/energymeters.pro +++ b/bgetech/bgetech.pro @@ -3,14 +3,12 @@ include(../plugins.pri) QT += serialport serialbus HEADERS += \ - integrationpluginenergymeters.h \ + integrationpluginbgetech.h \ sdm630modbusrtuconnection.h \ - pro380modbusrtuconnection.h \ ../modbus/modbusdatautils.h SOURCES += \ - integrationpluginenergymeters.cpp \ + integrationpluginbgetech.cpp \ sdm630modbusrtuconnection.cpp \ - pro380modbusrtuconnection.cpp \ ../modbus/modbusdatautils.cpp diff --git a/bgetech/integrationpluginbgetech.cpp b/bgetech/integrationpluginbgetech.cpp new file mode 100644 index 0000000..a1ecbda --- /dev/null +++ b/bgetech/integrationpluginbgetech.cpp @@ -0,0 +1,227 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 . +* +* 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 "integrationpluginbgetech.h" +#include "plugininfo.h" + +IntegrationPluginBGETech::IntegrationPluginBGETech() +{ +} + +void IntegrationPluginBGETech::init() +{ + connect(hardwareManager()->modbusRtuResource(), &ModbusRtuHardwareResource::modbusRtuMasterRemoved, this, [=] (const QUuid &modbusUuid){ + qCDebug(dcBgeTech()) << "Modbus RTU master has been removed" << modbusUuid.toString(); + + foreach (Thing *thing, myThings()) { + if (thing->paramValue(sdm630ThingModbusMasterUuidParamTypeId) == modbusUuid) { + qCWarning(dcBgeTech()) << "Modbus RTU hardware resource removed for" << thing << ". The thing will not be functional any more until a new resource has been configured for it."; + thing->setStateValue(sdm630ConnectedStateTypeId, false); + delete m_sdmConnections.take(thing); + } + } + }); +} + +void IntegrationPluginBGETech::discoverThings(ThingDiscoveryInfo *info) +{ + qCDebug(dcBgeTech()) << "Discover modbus RTU resources..."; + if (hardwareManager()->modbusRtuResource()->modbusRtuMasters().isEmpty()) { + info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("No Modbus RTU interface available. Please set up the Modbus RTU interface first.")); + return; + } + + uint slaveAddress = info->params().paramValue(sdm630DiscoverySlaveAddressParamTypeId).toUInt(); + if (slaveAddress > 254 || slaveAddress == 0) { + info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("The Modbus slave address must be a value between 1 and 254.")); + return; + } + + foreach (ModbusRtuMaster *modbusMaster, hardwareManager()->modbusRtuResource()->modbusRtuMasters()) { + qCDebug(dcBgeTech()) << "Found RTU master resource" << modbusMaster << "connected" << modbusMaster->connected(); + if (!modbusMaster->connected()) + continue; + + ThingDescriptor descriptor(info->thingClassId(), "SDM630", QString::number(slaveAddress) + " " + modbusMaster->serialPort()); + ParamList params; + params << Param(sdm630ThingSlaveAddressParamTypeId, slaveAddress); + params << Param(sdm630ThingModbusMasterUuidParamTypeId, modbusMaster->modbusUuid()); + descriptor.setParams(params); + info->addThingDescriptor(descriptor); + } + + info->finish(Thing::ThingErrorNoError); + return; +} + +void IntegrationPluginBGETech::setupThing(ThingSetupInfo *info) +{ + Thing *thing = info->thing(); + qCDebug(dcBgeTech()) << "Setup thing" << thing << thing->params(); + + uint address = thing->paramValue(sdm630ThingSlaveAddressParamTypeId).toUInt(); + if (address > 254 || address == 0) { + qCWarning(dcBgeTech()) << "Setup failed, slave address is not valid" << address; + info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("The Modbus address not valid. It must be a value between 1 and 254.")); + return; + } + + QUuid uuid = thing->paramValue(sdm630ThingModbusMasterUuidParamTypeId).toUuid(); + if (!hardwareManager()->modbusRtuResource()->hasModbusRtuMaster(uuid)) { + qCWarning(dcBgeTech()) << "Setup failed, hardware manager not available"; + info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("The Modbus RTU interface not available.")); + return; + } + + if (m_sdmConnections.contains(thing)) { + qCDebug(dcBgeTech()) << "Setup after rediscovery, cleaning up ..."; + m_sdmConnections.take(thing)->deleteLater(); + } + + Sdm630ModbusRtuConnection *sdmConnection = new Sdm630ModbusRtuConnection(hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), address, this); + connect(sdmConnection->modbusRtuMaster(), &ModbusRtuMaster::connectedChanged, this, [=](bool connected){ + if (connected) { + qCDebug(dcBgeTech()) << "Modbus RTU resource connected" << thing << sdmConnection->modbusRtuMaster()->serialPort(); + } else { + qCWarning(dcBgeTech()) << "Modbus RTU resource disconnected" << thing << sdmConnection->modbusRtuMaster()->serialPort(); + } + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::currentPhaseAChanged, this, [=](float currentPhaseA){ + thing->setStateValue(sdm630CurrentPhaseAStateTypeId, currentPhaseA); + thing->setStateValue(sdm630ConnectedStateTypeId, true); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::currentPhaseBChanged, this, [=](float currentPhaseB){ + thing->setStateValue(sdm630CurrentPhaseBStateTypeId, currentPhaseB); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::currentPhaseCChanged, this, [=](float currentPhaseC){ + thing->setStateValue(sdm630CurrentPhaseCStateTypeId, currentPhaseC); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::voltagePhaseAChanged, this, [=](float voltagePhaseA){ + thing->setStateValue(sdm630VoltagePhaseAStateTypeId, voltagePhaseA); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::voltagePhaseBChanged, this, [=](float voltagePhaseB){ + thing->setStateValue(sdm630VoltagePhaseBStateTypeId, voltagePhaseB); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::voltagePhaseCChanged, this, [=](float voltagePhaseC){ + thing->setStateValue(sdm630VoltagePhaseCStateTypeId, voltagePhaseC); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::totalCurrentPowerChanged, this, [=](float currentPower){ + thing->setStateValue(sdm630CurrentPowerStateTypeId, currentPower); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::powerPhaseAChanged, this, [=](float powerPhaseA){ + thing->setStateValue(sdm630CurrentPowerPhaseAStateTypeId, powerPhaseA); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::powerPhaseBChanged, this, [=](float powerPhaseB){ + thing->setStateValue(sdm630CurrentPowerPhaseBStateTypeId, powerPhaseB); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::powerPhaseCChanged, this, [=](float powerPhaseC){ + thing->setStateValue(sdm630CurrentPowerPhaseCStateTypeId, powerPhaseC); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::frequencyChanged, this, [=](float frequency){ + thing->setStateValue(sdm630FrequencyStateTypeId, frequency); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::totalEnergyConsumedChanged, this, [=](float totalEnergyConsumed){ + thing->setStateValue(sdm630TotalEnergyConsumedStateTypeId, totalEnergyConsumed); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::totalEnergyProducedChanged, this, [=](float totalEnergyProduced){ + thing->setStateValue(sdm630TotalEnergyProducedStateTypeId, totalEnergyProduced); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::energyProducedPhaseAChanged, this, [=](float energyProducedPhaseA){ + thing->setStateValue(sdm630EnergyProducedPhaseAStateTypeId, energyProducedPhaseA); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::energyProducedPhaseBChanged, this, [=](float energyProducedPhaseB){ + thing->setStateValue(sdm630EnergyProducedPhaseBStateTypeId, energyProducedPhaseB); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::energyProducedPhaseCChanged, this, [=](float energyProducedPhaseC){ + thing->setStateValue(sdm630EnergyProducedPhaseCStateTypeId, energyProducedPhaseC); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::energyConsumedPhaseAChanged, this, [=](float energyConsumedPhaseA){ + thing->setStateValue(sdm630EnergyConsumedPhaseAStateTypeId, energyConsumedPhaseA); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::energyConsumedPhaseBChanged, this, [=](float energyConsumedPhaseB){ + thing->setStateValue(sdm630EnergyConsumedPhaseBStateTypeId, energyConsumedPhaseB); + }); + + connect(sdmConnection, &Sdm630ModbusRtuConnection::energyConsumedPhaseCChanged, this, [=](float energyConsumedPhaseC){ + thing->setStateValue(sdm630EnergyConsumedPhaseCStateTypeId, energyConsumedPhaseC); + }); + + // FIXME: try to read before setup success + m_sdmConnections.insert(thing, sdmConnection); + info->finish(Thing::ThingErrorNoError); +} + +void IntegrationPluginBGETech::postSetupThing(Thing *thing) +{ + qCDebug(dcBgeTech) << "Post setup thing" << thing->name(); + if (!m_refreshTimer) { + m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(2); + connect(m_refreshTimer, &PluginTimer::timeout, this, [this] { + foreach (Thing *thing, myThings()) { + m_sdmConnections.value(thing)->update(); + } + }); + + qCDebug(dcBgeTech()) << "Starting refresh timer..."; + m_refreshTimer->start(); + } +} + +void IntegrationPluginBGETech::thingRemoved(Thing *thing) +{ + qCDebug(dcBgeTech()) << "Thing removed" << thing->name(); + + if (m_sdmConnections.contains(thing)) + m_sdmConnections.take(thing)->deleteLater(); + + if (myThings().isEmpty() && m_refreshTimer) { + qCDebug(dcBgeTech()) << "Stopping reconnect timer"; + hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer); + m_refreshTimer = nullptr; + } +} diff --git a/energymeters/integrationpluginenergymeters.h b/bgetech/integrationpluginbgetech.h similarity index 76% rename from energymeters/integrationpluginenergymeters.h rename to bgetech/integrationpluginbgetech.h index c836b42..c869f91 100644 --- a/energymeters/integrationpluginenergymeters.h +++ b/bgetech/integrationpluginbgetech.h @@ -28,28 +28,29 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#ifndef INTEGRATIONPLUGINENERGYMETERS_H -#define INTEGRATIONPLUGINENERGYMETERS_H +#ifndef INTEGRATIONPLUGINBGETECH_H +#define INTEGRATIONPLUGINBGETECH_H #include #include #include #include "sdm630modbusrtuconnection.h" -#include "pro380modbusrtuconnection.h" + +#include "extern-plugininfo.h" #include #include -class IntegrationPluginEnergyMeters : public IntegrationPlugin +class IntegrationPluginBGETech: public IntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginenergymeters.json") + Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginbgetech.json") Q_INTERFACES(IntegrationPlugin) public: - explicit IntegrationPluginEnergyMeters(); + explicit IntegrationPluginBGETech(); void init() override; void discoverThings(ThingDiscoveryInfo *info) override; void setupThing(ThingSetupInfo *info) override; @@ -59,14 +60,7 @@ public: private: PluginTimer *m_refreshTimer = nullptr; - QHash m_sdmConnections; // sdm 630 - QHash m_ineproConnections; // pro 380 - - QHash m_discoverySlaveAddressParamTypeIds; - QHash m_slaveIdParamTypeIds; - QHash m_modbusUuidParamTypeIds; - QHash m_connectionStateTypeIds; - + QHash m_sdmConnections; }; -#endif // INTEGRATIONPLUGINENERGYMETERS_H +#endif // INTEGRATIONPLUGINBGETECH_H diff --git a/bgetech/integrationpluginbgetech.json b/bgetech/integrationpluginbgetech.json new file mode 100644 index 0000000..ff36387 --- /dev/null +++ b/bgetech/integrationpluginbgetech.json @@ -0,0 +1,230 @@ +{ + "name": "bgeTech", + "displayName": "B+G E-Tech", + "id": "e373f492-4527-4d5f-aa48-34d38c55b0d6", + "paramTypes":[ ], + "vendors": [ + { + "name": "bgetech", + "displayName": "B+G E-Tech", + "id": "215035fe-95e8-43d8-a52e-0a31b787d902", + "thingClasses": [ + { + "name": "sdm630", + "displayName": "SDM630", + "id": "f37597bb-35fe-48f2-9617-343dd54c0903", + "createMethods": ["discovery"], + "interfaces": ["energymeter", "connectable"], + "discoveryParamTypes": [ + { + "id": "6ab43559-53ec-47ba-b8a0-8d3b7f8d90c2", + "name": "slaveAddress", + "displayName": "Slave address", + "type": "int", + "defaultValue": 1 + } + ], + "paramTypes": [ + { + "id": "ac77ea98-b006-486e-a3e8-b30a483f26c1", + "name": "slaveAddress", + "displayName": "Modbus slave address", + "type": "uint", + "defaultValue": 1 + }, + { + "id": "d90e9292-d03c-4f2a-957e-5d965018c9c9", + "name": "modbusMasterUuid", + "displayName": "Modbus RTU master", + "type": "QUuid", + "defaultValue": "", + "readOnly": true + } + ], + "stateTypes": [ + { + "id": "8050bd0b-1dad-4a7e-b632-c71ead3c9f8b", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "type": "bool", + "cached": false, + "defaultValue": false + }, + { + "id": "db018146-0441-4dc0-9834-6d43ebaf8311", + "name": "voltagePhaseA", + "displayName": "Voltage phase A", + "displayNameEvent": "Voltage phase A changed", + "type": "double", + "unit": "Volt", + "defaultValue": 0 + }, + { + "id": "406f6d02-d5eb-49b3-87da-3247568e6054", + "name": "voltagePhaseB", + "displayName": "Voltage phase B", + "displayNameEvent": "Voltage phase B changed", + "type": "double", + "unit": "Volt", + "defaultValue": 0 + }, + { + "id": "ace6294d-deaa-4d9a-af78-d64379bcb229", + "name": "voltagePhaseC", + "displayName": "Voltage phase C", + "displayNameEvent": "Voltage phase C changed", + "type": "double", + "unit": "Volt", + "defaultValue": 0 + }, + { + "id": "4baf1d08-5ffa-49cf-95ef-9527b0c6f081", + "name": "currentPhaseA", + "displayName": "Current phase A", + "displayNameEvent": "Current phase A changed", + "type": "double", + "unit": "Ampere", + "defaultValue": 0 + }, + { + "id": "99e47d06-0a6a-4bfd-b164-61ecb6ba2818", + "name": "currentPhaseB", + "displayName": "Current phase B", + "displayNameEvent": "Current phase B changed", + "type": "double", + "unit": "Ampere", + "defaultValue": 0 + }, + { + "id": "4a092a66-352d-4d60-90ab-6ac5f58b92fe", + "name": "currentPhaseC", + "displayName": "Current phase C", + "displayNameEvent": "Current phase C changed", + "type": "double", + "unit": "Ampere", + "defaultValue": 0 + }, + { + "id": "c824e97b-a6d1-4030-9d7a-00af6fb8e1c3", + "name": "currentPower", + "displayName": "Current power", + "displayNameEvent": "Current power changed", + "type": "double", + "unit": "Watt", + "defaultValue": 0 + }, + { + "id": "3982fb12-b179-40f7-9b27-36adb1cadd37", + "name": "currentPowerPhaseA", + "displayName": "Current power phase A", + "displayNameEvent": "Current power phase A changed", + "type": "double", + "unit": "Watt", + "defaultValue": 0 + }, + { + "id": "2a231c58-b095-4037-8394-a730431e70b8", + "name": "currentPowerPhaseB", + "displayName": "Current power phase B", + "displayNameEvent": "Current power phase B changed", + "type": "double", + "unit": "Watt", + "defaultValue": 0 + }, + { + "id": "ee8c4f0c-2b69-4210-9966-1553a592b06d", + "name": "currentPowerPhaseC", + "displayName": "Current power phase C", + "displayNameEvent": "Current power phase C changed", + "type": "double", + "unit": "Watt", + "defaultValue": 0 + }, + { + "id": "ab24f26c-dc15-4ec3-8d76-06a48285440b", + "name": "frequency", + "displayName": "Frequency", + "displayNameEvent": "Frequency changed", + "type": "double", + "unit": "Hertz", + "defaultValue": 0.00 + }, + { + "id": "98d858a8-22e8-4262-b5c7-25bb027942ad", + "name": "totalEnergyConsumed", + "displayName": "Total energy consumed", + "displayNameEvent": "Total energy consumed changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "e469b3ff-a4c2-42da-af35-ccafaef214af", + "name": "totalEnergyProduced", + "displayName": "Total energy produced", + "displayNameEvent": "Total energy produced changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "6ca06c81-fe75-4448-a22f-47c303421440", + "name": "energyConsumedPhaseA", + "displayName": "Energy consumed phase A", + "displayNameEvent": "Energy consumed phase A changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "fa2b879b-2a81-4bc8-9577-98082c4d9330", + "name": "energyConsumedPhaseB", + "displayName": "Energy consumed phase B", + "displayNameEvent": "Energy consumed phase B changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "4c084c9e-7a5d-42d1-96b2-a8a4b4a25713", + "name": "energyConsumedPhaseC", + "displayName": "Energy consumed phase C", + "displayNameEvent": "Energy consumed phase C changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "308fa88e-6054-4c79-b12a-be2d0a404ef6", + "name": "energyProducedPhaseA", + "displayName": "Energy produced phase A", + "displayNameEvent": "Energy produced phase A changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39", + "name": "energyProducedPhaseB", + "displayName": "Energy produced phase B", + "displayNameEvent": "Energy produced phase B changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff", + "name": "energyProducedPhaseC", + "displayName": "Energy produced phase C", + "displayNameEvent": "Energy produced phase C changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + } + ] + } + ] + } + ] +} diff --git a/energymeters/meta.json b/bgetech/meta.json similarity index 57% rename from energymeters/meta.json rename to bgetech/meta.json index 1158181..4e005bc 100644 --- a/energymeters/meta.json +++ b/bgetech/meta.json @@ -1,7 +1,7 @@ { - "title": "Energy Meters", - "tagline": "Connect Modbus RTU energy meters.", - "icon": "", + "title": "B+G E-Tech", + "tagline": "Connect B+G E-Tech energy meters.", + "icon": "bg-etech.jpg", "stability": "consumer", "offline": true, "technologies": [ diff --git a/energymeters/sdm630-registers.json b/bgetech/sdm630-registers.json similarity index 100% rename from energymeters/sdm630-registers.json rename to bgetech/sdm630-registers.json diff --git a/energymeters/sdm630modbusrtuconnection.cpp b/bgetech/sdm630modbusrtuconnection.cpp similarity index 100% rename from energymeters/sdm630modbusrtuconnection.cpp rename to bgetech/sdm630modbusrtuconnection.cpp diff --git a/energymeters/sdm630modbusrtuconnection.h b/bgetech/sdm630modbusrtuconnection.h similarity index 100% rename from energymeters/sdm630modbusrtuconnection.h rename to bgetech/sdm630modbusrtuconnection.h diff --git a/bgetech/translations/e373f492-4527-4d5f-aa48-34d38c55b0d6-de.ts b/bgetech/translations/e373f492-4527-4d5f-aa48-34d38c55b0d6-de.ts new file mode 100644 index 0000000..bee449d --- /dev/null +++ b/bgetech/translations/e373f492-4527-4d5f-aa48-34d38c55b0d6-de.ts @@ -0,0 +1,363 @@ + + + + + IntegrationPluginBGETech + + + No Modbus RTU interface available. Please set up the Modbus RTU interface first. + Keine Modbus RTU Schnittstelle verfügbar. Bitte richte zuerst die Modbus RTU Schnittstelle ein. + + + + The Modbus slave address must be a value between 1 and 254. + Die Modbus Adresse muss ein Wert zwischen 1 und 254 sein. + + + + The Modbus address not valid. It must be a value between 1 and 254. + Die Modbus Adresse is ungültig. Sie muss ein Wert zwischen 1 und 254 sein. + + + + The Modbus RTU interface not available. + Die Modbus RTU Schnittstelle ist nicht verfügbar. + + + + bgeTech + + + + B+G E-Tech + The name of the vendor ({215035fe-95e8-43d8-a52e-0a31b787d902}) +---------- +The name of the plugin bgeTech ({e373f492-4527-4d5f-aa48-34d38c55b0d6}) + B+G E-Tech + + + + + Connected + The name of the ParamType (ThingClass: sdm630, EventType: connected, ID: {8050bd0b-1dad-4a7e-b632-c71ead3c9f8b}) +---------- +The name of the StateType ({8050bd0b-1dad-4a7e-b632-c71ead3c9f8b}) of ThingClass sdm630 + + + + + Connected changed + The name of the EventType ({8050bd0b-1dad-4a7e-b632-c71ead3c9f8b}) of ThingClass sdm630 + Verbunden oder getrennt + + + + + Current phase A + The name of the ParamType (ThingClass: sdm630, EventType: currentPhaseA, ID: {4baf1d08-5ffa-49cf-95ef-9527b0c6f081}) +---------- +The name of the StateType ({4baf1d08-5ffa-49cf-95ef-9527b0c6f081}) of ThingClass sdm630 + Strom Phase A + + + + Current phase A changed + The name of the EventType ({4baf1d08-5ffa-49cf-95ef-9527b0c6f081}) of ThingClass sdm630 + Strom Phase A geändert + + + + + Current phase B + The name of the ParamType (ThingClass: sdm630, EventType: currentPhaseB, ID: {99e47d06-0a6a-4bfd-b164-61ecb6ba2818}) +---------- +The name of the StateType ({99e47d06-0a6a-4bfd-b164-61ecb6ba2818}) of ThingClass sdm630 + Strom Phase B + + + + Current phase B changed + The name of the EventType ({99e47d06-0a6a-4bfd-b164-61ecb6ba2818}) of ThingClass sdm630 + Strom Phase B geändert + + + + + Current phase C + The name of the ParamType (ThingClass: sdm630, EventType: currentPhaseC, ID: {4a092a66-352d-4d60-90ab-6ac5f58b92fe}) +---------- +The name of the StateType ({4a092a66-352d-4d60-90ab-6ac5f58b92fe}) of ThingClass sdm630 + Strom Phase C + + + + Current phase C changed + The name of the EventType ({4a092a66-352d-4d60-90ab-6ac5f58b92fe}) of ThingClass sdm630 + Strom Phase C geändert + + + + + Current power + The name of the ParamType (ThingClass: sdm630, EventType: currentPower, ID: {c824e97b-a6d1-4030-9d7a-00af6fb8e1c3}) +---------- +The name of the StateType ({c824e97b-a6d1-4030-9d7a-00af6fb8e1c3}) of ThingClass sdm630 + Aktueller Energieverbrauch + + + + Current power changed + The name of the EventType ({c824e97b-a6d1-4030-9d7a-00af6fb8e1c3}) of ThingClass sdm630 + Aktueller Energieverbrauch geändert + + + + + Current power phase A + The name of the ParamType (ThingClass: sdm630, EventType: currentPowerPhaseA, ID: {3982fb12-b179-40f7-9b27-36adb1cadd37}) +---------- +The name of the StateType ({3982fb12-b179-40f7-9b27-36adb1cadd37}) of ThingClass sdm630 + Aktueller Energieverbrauch Phase A + + + + Current power phase A changed + The name of the EventType ({3982fb12-b179-40f7-9b27-36adb1cadd37}) of ThingClass sdm630 + Aktueller Energieverbrauch Phase A geändert + + + + + Current power phase B + The name of the ParamType (ThingClass: sdm630, EventType: currentPowerPhaseB, ID: {2a231c58-b095-4037-8394-a730431e70b8}) +---------- +The name of the StateType ({2a231c58-b095-4037-8394-a730431e70b8}) of ThingClass sdm630 + Aktueller Energieverbrauch Phase B + + + + Current power phase B changed + The name of the EventType ({2a231c58-b095-4037-8394-a730431e70b8}) of ThingClass sdm630 + Aktueller Energieverbrauch Phase B geändert + + + + + Current power phase C + The name of the ParamType (ThingClass: sdm630, EventType: currentPowerPhaseC, ID: {ee8c4f0c-2b69-4210-9966-1553a592b06d}) +---------- +The name of the StateType ({ee8c4f0c-2b69-4210-9966-1553a592b06d}) of ThingClass sdm630 + Aktueller Energieverbrauch Phase C + + + + Current power phase C changed + The name of the EventType ({ee8c4f0c-2b69-4210-9966-1553a592b06d}) of ThingClass sdm630 + Aktueller Energieverbrauch Phase C geändert + + + + + Energy consumed phase A + The name of the ParamType (ThingClass: sdm630, EventType: energyConsumedPhaseA, ID: {6ca06c81-fe75-4448-a22f-47c303421440}) +---------- +The name of the StateType ({6ca06c81-fe75-4448-a22f-47c303421440}) of ThingClass sdm630 + Gesamtverbrauch Phase A + + + + Energy consumed phase A changed + The name of the EventType ({6ca06c81-fe75-4448-a22f-47c303421440}) of ThingClass sdm630 + Gesamtverbrauch Phase A geändert + + + + + Energy consumed phase B + The name of the ParamType (ThingClass: sdm630, EventType: energyConsumedPhaseB, ID: {fa2b879b-2a81-4bc8-9577-98082c4d9330}) +---------- +The name of the StateType ({fa2b879b-2a81-4bc8-9577-98082c4d9330}) of ThingClass sdm630 + Gesamtverbrauch Phase B + + + + Energy consumed phase B changed + The name of the EventType ({fa2b879b-2a81-4bc8-9577-98082c4d9330}) of ThingClass sdm630 + Gesamtverbrauch Phase B geändert + + + + + Energy consumed phase C + The name of the ParamType (ThingClass: sdm630, EventType: energyConsumedPhaseC, ID: {4c084c9e-7a5d-42d1-96b2-a8a4b4a25713}) +---------- +The name of the StateType ({4c084c9e-7a5d-42d1-96b2-a8a4b4a25713}) of ThingClass sdm630 + Gesamtverbrauch Phase C + + + + Energy consumed phase C changed + The name of the EventType ({4c084c9e-7a5d-42d1-96b2-a8a4b4a25713}) of ThingClass sdm630 + Gesamtverbrauch Phase C geändert + + + + + Energy produced phase A + The name of the ParamType (ThingClass: sdm630, EventType: energyProducedPhaseA, ID: {308fa88e-6054-4c79-b12a-be2d0a404ef6}) +---------- +The name of the StateType ({308fa88e-6054-4c79-b12a-be2d0a404ef6}) of ThingClass sdm630 + Erzeugte Energie Phase A + + + + Energy produced phase A changed + The name of the EventType ({308fa88e-6054-4c79-b12a-be2d0a404ef6}) of ThingClass sdm630 + Erzeugte Energie Phase A geändert + + + + + Energy produced phase B + The name of the ParamType (ThingClass: sdm630, EventType: energyProducedPhaseB, ID: {48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39}) +---------- +The name of the StateType ({48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39}) of ThingClass sdm630 + Erzeugte Energie Phase B + + + + Energy produced phase B changed + The name of the EventType ({48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39}) of ThingClass sdm630 + Erzeugte Energie Phase B geändert + + + + + Energy produced phase C + The name of the ParamType (ThingClass: sdm630, EventType: energyProducedPhaseC, ID: {6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff}) +---------- +The name of the StateType ({6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff}) of ThingClass sdm630 + Erzeugte Energie Phase C + + + + Energy produced phase C changed + The name of the EventType ({6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff}) of ThingClass sdm630 + Erzeugte Energie Phase C geändert + + + + + Frequency + The name of the ParamType (ThingClass: sdm630, EventType: frequency, ID: {ab24f26c-dc15-4ec3-8d76-06a48285440b}) +---------- +The name of the StateType ({ab24f26c-dc15-4ec3-8d76-06a48285440b}) of ThingClass sdm630 + Frequenz + + + + Frequency changed + The name of the EventType ({ab24f26c-dc15-4ec3-8d76-06a48285440b}) of ThingClass sdm630 + Frequenz geändert + + + + Modbus RTU master + The name of the ParamType (ThingClass: sdm630, Type: thing, ID: {d90e9292-d03c-4f2a-957e-5d965018c9c9}) + Modbus RTU Master + + + + Modbus slave address + The name of the ParamType (ThingClass: sdm630, Type: thing, ID: {ac77ea98-b006-486e-a3e8-b30a483f26c1}) + Modbus Adresse + + + + SDM630 + The name of the ThingClass ({f37597bb-35fe-48f2-9617-343dd54c0903}) + SDM630 + + + + Slave address + The name of the ParamType (ThingClass: sdm630, Type: discovery, ID: {6ab43559-53ec-47ba-b8a0-8d3b7f8d90c2}) + Modbus Adresse + + + + + Total energy consumed + The name of the ParamType (ThingClass: sdm630, EventType: totalEnergyConsumed, ID: {98d858a8-22e8-4262-b5c7-25bb027942ad}) +---------- +The name of the StateType ({98d858a8-22e8-4262-b5c7-25bb027942ad}) of ThingClass sdm630 + Gesamter Energieverbrauch + + + + Total energy consumed changed + The name of the EventType ({98d858a8-22e8-4262-b5c7-25bb027942ad}) of ThingClass sdm630 + Gesamter Energieverbrauch geändert + + + + + Total energy produced + The name of the ParamType (ThingClass: sdm630, EventType: totalEnergyProduced, ID: {e469b3ff-a4c2-42da-af35-ccafaef214af}) +---------- +The name of the StateType ({e469b3ff-a4c2-42da-af35-ccafaef214af}) of ThingClass sdm630 + Gesamte erzeugte Energie + + + + Total energy produced changed + The name of the EventType ({e469b3ff-a4c2-42da-af35-ccafaef214af}) of ThingClass sdm630 + Gesamte erzeugte Energie geändert + + + + + Voltage phase A + The name of the ParamType (ThingClass: sdm630, EventType: voltagePhaseA, ID: {db018146-0441-4dc0-9834-6d43ebaf8311}) +---------- +The name of the StateType ({db018146-0441-4dc0-9834-6d43ebaf8311}) of ThingClass sdm630 + Spannung Phase A + + + + Voltage phase A changed + The name of the EventType ({db018146-0441-4dc0-9834-6d43ebaf8311}) of ThingClass sdm630 + Spannung Phase A geändert + + + + + Voltage phase B + The name of the ParamType (ThingClass: sdm630, EventType: voltagePhaseB, ID: {406f6d02-d5eb-49b3-87da-3247568e6054}) +---------- +The name of the StateType ({406f6d02-d5eb-49b3-87da-3247568e6054}) of ThingClass sdm630 + Spannung Phase B + + + + Voltage phase B changed + The name of the EventType ({406f6d02-d5eb-49b3-87da-3247568e6054}) of ThingClass sdm630 + Spannung Phase B geändert + + + + + Voltage phase C + The name of the ParamType (ThingClass: sdm630, EventType: voltagePhaseC, ID: {ace6294d-deaa-4d9a-af78-d64379bcb229}) +---------- +The name of the StateType ({ace6294d-deaa-4d9a-af78-d64379bcb229}) of ThingClass sdm630 + Spannung Phase C + + + + Voltage phase C changed + The name of the EventType ({ace6294d-deaa-4d9a-af78-d64379bcb229}) of ThingClass sdm630 + Spannung Phase C geändert + + + diff --git a/bgetech/translations/e373f492-4527-4d5f-aa48-34d38c55b0d6-en_US.ts b/bgetech/translations/e373f492-4527-4d5f-aa48-34d38c55b0d6-en_US.ts new file mode 100644 index 0000000..3c99c6a --- /dev/null +++ b/bgetech/translations/e373f492-4527-4d5f-aa48-34d38c55b0d6-en_US.ts @@ -0,0 +1,363 @@ + + + + + IntegrationPluginBGETech + + + No Modbus RTU interface available. Please set up the Modbus RTU interface first. + + + + + The Modbus slave address must be a value between 1 and 254. + + + + + The Modbus address not valid. It must be a value between 1 and 254. + + + + + The Modbus RTU interface not available. + + + + + bgeTech + + + + B+G E-Tech + The name of the vendor ({215035fe-95e8-43d8-a52e-0a31b787d902}) +---------- +The name of the plugin bgeTech ({e373f492-4527-4d5f-aa48-34d38c55b0d6}) + + + + + + Connected + The name of the ParamType (ThingClass: sdm630, EventType: connected, ID: {8050bd0b-1dad-4a7e-b632-c71ead3c9f8b}) +---------- +The name of the StateType ({8050bd0b-1dad-4a7e-b632-c71ead3c9f8b}) of ThingClass sdm630 + + + + + Connected changed + The name of the EventType ({8050bd0b-1dad-4a7e-b632-c71ead3c9f8b}) of ThingClass sdm630 + + + + + + Current phase A + The name of the ParamType (ThingClass: sdm630, EventType: currentPhaseA, ID: {4baf1d08-5ffa-49cf-95ef-9527b0c6f081}) +---------- +The name of the StateType ({4baf1d08-5ffa-49cf-95ef-9527b0c6f081}) of ThingClass sdm630 + + + + + Current phase A changed + The name of the EventType ({4baf1d08-5ffa-49cf-95ef-9527b0c6f081}) of ThingClass sdm630 + + + + + + Current phase B + The name of the ParamType (ThingClass: sdm630, EventType: currentPhaseB, ID: {99e47d06-0a6a-4bfd-b164-61ecb6ba2818}) +---------- +The name of the StateType ({99e47d06-0a6a-4bfd-b164-61ecb6ba2818}) of ThingClass sdm630 + + + + + Current phase B changed + The name of the EventType ({99e47d06-0a6a-4bfd-b164-61ecb6ba2818}) of ThingClass sdm630 + + + + + + Current phase C + The name of the ParamType (ThingClass: sdm630, EventType: currentPhaseC, ID: {4a092a66-352d-4d60-90ab-6ac5f58b92fe}) +---------- +The name of the StateType ({4a092a66-352d-4d60-90ab-6ac5f58b92fe}) of ThingClass sdm630 + + + + + Current phase C changed + The name of the EventType ({4a092a66-352d-4d60-90ab-6ac5f58b92fe}) of ThingClass sdm630 + + + + + + Current power + The name of the ParamType (ThingClass: sdm630, EventType: currentPower, ID: {c824e97b-a6d1-4030-9d7a-00af6fb8e1c3}) +---------- +The name of the StateType ({c824e97b-a6d1-4030-9d7a-00af6fb8e1c3}) of ThingClass sdm630 + + + + + Current power changed + The name of the EventType ({c824e97b-a6d1-4030-9d7a-00af6fb8e1c3}) of ThingClass sdm630 + + + + + + Current power phase A + The name of the ParamType (ThingClass: sdm630, EventType: currentPowerPhaseA, ID: {3982fb12-b179-40f7-9b27-36adb1cadd37}) +---------- +The name of the StateType ({3982fb12-b179-40f7-9b27-36adb1cadd37}) of ThingClass sdm630 + + + + + Current power phase A changed + The name of the EventType ({3982fb12-b179-40f7-9b27-36adb1cadd37}) of ThingClass sdm630 + + + + + + Current power phase B + The name of the ParamType (ThingClass: sdm630, EventType: currentPowerPhaseB, ID: {2a231c58-b095-4037-8394-a730431e70b8}) +---------- +The name of the StateType ({2a231c58-b095-4037-8394-a730431e70b8}) of ThingClass sdm630 + + + + + Current power phase B changed + The name of the EventType ({2a231c58-b095-4037-8394-a730431e70b8}) of ThingClass sdm630 + + + + + + Current power phase C + The name of the ParamType (ThingClass: sdm630, EventType: currentPowerPhaseC, ID: {ee8c4f0c-2b69-4210-9966-1553a592b06d}) +---------- +The name of the StateType ({ee8c4f0c-2b69-4210-9966-1553a592b06d}) of ThingClass sdm630 + + + + + Current power phase C changed + The name of the EventType ({ee8c4f0c-2b69-4210-9966-1553a592b06d}) of ThingClass sdm630 + + + + + + Energy consumed phase A + The name of the ParamType (ThingClass: sdm630, EventType: energyConsumedPhaseA, ID: {6ca06c81-fe75-4448-a22f-47c303421440}) +---------- +The name of the StateType ({6ca06c81-fe75-4448-a22f-47c303421440}) of ThingClass sdm630 + + + + + Energy consumed phase A changed + The name of the EventType ({6ca06c81-fe75-4448-a22f-47c303421440}) of ThingClass sdm630 + + + + + + Energy consumed phase B + The name of the ParamType (ThingClass: sdm630, EventType: energyConsumedPhaseB, ID: {fa2b879b-2a81-4bc8-9577-98082c4d9330}) +---------- +The name of the StateType ({fa2b879b-2a81-4bc8-9577-98082c4d9330}) of ThingClass sdm630 + + + + + Energy consumed phase B changed + The name of the EventType ({fa2b879b-2a81-4bc8-9577-98082c4d9330}) of ThingClass sdm630 + + + + + + Energy consumed phase C + The name of the ParamType (ThingClass: sdm630, EventType: energyConsumedPhaseC, ID: {4c084c9e-7a5d-42d1-96b2-a8a4b4a25713}) +---------- +The name of the StateType ({4c084c9e-7a5d-42d1-96b2-a8a4b4a25713}) of ThingClass sdm630 + + + + + Energy consumed phase C changed + The name of the EventType ({4c084c9e-7a5d-42d1-96b2-a8a4b4a25713}) of ThingClass sdm630 + + + + + + Energy produced phase A + The name of the ParamType (ThingClass: sdm630, EventType: energyProducedPhaseA, ID: {308fa88e-6054-4c79-b12a-be2d0a404ef6}) +---------- +The name of the StateType ({308fa88e-6054-4c79-b12a-be2d0a404ef6}) of ThingClass sdm630 + + + + + Energy produced phase A changed + The name of the EventType ({308fa88e-6054-4c79-b12a-be2d0a404ef6}) of ThingClass sdm630 + + + + + + Energy produced phase B + The name of the ParamType (ThingClass: sdm630, EventType: energyProducedPhaseB, ID: {48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39}) +---------- +The name of the StateType ({48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39}) of ThingClass sdm630 + + + + + Energy produced phase B changed + The name of the EventType ({48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39}) of ThingClass sdm630 + + + + + + Energy produced phase C + The name of the ParamType (ThingClass: sdm630, EventType: energyProducedPhaseC, ID: {6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff}) +---------- +The name of the StateType ({6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff}) of ThingClass sdm630 + + + + + Energy produced phase C changed + The name of the EventType ({6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff}) of ThingClass sdm630 + + + + + + Frequency + The name of the ParamType (ThingClass: sdm630, EventType: frequency, ID: {ab24f26c-dc15-4ec3-8d76-06a48285440b}) +---------- +The name of the StateType ({ab24f26c-dc15-4ec3-8d76-06a48285440b}) of ThingClass sdm630 + + + + + Frequency changed + The name of the EventType ({ab24f26c-dc15-4ec3-8d76-06a48285440b}) of ThingClass sdm630 + + + + + Modbus RTU master + The name of the ParamType (ThingClass: sdm630, Type: thing, ID: {d90e9292-d03c-4f2a-957e-5d965018c9c9}) + + + + + Modbus slave address + The name of the ParamType (ThingClass: sdm630, Type: thing, ID: {ac77ea98-b006-486e-a3e8-b30a483f26c1}) + + + + + SDM630 + The name of the ThingClass ({f37597bb-35fe-48f2-9617-343dd54c0903}) + + + + + Slave address + The name of the ParamType (ThingClass: sdm630, Type: discovery, ID: {6ab43559-53ec-47ba-b8a0-8d3b7f8d90c2}) + + + + + + Total energy consumed + The name of the ParamType (ThingClass: sdm630, EventType: totalEnergyConsumed, ID: {98d858a8-22e8-4262-b5c7-25bb027942ad}) +---------- +The name of the StateType ({98d858a8-22e8-4262-b5c7-25bb027942ad}) of ThingClass sdm630 + + + + + Total energy consumed changed + The name of the EventType ({98d858a8-22e8-4262-b5c7-25bb027942ad}) of ThingClass sdm630 + + + + + + Total energy produced + The name of the ParamType (ThingClass: sdm630, EventType: totalEnergyProduced, ID: {e469b3ff-a4c2-42da-af35-ccafaef214af}) +---------- +The name of the StateType ({e469b3ff-a4c2-42da-af35-ccafaef214af}) of ThingClass sdm630 + + + + + Total energy produced changed + The name of the EventType ({e469b3ff-a4c2-42da-af35-ccafaef214af}) of ThingClass sdm630 + + + + + + Voltage phase A + The name of the ParamType (ThingClass: sdm630, EventType: voltagePhaseA, ID: {db018146-0441-4dc0-9834-6d43ebaf8311}) +---------- +The name of the StateType ({db018146-0441-4dc0-9834-6d43ebaf8311}) of ThingClass sdm630 + + + + + Voltage phase A changed + The name of the EventType ({db018146-0441-4dc0-9834-6d43ebaf8311}) of ThingClass sdm630 + + + + + + Voltage phase B + The name of the ParamType (ThingClass: sdm630, EventType: voltagePhaseB, ID: {406f6d02-d5eb-49b3-87da-3247568e6054}) +---------- +The name of the StateType ({406f6d02-d5eb-49b3-87da-3247568e6054}) of ThingClass sdm630 + + + + + Voltage phase B changed + The name of the EventType ({406f6d02-d5eb-49b3-87da-3247568e6054}) of ThingClass sdm630 + + + + + + Voltage phase C + The name of the ParamType (ThingClass: sdm630, EventType: voltagePhaseC, ID: {ace6294d-deaa-4d9a-af78-d64379bcb229}) +---------- +The name of the StateType ({ace6294d-deaa-4d9a-af78-d64379bcb229}) of ThingClass sdm630 + + + + + Voltage phase C changed + The name of the EventType ({ace6294d-deaa-4d9a-af78-d64379bcb229}) of ThingClass sdm630 + + + + diff --git a/debian/control b/debian/control index ca0a9de..8738471 100644 --- a/debian/control +++ b/debian/control @@ -43,6 +43,17 @@ Description: nymea integration plugin for alpha innotec heat pumps This package contains the nymea integration plugin for alpha innotec head pumps. +Package: nymea-plugin-bgetech +Architecture: any +Multi-Arch: same +Section: libs +Depends: ${shlibs:Depends}, + ${misc:Depends}, +Description: nymea integration plugin for B+G E-Tech Modbus based energy meters + This package contains the nymea integration plugin for Modbus based energy meters + made by B+G E-Tech. + + Package: nymea-plugin-drexelundweiss Architecture: any Section: libs @@ -61,14 +72,15 @@ Description: nymea integration plugin for iDM heat pumps This package contains the nymea integration plugin for iDM heat pumps. -Package: nymea-plugin-energymeters +Package: nymea-plugin-inepro Architecture: any Multi-Arch: same Section: libs Depends: ${shlibs:Depends}, ${misc:Depends}, -Description: nymea integration plugin for Modbus based energy meters - This package contains a collection of energy meters. +Description: nymea integration plugin for inepro Metering Modbus based energy meters + This package contains the nymea integration plugin for Modbus based energy meters + made by inepro Metering. Package: nymea-plugin-huawei diff --git a/debian/nymea-plugin-bgetech.install.in b/debian/nymea-plugin-bgetech.install.in new file mode 100644 index 0000000..c02dd47 --- /dev/null +++ b/debian/nymea-plugin-bgetech.install.in @@ -0,0 +1,2 @@ +usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginbgetech.so +bgetech/translations/*qm usr/share/nymea/translations/ diff --git a/debian/nymea-plugin-energymeters.install.in b/debian/nymea-plugin-energymeters.install.in deleted file mode 100644 index cc7039a..0000000 --- a/debian/nymea-plugin-energymeters.install.in +++ /dev/null @@ -1,2 +0,0 @@ -usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginenergymeters.so -energymeters/translations/*qm usr/share/nymea/translations/ diff --git a/debian/nymea-plugin-inepro.install.in b/debian/nymea-plugin-inepro.install.in new file mode 100644 index 0000000..2cf6128 --- /dev/null +++ b/debian/nymea-plugin-inepro.install.in @@ -0,0 +1,2 @@ +usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationplugininepro.so +inepro/translations/*qm usr/share/nymea/translations/ diff --git a/energymeters/README.md b/energymeters/README.md deleted file mode 100644 index 9f0e154..0000000 --- a/energymeters/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Energy Meters - -Connect Modbus RTU based energy meters. - -Once you configured in the system settings a Modbus RTU resource using the configured settings of your meter, you can start adding the energy meter to your system. - -While discovering, nymea will offer you the configured modbus resources as possible connections. - - -## Supported things - -* b+g e-tech - * SDM630Modbus -* inepro Metering - * PRO380-Mod - - -## Requirements - -* The plugin 'nymea-plugin-energymeters' must be installed. -* At least one Modbus RTU interface must be setup. diff --git a/energymeters/integrationpluginenergymeters.cpp b/energymeters/integrationpluginenergymeters.cpp deleted file mode 100644 index 01272ad..0000000 --- a/energymeters/integrationpluginenergymeters.cpp +++ /dev/null @@ -1,354 +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 . -* -* 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 "integrationpluginenergymeters.h" -#include "plugininfo.h" - -IntegrationPluginEnergyMeters::IntegrationPluginEnergyMeters() -{ - m_slaveIdParamTypeIds.insert(pro380ThingClassId, pro380ThingSlaveAddressParamTypeId); - m_slaveIdParamTypeIds.insert(sdm630ThingClassId, sdm630ThingSlaveAddressParamTypeId); - - m_modbusUuidParamTypeIds.insert(pro380ThingClassId, pro380ThingModbusMasterUuidParamTypeId); - m_modbusUuidParamTypeIds.insert(sdm630ThingClassId, sdm630ThingModbusMasterUuidParamTypeId); - - m_discoverySlaveAddressParamTypeIds.insert(pro380ThingClassId, pro380DiscoverySlaveAddressParamTypeId); - m_discoverySlaveAddressParamTypeIds.insert(sdm630ThingClassId, sdm630DiscoverySlaveAddressParamTypeId); - - m_connectionStateTypeIds.insert(pro380ThingClassId, pro380ConnectedStateTypeId); - m_connectionStateTypeIds.insert(sdm630ThingClassId, sdm630ConnectedStateTypeId); -} - -void IntegrationPluginEnergyMeters::init() -{ - connect(hardwareManager()->modbusRtuResource(), &ModbusRtuHardwareResource::modbusRtuMasterRemoved, this, [=] (const QUuid &modbusUuid){ - qCDebug(dcEnergyMeters()) << "Modbus RTU master has been removed" << modbusUuid.toString(); - - foreach (Thing *thing, myThings()) { - if (m_modbusUuidParamTypeIds.contains(thing->thingClassId())) { - if (thing->paramValue(m_modbusUuidParamTypeIds.value(thing->thingClassId())) == modbusUuid) { - qCWarning(dcEnergyMeters()) << "Modbus RTU hardware resource removed for" << thing << ". The thing will not be functional any more until a new resource has been configured for it."; - thing->setStateValue(m_connectionStateTypeIds[thing->thingClassId()], false); - - if (thing->thingClassId() == sdm630ThingClassId) { - delete m_sdmConnections.take(thing); - } else if (thing->thingClassId() == pro380ThingClassId) { - delete m_ineproConnections.take(thing); - } - } - } - } - }); -} - -void IntegrationPluginEnergyMeters::discoverThings(ThingDiscoveryInfo *info) -{ - qCDebug(dcEnergyMeters()) << "Discover modbus RTU resources..."; - if (hardwareManager()->modbusRtuResource()->modbusRtuMasters().isEmpty()) { - info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("No Modbus RTU interface available.")); - return; - } - - Q_ASSERT_X(m_connectionStateTypeIds.contains(info->thingClassId()), "discoverThings", QString("Unhandled thingClassId: %1").arg(info->thingClassId().toString()).toUtf8()); - - uint slaveAddress = info->params().paramValue(m_discoverySlaveAddressParamTypeIds.value(info->thingClassId())).toUInt(); - if (slaveAddress > 254 || slaveAddress == 0) { - info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("Modbus slave address must be between 1 and 254")); - return; - } - - foreach (ModbusRtuMaster *modbusMaster, hardwareManager()->modbusRtuResource()->modbusRtuMasters()) { - qCDebug(dcEnergyMeters()) << "Found RTU master resource" << modbusMaster << "connected" << modbusMaster->connected(); - if (!modbusMaster->connected()) - continue; - - ThingDescriptor descriptor(info->thingClassId(), QT_TR_NOOP("Energy meter"), QT_TR_NOOP("Slave address ") + QString::number(slaveAddress) + " " + modbusMaster->serialPort()); - ParamList params; - params << Param(m_slaveIdParamTypeIds.value(info->thingClassId()), slaveAddress); - params << Param(m_modbusUuidParamTypeIds.value(info->thingClassId()), modbusMaster->modbusUuid()); - descriptor.setParams(params); - info->addThingDescriptor(descriptor); - } - - info->finish(Thing::ThingErrorNoError); - return; -} - -void IntegrationPluginEnergyMeters::setupThing(ThingSetupInfo *info) -{ - Thing *thing = info->thing(); - qCDebug(dcEnergyMeters()) << "Setup thing" << thing << thing->params(); - Q_ASSERT_X(m_connectionStateTypeIds.contains(thing->thingClassId()), "setupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8()); - - uint address = thing->paramValue(m_slaveIdParamTypeIds.value(thing->thingClassId())).toUInt(); - if (address > 254 || address == 0) { - qCWarning(dcEnergyMeters()) << "Setup failed, slave address is not valid" << address; - info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("Slave address not valid, must be between 1 and 254")); - return; - } - - QUuid uuid = thing->paramValue(m_modbusUuidParamTypeIds.value(thing->thingClassId())).toUuid(); - if (!hardwareManager()->modbusRtuResource()->hasModbusRtuMaster(uuid)) { - qCWarning(dcEnergyMeters()) << "Setup failed, hardware manager not available"; - info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("Modbus RTU resource not available.")); - return; - } - - if (thing->thingClassId() == sdm630ThingClassId) { - if (m_sdmConnections.contains(thing)) { - qCDebug(dcEnergyMeters()) << "Setup after rediscovery, cleaning up ..."; - m_sdmConnections.take(thing)->deleteLater(); - } - - Sdm630ModbusRtuConnection *sdmConnection = new Sdm630ModbusRtuConnection(hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), address, this); - connect(sdmConnection->modbusRtuMaster(), &ModbusRtuMaster::connectedChanged, this, [=](bool connected){ - if (connected) { - qCDebug(dcEnergyMeters()) << "Modbus RTU resource connected" << thing << sdmConnection->modbusRtuMaster()->serialPort(); - } else { - qCWarning(dcEnergyMeters()) << "Modbus RTU resource disconnected" << thing << sdmConnection->modbusRtuMaster()->serialPort(); - } - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::currentPhaseAChanged, this, [=](float currentPhaseA){ - thing->setStateValue(sdm630CurrentPhaseAStateTypeId, currentPhaseA); - thing->setStateValue(sdm630ConnectedStateTypeId, true); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::currentPhaseBChanged, this, [=](float currentPhaseB){ - thing->setStateValue(sdm630CurrentPhaseBStateTypeId, currentPhaseB); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::currentPhaseCChanged, this, [=](float currentPhaseC){ - thing->setStateValue(sdm630CurrentPhaseCStateTypeId, currentPhaseC); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::voltagePhaseAChanged, this, [=](float voltagePhaseA){ - thing->setStateValue(sdm630VoltagePhaseAStateTypeId, voltagePhaseA); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::voltagePhaseBChanged, this, [=](float voltagePhaseB){ - thing->setStateValue(sdm630VoltagePhaseBStateTypeId, voltagePhaseB); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::voltagePhaseCChanged, this, [=](float voltagePhaseC){ - thing->setStateValue(sdm630VoltagePhaseCStateTypeId, voltagePhaseC); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::totalCurrentPowerChanged, this, [=](float currentPower){ - thing->setStateValue(sdm630CurrentPowerStateTypeId, currentPower); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::powerPhaseAChanged, this, [=](float powerPhaseA){ - thing->setStateValue(sdm630CurrentPowerPhaseAStateTypeId, powerPhaseA); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::powerPhaseBChanged, this, [=](float powerPhaseB){ - thing->setStateValue(sdm630CurrentPowerPhaseBStateTypeId, powerPhaseB); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::powerPhaseCChanged, this, [=](float powerPhaseC){ - thing->setStateValue(sdm630CurrentPowerPhaseCStateTypeId, powerPhaseC); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::frequencyChanged, this, [=](float frequency){ - thing->setStateValue(sdm630FrequencyStateTypeId, frequency); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::totalEnergyConsumedChanged, this, [=](float totalEnergyConsumed){ - thing->setStateValue(sdm630TotalEnergyConsumedStateTypeId, totalEnergyConsumed); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::totalEnergyProducedChanged, this, [=](float totalEnergyProduced){ - thing->setStateValue(sdm630TotalEnergyProducedStateTypeId, totalEnergyProduced); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::energyProducedPhaseAChanged, this, [=](float energyProducedPhaseA){ - thing->setStateValue(sdm630EnergyProducedPhaseAStateTypeId, energyProducedPhaseA); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::energyProducedPhaseBChanged, this, [=](float energyProducedPhaseB){ - thing->setStateValue(sdm630EnergyProducedPhaseBStateTypeId, energyProducedPhaseB); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::energyProducedPhaseCChanged, this, [=](float energyProducedPhaseC){ - thing->setStateValue(sdm630EnergyProducedPhaseCStateTypeId, energyProducedPhaseC); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::energyConsumedPhaseAChanged, this, [=](float energyConsumedPhaseA){ - thing->setStateValue(sdm630EnergyConsumedPhaseAStateTypeId, energyConsumedPhaseA); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::energyConsumedPhaseBChanged, this, [=](float energyConsumedPhaseB){ - thing->setStateValue(sdm630EnergyConsumedPhaseBStateTypeId, energyConsumedPhaseB); - }); - - connect(sdmConnection, &Sdm630ModbusRtuConnection::energyConsumedPhaseCChanged, this, [=](float energyConsumedPhaseC){ - thing->setStateValue(sdm630EnergyConsumedPhaseCStateTypeId, energyConsumedPhaseC); - }); - - // FIXME: try to read before setup success - m_sdmConnections.insert(thing, sdmConnection); - info->finish(Thing::ThingErrorNoError); - - } else if (thing->thingClassId() == pro380ThingClassId) { - if (m_ineproConnections.contains(thing)) { - qCDebug(dcEnergyMeters()) << "Setup after rediscovery, cleaning up ..."; - m_ineproConnections.take(thing)->deleteLater(); - } - - Pro380ModbusRtuConnection *proConnection = new Pro380ModbusRtuConnection(hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), address, this); - connect(proConnection->modbusRtuMaster(), &ModbusRtuMaster::connectedChanged, this, [=](bool connected){ - if (connected) { - qCDebug(dcEnergyMeters()) << "Modbus RTU resource connected" << thing << proConnection->modbusRtuMaster()->serialPort(); - } else { - qCWarning(dcEnergyMeters()) << "Modbus RTU resource disconnected" << thing << proConnection->modbusRtuMaster()->serialPort(); - } - }); - - connect(proConnection, &Pro380ModbusRtuConnection::currentPhaseAChanged, this, [=](float currentPhaseA){ - thing->setStateValue(pro380CurrentPhaseAStateTypeId, currentPhaseA); - thing->setStateValue(pro380ConnectedStateTypeId, true); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::currentPhaseBChanged, this, [=](float currentPhaseB){ - thing->setStateValue(pro380CurrentPhaseBStateTypeId, currentPhaseB); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::currentPhaseCChanged, this, [=](float currentPhaseC){ - thing->setStateValue(pro380CurrentPhaseCStateTypeId, currentPhaseC); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::voltagePhaseAChanged, this, [=](float voltagePhaseA){ - thing->setStateValue(pro380VoltagePhaseAStateTypeId, voltagePhaseA); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::voltagePhaseBChanged, this, [=](float voltagePhaseB){ - thing->setStateValue(pro380VoltagePhaseBStateTypeId, voltagePhaseB); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::voltagePhaseCChanged, this, [=](float voltagePhaseC){ - thing->setStateValue(pro380VoltagePhaseCStateTypeId, voltagePhaseC); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::totalCurrentPowerChanged, this, [=](float currentPower){ - thing->setStateValue(pro380CurrentPowerStateTypeId, currentPower * 1000); // kW - }); - - connect(proConnection, &Pro380ModbusRtuConnection::powerPhaseAChanged, this, [=](float powerPhaseA){ - thing->setStateValue(pro380CurrentPowerPhaseAStateTypeId, powerPhaseA * 1000); // kW - }); - - connect(proConnection, &Pro380ModbusRtuConnection::powerPhaseBChanged, this, [=](float powerPhaseB){ - thing->setStateValue(pro380CurrentPowerPhaseBStateTypeId, powerPhaseB * 1000); // kW - }); - - connect(proConnection, &Pro380ModbusRtuConnection::powerPhaseCChanged, this, [=](float powerPhaseC){ - thing->setStateValue(pro380CurrentPowerPhaseCStateTypeId, powerPhaseC * 1000); // kW - }); - - connect(proConnection, &Pro380ModbusRtuConnection::frequencyChanged, this, [=](float frequency){ - thing->setStateValue(pro380FrequencyStateTypeId, frequency); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::totalEnergyConsumedChanged, this, [=](float totalEnergyConsumed){ - thing->setStateValue(pro380TotalEnergyConsumedStateTypeId, totalEnergyConsumed); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::totalEnergyProducedChanged, this, [=](float totalEnergyProduced){ - thing->setStateValue(pro380TotalEnergyProducedStateTypeId, totalEnergyProduced); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::energyProducedPhaseAChanged, this, [=](float energyProducedPhaseA){ - thing->setStateValue(pro380EnergyProducedPhaseAStateTypeId, energyProducedPhaseA); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::energyProducedPhaseBChanged, this, [=](float energyProducedPhaseB){ - thing->setStateValue(pro380EnergyProducedPhaseBStateTypeId, energyProducedPhaseB); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::energyProducedPhaseCChanged, this, [=](float energyProducedPhaseC){ - thing->setStateValue(pro380EnergyProducedPhaseCStateTypeId, energyProducedPhaseC); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::energyConsumedPhaseAChanged, this, [=](float energyConsumedPhaseA){ - thing->setStateValue(pro380EnergyConsumedPhaseAStateTypeId, energyConsumedPhaseA); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::energyConsumedPhaseBChanged, this, [=](float energyConsumedPhaseB){ - thing->setStateValue(pro380EnergyConsumedPhaseBStateTypeId, energyConsumedPhaseB); - }); - - connect(proConnection, &Pro380ModbusRtuConnection::energyConsumedPhaseCChanged, this, [=](float energyConsumedPhaseC){ - thing->setStateValue(pro380EnergyConsumedPhaseCStateTypeId, energyConsumedPhaseC); - }); - - - // FIXME: try to read before setup success - m_ineproConnections.insert(thing, proConnection); - info->finish(Thing::ThingErrorNoError); - } -} - -void IntegrationPluginEnergyMeters::postSetupThing(Thing *thing) -{ - qCDebug(dcEnergyMeters) << "Post setup thing" << thing->name(); - if (!m_refreshTimer) { - m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(2); - connect(m_refreshTimer, &PluginTimer::timeout, this, [this] { - foreach (Thing *thing, myThings().filterByThingClassId(sdm630ThingClassId)) { - m_sdmConnections.value(thing)->update(); - } - - foreach (Thing *thing, myThings().filterByThingClassId(pro380ThingClassId)) { - m_sdmConnections.value(thing)->update(); - } - }); - - qCDebug(dcEnergyMeters()) << "Starting refresh timer..."; - m_refreshTimer->start(); - } -} - -void IntegrationPluginEnergyMeters::thingRemoved(Thing *thing) -{ - qCDebug(dcEnergyMeters()) << "Thing removed" << thing->name(); - - if (m_sdmConnections.contains(thing)) - m_sdmConnections.take(thing)->deleteLater(); - - if (m_ineproConnections.contains(thing)) - m_ineproConnections.take(thing)->deleteLater(); - - if (myThings().isEmpty() && m_refreshTimer) { - qCDebug(dcEnergyMeters()) << "Stopping reconnect timer"; - hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer); - m_refreshTimer = nullptr; - } -} diff --git a/energymeters/integrationpluginenergymeters.json b/energymeters/integrationpluginenergymeters.json deleted file mode 100644 index fb48126..0000000 --- a/energymeters/integrationpluginenergymeters.json +++ /dev/null @@ -1,452 +0,0 @@ -{ - "name": "EnergyMeters", - "displayName": "EnergyMeters", - "id": "56e95111-fb6b-4f63-9a0a-a5ee001e89ed", - "paramTypes":[ ], - "vendors": [ - { - "name": "ineproMetering", - "displayName": "inepro Metering", - "id": "64f4df0f-18ce-409c-bf32-84a086c691ca", - "thingClasses": [ - { - "name": "pro380", - "displayName": "PRO380-Mod", - "id": "d7c6440b-54f9-4cc0-a96b-9bb7304b3e77", - "createMethods": ["discovery"], - "interfaces": ["energymeter", "connectable"], - "discoveryParamTypes": [ - { - "id": "a29f37f6-b344-4628-8ab4-8f4c18fada4a", - "name": "slaveAddress", - "displayName": "Slave address", - "type": "int", - "defaultValue": 1 - } - ], - "paramTypes": [ - { - "id": "c75b2c31-6ec3-49ab-8c8f-5231d0a7e941", - "name": "slaveAddress", - "displayName": "Modbus slave address", - "type": "uint", - "defaultValue": 1 - }, - { - "id": "6cdbec8c-21b9-42dc-b1ab-8901ac609482", - "name": "modbusMasterUuid", - "displayName": "Modbus RTU master", - "type": "QUuid", - "defaultValue": "", - "readOnly": true - } - ], - "stateTypes": [ - { - "id": "7f9bc504-0882-4b86-83b1-42fa345acfd9", - "name": "connected", - "displayName": "Connected", - "displayNameEvent": "Connected changed", - "type": "bool", - "cached": false, - "defaultValue": false - }, - { - "id": "04dba21a-7447-46b9-b9ae-095e5769e511", - "name": "voltagePhaseA", - "displayName": "Voltage phase A", - "displayNameEvent": "Voltage phase A changed", - "type": "double", - "unit": "Volt", - "defaultValue": 0 - }, - { - "id": "270d0c34-0a0c-4655-985f-faad6efd1afd", - "name": "voltagePhaseB", - "displayName": "Voltage phase B", - "displayNameEvent": "Voltage phase B changed", - "type": "double", - "unit": "Volt", - "defaultValue": 0 - }, - { - "id": "a1da8cfd-37cc-4c87-b857-e942cd90daec", - "name": "voltagePhaseC", - "displayName": "Voltage phase C", - "displayNameEvent": "Voltage phase C changed", - "type": "double", - "unit": "Volt", - "defaultValue": 0 - }, - { - "id": "1e077a3b-2dab-4ec4-ae96-ab49a564fe31", - "name": "currentPhaseA", - "displayName": "Current phase A", - "displayNameEvent": "Current phase A changed", - "type": "double", - "unit": "Ampere", - "defaultValue": 0 - }, - { - "id": "d2f54061-0807-47de-944c-68c8118ece91", - "name": "currentPhaseB", - "displayName": "Current phase B", - "displayNameEvent": "Current phase B changed", - "type": "double", - "unit": "Ampere", - "defaultValue": 0 - }, - { - "id": "610b20fb-2718-4f02-ac6e-12a9ef8c7615", - "name": "currentPhaseC", - "displayName": "Current phase C", - "displayNameEvent": "Current phase C changed", - "type": "double", - "unit": "Ampere", - "defaultValue": 0 - }, - { - "id": "464eff60-11c2-46b7-98f5-1aa8172e5a2d", - "name": "currentPower", - "displayName": "Current power", - "displayNameEvent": "Current power changed", - "type": "double", - "unit": "Watt", - "defaultValue": 0 - }, - { - "id": "55283773-0a4e-4574-b21a-d4a3f287eab1", - "name": "currentPowerPhaseA", - "displayName": "Current power phase A", - "displayNameEvent": "Current power phase A changed", - "type": "double", - "unit": "Watt", - "defaultValue": 0 - }, - { - "id": "8f15d104-5ff7-4c33-9cf9-fdbef4b6f721", - "name": "currentPowerPhaseB", - "displayName": "Current power phase B", - "displayNameEvent": "Current power phase B changed", - "type": "double", - "unit": "Watt", - "defaultValue": 0 - }, - { - "id": "86c0f968-ee70-4f56-bdfc-33b8e2b134a4", - "name": "currentPowerPhaseC", - "displayName": "Current power phase C", - "displayNameEvent": "Current power phase C changed", - "type": "double", - "unit": "Watt", - "defaultValue": 0 - }, - { - "id": "bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5", - "name": "frequency", - "displayName": "Frequency", - "displayNameEvent": "Frequency changed", - "type": "double", - "unit": "Hertz", - "defaultValue": 0.00 - }, - { - "id": "f18fd596-b47f-44be-a0f0-6ca44369ebf5", - "name": "totalEnergyConsumed", - "displayName": "Total energy consumed", - "displayNameEvent": "Total energy consumed changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "112911c9-14e0-4c83-ac92-f2ceb3bdecdf", - "name": "totalEnergyProduced", - "displayName": "Total energy produced", - "displayNameEvent": "Total energy produced changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "b16b3b0c-82d9-4b3c-a172-0e6631c8ce16", - "name": "energyConsumedPhaseA", - "displayName": "Energy consumed phase A", - "displayNameEvent": "Energy consumed phase A changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "64225f7f-9b2f-4bfc-87b2-38758804a28b", - "name": "energyConsumedPhaseB", - "displayName": "Energy consumed phase B", - "displayNameEvent": "Energy consumed phase B changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "a6e82d61-e837-4ec8-b14a-af0d49bea9d2", - "name": "energyConsumedPhaseC", - "displayName": "Energy consumed phase C", - "displayNameEvent": "Energy consumed phase C changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "95bd476e-c247-4f7d-ab01-d9f1b7c0d996", - "name": "energyProducedPhaseA", - "displayName": "Energy produced phase A", - "displayNameEvent": "Energy produced phase A changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "f0a0bd81-708c-48d6-b5c9-165464a5b309", - "name": "energyProducedPhaseB", - "displayName": "Energy produced phase B", - "displayNameEvent": "Energy produced phase B changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1", - "name": "energyProducedPhaseC", - "displayName": "Energy produced phase C", - "displayNameEvent": "Energy produced phase C changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - } - ] - } - ] - }, - { - "name": "bgetech", - "displayName": "B+G e-tech", - "id": "215035fe-95e8-43d8-a52e-0a31b787d902", - "thingClasses": [ - { - "name": "sdm630", - "displayName": "SDM630 Modbus", - "id": "f37597bb-35fe-48f2-9617-343dd54c0903", - "createMethods": ["discovery"], - "interfaces": ["energymeter", "connectable"], - "discoveryParamTypes": [ - { - "id": "6ab43559-53ec-47ba-b8a0-8d3b7f8d90c2", - "name": "slaveAddress", - "displayName": "Slave address", - "type": "int", - "defaultValue": 1 - } - ], - "paramTypes": [ - { - "id": "ac77ea98-b006-486e-a3e8-b30a483f26c1", - "name": "slaveAddress", - "displayName": "Modbus slave address", - "type": "uint", - "defaultValue": 1 - }, - { - "id": "d90e9292-d03c-4f2a-957e-5d965018c9c9", - "name": "modbusMasterUuid", - "displayName": "Modbus RTU master", - "type": "QUuid", - "defaultValue": "", - "readOnly": true - } - ], - "stateTypes": [ - { - "id": "8050bd0b-1dad-4a7e-b632-c71ead3c9f8b", - "name": "connected", - "displayName": "Connected", - "displayNameEvent": "Connected changed", - "type": "bool", - "cached": false, - "defaultValue": false - }, - { - "id": "db018146-0441-4dc0-9834-6d43ebaf8311", - "name": "voltagePhaseA", - "displayName": "Voltage phase A", - "displayNameEvent": "Voltage phase A changed", - "type": "double", - "unit": "Volt", - "defaultValue": 0 - }, - { - "id": "406f6d02-d5eb-49b3-87da-3247568e6054", - "name": "voltagePhaseB", - "displayName": "Voltage phase B", - "displayNameEvent": "Voltage phase B changed", - "type": "double", - "unit": "Volt", - "defaultValue": 0 - }, - { - "id": "ace6294d-deaa-4d9a-af78-d64379bcb229", - "name": "voltagePhaseC", - "displayName": "Voltage phase C", - "displayNameEvent": "Voltage phase C changed", - "type": "double", - "unit": "Volt", - "defaultValue": 0 - }, - { - "id": "4baf1d08-5ffa-49cf-95ef-9527b0c6f081", - "name": "currentPhaseA", - "displayName": "Current phase A", - "displayNameEvent": "Current phase A changed", - "type": "double", - "unit": "Ampere", - "defaultValue": 0 - }, - { - "id": "99e47d06-0a6a-4bfd-b164-61ecb6ba2818", - "name": "currentPhaseB", - "displayName": "Current phase B", - "displayNameEvent": "Current phase B changed", - "type": "double", - "unit": "Ampere", - "defaultValue": 0 - }, - { - "id": "4a092a66-352d-4d60-90ab-6ac5f58b92fe", - "name": "currentPhaseC", - "displayName": "Current phase C", - "displayNameEvent": "Current phase C changed", - "type": "double", - "unit": "Ampere", - "defaultValue": 0 - }, - { - "id": "c824e97b-a6d1-4030-9d7a-00af6fb8e1c3", - "name": "currentPower", - "displayName": "Current power", - "displayNameEvent": "Current power changed", - "type": "double", - "unit": "Watt", - "defaultValue": 0 - }, - { - "id": "3982fb12-b179-40f7-9b27-36adb1cadd37", - "name": "currentPowerPhaseA", - "displayName": "Current power phase A", - "displayNameEvent": "Current power phase A changed", - "type": "double", - "unit": "Watt", - "defaultValue": 0 - }, - { - "id": "2a231c58-b095-4037-8394-a730431e70b8", - "name": "currentPowerPhaseB", - "displayName": "Current power phase B", - "displayNameEvent": "Current power phase B changed", - "type": "double", - "unit": "Watt", - "defaultValue": 0 - }, - { - "id": "ee8c4f0c-2b69-4210-9966-1553a592b06d", - "name": "currentPowerPhaseC", - "displayName": "Current power phase C", - "displayNameEvent": "Current power phase C changed", - "type": "double", - "unit": "Watt", - "defaultValue": 0 - }, - { - "id": "ab24f26c-dc15-4ec3-8d76-06a48285440b", - "name": "frequency", - "displayName": "Frequency", - "displayNameEvent": "Frequency changed", - "type": "double", - "unit": "Hertz", - "defaultValue": 0.00 - }, - { - "id": "98d858a8-22e8-4262-b5c7-25bb027942ad", - "name": "totalEnergyConsumed", - "displayName": "Total energy consumed", - "displayNameEvent": "Total energy consumed changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "e469b3ff-a4c2-42da-af35-ccafaef214af", - "name": "totalEnergyProduced", - "displayName": "Total energy produced", - "displayNameEvent": "Total energy produced changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "6ca06c81-fe75-4448-a22f-47c303421440", - "name": "energyConsumedPhaseA", - "displayName": "Energy consumed phase A", - "displayNameEvent": "Energy consumed phase A changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "fa2b879b-2a81-4bc8-9577-98082c4d9330", - "name": "energyConsumedPhaseB", - "displayName": "Energy consumed phase B", - "displayNameEvent": "Energy consumed phase B changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "4c084c9e-7a5d-42d1-96b2-a8a4b4a25713", - "name": "energyConsumedPhaseC", - "displayName": "Energy consumed phase C", - "displayNameEvent": "Energy consumed phase C changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "308fa88e-6054-4c79-b12a-be2d0a404ef6", - "name": "energyProducedPhaseA", - "displayName": "Energy produced phase A", - "displayNameEvent": "Energy produced phase A changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39", - "name": "energyProducedPhaseB", - "displayName": "Energy produced phase B", - "displayNameEvent": "Energy produced phase B changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - }, - { - "id": "6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff", - "name": "energyProducedPhaseC", - "displayName": "Energy produced phase C", - "displayNameEvent": "Energy produced phase C changed", - "type": "double", - "unit": "KiloWattHour", - "defaultValue": 0.00 - } - ] - } - ] - } - ] -} diff --git a/energymeters/translations/56e95111-fb6b-4f63-9a0a-a5ee001e89ed-de.ts b/energymeters/translations/56e95111-fb6b-4f63-9a0a-a5ee001e89ed-de.ts deleted file mode 100644 index 1ac5b4d..0000000 --- a/energymeters/translations/56e95111-fb6b-4f63-9a0a-a5ee001e89ed-de.ts +++ /dev/null @@ -1,577 +0,0 @@ - - - - - EnergyMeters - - - B+G e-tech - The name of the vendor ({215035fe-95e8-43d8-a52e-0a31b787d902}) - B+G e-tech - - - - - - - Connected - The name of the ParamType (ThingClass: sdm630, EventType: connected, ID: {8050bd0b-1dad-4a7e-b632-c71ead3c9f8b}) ----------- -The name of the StateType ({8050bd0b-1dad-4a7e-b632-c71ead3c9f8b}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: connected, ID: {7f9bc504-0882-4b86-83b1-42fa345acfd9}) ----------- -The name of the StateType ({7f9bc504-0882-4b86-83b1-42fa345acfd9}) of ThingClass pro380 - Verbunden - - - - - Connected changed - The name of the EventType ({8050bd0b-1dad-4a7e-b632-c71ead3c9f8b}) of ThingClass sdm630 ----------- -The name of the EventType ({7f9bc504-0882-4b86-83b1-42fa345acfd9}) of ThingClass pro380 - Verbunden - - - - - - - Current phase A - The name of the ParamType (ThingClass: sdm630, EventType: currentPhaseA, ID: {4baf1d08-5ffa-49cf-95ef-9527b0c6f081}) ----------- -The name of the StateType ({4baf1d08-5ffa-49cf-95ef-9527b0c6f081}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPhaseA, ID: {1e077a3b-2dab-4ec4-ae96-ab49a564fe31}) ----------- -The name of the StateType ({1e077a3b-2dab-4ec4-ae96-ab49a564fe31}) of ThingClass pro380 - - - - - - Current phase A changed - The name of the EventType ({4baf1d08-5ffa-49cf-95ef-9527b0c6f081}) of ThingClass sdm630 ----------- -The name of the EventType ({1e077a3b-2dab-4ec4-ae96-ab49a564fe31}) of ThingClass pro380 - - - - - - - - Current phase B - The name of the ParamType (ThingClass: sdm630, EventType: currentPhaseB, ID: {99e47d06-0a6a-4bfd-b164-61ecb6ba2818}) ----------- -The name of the StateType ({99e47d06-0a6a-4bfd-b164-61ecb6ba2818}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPhaseB, ID: {d2f54061-0807-47de-944c-68c8118ece91}) ----------- -The name of the StateType ({d2f54061-0807-47de-944c-68c8118ece91}) of ThingClass pro380 - - - - - - Current phase B changed - The name of the EventType ({99e47d06-0a6a-4bfd-b164-61ecb6ba2818}) of ThingClass sdm630 ----------- -The name of the EventType ({d2f54061-0807-47de-944c-68c8118ece91}) of ThingClass pro380 - - - - - - - - Current phase C - The name of the ParamType (ThingClass: sdm630, EventType: currentPhaseC, ID: {4a092a66-352d-4d60-90ab-6ac5f58b92fe}) ----------- -The name of the StateType ({4a092a66-352d-4d60-90ab-6ac5f58b92fe}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPhaseC, ID: {610b20fb-2718-4f02-ac6e-12a9ef8c7615}) ----------- -The name of the StateType ({610b20fb-2718-4f02-ac6e-12a9ef8c7615}) of ThingClass pro380 - - - - - - Current phase C changed - The name of the EventType ({4a092a66-352d-4d60-90ab-6ac5f58b92fe}) of ThingClass sdm630 ----------- -The name of the EventType ({610b20fb-2718-4f02-ac6e-12a9ef8c7615}) of ThingClass pro380 - - - - - - - - Current power - The name of the ParamType (ThingClass: sdm630, EventType: currentPower, ID: {c824e97b-a6d1-4030-9d7a-00af6fb8e1c3}) ----------- -The name of the StateType ({c824e97b-a6d1-4030-9d7a-00af6fb8e1c3}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPower, ID: {464eff60-11c2-46b7-98f5-1aa8172e5a2d}) ----------- -The name of the StateType ({464eff60-11c2-46b7-98f5-1aa8172e5a2d}) of ThingClass pro380 - - - - - - Current power changed - The name of the EventType ({c824e97b-a6d1-4030-9d7a-00af6fb8e1c3}) of ThingClass sdm630 ----------- -The name of the EventType ({464eff60-11c2-46b7-98f5-1aa8172e5a2d}) of ThingClass pro380 - - - - - - - - Current power phase A - The name of the ParamType (ThingClass: sdm630, EventType: currentPowerPhaseA, ID: {3982fb12-b179-40f7-9b27-36adb1cadd37}) ----------- -The name of the StateType ({3982fb12-b179-40f7-9b27-36adb1cadd37}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPowerPhaseA, ID: {55283773-0a4e-4574-b21a-d4a3f287eab1}) ----------- -The name of the StateType ({55283773-0a4e-4574-b21a-d4a3f287eab1}) of ThingClass pro380 - - - - - - Current power phase A changed - The name of the EventType ({3982fb12-b179-40f7-9b27-36adb1cadd37}) of ThingClass sdm630 ----------- -The name of the EventType ({55283773-0a4e-4574-b21a-d4a3f287eab1}) of ThingClass pro380 - - - - - - - - Current power phase B - The name of the ParamType (ThingClass: sdm630, EventType: currentPowerPhaseB, ID: {2a231c58-b095-4037-8394-a730431e70b8}) ----------- -The name of the StateType ({2a231c58-b095-4037-8394-a730431e70b8}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPowerPhaseB, ID: {8f15d104-5ff7-4c33-9cf9-fdbef4b6f721}) ----------- -The name of the StateType ({8f15d104-5ff7-4c33-9cf9-fdbef4b6f721}) of ThingClass pro380 - - - - - - Current power phase B changed - The name of the EventType ({2a231c58-b095-4037-8394-a730431e70b8}) of ThingClass sdm630 ----------- -The name of the EventType ({8f15d104-5ff7-4c33-9cf9-fdbef4b6f721}) of ThingClass pro380 - - - - - - - - Current power phase C - The name of the ParamType (ThingClass: sdm630, EventType: currentPowerPhaseC, ID: {ee8c4f0c-2b69-4210-9966-1553a592b06d}) ----------- -The name of the StateType ({ee8c4f0c-2b69-4210-9966-1553a592b06d}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPowerPhaseC, ID: {86c0f968-ee70-4f56-bdfc-33b8e2b134a4}) ----------- -The name of the StateType ({86c0f968-ee70-4f56-bdfc-33b8e2b134a4}) of ThingClass pro380 - - - - - - Current power phase C changed - The name of the EventType ({ee8c4f0c-2b69-4210-9966-1553a592b06d}) of ThingClass sdm630 ----------- -The name of the EventType ({86c0f968-ee70-4f56-bdfc-33b8e2b134a4}) of ThingClass pro380 - - - - - - - - Energy consumed phase A - The name of the ParamType (ThingClass: sdm630, EventType: energyConsumedPhaseA, ID: {6ca06c81-fe75-4448-a22f-47c303421440}) ----------- -The name of the StateType ({6ca06c81-fe75-4448-a22f-47c303421440}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: energyConsumedPhaseA, ID: {b16b3b0c-82d9-4b3c-a172-0e6631c8ce16}) ----------- -The name of the StateType ({b16b3b0c-82d9-4b3c-a172-0e6631c8ce16}) of ThingClass pro380 - - - - - - Energy consumed phase A changed - The name of the EventType ({6ca06c81-fe75-4448-a22f-47c303421440}) of ThingClass sdm630 ----------- -The name of the EventType ({b16b3b0c-82d9-4b3c-a172-0e6631c8ce16}) of ThingClass pro380 - - - - - - - - Energy consumed phase B - The name of the ParamType (ThingClass: sdm630, EventType: energyConsumedPhaseB, ID: {fa2b879b-2a81-4bc8-9577-98082c4d9330}) ----------- -The name of the StateType ({fa2b879b-2a81-4bc8-9577-98082c4d9330}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: energyConsumedPhaseB, ID: {64225f7f-9b2f-4bfc-87b2-38758804a28b}) ----------- -The name of the StateType ({64225f7f-9b2f-4bfc-87b2-38758804a28b}) of ThingClass pro380 - - - - - - Energy consumed phase B changed - The name of the EventType ({fa2b879b-2a81-4bc8-9577-98082c4d9330}) of ThingClass sdm630 ----------- -The name of the EventType ({64225f7f-9b2f-4bfc-87b2-38758804a28b}) of ThingClass pro380 - - - - - - - - Energy consumed phase C - The name of the ParamType (ThingClass: sdm630, EventType: energyConsumedPhaseC, ID: {4c084c9e-7a5d-42d1-96b2-a8a4b4a25713}) ----------- -The name of the StateType ({4c084c9e-7a5d-42d1-96b2-a8a4b4a25713}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: energyConsumedPhaseC, ID: {a6e82d61-e837-4ec8-b14a-af0d49bea9d2}) ----------- -The name of the StateType ({a6e82d61-e837-4ec8-b14a-af0d49bea9d2}) of ThingClass pro380 - - - - - - Energy consumed phase C changed - The name of the EventType ({4c084c9e-7a5d-42d1-96b2-a8a4b4a25713}) of ThingClass sdm630 ----------- -The name of the EventType ({a6e82d61-e837-4ec8-b14a-af0d49bea9d2}) of ThingClass pro380 - - - - - - - - Energy produced phase A - The name of the ParamType (ThingClass: sdm630, EventType: energyProducedPhaseA, ID: {308fa88e-6054-4c79-b12a-be2d0a404ef6}) ----------- -The name of the StateType ({308fa88e-6054-4c79-b12a-be2d0a404ef6}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: energyProducedPhaseA, ID: {95bd476e-c247-4f7d-ab01-d9f1b7c0d996}) ----------- -The name of the StateType ({95bd476e-c247-4f7d-ab01-d9f1b7c0d996}) of ThingClass pro380 - - - - - - Energy produced phase A changed - The name of the EventType ({308fa88e-6054-4c79-b12a-be2d0a404ef6}) of ThingClass sdm630 ----------- -The name of the EventType ({95bd476e-c247-4f7d-ab01-d9f1b7c0d996}) of ThingClass pro380 - - - - - - - - Energy produced phase B - The name of the ParamType (ThingClass: sdm630, EventType: energyProducedPhaseB, ID: {48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39}) ----------- -The name of the StateType ({48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: energyProducedPhaseB, ID: {f0a0bd81-708c-48d6-b5c9-165464a5b309}) ----------- -The name of the StateType ({f0a0bd81-708c-48d6-b5c9-165464a5b309}) of ThingClass pro380 - - - - - - Energy produced phase B changed - The name of the EventType ({48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39}) of ThingClass sdm630 ----------- -The name of the EventType ({f0a0bd81-708c-48d6-b5c9-165464a5b309}) of ThingClass pro380 - - - - - - - - Energy produced phase C - The name of the ParamType (ThingClass: sdm630, EventType: energyProducedPhaseC, ID: {6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff}) ----------- -The name of the StateType ({6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: energyProducedPhaseC, ID: {c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1}) ----------- -The name of the StateType ({c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1}) of ThingClass pro380 - - - - - - Energy produced phase C changed - The name of the EventType ({6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff}) of ThingClass sdm630 ----------- -The name of the EventType ({c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1}) of ThingClass pro380 - - - - - EnergyMeters - The name of the plugin EnergyMeters ({56e95111-fb6b-4f63-9a0a-a5ee001e89ed}) - Energiezähler - - - - - - - Frequency - The name of the ParamType (ThingClass: sdm630, EventType: frequency, ID: {ab24f26c-dc15-4ec3-8d76-06a48285440b}) ----------- -The name of the StateType ({ab24f26c-dc15-4ec3-8d76-06a48285440b}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: frequency, ID: {bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5}) ----------- -The name of the StateType ({bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5}) of ThingClass pro380 - Frequenz - - - - - Frequency changed - The name of the EventType ({ab24f26c-dc15-4ec3-8d76-06a48285440b}) of ThingClass sdm630 ----------- -The name of the EventType ({bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5}) of ThingClass pro380 - Frequenz geändert - - - - - Modbus RTU master - The name of the ParamType (ThingClass: sdm630, Type: thing, ID: {d90e9292-d03c-4f2a-957e-5d965018c9c9}) ----------- -The name of the ParamType (ThingClass: pro380, Type: thing, ID: {6cdbec8c-21b9-42dc-b1ab-8901ac609482}) - Modbus RTU Master - - - - - Modbus slave address - The name of the ParamType (ThingClass: sdm630, Type: thing, ID: {ac77ea98-b006-486e-a3e8-b30a483f26c1}) ----------- -The name of the ParamType (ThingClass: pro380, Type: thing, ID: {c75b2c31-6ec3-49ab-8c8f-5231d0a7e941}) - Modbus Slave-Adresse - - - - PRO380-Mod - The name of the ThingClass ({d7c6440b-54f9-4cc0-a96b-9bb7304b3e77}) - PRO380-Mod - - - - SDM630 Modbus - The name of the ThingClass ({f37597bb-35fe-48f2-9617-343dd54c0903}) - - - - - - - - Voltage phase A - The name of the ParamType (ThingClass: sdm630, EventType: voltagePhaseA, ID: {db018146-0441-4dc0-9834-6d43ebaf8311}) ----------- -The name of the StateType ({db018146-0441-4dc0-9834-6d43ebaf8311}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: voltagePhaseA, ID: {04dba21a-7447-46b9-b9ae-095e5769e511}) ----------- -The name of the StateType ({04dba21a-7447-46b9-b9ae-095e5769e511}) of ThingClass pro380 - - - - - - Voltage phase A changed - The name of the EventType ({db018146-0441-4dc0-9834-6d43ebaf8311}) of ThingClass sdm630 ----------- -The name of the EventType ({04dba21a-7447-46b9-b9ae-095e5769e511}) of ThingClass pro380 - - - - - - - - Voltage phase B - The name of the ParamType (ThingClass: sdm630, EventType: voltagePhaseB, ID: {406f6d02-d5eb-49b3-87da-3247568e6054}) ----------- -The name of the StateType ({406f6d02-d5eb-49b3-87da-3247568e6054}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: voltagePhaseB, ID: {270d0c34-0a0c-4655-985f-faad6efd1afd}) ----------- -The name of the StateType ({270d0c34-0a0c-4655-985f-faad6efd1afd}) of ThingClass pro380 - - - - - - Voltage phase B changed - The name of the EventType ({406f6d02-d5eb-49b3-87da-3247568e6054}) of ThingClass sdm630 ----------- -The name of the EventType ({270d0c34-0a0c-4655-985f-faad6efd1afd}) of ThingClass pro380 - - - - - - - - Voltage phase C - The name of the ParamType (ThingClass: sdm630, EventType: voltagePhaseC, ID: {ace6294d-deaa-4d9a-af78-d64379bcb229}) ----------- -The name of the StateType ({ace6294d-deaa-4d9a-af78-d64379bcb229}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: voltagePhaseC, ID: {a1da8cfd-37cc-4c87-b857-e942cd90daec}) ----------- -The name of the StateType ({a1da8cfd-37cc-4c87-b857-e942cd90daec}) of ThingClass pro380 - - - - - - Voltage phase C changed - The name of the EventType ({ace6294d-deaa-4d9a-af78-d64379bcb229}) of ThingClass sdm630 ----------- -The name of the EventType ({a1da8cfd-37cc-4c87-b857-e942cd90daec}) of ThingClass pro380 - - - - - - Slave address - The name of the ParamType (ThingClass: sdm630, Type: discovery, ID: {6ab43559-53ec-47ba-b8a0-8d3b7f8d90c2}) ----------- -The name of the ParamType (ThingClass: pro380, Type: discovery, ID: {a29f37f6-b344-4628-8ab4-8f4c18fada4a}) - Slave-Adresse - - - - - - - Total energy consumed - The name of the ParamType (ThingClass: sdm630, EventType: totalEnergyConsumed, ID: {98d858a8-22e8-4262-b5c7-25bb027942ad}) ----------- -The name of the StateType ({98d858a8-22e8-4262-b5c7-25bb027942ad}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: totalEnergyConsumed, ID: {f18fd596-b47f-44be-a0f0-6ca44369ebf5}) ----------- -The name of the StateType ({f18fd596-b47f-44be-a0f0-6ca44369ebf5}) of ThingClass pro380 - Gesamte verbrauchte Energy - - - - - Total energy consumed changed - The name of the EventType ({98d858a8-22e8-4262-b5c7-25bb027942ad}) of ThingClass sdm630 ----------- -The name of the EventType ({f18fd596-b47f-44be-a0f0-6ca44369ebf5}) of ThingClass pro380 - Gesamte verbrauchte Energie geändert - - - - - - - Total energy produced - The name of the ParamType (ThingClass: sdm630, EventType: totalEnergyProduced, ID: {e469b3ff-a4c2-42da-af35-ccafaef214af}) ----------- -The name of the StateType ({e469b3ff-a4c2-42da-af35-ccafaef214af}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: totalEnergyProduced, ID: {112911c9-14e0-4c83-ac92-f2ceb3bdecdf}) ----------- -The name of the StateType ({112911c9-14e0-4c83-ac92-f2ceb3bdecdf}) of ThingClass pro380 - Gesamte produzierte Energie - - - - - Total energy produced changed - The name of the EventType ({e469b3ff-a4c2-42da-af35-ccafaef214af}) of ThingClass sdm630 ----------- -The name of the EventType ({112911c9-14e0-4c83-ac92-f2ceb3bdecdf}) of ThingClass pro380 - Gesamte produzierte Energie geändert - - - - inepro Metering - The name of the vendor ({64f4df0f-18ce-409c-bf32-84a086c691ca}) - inepro Metering - - - - IntegrationPluginEnergyMeters - - - No Modbus RTU interface available. - Keine Modbus RTU Schnittstelle verfügbar - - - - Modbus slave address must be between 1 and 254 - Die Modbus-Slave-Adresse muss zwischen 1 und 254 liegen - - - - Energy meter - Energiezähler - - - - Slave address - Slave-Adresse - - - - Slave address not valid, must be between 1 and 254 - Die Slave-Adresse ist ungültig, sie muss zwischen 1 und 254 liegen - - - - Modbus RTU resource not available. - Modbus RTU Schnittstelle nicht verfügbar - - - diff --git a/energymeters/translations/56e95111-fb6b-4f63-9a0a-a5ee001e89ed-en_US.ts b/energymeters/translations/56e95111-fb6b-4f63-9a0a-a5ee001e89ed-en_US.ts deleted file mode 100644 index f84148f..0000000 --- a/energymeters/translations/56e95111-fb6b-4f63-9a0a-a5ee001e89ed-en_US.ts +++ /dev/null @@ -1,577 +0,0 @@ - - - - - EnergyMeters - - - B+G e-tech - The name of the vendor ({215035fe-95e8-43d8-a52e-0a31b787d902}) - - - - - - - - Connected - The name of the ParamType (ThingClass: sdm630, EventType: connected, ID: {8050bd0b-1dad-4a7e-b632-c71ead3c9f8b}) ----------- -The name of the StateType ({8050bd0b-1dad-4a7e-b632-c71ead3c9f8b}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: connected, ID: {7f9bc504-0882-4b86-83b1-42fa345acfd9}) ----------- -The name of the StateType ({7f9bc504-0882-4b86-83b1-42fa345acfd9}) of ThingClass pro380 - - - - - - Connected changed - The name of the EventType ({8050bd0b-1dad-4a7e-b632-c71ead3c9f8b}) of ThingClass sdm630 ----------- -The name of the EventType ({7f9bc504-0882-4b86-83b1-42fa345acfd9}) of ThingClass pro380 - - - - - - - - Current phase A - The name of the ParamType (ThingClass: sdm630, EventType: currentPhaseA, ID: {4baf1d08-5ffa-49cf-95ef-9527b0c6f081}) ----------- -The name of the StateType ({4baf1d08-5ffa-49cf-95ef-9527b0c6f081}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPhaseA, ID: {1e077a3b-2dab-4ec4-ae96-ab49a564fe31}) ----------- -The name of the StateType ({1e077a3b-2dab-4ec4-ae96-ab49a564fe31}) of ThingClass pro380 - - - - - - Current phase A changed - The name of the EventType ({4baf1d08-5ffa-49cf-95ef-9527b0c6f081}) of ThingClass sdm630 ----------- -The name of the EventType ({1e077a3b-2dab-4ec4-ae96-ab49a564fe31}) of ThingClass pro380 - - - - - - - - Current phase B - The name of the ParamType (ThingClass: sdm630, EventType: currentPhaseB, ID: {99e47d06-0a6a-4bfd-b164-61ecb6ba2818}) ----------- -The name of the StateType ({99e47d06-0a6a-4bfd-b164-61ecb6ba2818}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPhaseB, ID: {d2f54061-0807-47de-944c-68c8118ece91}) ----------- -The name of the StateType ({d2f54061-0807-47de-944c-68c8118ece91}) of ThingClass pro380 - - - - - - Current phase B changed - The name of the EventType ({99e47d06-0a6a-4bfd-b164-61ecb6ba2818}) of ThingClass sdm630 ----------- -The name of the EventType ({d2f54061-0807-47de-944c-68c8118ece91}) of ThingClass pro380 - - - - - - - - Current phase C - The name of the ParamType (ThingClass: sdm630, EventType: currentPhaseC, ID: {4a092a66-352d-4d60-90ab-6ac5f58b92fe}) ----------- -The name of the StateType ({4a092a66-352d-4d60-90ab-6ac5f58b92fe}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPhaseC, ID: {610b20fb-2718-4f02-ac6e-12a9ef8c7615}) ----------- -The name of the StateType ({610b20fb-2718-4f02-ac6e-12a9ef8c7615}) of ThingClass pro380 - - - - - - Current phase C changed - The name of the EventType ({4a092a66-352d-4d60-90ab-6ac5f58b92fe}) of ThingClass sdm630 ----------- -The name of the EventType ({610b20fb-2718-4f02-ac6e-12a9ef8c7615}) of ThingClass pro380 - - - - - - - - Current power - The name of the ParamType (ThingClass: sdm630, EventType: currentPower, ID: {c824e97b-a6d1-4030-9d7a-00af6fb8e1c3}) ----------- -The name of the StateType ({c824e97b-a6d1-4030-9d7a-00af6fb8e1c3}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPower, ID: {464eff60-11c2-46b7-98f5-1aa8172e5a2d}) ----------- -The name of the StateType ({464eff60-11c2-46b7-98f5-1aa8172e5a2d}) of ThingClass pro380 - - - - - - Current power changed - The name of the EventType ({c824e97b-a6d1-4030-9d7a-00af6fb8e1c3}) of ThingClass sdm630 ----------- -The name of the EventType ({464eff60-11c2-46b7-98f5-1aa8172e5a2d}) of ThingClass pro380 - - - - - - - - Current power phase A - The name of the ParamType (ThingClass: sdm630, EventType: currentPowerPhaseA, ID: {3982fb12-b179-40f7-9b27-36adb1cadd37}) ----------- -The name of the StateType ({3982fb12-b179-40f7-9b27-36adb1cadd37}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPowerPhaseA, ID: {55283773-0a4e-4574-b21a-d4a3f287eab1}) ----------- -The name of the StateType ({55283773-0a4e-4574-b21a-d4a3f287eab1}) of ThingClass pro380 - - - - - - Current power phase A changed - The name of the EventType ({3982fb12-b179-40f7-9b27-36adb1cadd37}) of ThingClass sdm630 ----------- -The name of the EventType ({55283773-0a4e-4574-b21a-d4a3f287eab1}) of ThingClass pro380 - - - - - - - - Current power phase B - The name of the ParamType (ThingClass: sdm630, EventType: currentPowerPhaseB, ID: {2a231c58-b095-4037-8394-a730431e70b8}) ----------- -The name of the StateType ({2a231c58-b095-4037-8394-a730431e70b8}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPowerPhaseB, ID: {8f15d104-5ff7-4c33-9cf9-fdbef4b6f721}) ----------- -The name of the StateType ({8f15d104-5ff7-4c33-9cf9-fdbef4b6f721}) of ThingClass pro380 - - - - - - Current power phase B changed - The name of the EventType ({2a231c58-b095-4037-8394-a730431e70b8}) of ThingClass sdm630 ----------- -The name of the EventType ({8f15d104-5ff7-4c33-9cf9-fdbef4b6f721}) of ThingClass pro380 - - - - - - - - Current power phase C - The name of the ParamType (ThingClass: sdm630, EventType: currentPowerPhaseC, ID: {ee8c4f0c-2b69-4210-9966-1553a592b06d}) ----------- -The name of the StateType ({ee8c4f0c-2b69-4210-9966-1553a592b06d}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: currentPowerPhaseC, ID: {86c0f968-ee70-4f56-bdfc-33b8e2b134a4}) ----------- -The name of the StateType ({86c0f968-ee70-4f56-bdfc-33b8e2b134a4}) of ThingClass pro380 - - - - - - Current power phase C changed - The name of the EventType ({ee8c4f0c-2b69-4210-9966-1553a592b06d}) of ThingClass sdm630 ----------- -The name of the EventType ({86c0f968-ee70-4f56-bdfc-33b8e2b134a4}) of ThingClass pro380 - - - - - - - - Energy consumed phase A - The name of the ParamType (ThingClass: sdm630, EventType: energyConsumedPhaseA, ID: {6ca06c81-fe75-4448-a22f-47c303421440}) ----------- -The name of the StateType ({6ca06c81-fe75-4448-a22f-47c303421440}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: energyConsumedPhaseA, ID: {b16b3b0c-82d9-4b3c-a172-0e6631c8ce16}) ----------- -The name of the StateType ({b16b3b0c-82d9-4b3c-a172-0e6631c8ce16}) of ThingClass pro380 - - - - - - Energy consumed phase A changed - The name of the EventType ({6ca06c81-fe75-4448-a22f-47c303421440}) of ThingClass sdm630 ----------- -The name of the EventType ({b16b3b0c-82d9-4b3c-a172-0e6631c8ce16}) of ThingClass pro380 - - - - - - - - Energy consumed phase B - The name of the ParamType (ThingClass: sdm630, EventType: energyConsumedPhaseB, ID: {fa2b879b-2a81-4bc8-9577-98082c4d9330}) ----------- -The name of the StateType ({fa2b879b-2a81-4bc8-9577-98082c4d9330}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: energyConsumedPhaseB, ID: {64225f7f-9b2f-4bfc-87b2-38758804a28b}) ----------- -The name of the StateType ({64225f7f-9b2f-4bfc-87b2-38758804a28b}) of ThingClass pro380 - - - - - - Energy consumed phase B changed - The name of the EventType ({fa2b879b-2a81-4bc8-9577-98082c4d9330}) of ThingClass sdm630 ----------- -The name of the EventType ({64225f7f-9b2f-4bfc-87b2-38758804a28b}) of ThingClass pro380 - - - - - - - - Energy consumed phase C - The name of the ParamType (ThingClass: sdm630, EventType: energyConsumedPhaseC, ID: {4c084c9e-7a5d-42d1-96b2-a8a4b4a25713}) ----------- -The name of the StateType ({4c084c9e-7a5d-42d1-96b2-a8a4b4a25713}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: energyConsumedPhaseC, ID: {a6e82d61-e837-4ec8-b14a-af0d49bea9d2}) ----------- -The name of the StateType ({a6e82d61-e837-4ec8-b14a-af0d49bea9d2}) of ThingClass pro380 - - - - - - Energy consumed phase C changed - The name of the EventType ({4c084c9e-7a5d-42d1-96b2-a8a4b4a25713}) of ThingClass sdm630 ----------- -The name of the EventType ({a6e82d61-e837-4ec8-b14a-af0d49bea9d2}) of ThingClass pro380 - - - - - - - - Energy produced phase A - The name of the ParamType (ThingClass: sdm630, EventType: energyProducedPhaseA, ID: {308fa88e-6054-4c79-b12a-be2d0a404ef6}) ----------- -The name of the StateType ({308fa88e-6054-4c79-b12a-be2d0a404ef6}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: energyProducedPhaseA, ID: {95bd476e-c247-4f7d-ab01-d9f1b7c0d996}) ----------- -The name of the StateType ({95bd476e-c247-4f7d-ab01-d9f1b7c0d996}) of ThingClass pro380 - - - - - - Energy produced phase A changed - The name of the EventType ({308fa88e-6054-4c79-b12a-be2d0a404ef6}) of ThingClass sdm630 ----------- -The name of the EventType ({95bd476e-c247-4f7d-ab01-d9f1b7c0d996}) of ThingClass pro380 - - - - - - - - Energy produced phase B - The name of the ParamType (ThingClass: sdm630, EventType: energyProducedPhaseB, ID: {48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39}) ----------- -The name of the StateType ({48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: energyProducedPhaseB, ID: {f0a0bd81-708c-48d6-b5c9-165464a5b309}) ----------- -The name of the StateType ({f0a0bd81-708c-48d6-b5c9-165464a5b309}) of ThingClass pro380 - - - - - - Energy produced phase B changed - The name of the EventType ({48ab6e61-dfb4-4f85-b5cc-9d89e53c6b39}) of ThingClass sdm630 ----------- -The name of the EventType ({f0a0bd81-708c-48d6-b5c9-165464a5b309}) of ThingClass pro380 - - - - - - - - Energy produced phase C - The name of the ParamType (ThingClass: sdm630, EventType: energyProducedPhaseC, ID: {6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff}) ----------- -The name of the StateType ({6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: energyProducedPhaseC, ID: {c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1}) ----------- -The name of the StateType ({c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1}) of ThingClass pro380 - - - - - - Energy produced phase C changed - The name of the EventType ({6b3ddf15-3d4b-4dc1-8e5a-84fbf90b49ff}) of ThingClass sdm630 ----------- -The name of the EventType ({c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1}) of ThingClass pro380 - - - - - EnergyMeters - The name of the plugin EnergyMeters ({56e95111-fb6b-4f63-9a0a-a5ee001e89ed}) - - - - - - - - Frequency - The name of the ParamType (ThingClass: sdm630, EventType: frequency, ID: {ab24f26c-dc15-4ec3-8d76-06a48285440b}) ----------- -The name of the StateType ({ab24f26c-dc15-4ec3-8d76-06a48285440b}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: frequency, ID: {bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5}) ----------- -The name of the StateType ({bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5}) of ThingClass pro380 - - - - - - Frequency changed - The name of the EventType ({ab24f26c-dc15-4ec3-8d76-06a48285440b}) of ThingClass sdm630 ----------- -The name of the EventType ({bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5}) of ThingClass pro380 - - - - - - Modbus RTU master - The name of the ParamType (ThingClass: sdm630, Type: thing, ID: {d90e9292-d03c-4f2a-957e-5d965018c9c9}) ----------- -The name of the ParamType (ThingClass: pro380, Type: thing, ID: {6cdbec8c-21b9-42dc-b1ab-8901ac609482}) - - - - - - Modbus slave address - The name of the ParamType (ThingClass: sdm630, Type: thing, ID: {ac77ea98-b006-486e-a3e8-b30a483f26c1}) ----------- -The name of the ParamType (ThingClass: pro380, Type: thing, ID: {c75b2c31-6ec3-49ab-8c8f-5231d0a7e941}) - - - - - PRO380-Mod - The name of the ThingClass ({d7c6440b-54f9-4cc0-a96b-9bb7304b3e77}) - - - - - SDM630 Modbus - The name of the ThingClass ({f37597bb-35fe-48f2-9617-343dd54c0903}) - - - - - - - - Voltage phase A - The name of the ParamType (ThingClass: sdm630, EventType: voltagePhaseA, ID: {db018146-0441-4dc0-9834-6d43ebaf8311}) ----------- -The name of the StateType ({db018146-0441-4dc0-9834-6d43ebaf8311}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: voltagePhaseA, ID: {04dba21a-7447-46b9-b9ae-095e5769e511}) ----------- -The name of the StateType ({04dba21a-7447-46b9-b9ae-095e5769e511}) of ThingClass pro380 - - - - - - Voltage phase A changed - The name of the EventType ({db018146-0441-4dc0-9834-6d43ebaf8311}) of ThingClass sdm630 ----------- -The name of the EventType ({04dba21a-7447-46b9-b9ae-095e5769e511}) of ThingClass pro380 - - - - - - - - Voltage phase B - The name of the ParamType (ThingClass: sdm630, EventType: voltagePhaseB, ID: {406f6d02-d5eb-49b3-87da-3247568e6054}) ----------- -The name of the StateType ({406f6d02-d5eb-49b3-87da-3247568e6054}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: voltagePhaseB, ID: {270d0c34-0a0c-4655-985f-faad6efd1afd}) ----------- -The name of the StateType ({270d0c34-0a0c-4655-985f-faad6efd1afd}) of ThingClass pro380 - - - - - - Voltage phase B changed - The name of the EventType ({406f6d02-d5eb-49b3-87da-3247568e6054}) of ThingClass sdm630 ----------- -The name of the EventType ({270d0c34-0a0c-4655-985f-faad6efd1afd}) of ThingClass pro380 - - - - - - - - Voltage phase C - The name of the ParamType (ThingClass: sdm630, EventType: voltagePhaseC, ID: {ace6294d-deaa-4d9a-af78-d64379bcb229}) ----------- -The name of the StateType ({ace6294d-deaa-4d9a-af78-d64379bcb229}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: voltagePhaseC, ID: {a1da8cfd-37cc-4c87-b857-e942cd90daec}) ----------- -The name of the StateType ({a1da8cfd-37cc-4c87-b857-e942cd90daec}) of ThingClass pro380 - - - - - - Voltage phase C changed - The name of the EventType ({ace6294d-deaa-4d9a-af78-d64379bcb229}) of ThingClass sdm630 ----------- -The name of the EventType ({a1da8cfd-37cc-4c87-b857-e942cd90daec}) of ThingClass pro380 - - - - - - Slave address - The name of the ParamType (ThingClass: sdm630, Type: discovery, ID: {6ab43559-53ec-47ba-b8a0-8d3b7f8d90c2}) ----------- -The name of the ParamType (ThingClass: pro380, Type: discovery, ID: {a29f37f6-b344-4628-8ab4-8f4c18fada4a}) - - - - - - - - Total energy consumed - The name of the ParamType (ThingClass: sdm630, EventType: totalEnergyConsumed, ID: {98d858a8-22e8-4262-b5c7-25bb027942ad}) ----------- -The name of the StateType ({98d858a8-22e8-4262-b5c7-25bb027942ad}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: totalEnergyConsumed, ID: {f18fd596-b47f-44be-a0f0-6ca44369ebf5}) ----------- -The name of the StateType ({f18fd596-b47f-44be-a0f0-6ca44369ebf5}) of ThingClass pro380 - - - - - - Total energy consumed changed - The name of the EventType ({98d858a8-22e8-4262-b5c7-25bb027942ad}) of ThingClass sdm630 ----------- -The name of the EventType ({f18fd596-b47f-44be-a0f0-6ca44369ebf5}) of ThingClass pro380 - - - - - - - - Total energy produced - The name of the ParamType (ThingClass: sdm630, EventType: totalEnergyProduced, ID: {e469b3ff-a4c2-42da-af35-ccafaef214af}) ----------- -The name of the StateType ({e469b3ff-a4c2-42da-af35-ccafaef214af}) of ThingClass sdm630 ----------- -The name of the ParamType (ThingClass: pro380, EventType: totalEnergyProduced, ID: {112911c9-14e0-4c83-ac92-f2ceb3bdecdf}) ----------- -The name of the StateType ({112911c9-14e0-4c83-ac92-f2ceb3bdecdf}) of ThingClass pro380 - - - - - - Total energy produced changed - The name of the EventType ({e469b3ff-a4c2-42da-af35-ccafaef214af}) of ThingClass sdm630 ----------- -The name of the EventType ({112911c9-14e0-4c83-ac92-f2ceb3bdecdf}) of ThingClass pro380 - - - - - inepro Metering - The name of the vendor ({64f4df0f-18ce-409c-bf32-84a086c691ca}) - - - - - IntegrationPluginEnergyMeters - - - No Modbus RTU interface available. - - - - - Modbus slave address must be between 1 and 254 - - - - - Energy meter - - - - - Slave address - - - - - Slave address not valid, must be between 1 and 254 - - - - - Modbus RTU resource not available. - - - - diff --git a/inepro/README.md b/inepro/README.md new file mode 100644 index 0000000..f0070d1 --- /dev/null +++ b/inepro/README.md @@ -0,0 +1,9 @@ +# inepro Metering + +This plugin adds support for the inepro Metering PRO380 energy meter connected via Modbus RTU. + +# Setup instructions +First, set up a Modbus RTU resource using the configured settings of your meter. Once +that's set up, the PRO380 can be set up like any other thing. During discovery, nymea will +offer the configured Modbus resources as possible connections. Select the one that +you've set up previously. diff --git a/inepro/inepro.jpg b/inepro/inepro.jpg new file mode 100644 index 0000000000000000000000000000000000000000..954a7ad38e2c8d8e5fc4ba72c5c7494bda46720e GIT binary patch literal 181361 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

N}IK2QiAm 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 Vzv=pSsO$c3y8fo?-=VHY{|)n6EEoU) literal 0 HcmV?d00001 diff --git a/inepro/inepro.pro b/inepro/inepro.pro new file mode 100644 index 0000000..4067273 --- /dev/null +++ b/inepro/inepro.pro @@ -0,0 +1,14 @@ +include(../plugins.pri) + +QT += serialport serialbus + +HEADERS += \ + integrationplugininepro.h \ + pro380modbusrtuconnection.h \ + ../modbus/modbusdatautils.h + +SOURCES += \ + integrationplugininepro.cpp \ + pro380modbusrtuconnection.cpp \ + ../modbus/modbusdatautils.cpp + diff --git a/inepro/integrationplugininepro.cpp b/inepro/integrationplugininepro.cpp new file mode 100644 index 0000000..af5ff77 --- /dev/null +++ b/inepro/integrationplugininepro.cpp @@ -0,0 +1,229 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 . +* +* 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 "integrationplugininepro.h" +#include "plugininfo.h" + +IntegrationPluginInepro::IntegrationPluginInepro() +{ +} + +void IntegrationPluginInepro::init() +{ + connect(hardwareManager()->modbusRtuResource(), &ModbusRtuHardwareResource::modbusRtuMasterRemoved, this, [=] (const QUuid &modbusUuid){ + qCDebug(dcInepro()) << "Modbus RTU master has been removed" << modbusUuid.toString(); + + foreach (Thing *thing, myThings()) { + if (thing->paramValue(pro380ThingModbusMasterUuidParamTypeId) == modbusUuid) { + qCWarning(dcInepro()) << "Modbus RTU hardware resource removed for" << thing << ". The thing will not be functional any more until a new resource has been configured for it."; + thing->setStateValue(pro380ConnectedStateTypeId, false); + + delete m_pro380Connections.take(thing); + } + } + }); +} + +void IntegrationPluginInepro::discoverThings(ThingDiscoveryInfo *info) +{ + qCDebug(dcInepro()) << "Discover modbus RTU resources..."; + if (hardwareManager()->modbusRtuResource()->modbusRtuMasters().isEmpty()) { + info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("No Modbus RTU interface available. Please set up the Modbus RTU interface first.")); + return; + } + + uint slaveAddress = info->params().paramValue(pro380DiscoverySlaveAddressParamTypeId).toUInt(); + if (slaveAddress > 254 || slaveAddress == 0) { + info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("The Modbus slave address must be a value between 1 and 254.")); + return; + } + + foreach (ModbusRtuMaster *modbusMaster, hardwareManager()->modbusRtuResource()->modbusRtuMasters()) { + qCDebug(dcInepro()) << "Found RTU master resource" << modbusMaster << "connected" << modbusMaster->connected(); + if (!modbusMaster->connected()) + continue; + + ThingDescriptor descriptor(info->thingClassId(), "PRO380", QString::number(slaveAddress) + " " + modbusMaster->serialPort()); + ParamList params; + params << Param(pro380ThingSlaveAddressParamTypeId, slaveAddress); + params << Param(pro380ThingModbusMasterUuidParamTypeId, modbusMaster->modbusUuid()); + descriptor.setParams(params); + info->addThingDescriptor(descriptor); + } + + info->finish(Thing::ThingErrorNoError); + return; +} + +void IntegrationPluginInepro::setupThing(ThingSetupInfo *info) +{ + Thing *thing = info->thing(); + qCDebug(dcInepro()) << "Setup thing" << thing << thing->params(); + + uint address = thing->paramValue(pro380ThingSlaveAddressParamTypeId).toUInt(); + if (address > 254 || address == 0) { + qCWarning(dcInepro()) << "Setup failed, slave address is not valid" << address; + info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("The Modbus address not valid. It must be a Value between 1 and 254.")); + return; + } + + QUuid uuid = thing->paramValue(pro380ThingModbusMasterUuidParamTypeId).toUuid(); + if (!hardwareManager()->modbusRtuResource()->hasModbusRtuMaster(uuid)) { + qCWarning(dcInepro()) << "Setup failed, hardware manager not available"; + info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("The Modbus RTU interface is not available.")); + return; + } + + if (m_pro380Connections.contains(thing)) { + qCDebug(dcInepro()) << "Setup after rediscovery, cleaning up ..."; + m_pro380Connections.take(thing)->deleteLater(); + } + + Pro380ModbusRtuConnection *proConnection = new Pro380ModbusRtuConnection(hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), address, this); + connect(proConnection->modbusRtuMaster(), &ModbusRtuMaster::connectedChanged, this, [=](bool connected){ + if (connected) { + qCDebug(dcInepro()) << "Modbus RTU resource connected" << thing << proConnection->modbusRtuMaster()->serialPort(); + } else { + qCWarning(dcInepro()) << "Modbus RTU resource disconnected" << thing << proConnection->modbusRtuMaster()->serialPort(); + } + }); + + connect(proConnection, &Pro380ModbusRtuConnection::currentPhaseAChanged, this, [=](float currentPhaseA){ + thing->setStateValue(pro380CurrentPhaseAStateTypeId, currentPhaseA); + thing->setStateValue(pro380ConnectedStateTypeId, true); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::currentPhaseBChanged, this, [=](float currentPhaseB){ + thing->setStateValue(pro380CurrentPhaseBStateTypeId, currentPhaseB); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::currentPhaseCChanged, this, [=](float currentPhaseC){ + thing->setStateValue(pro380CurrentPhaseCStateTypeId, currentPhaseC); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::voltagePhaseAChanged, this, [=](float voltagePhaseA){ + thing->setStateValue(pro380VoltagePhaseAStateTypeId, voltagePhaseA); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::voltagePhaseBChanged, this, [=](float voltagePhaseB){ + thing->setStateValue(pro380VoltagePhaseBStateTypeId, voltagePhaseB); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::voltagePhaseCChanged, this, [=](float voltagePhaseC){ + thing->setStateValue(pro380VoltagePhaseCStateTypeId, voltagePhaseC); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::totalCurrentPowerChanged, this, [=](float currentPower){ + thing->setStateValue(pro380CurrentPowerStateTypeId, currentPower * 1000); // kW + }); + + connect(proConnection, &Pro380ModbusRtuConnection::powerPhaseAChanged, this, [=](float powerPhaseA){ + thing->setStateValue(pro380CurrentPowerPhaseAStateTypeId, powerPhaseA * 1000); // kW + }); + + connect(proConnection, &Pro380ModbusRtuConnection::powerPhaseBChanged, this, [=](float powerPhaseB){ + thing->setStateValue(pro380CurrentPowerPhaseBStateTypeId, powerPhaseB * 1000); // kW + }); + + connect(proConnection, &Pro380ModbusRtuConnection::powerPhaseCChanged, this, [=](float powerPhaseC){ + thing->setStateValue(pro380CurrentPowerPhaseCStateTypeId, powerPhaseC * 1000); // kW + }); + + connect(proConnection, &Pro380ModbusRtuConnection::frequencyChanged, this, [=](float frequency){ + thing->setStateValue(pro380FrequencyStateTypeId, frequency); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::totalEnergyConsumedChanged, this, [=](float totalEnergyConsumed){ + thing->setStateValue(pro380TotalEnergyConsumedStateTypeId, totalEnergyConsumed); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::totalEnergyProducedChanged, this, [=](float totalEnergyProduced){ + thing->setStateValue(pro380TotalEnergyProducedStateTypeId, totalEnergyProduced); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::energyProducedPhaseAChanged, this, [=](float energyProducedPhaseA){ + thing->setStateValue(pro380EnergyProducedPhaseAStateTypeId, energyProducedPhaseA); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::energyProducedPhaseBChanged, this, [=](float energyProducedPhaseB){ + thing->setStateValue(pro380EnergyProducedPhaseBStateTypeId, energyProducedPhaseB); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::energyProducedPhaseCChanged, this, [=](float energyProducedPhaseC){ + thing->setStateValue(pro380EnergyProducedPhaseCStateTypeId, energyProducedPhaseC); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::energyConsumedPhaseAChanged, this, [=](float energyConsumedPhaseA){ + thing->setStateValue(pro380EnergyConsumedPhaseAStateTypeId, energyConsumedPhaseA); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::energyConsumedPhaseBChanged, this, [=](float energyConsumedPhaseB){ + thing->setStateValue(pro380EnergyConsumedPhaseBStateTypeId, energyConsumedPhaseB); + }); + + connect(proConnection, &Pro380ModbusRtuConnection::energyConsumedPhaseCChanged, this, [=](float energyConsumedPhaseC){ + thing->setStateValue(pro380EnergyConsumedPhaseCStateTypeId, energyConsumedPhaseC); + }); + + + // FIXME: try to read before setup success + m_pro380Connections.insert(thing, proConnection); + info->finish(Thing::ThingErrorNoError); +} + +void IntegrationPluginInepro::postSetupThing(Thing *thing) +{ + qCDebug(dcInepro) << "Post setup thing" << thing->name(); + if (!m_refreshTimer) { + m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(2); + connect(m_refreshTimer, &PluginTimer::timeout, this, [this] { + foreach (Thing *thing, myThings()) { + m_pro380Connections.value(thing)->update(); + } + }); + + qCDebug(dcInepro()) << "Starting refresh timer..."; + m_refreshTimer->start(); + } +} + +void IntegrationPluginInepro::thingRemoved(Thing *thing) +{ + qCDebug(dcInepro()) << "Thing removed" << thing->name(); + + if (m_pro380Connections.contains(thing)) + m_pro380Connections.take(thing)->deleteLater(); + + if (myThings().isEmpty() && m_refreshTimer) { + qCDebug(dcInepro()) << "Stopping reconnect timer"; + hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer); + m_refreshTimer = nullptr; + } +} diff --git a/inepro/integrationplugininepro.h b/inepro/integrationplugininepro.h new file mode 100644 index 0000000..dfd8ce0 --- /dev/null +++ b/inepro/integrationplugininepro.h @@ -0,0 +1,66 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* 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 . +* +* 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 INTEGRATIONPLUGININEPRO_H +#define INTEGRATIONPLUGININEPRO_H + +#include +#include +#include + +#include "pro380modbusrtuconnection.h" + +#include "extern-plugininfo.h" + +#include +#include + +class IntegrationPluginInepro : public IntegrationPlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationplugininepro.json") + Q_INTERFACES(IntegrationPlugin) + +public: + explicit IntegrationPluginInepro(); + void init() override; + void discoverThings(ThingDiscoveryInfo *info) override; + void setupThing(ThingSetupInfo *info) override; + void postSetupThing(Thing *thing) override; + void thingRemoved(Thing *thing) override; + +private: + PluginTimer *m_refreshTimer = nullptr; + + QHash m_pro380Connections; +}; + +#endif // INTEGRATIONPLUGININEPRO_H diff --git a/inepro/integrationplugininepro.json b/inepro/integrationplugininepro.json new file mode 100644 index 0000000..bf04b89 --- /dev/null +++ b/inepro/integrationplugininepro.json @@ -0,0 +1,230 @@ +{ + "name": "inepro", + "displayName": "inepro Metering", + "id": "9bc19f8c-ff9e-4036-95a4-c79038709656", + "paramTypes":[ ], + "vendors": [ + { + "name": "ineproMetering", + "displayName": "inepro Metering", + "id": "64f4df0f-18ce-409c-bf32-84a086c691ca", + "thingClasses": [ + { + "name": "pro380", + "displayName": "PRO380", + "id": "d7c6440b-54f9-4cc0-a96b-9bb7304b3e77", + "createMethods": ["discovery"], + "interfaces": ["energymeter", "connectable"], + "discoveryParamTypes": [ + { + "id": "a29f37f6-b344-4628-8ab4-8f4c18fada4a", + "name": "slaveAddress", + "displayName": "Slave address", + "type": "int", + "defaultValue": 1 + } + ], + "paramTypes": [ + { + "id": "c75b2c31-6ec3-49ab-8c8f-5231d0a7e941", + "name": "slaveAddress", + "displayName": "Modbus slave address", + "type": "uint", + "defaultValue": 1 + }, + { + "id": "6cdbec8c-21b9-42dc-b1ab-8901ac609482", + "name": "modbusMasterUuid", + "displayName": "Modbus RTU master", + "type": "QUuid", + "defaultValue": "", + "readOnly": true + } + ], + "stateTypes": [ + { + "id": "7f9bc504-0882-4b86-83b1-42fa345acfd9", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "type": "bool", + "cached": false, + "defaultValue": false + }, + { + "id": "04dba21a-7447-46b9-b9ae-095e5769e511", + "name": "voltagePhaseA", + "displayName": "Voltage phase A", + "displayNameEvent": "Voltage phase A changed", + "type": "double", + "unit": "Volt", + "defaultValue": 0 + }, + { + "id": "270d0c34-0a0c-4655-985f-faad6efd1afd", + "name": "voltagePhaseB", + "displayName": "Voltage phase B", + "displayNameEvent": "Voltage phase B changed", + "type": "double", + "unit": "Volt", + "defaultValue": 0 + }, + { + "id": "a1da8cfd-37cc-4c87-b857-e942cd90daec", + "name": "voltagePhaseC", + "displayName": "Voltage phase C", + "displayNameEvent": "Voltage phase C changed", + "type": "double", + "unit": "Volt", + "defaultValue": 0 + }, + { + "id": "1e077a3b-2dab-4ec4-ae96-ab49a564fe31", + "name": "currentPhaseA", + "displayName": "Current phase A", + "displayNameEvent": "Current phase A changed", + "type": "double", + "unit": "Ampere", + "defaultValue": 0 + }, + { + "id": "d2f54061-0807-47de-944c-68c8118ece91", + "name": "currentPhaseB", + "displayName": "Current phase B", + "displayNameEvent": "Current phase B changed", + "type": "double", + "unit": "Ampere", + "defaultValue": 0 + }, + { + "id": "610b20fb-2718-4f02-ac6e-12a9ef8c7615", + "name": "currentPhaseC", + "displayName": "Current phase C", + "displayNameEvent": "Current phase C changed", + "type": "double", + "unit": "Ampere", + "defaultValue": 0 + }, + { + "id": "464eff60-11c2-46b7-98f5-1aa8172e5a2d", + "name": "currentPower", + "displayName": "Current power", + "displayNameEvent": "Current power changed", + "type": "double", + "unit": "Watt", + "defaultValue": 0 + }, + { + "id": "55283773-0a4e-4574-b21a-d4a3f287eab1", + "name": "currentPowerPhaseA", + "displayName": "Current power phase A", + "displayNameEvent": "Current power phase A changed", + "type": "double", + "unit": "Watt", + "defaultValue": 0 + }, + { + "id": "8f15d104-5ff7-4c33-9cf9-fdbef4b6f721", + "name": "currentPowerPhaseB", + "displayName": "Current power phase B", + "displayNameEvent": "Current power phase B changed", + "type": "double", + "unit": "Watt", + "defaultValue": 0 + }, + { + "id": "86c0f968-ee70-4f56-bdfc-33b8e2b134a4", + "name": "currentPowerPhaseC", + "displayName": "Current power phase C", + "displayNameEvent": "Current power phase C changed", + "type": "double", + "unit": "Watt", + "defaultValue": 0 + }, + { + "id": "bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5", + "name": "frequency", + "displayName": "Frequency", + "displayNameEvent": "Frequency changed", + "type": "double", + "unit": "Hertz", + "defaultValue": 0.00 + }, + { + "id": "f18fd596-b47f-44be-a0f0-6ca44369ebf5", + "name": "totalEnergyConsumed", + "displayName": "Total energy consumed", + "displayNameEvent": "Total energy consumed changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "112911c9-14e0-4c83-ac92-f2ceb3bdecdf", + "name": "totalEnergyProduced", + "displayName": "Total energy produced", + "displayNameEvent": "Total energy produced changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "b16b3b0c-82d9-4b3c-a172-0e6631c8ce16", + "name": "energyConsumedPhaseA", + "displayName": "Energy consumed phase A", + "displayNameEvent": "Energy consumed phase A changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "64225f7f-9b2f-4bfc-87b2-38758804a28b", + "name": "energyConsumedPhaseB", + "displayName": "Energy consumed phase B", + "displayNameEvent": "Energy consumed phase B changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "a6e82d61-e837-4ec8-b14a-af0d49bea9d2", + "name": "energyConsumedPhaseC", + "displayName": "Energy consumed phase C", + "displayNameEvent": "Energy consumed phase C changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "95bd476e-c247-4f7d-ab01-d9f1b7c0d996", + "name": "energyProducedPhaseA", + "displayName": "Energy produced phase A", + "displayNameEvent": "Energy produced phase A changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "f0a0bd81-708c-48d6-b5c9-165464a5b309", + "name": "energyProducedPhaseB", + "displayName": "Energy produced phase B", + "displayNameEvent": "Energy produced phase B changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + }, + { + "id": "c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1", + "name": "energyProducedPhaseC", + "displayName": "Energy produced phase C", + "displayNameEvent": "Energy produced phase C changed", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0.00 + } + ] + } + ] + } + ] +} diff --git a/inepro/meta.json b/inepro/meta.json new file mode 100644 index 0000000..9f3565b --- /dev/null +++ b/inepro/meta.json @@ -0,0 +1,13 @@ +{ + "title": "inepro Metering", + "tagline": "Connect inepro Metering Modbus RTU energy meters.", + "icon": "inepro.jpg", + "stability": "consumer", + "offline": true, + "technologies": [ + "modbus" + ], + "categories": [ + "energy" + ] +} diff --git a/energymeters/pro380-registers.json b/inepro/pro380-registers.json similarity index 100% rename from energymeters/pro380-registers.json rename to inepro/pro380-registers.json diff --git a/energymeters/pro380modbusrtuconnection.cpp b/inepro/pro380modbusrtuconnection.cpp similarity index 100% rename from energymeters/pro380modbusrtuconnection.cpp rename to inepro/pro380modbusrtuconnection.cpp diff --git a/energymeters/pro380modbusrtuconnection.h b/inepro/pro380modbusrtuconnection.h similarity index 100% rename from energymeters/pro380modbusrtuconnection.h rename to inepro/pro380modbusrtuconnection.h diff --git a/inepro/translations/9bc19f8c-ff9e-4036-95a4-c79038709656-de.ts b/inepro/translations/9bc19f8c-ff9e-4036-95a4-c79038709656-de.ts new file mode 100644 index 0000000..5ddc234 --- /dev/null +++ b/inepro/translations/9bc19f8c-ff9e-4036-95a4-c79038709656-de.ts @@ -0,0 +1,363 @@ + + + + + IntegrationPluginInepro + + + No Modbus RTU interface available. Please set up the Modbus RTU interface first. + Keine Modbus RTU Schnittstelle verfügbar. Bitte richte zuerst die Modbus RTU Schnittstelle ein. + + + + The Modbus slave address must be a value between 1 and 254. + Die Modbus Adresse muss ein Wert zwischen 1 und 254 sein. + + + + The Modbus address not valid. It must be a Value between 1 and 254. + Die Modbus Adresse ist ungültig. Es muss ein Wert zwischen 1 und 254 sein. + + + + The Modbus RTU interface is not available. + Die Modbus RTU Schnittstelle ist nicht verfügbar. + + + + inepro + + + + Connected + The name of the ParamType (ThingClass: pro380, EventType: connected, ID: {7f9bc504-0882-4b86-83b1-42fa345acfd9}) +---------- +The name of the StateType ({7f9bc504-0882-4b86-83b1-42fa345acfd9}) of ThingClass pro380 + Verbunden + + + + Connected changed + The name of the EventType ({7f9bc504-0882-4b86-83b1-42fa345acfd9}) of ThingClass pro380 + Verbunden oder getrennt + + + + + Current phase A + The name of the ParamType (ThingClass: pro380, EventType: currentPhaseA, ID: {1e077a3b-2dab-4ec4-ae96-ab49a564fe31}) +---------- +The name of the StateType ({1e077a3b-2dab-4ec4-ae96-ab49a564fe31}) of ThingClass pro380 + Strom Phase A + + + + Current phase A changed + The name of the EventType ({1e077a3b-2dab-4ec4-ae96-ab49a564fe31}) of ThingClass pro380 + Strom Phase A geändert + + + + + Current phase B + The name of the ParamType (ThingClass: pro380, EventType: currentPhaseB, ID: {d2f54061-0807-47de-944c-68c8118ece91}) +---------- +The name of the StateType ({d2f54061-0807-47de-944c-68c8118ece91}) of ThingClass pro380 + Strom Phase B + + + + Current phase B changed + The name of the EventType ({d2f54061-0807-47de-944c-68c8118ece91}) of ThingClass pro380 + Strom Phase B geändert + + + + + Current phase C + The name of the ParamType (ThingClass: pro380, EventType: currentPhaseC, ID: {610b20fb-2718-4f02-ac6e-12a9ef8c7615}) +---------- +The name of the StateType ({610b20fb-2718-4f02-ac6e-12a9ef8c7615}) of ThingClass pro380 + Strom Phase C + + + + Current phase C changed + The name of the EventType ({610b20fb-2718-4f02-ac6e-12a9ef8c7615}) of ThingClass pro380 + Strom Phase C geänert + + + + + Current power + The name of the ParamType (ThingClass: pro380, EventType: currentPower, ID: {464eff60-11c2-46b7-98f5-1aa8172e5a2d}) +---------- +The name of the StateType ({464eff60-11c2-46b7-98f5-1aa8172e5a2d}) of ThingClass pro380 + Aktueller Energieverbrauch + + + + Current power changed + The name of the EventType ({464eff60-11c2-46b7-98f5-1aa8172e5a2d}) of ThingClass pro380 + Aktueller Energieverbrauch geändert + + + + + Current power phase A + The name of the ParamType (ThingClass: pro380, EventType: currentPowerPhaseA, ID: {55283773-0a4e-4574-b21a-d4a3f287eab1}) +---------- +The name of the StateType ({55283773-0a4e-4574-b21a-d4a3f287eab1}) of ThingClass pro380 + Aktueller Energieverbrauch Phase A + + + + Current power phase A changed + The name of the EventType ({55283773-0a4e-4574-b21a-d4a3f287eab1}) of ThingClass pro380 + Aktueller Energieverbrauch Phase A geändert + + + + + Current power phase B + The name of the ParamType (ThingClass: pro380, EventType: currentPowerPhaseB, ID: {8f15d104-5ff7-4c33-9cf9-fdbef4b6f721}) +---------- +The name of the StateType ({8f15d104-5ff7-4c33-9cf9-fdbef4b6f721}) of ThingClass pro380 + Aktueller Energieverbrauch Phase B + + + + Current power phase B changed + The name of the EventType ({8f15d104-5ff7-4c33-9cf9-fdbef4b6f721}) of ThingClass pro380 + Aktueller Energieverbrauch Phase B geändert + + + + + Current power phase C + The name of the ParamType (ThingClass: pro380, EventType: currentPowerPhaseC, ID: {86c0f968-ee70-4f56-bdfc-33b8e2b134a4}) +---------- +The name of the StateType ({86c0f968-ee70-4f56-bdfc-33b8e2b134a4}) of ThingClass pro380 + Aktueller Energieverbrauch Phase C + + + + Current power phase C changed + The name of the EventType ({86c0f968-ee70-4f56-bdfc-33b8e2b134a4}) of ThingClass pro380 + Aktueller Energieverbrauch Phase C geändert + + + + + Energy consumed phase A + The name of the ParamType (ThingClass: pro380, EventType: energyConsumedPhaseA, ID: {b16b3b0c-82d9-4b3c-a172-0e6631c8ce16}) +---------- +The name of the StateType ({b16b3b0c-82d9-4b3c-a172-0e6631c8ce16}) of ThingClass pro380 + Gesamtverbrauch Phase A + + + + Energy consumed phase A changed + The name of the EventType ({b16b3b0c-82d9-4b3c-a172-0e6631c8ce16}) of ThingClass pro380 + Gesamtverbrauch Phase A geändert + + + + + Energy consumed phase B + The name of the ParamType (ThingClass: pro380, EventType: energyConsumedPhaseB, ID: {64225f7f-9b2f-4bfc-87b2-38758804a28b}) +---------- +The name of the StateType ({64225f7f-9b2f-4bfc-87b2-38758804a28b}) of ThingClass pro380 + Gesamtverbrauch Phase B + + + + Energy consumed phase B changed + The name of the EventType ({64225f7f-9b2f-4bfc-87b2-38758804a28b}) of ThingClass pro380 + Gesamtverbrauch Phase B geändert + + + + + Energy consumed phase C + The name of the ParamType (ThingClass: pro380, EventType: energyConsumedPhaseC, ID: {a6e82d61-e837-4ec8-b14a-af0d49bea9d2}) +---------- +The name of the StateType ({a6e82d61-e837-4ec8-b14a-af0d49bea9d2}) of ThingClass pro380 + Gesamtverbrauch Phase C + + + + Energy consumed phase C changed + The name of the EventType ({a6e82d61-e837-4ec8-b14a-af0d49bea9d2}) of ThingClass pro380 + Gesamtverbrauch Phase C geändert + + + + + Energy produced phase A + The name of the ParamType (ThingClass: pro380, EventType: energyProducedPhaseA, ID: {95bd476e-c247-4f7d-ab01-d9f1b7c0d996}) +---------- +The name of the StateType ({95bd476e-c247-4f7d-ab01-d9f1b7c0d996}) of ThingClass pro380 + Erzeugte Energie Phase A + + + + Energy produced phase A changed + The name of the EventType ({95bd476e-c247-4f7d-ab01-d9f1b7c0d996}) of ThingClass pro380 + Erzeugte Energie Phase A geändert + + + + + Energy produced phase B + The name of the ParamType (ThingClass: pro380, EventType: energyProducedPhaseB, ID: {f0a0bd81-708c-48d6-b5c9-165464a5b309}) +---------- +The name of the StateType ({f0a0bd81-708c-48d6-b5c9-165464a5b309}) of ThingClass pro380 + Erzeugte Energie Phase B + + + + Energy produced phase B changed + The name of the EventType ({f0a0bd81-708c-48d6-b5c9-165464a5b309}) of ThingClass pro380 + Erzeugte Energie Phase B geändert + + + + + Energy produced phase C + The name of the ParamType (ThingClass: pro380, EventType: energyProducedPhaseC, ID: {c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1}) +---------- +The name of the StateType ({c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1}) of ThingClass pro380 + Erzeugte Energie Phase C + + + + Energy produced phase C changed + The name of the EventType ({c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1}) of ThingClass pro380 + Erzeugte Energie Phase C geändert + + + + + Frequency + The name of the ParamType (ThingClass: pro380, EventType: frequency, ID: {bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5}) +---------- +The name of the StateType ({bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5}) of ThingClass pro380 + Frequenz + + + + Frequency changed + The name of the EventType ({bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5}) of ThingClass pro380 + Frequenz geändert + + + + Modbus RTU master + The name of the ParamType (ThingClass: pro380, Type: thing, ID: {6cdbec8c-21b9-42dc-b1ab-8901ac609482}) + Modbus RTU Master + + + + Modbus slave address + The name of the ParamType (ThingClass: pro380, Type: thing, ID: {c75b2c31-6ec3-49ab-8c8f-5231d0a7e941}) + Modbus Adresse + + + + PRO380 + The name of the ThingClass ({d7c6440b-54f9-4cc0-a96b-9bb7304b3e77}) + PRO380 + + + + Slave address + The name of the ParamType (ThingClass: pro380, Type: discovery, ID: {a29f37f6-b344-4628-8ab4-8f4c18fada4a}) + Adresse + + + + + Total energy consumed + The name of the ParamType (ThingClass: pro380, EventType: totalEnergyConsumed, ID: {f18fd596-b47f-44be-a0f0-6ca44369ebf5}) +---------- +The name of the StateType ({f18fd596-b47f-44be-a0f0-6ca44369ebf5}) of ThingClass pro380 + Gesamter Energieverbrauch + + + + Total energy consumed changed + The name of the EventType ({f18fd596-b47f-44be-a0f0-6ca44369ebf5}) of ThingClass pro380 + Gesamter Energieverbrauch geändert + + + + + Total energy produced + The name of the ParamType (ThingClass: pro380, EventType: totalEnergyProduced, ID: {112911c9-14e0-4c83-ac92-f2ceb3bdecdf}) +---------- +The name of the StateType ({112911c9-14e0-4c83-ac92-f2ceb3bdecdf}) of ThingClass pro380 + Gesamte erzeugte Energie + + + + Total energy produced changed + The name of the EventType ({112911c9-14e0-4c83-ac92-f2ceb3bdecdf}) of ThingClass pro380 + Gesamte erzeugte Energie geändert + + + + + Voltage phase A + The name of the ParamType (ThingClass: pro380, EventType: voltagePhaseA, ID: {04dba21a-7447-46b9-b9ae-095e5769e511}) +---------- +The name of the StateType ({04dba21a-7447-46b9-b9ae-095e5769e511}) of ThingClass pro380 + Spannung Phase A + + + + Voltage phase A changed + The name of the EventType ({04dba21a-7447-46b9-b9ae-095e5769e511}) of ThingClass pro380 + Spannung Phase A geändert + + + + + Voltage phase B + The name of the ParamType (ThingClass: pro380, EventType: voltagePhaseB, ID: {270d0c34-0a0c-4655-985f-faad6efd1afd}) +---------- +The name of the StateType ({270d0c34-0a0c-4655-985f-faad6efd1afd}) of ThingClass pro380 + Spannung Phase B + + + + Voltage phase B changed + The name of the EventType ({270d0c34-0a0c-4655-985f-faad6efd1afd}) of ThingClass pro380 + Spannung Phase B geändert + + + + + Voltage phase C + The name of the ParamType (ThingClass: pro380, EventType: voltagePhaseC, ID: {a1da8cfd-37cc-4c87-b857-e942cd90daec}) +---------- +The name of the StateType ({a1da8cfd-37cc-4c87-b857-e942cd90daec}) of ThingClass pro380 + Spannung Phase C + + + + Voltage phase C changed + The name of the EventType ({a1da8cfd-37cc-4c87-b857-e942cd90daec}) of ThingClass pro380 + Spannung Phase C geändert + + + + + inepro Metering + The name of the vendor ({64f4df0f-18ce-409c-bf32-84a086c691ca}) +---------- +The name of the plugin inepro ({9bc19f8c-ff9e-4036-95a4-c79038709656}) + inepro Metering + + + diff --git a/inepro/translations/9bc19f8c-ff9e-4036-95a4-c79038709656-en_US.ts b/inepro/translations/9bc19f8c-ff9e-4036-95a4-c79038709656-en_US.ts new file mode 100644 index 0000000..1f736c1 --- /dev/null +++ b/inepro/translations/9bc19f8c-ff9e-4036-95a4-c79038709656-en_US.ts @@ -0,0 +1,363 @@ + + + + + IntegrationPluginInepro + + + No Modbus RTU interface available. Please set up the Modbus RTU interface first. + + + + + The Modbus slave address must be a value between 1 and 254. + + + + + The Modbus address not valid. It must be a Value between 1 and 254. + + + + + The Modbus RTU interface is not available. + + + + + inepro + + + + Connected + The name of the ParamType (ThingClass: pro380, EventType: connected, ID: {7f9bc504-0882-4b86-83b1-42fa345acfd9}) +---------- +The name of the StateType ({7f9bc504-0882-4b86-83b1-42fa345acfd9}) of ThingClass pro380 + + + + + Connected changed + The name of the EventType ({7f9bc504-0882-4b86-83b1-42fa345acfd9}) of ThingClass pro380 + + + + + + Current phase A + The name of the ParamType (ThingClass: pro380, EventType: currentPhaseA, ID: {1e077a3b-2dab-4ec4-ae96-ab49a564fe31}) +---------- +The name of the StateType ({1e077a3b-2dab-4ec4-ae96-ab49a564fe31}) of ThingClass pro380 + + + + + Current phase A changed + The name of the EventType ({1e077a3b-2dab-4ec4-ae96-ab49a564fe31}) of ThingClass pro380 + + + + + + Current phase B + The name of the ParamType (ThingClass: pro380, EventType: currentPhaseB, ID: {d2f54061-0807-47de-944c-68c8118ece91}) +---------- +The name of the StateType ({d2f54061-0807-47de-944c-68c8118ece91}) of ThingClass pro380 + + + + + Current phase B changed + The name of the EventType ({d2f54061-0807-47de-944c-68c8118ece91}) of ThingClass pro380 + + + + + + Current phase C + The name of the ParamType (ThingClass: pro380, EventType: currentPhaseC, ID: {610b20fb-2718-4f02-ac6e-12a9ef8c7615}) +---------- +The name of the StateType ({610b20fb-2718-4f02-ac6e-12a9ef8c7615}) of ThingClass pro380 + + + + + Current phase C changed + The name of the EventType ({610b20fb-2718-4f02-ac6e-12a9ef8c7615}) of ThingClass pro380 + + + + + + Current power + The name of the ParamType (ThingClass: pro380, EventType: currentPower, ID: {464eff60-11c2-46b7-98f5-1aa8172e5a2d}) +---------- +The name of the StateType ({464eff60-11c2-46b7-98f5-1aa8172e5a2d}) of ThingClass pro380 + + + + + Current power changed + The name of the EventType ({464eff60-11c2-46b7-98f5-1aa8172e5a2d}) of ThingClass pro380 + + + + + + Current power phase A + The name of the ParamType (ThingClass: pro380, EventType: currentPowerPhaseA, ID: {55283773-0a4e-4574-b21a-d4a3f287eab1}) +---------- +The name of the StateType ({55283773-0a4e-4574-b21a-d4a3f287eab1}) of ThingClass pro380 + + + + + Current power phase A changed + The name of the EventType ({55283773-0a4e-4574-b21a-d4a3f287eab1}) of ThingClass pro380 + + + + + + Current power phase B + The name of the ParamType (ThingClass: pro380, EventType: currentPowerPhaseB, ID: {8f15d104-5ff7-4c33-9cf9-fdbef4b6f721}) +---------- +The name of the StateType ({8f15d104-5ff7-4c33-9cf9-fdbef4b6f721}) of ThingClass pro380 + + + + + Current power phase B changed + The name of the EventType ({8f15d104-5ff7-4c33-9cf9-fdbef4b6f721}) of ThingClass pro380 + + + + + + Current power phase C + The name of the ParamType (ThingClass: pro380, EventType: currentPowerPhaseC, ID: {86c0f968-ee70-4f56-bdfc-33b8e2b134a4}) +---------- +The name of the StateType ({86c0f968-ee70-4f56-bdfc-33b8e2b134a4}) of ThingClass pro380 + + + + + Current power phase C changed + The name of the EventType ({86c0f968-ee70-4f56-bdfc-33b8e2b134a4}) of ThingClass pro380 + + + + + + Energy consumed phase A + The name of the ParamType (ThingClass: pro380, EventType: energyConsumedPhaseA, ID: {b16b3b0c-82d9-4b3c-a172-0e6631c8ce16}) +---------- +The name of the StateType ({b16b3b0c-82d9-4b3c-a172-0e6631c8ce16}) of ThingClass pro380 + + + + + Energy consumed phase A changed + The name of the EventType ({b16b3b0c-82d9-4b3c-a172-0e6631c8ce16}) of ThingClass pro380 + + + + + + Energy consumed phase B + The name of the ParamType (ThingClass: pro380, EventType: energyConsumedPhaseB, ID: {64225f7f-9b2f-4bfc-87b2-38758804a28b}) +---------- +The name of the StateType ({64225f7f-9b2f-4bfc-87b2-38758804a28b}) of ThingClass pro380 + + + + + Energy consumed phase B changed + The name of the EventType ({64225f7f-9b2f-4bfc-87b2-38758804a28b}) of ThingClass pro380 + + + + + + Energy consumed phase C + The name of the ParamType (ThingClass: pro380, EventType: energyConsumedPhaseC, ID: {a6e82d61-e837-4ec8-b14a-af0d49bea9d2}) +---------- +The name of the StateType ({a6e82d61-e837-4ec8-b14a-af0d49bea9d2}) of ThingClass pro380 + + + + + Energy consumed phase C changed + The name of the EventType ({a6e82d61-e837-4ec8-b14a-af0d49bea9d2}) of ThingClass pro380 + + + + + + Energy produced phase A + The name of the ParamType (ThingClass: pro380, EventType: energyProducedPhaseA, ID: {95bd476e-c247-4f7d-ab01-d9f1b7c0d996}) +---------- +The name of the StateType ({95bd476e-c247-4f7d-ab01-d9f1b7c0d996}) of ThingClass pro380 + + + + + Energy produced phase A changed + The name of the EventType ({95bd476e-c247-4f7d-ab01-d9f1b7c0d996}) of ThingClass pro380 + + + + + + Energy produced phase B + The name of the ParamType (ThingClass: pro380, EventType: energyProducedPhaseB, ID: {f0a0bd81-708c-48d6-b5c9-165464a5b309}) +---------- +The name of the StateType ({f0a0bd81-708c-48d6-b5c9-165464a5b309}) of ThingClass pro380 + + + + + Energy produced phase B changed + The name of the EventType ({f0a0bd81-708c-48d6-b5c9-165464a5b309}) of ThingClass pro380 + + + + + + Energy produced phase C + The name of the ParamType (ThingClass: pro380, EventType: energyProducedPhaseC, ID: {c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1}) +---------- +The name of the StateType ({c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1}) of ThingClass pro380 + + + + + Energy produced phase C changed + The name of the EventType ({c33fcd11-b4a9-44b2-9e30-40dfa2e4c9b1}) of ThingClass pro380 + + + + + + Frequency + The name of the ParamType (ThingClass: pro380, EventType: frequency, ID: {bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5}) +---------- +The name of the StateType ({bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5}) of ThingClass pro380 + + + + + Frequency changed + The name of the EventType ({bb6fd00c-3bbb-4977-bb8a-96787bb6f5c5}) of ThingClass pro380 + + + + + Modbus RTU master + The name of the ParamType (ThingClass: pro380, Type: thing, ID: {6cdbec8c-21b9-42dc-b1ab-8901ac609482}) + + + + + Modbus slave address + The name of the ParamType (ThingClass: pro380, Type: thing, ID: {c75b2c31-6ec3-49ab-8c8f-5231d0a7e941}) + + + + + PRO380 + The name of the ThingClass ({d7c6440b-54f9-4cc0-a96b-9bb7304b3e77}) + + + + + Slave address + The name of the ParamType (ThingClass: pro380, Type: discovery, ID: {a29f37f6-b344-4628-8ab4-8f4c18fada4a}) + + + + + + Total energy consumed + The name of the ParamType (ThingClass: pro380, EventType: totalEnergyConsumed, ID: {f18fd596-b47f-44be-a0f0-6ca44369ebf5}) +---------- +The name of the StateType ({f18fd596-b47f-44be-a0f0-6ca44369ebf5}) of ThingClass pro380 + + + + + Total energy consumed changed + The name of the EventType ({f18fd596-b47f-44be-a0f0-6ca44369ebf5}) of ThingClass pro380 + + + + + + Total energy produced + The name of the ParamType (ThingClass: pro380, EventType: totalEnergyProduced, ID: {112911c9-14e0-4c83-ac92-f2ceb3bdecdf}) +---------- +The name of the StateType ({112911c9-14e0-4c83-ac92-f2ceb3bdecdf}) of ThingClass pro380 + + + + + Total energy produced changed + The name of the EventType ({112911c9-14e0-4c83-ac92-f2ceb3bdecdf}) of ThingClass pro380 + + + + + + Voltage phase A + The name of the ParamType (ThingClass: pro380, EventType: voltagePhaseA, ID: {04dba21a-7447-46b9-b9ae-095e5769e511}) +---------- +The name of the StateType ({04dba21a-7447-46b9-b9ae-095e5769e511}) of ThingClass pro380 + + + + + Voltage phase A changed + The name of the EventType ({04dba21a-7447-46b9-b9ae-095e5769e511}) of ThingClass pro380 + + + + + + Voltage phase B + The name of the ParamType (ThingClass: pro380, EventType: voltagePhaseB, ID: {270d0c34-0a0c-4655-985f-faad6efd1afd}) +---------- +The name of the StateType ({270d0c34-0a0c-4655-985f-faad6efd1afd}) of ThingClass pro380 + + + + + Voltage phase B changed + The name of the EventType ({270d0c34-0a0c-4655-985f-faad6efd1afd}) of ThingClass pro380 + + + + + + Voltage phase C + The name of the ParamType (ThingClass: pro380, EventType: voltagePhaseC, ID: {a1da8cfd-37cc-4c87-b857-e942cd90daec}) +---------- +The name of the StateType ({a1da8cfd-37cc-4c87-b857-e942cd90daec}) of ThingClass pro380 + + + + + Voltage phase C changed + The name of the EventType ({a1da8cfd-37cc-4c87-b857-e942cd90daec}) of ThingClass pro380 + + + + + + inepro Metering + The name of the vendor ({64f4df0f-18ce-409c-bf32-84a086c691ca}) +---------- +The name of the plugin inepro ({9bc19f8c-ff9e-4036-95a4-c79038709656}) + + + + diff --git a/nymea-plugins-modbus.pro b/nymea-plugins-modbus.pro index c851b8c..717131d 100644 --- a/nymea-plugins-modbus.pro +++ b/nymea-plugins-modbus.pro @@ -6,15 +6,16 @@ SUBDIRS += libnymea-sunspec PLUGIN_DIRS = \ alphainnotec \ + bgetech \ drexelundweiss \ - energymeters \ huawei \ + idm \ + inepro \ modbuscommander \ mtec \ mypv \ sunspec \ unipi \ - idm \ wallbe \ webasto \