Added initial version of M-Tec heatpump plugin

Currently only read functionality.
Not yet tested with actual hardware.
pull/21/head
Hermann Detz 2021-04-21 11:03:47 +02:00 committed by Michael Zanetti
parent a62032ae45
commit 621c98369e
14 changed files with 1005 additions and 0 deletions

16
debian/control vendored
View File

@ -94,6 +94,22 @@ Description: nymea.io plugin for my-pv heating rods
This package will install the nymea.io plugin for my-pv
Package: nymea-plugin-mtec
Architecture: any
Section: libs
Depends: ${shlibs:Depends},
${misc:Depends},
nymea-plugins-modbus-translations
Description: nymea.io plugin for M-TEC heat pumps
The nymea daemon is a plugin based IoT (Internet of Things) server. The
server works like a translator for devices, things and services and
allows them to interact.
With the powerful rule engine you are able to connect any device available
in the system and create individual scenes and behaviors for your environment.
.
This package will install the nymea.io plugin for M-TEC heat pumps
Package: nymea-plugin-sunspec
Architecture: any
Depends: ${shlibs:Depends},

1
debian/nymea-plugin-mtec.install.in vendored Normal file
View File

@ -0,0 +1 @@
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginmtec.so

View File

@ -59,6 +59,7 @@ public:
int timeout() const;
void setTimeout(int timeout);
int timeout();
QString errorString() const;
QModbusDevice::Error error() const;
@ -104,6 +105,7 @@ signals:
void writeRequestExecuted(const QUuid &requestId, bool success);
void writeRequestError(const QUuid &requestId, const QString &error);
void readRequestError(const QUuid &requestId, const QString &error);
void readRequestExecuted(const QUuid &requestId, bool success);
void readRequestError(const QUuid &requestId, const QString &error);

View File

@ -0,0 +1,198 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "integrationpluginmtec.h"
#include "plugininfo.h"
IntegrationPluginMTec::IntegrationPluginMTec()
{
}
void IntegrationPluginMTec::discoverThings(ThingDiscoveryInfo *info)
{
qCDebug(dcMTec()) << "Discover M-Tec heat pumps";
if (info->thingClassId() == mtecThingClassId) {
QString description = "Heatpump";
ThingDescriptor descriptor(info->thingClassId(), "M-Tec", description);
info->addThingDescriptor(descriptor);
// TODO Find out, if a discovery is possible/needed
// Otherwise, just report no error for now
info->finish(Thing::ThingErrorNoError);
}
}
void IntegrationPluginMTec::setupThing(ThingSetupInfo *info)
{
qCDebug(dcMTec()) << "Setup" << info->thing();
Thing *thing = info->thing();
if (thing->thingClassId() == mtecThingClassId) {
QHostAddress hostAddress = QHostAddress(thing->paramValue(mtecThingIpAddressParamTypeId).toString());
if (hostAddress.isNull()) {
info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("No IP address given"));
return;
}
qCDebug(dcMTec()) << "User entered address: " << hostAddress.toString();
/* Check, if address is already in use for another device */
/* for (QHash<Thing *, MTec *>::iterator item=m_mtecConnections.begin(); item != m_mtecConnections.end(); item++) { */
/* if (hostAddress.isEqual(item.value()->getHostAddress())) { */
/* qCDebug(dcMTec()) << "Address of thing: " << item.value()->getHostAddress().toString(); */
/* qCDebug(dcMTec()) << "Address in use already"; */
/* } else { */
/* qCDebug(dcMTec()) << "Different address of other thing: " << item.value()->getHostAddress().toString(); */
/* } */
/* } */
foreach (MTec *mtecConnection, m_mtecConnections.values()) {
if (mtecConnection->getHostAddress().isEqual(hostAddress)) {
qCWarning(dcMTec()) << "Address" << hostAddress.toString() << "already in use by" << m_mtecConnections.key(mtecConnection);
info->finish(Thing::ThingErrorThingInUse, QT_TR_NOOP("IP address already in use by another thing."));
return;
}
}
qCDebug(dcMTec()) << "Creating M-Tec object";
/* Create new MTec object and store it in hash table */
MTec *mtec = new MTec(hostAddress, this);
m_mtecConnections.insert(thing, mtec);
info->thing()->setStateValue(mtecConnectedStateTypeId, true);
info->finish(Thing::ThingErrorNoError);
}
}
void IntegrationPluginMTec::postSetupThing(Thing *thing)
{
qCDebug(dcMTec()) << "PostSetup called for" << thing;
if (thing->thingClassId() == mtecThingClassId) {
MTec *mtec = m_mtecConnections.value(thing);
if (mtec) {
connect(mtec, &MTec::statusUpdated, this, &IntegrationPluginMTec::onStatusUpdated);
connect(mtec, &MTec::connectedChanged, this, &IntegrationPluginMTec::onConnectedChanged);
qCDebug(dcMTec()) << "Thing set up, calling update";
update(thing);
thing->setStateValue(mtecConnectedStateTypeId, true);
}
}
}
void IntegrationPluginMTec::thingRemoved(Thing *thing)
{
if (m_mtecConnections.contains(thing)) {
m_mtecConnections.take(thing)->deleteLater();
}
}
void IntegrationPluginMTec::executeAction(ThingActionInfo *info)
{
Thing *thing = info->thing();
Action action = info->action();
if (thing->thingClassId() == mtecThingClassId) {
/* if (action.actionTypeId() == mtecPowerActionTypeId) { */
/* } else { */
/* Q_ASSERT_X(false, "executeAction", QString("Unhandled action: %1").arg(action.actionTypeId().toString()).toUtf8()); */
/* } */
} else {
Q_ASSERT_X(false, "executeAction", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
}
}
void IntegrationPluginMTec::update(Thing *thing)
{
if (thing->thingClassId() == mtecThingClassId) {
qCDebug(dcMTec()) << "Updating thing" << thing;
MTec *mtec = m_mtecConnections.value(thing);
if (mtec) {
mtec->onRequestStatus();
}
}
}
void IntegrationPluginMTec::onConnectedChanged(bool connected)
{
MTec *mtec = qobject_cast<MTec *>(sender());
Thing *thing = m_mtecConnections.key(mtec);
qCDebug(dcMTec()) << "Received connection change event from heat pump" << thing;
if (!thing)
return;
thing->setStateValue(mtecConnectedStateTypeId, connected);
}
void IntegrationPluginMTec::onStatusUpdated(const MTecInfo &info)
{
MTec *mtec = qobject_cast<MTec *>(sender());
Thing *thing = m_mtecConnections.key(mtec);
qCDebug(dcMTec()) << "Received status from heat pump" << thing;
if (!thing)
return;
/* Received a structure holding the status info of the
* heat pump. Update the thing states with the individual fields. */
thing->setStateValue(mtecStatusStateTypeId, info.status);
thing->setStateValue(mtecActualPowerConsumptionStateTypeId, info.actualPowerConsumption);
thing->setStateValue(mtecActualExcessEnergySmartHomeStateTypeId, info.actualExcessEnergySmartHome);
thing->setStateValue(mtecActualExcessEnergyElectricityMeterStateTypeId, info.actualExcessEnergyElectricityMeter);
thing->setStateValue(mtecExternalSetValueScalingStateTypeId, info.externalSetValueScaling);
thing->setStateValue(mtecRequestExternalHeatSourceStateTypeId, info.requestExternalHeatSource);
}
void IntegrationPluginMTec::onRefreshTimer()
{
qCDebug(dcMTec()) << "onRefreshTimer called";
foreach (Thing *thing, myThings().filterByThingClassId(mtecThingClassId)) {
update(thing);
}
}

View File

@ -0,0 +1,73 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef INTEGRATIONPLUGINMTEC_H
#define INTEGRATIONPLUGINMTEC_H
#include "integrations/integrationplugin.h"
#include "plugintimer.h"
#include "mtec.h"
#include <QUuid>
class IntegrationPluginMTec: public IntegrationPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginmtec.json")
Q_INTERFACES(IntegrationPlugin)
public:
/** Constructor */
explicit IntegrationPluginMTec();
void discoverThings(ThingDiscoveryInfo *info) override;
void setupThing(ThingSetupInfo *info) override;
private:
void postSetupThing(Thing *thing) override;
void thingRemoved(Thing *thing) override;
void executeAction(ThingActionInfo *info) override;
void update(Thing *thing);
QHash<Thing *, MTec *> m_mtecConnections;
QHash<QUuid, ThingActionInfo *> m_asyncActions;
private slots:
void onConnectedChanged(bool connected);
void onRefreshTimer();
void onStatusUpdated(const MTecInfo &info);
};
#endif // INTEGRATIONPLUGINMTEC_H

View File

@ -0,0 +1,106 @@
{
"name": "MTec",
"displayName": "M-Tec",
"id": "07cd316b-1e2c-40cf-8358-88d7407506ae",
"vendors": [
{
"name": "MTec",
"displayName": "M-Tec",
"id": "04d3fa7c-e469-4a79-a119-155426e5a846",
"thingClasses": [
{
"name": "mtec",
"displayName": "MTec",
"id": "451e38d8-50d5-4ae9-8d9f-21af9347128d",
"createMethods": ["user"],
"interfaces": ["connectable"],
"paramTypes": [
{
"id": "f1c43b1e-cffe-4d30-bda0-c23ed648dd71",
"name": "ipAddress",
"displayName": "IP address",
"type": "QString"
}
],
"stateTypes": [
{
"id": "8d64954a-855d-44ea-8bc9-88a71ab47b6b",
"name": "connected",
"displayName": "Connected",
"displayNameEvent": "Connected changed",
"type": "bool",
"defaultValue": false,
"cached": false
},
{
"id": "9bf5f8d6-116a-4399-a728-51470a3a5620",
"name": "status",
"displayName": "Status",
"displayNameEvent": "Status changed",
"type": "QString",
"defaultValue": "Off",
"possibleValues": [
"Off",
"Connecting",
"Connected",
"Error"
]
},
{
"id": "c67c79cf-7369-409f-b170-16c4ece9d25a",
"name": "actualPowerConsumption",
"displayName": "Actual power consumption",
"displayNameEvent": "Actual power consumption changed",
"type": "double",
"unit": "Watt",
"defaultValue": 0
},
{
"id": "663718fa-807e-4d85-bd78-61a65f8c0b5e",
"name": "actualExcessEnergySmartHome",
"displayName": "Actual excess energy from Smart home System",
"displayNameEvent": "Actual excess energy from Smart home System changed",
"displayNameAction": "Change actual excess energy from Smart home System",
"type": "double",
"unit": "Watt",
"defaultValue": 0
},
{
"id": "fd94d39c-0db6-497f-a0a5-6c5452cbcaaf",
"name": "actualExcessEnergyElectricityMeter",
"displayName": "Actual excess energy from Electricity Meter",
"displayNameEvent": "Actual excess energy from Electricity Meter changed",
"type": "double",
"unit": "Watt",
"defaultValue": 0
},
{
"id": "087c0296-705b-483a-b1e9-7ce08202c035",
"name": "externalSetValueScaling",
"displayName": "Control of the heat source by an external control [100%]",
"displayNameEvent": "Control of the heat source by an external control [100%] changed",
"type": "double",
"unit": "Percentage",
"defaultValue": 100
},
{
"id": "90b17788-ce63-47e3-b97d-1b025a41ce35",
"name": "requestExternalHeatSource",
"displayName": "Request external heat source",
"displayNameEvent": "Request external heat source changed",
"type": "QString",
"defaultValue": "No request, external heat source must be turned off",
"possibleValues": [
"No request, external heat source must be turned off",
"External heat source is released and can be switched on",
"External heat source is required and must be turned on"
]
}
],
"actionTypes": [
]
}
]
}
]
}

143
mtec/mtec.cpp Normal file
View File

@ -0,0 +1,143 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "mtec.h"
#include "extern-plugininfo.h"
#include "mtechelpers.h"
#include <cstring>
MTec::MTec(const QHostAddress &address, QObject *parent) :
QObject(parent),
m_hostAddress(address)
{
m_modbusMaster = new ModbusTCPMaster(address, 502, this);
qCDebug(dcMTec()) << "created ModbusTCPMaster";
m_connected = m_modbusMaster->connectDevice();
connect(m_modbusMaster, &ModbusTCPMaster::receivedHoldingRegister, this, &MTec::onReceivedHoldingRegister);
connect(m_modbusMaster, &ModbusTCPMaster::readRequestError, this, &MTec::onModbusError);
connect(m_modbusMaster, &ModbusTCPMaster::writeRequestError, this, &MTec::onModbusError);
}
MTec::~MTec()
{
}
void MTec::onModbusError()
{
qCWarning(dcMTec()) << "MTec: Received modbus error";
emit connectedChanged(false);
}
void MTec::onRequestStatus()
{
if ((m_connected) && (!m_firstTimeout.isValid())) {
/* No timestamp for timeout of first telegram defined,
* -> first request has not yet been sent
* -> do it now */
/* Note: m_firstRequest is set to false in
* the onReceivedHoldingRegister function */
if (m_firstRequest == true) {
m_firstTimeout = QDateTime::currentDateTime();
m_firstTimeout = m_firstTimeout.addSecs(MTec::FirstConnectionTimeout);
/* Save original modbus timeout, will be set again
* after first response is received */
m_modbusTimeout = m_modbusMaster->timeout();
/* The M-Tec heatpump requires a longer timeout to
* start-up the modbus communication */
m_modbusMaster->setTimeout(MTec::FirstConnectionTimeout);
} else {
/* Set back original modbus timeout */
m_modbusMaster->setTimeout(m_modbusTimeout);
}
} else {
QDateTime now = QDateTime::currentDateTime();
if (m_firstTimeout.msecsTo(now) < MTec::FirstConnectionTimeout) {
/* Timeout of first request not yet reached
* -> return without sending another request */
return;
}
}
m_modbusMaster->readHoldingRegister(MTec::ModbusUnitID, MTec::ActualPowerConsumption, 1);
}
void MTec::onReceivedHoldingRegister(int slaveAddress, int modbusRegister, const QVector<quint16> &value)
{
Q_UNUSED(slaveAddress);
/* Some response was received, so the modbus communication is
* established. */
m_firstRequest = false;
switch (modbusRegister) {
case ActualPowerConsumption:
if (value.length() == 1) {
m_info.actualPowerConsumption = MTecHelpers::convertRegisterToFloat(value[0]);
}
m_modbusMaster->readHoldingRegister(MTec::ModbusUnitID, MTec::ActualExcessEnergySmartHome, 1);
break;
case ActualExcessEnergySmartHome:
if (value.length() == 1) {
m_info.actualExcessEnergySmartHome = MTecHelpers::convertRegisterToFloat(value[0]);
}
m_modbusMaster->readHoldingRegister(MTec::ModbusUnitID, MTec::ActualExcessEnergyElectricityMeter, 1);
break;
case ActualExcessEnergyElectricityMeter:
if (value.length() == 1) {
m_info.actualExcessEnergyElectricityMeter = MTecHelpers::convertRegisterToFloat(value[0]);
}
m_modbusMaster->readHoldingRegister(MTec::ModbusUnitID, MTec::ExternalSetValueScaling, 1);
break;
case ExternalSetValueScaling:
if (value.length() == 1) {
m_info.externalSetValueScaling = MTecHelpers::convertRegisterToFloat(value[0]);
}
m_modbusMaster->readHoldingRegister(MTec::ModbusUnitID, MTec::RequestExternalHeatSource, 1);
break;
case RequestExternalHeatSource:
if (value.length() == 1) {
m_info.requestExternalHeatSource = MTecHelpers::externalHeatSourceRequestToString(value[0]);
/* Everything read without errors
* -> update status in plugin */
emit statusUpdated(m_info);
}
break;
}
}

130
mtec/mtec.h Normal file
View File

@ -0,0 +1,130 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef MTEC_H
#define MTEC_H
#include <QDateTime>
#include <QObject>
#include "../modbus/modbustcpmaster.h"
#include "mtecinfo.h"
class MTec : public QObject
{
Q_OBJECT
public:
/** Constructor */
explicit MTec(const QHostAddress &address, QObject *parent = nullptr);
/** Destructor */
~MTec();
inline QHostAddress getHostAddress() const { return m_hostAddress; };
private:
/**
* The first response of the M-Tec heatpump may be delayed
* by 10 s. The plugin will wait for the defined time in milliseconds
* for a response before sending an additional request or setting
* an error code.
*/
static const int FirstConnectionTimeout = 15000;
/** Modbus Unit ID (undocumented, guessing 1 for now) */
static const quint16 ModbusUnitID = 1;
/** The following modbus addresses can be read: */
enum RegisterList {
/**
* APPL.CtrlAppl.sParam.heatpump[0].ElectricEnergyMeter.values.power
* Actual power consumtion [W]
*/
ActualPowerConsumption = 707,
/**
* APPL.CtrlAppl.sIOModule.Virt[0].param.sensor[0]
* Acutal excess energy given from Smart home System [W]
*/
ActualExcessEnergySmartHome = 1000,
/**
* APPL.CtrlAppl.sParam.photovoltaics.ElectricEnergyMeter.values.power
* Acutal excess energy given from Electricity Meter [W]
*/
ActualExcessEnergyElectricityMeter = 1002,
/**
* APPL.CtrlAppl.sParam.extHeatSource[0].param.externalSetvalueScaled
* Control of the heat source by an external control [100%]
*/
ExternalSetValueScaling = 1600,
/**
* APPL.CtrlAppl.sParam.extHeatSource[0].values.requestExtHeatsource
* 0no request, external heat source must be turned off.
* 1external heat source is released and can be switched on.
* 2external heat source is required and must be turned on.
*/
RequestExternalHeatSource = 1601
};
/* Note: This class only requires one IP address and one
* TCP Modbus connection. Multiple devices are managed
* within the IntegrationPluginMTec class. */
QHostAddress m_hostAddress;
/** Pointer to ModbusTCPMaster object, responseible for low-level communicaiton */
ModbusTCPMaster *m_modbusMaster = nullptr;
/** This structure is filled by the receivedStatus... functions */
MTecInfo m_info ;
bool m_firstRequest = true;
bool m_connected = false;
QDateTime m_firstTimeout;
int m_modbusTimeout;
signals:
void connectedChanged(bool connected);
void statusUpdated(const MTecInfo &info);
public slots:
void onModbusError();
void onRequestStatus();
void onReceivedHoldingRegister(int slaveAddress, int modbusRegister, const QVector<quint16> &value);
};
#endif // MTEC_H

19
mtec/mtec.pro Normal file
View File

@ -0,0 +1,19 @@
include(../plugins.pri)
QT += \
network \
serialbus \
SOURCES += \
mtec.cpp \
mtechelpers.cpp \
integrationpluginmtec.cpp \
../modbus/modbustcpmaster.cpp
HEADERS += \
mtec.h \
mtechelpers.h \
mtecinfo.h \
integrationpluginmtec.h \
../modbus/modbustcpmaster.h \

65
mtec/mtechelpers.cpp Normal file
View File

@ -0,0 +1,65 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "mtechelpers.h"
float MTecHelpers::convertRegisterToFloat(const quint16 reg)
{
float value = 0.0;
value = reg/100.0;
return value;
}
void MTecHelpers::convertFloatToRegister(quint16 &reg, float value)
{
reg = qRound(value * 100.0);
}
QString MTecHelpers::externalHeatSourceRequestToString(quint16 value)
{
QString str{};
switch (value) {
case 0:
str = "No request, external heat source must be turned off";
break;
case 1:
str = "External heat source is released and can be switched on";
break;
case 2:
str = "External heat source is required and must be turned on";
break;
}
return str;
}

46
mtec/mtechelpers.h Normal file
View File

@ -0,0 +1,46 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef MTECHELPERS_H
#define MTECHELPERS_H
#include <QtGlobal>
#include <QString>
class MTecHelpers {
public:
static float convertRegisterToFloat(quint16 reg);
static void convertFloatToRegister(quint16 &reg, float value);
static QString externalHeatSourceRequestToString(quint16 value);
};
#endif

59
mtec/mtecinfo.h Normal file
View File

@ -0,0 +1,59 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef MTECINFO_H
#define MTECINFO_H
#include <QMetaType>
#include <QString>
/** This struct holds the status information that is read from the MTec device
* and passed to the nymea framework within this plugin.
*/
struct MTecInfo {
/** Contains more detailed info on the status
* (Off, Connecting, Connected, Error) */
QString status;
double actualPowerConsumption;
double actualExcessEnergySmartHome;
double actualExcessEnergyElectricityMeter;
double externalSetValueScaling;
QString requestExternalHeatSource;
};
Q_DECLARE_METATYPE(MTecInfo);
#endif

View File

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1">
<context>
<name>IntegrationPluginMTec</name>
<message>
<location filename="../integrationpluginmtec.cpp" line="64"/>
<source>No IP address given</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../integrationpluginmtec.cpp" line="85"/>
<source>IP address already in use by another thing.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MTec</name>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="50"/>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="53"/>
<source>Actual excess energy from Electricity Meter</source>
<extracomment>The name of the ParamType (ThingClass: mtec, EventType: actualExcessEnergyElectricityMeter, ID: {fd94d39c-0db6-497f-a0a5-6c5452cbcaaf})
----------
The name of the StateType ({fd94d39c-0db6-497f-a0a5-6c5452cbcaaf}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="56"/>
<source>Actual excess energy from Electricity Meter changed</source>
<extracomment>The name of the EventType ({fd94d39c-0db6-497f-a0a5-6c5452cbcaaf}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="59"/>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="62"/>
<source>Actual excess energy from Smart home System</source>
<extracomment>The name of the ParamType (ThingClass: mtec, EventType: actualExcessEnergySmartHome, ID: {663718fa-807e-4d85-bd78-61a65f8c0b5e})
----------
The name of the StateType ({663718fa-807e-4d85-bd78-61a65f8c0b5e}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="65"/>
<source>Actual excess energy from Smart home System changed</source>
<extracomment>The name of the EventType ({663718fa-807e-4d85-bd78-61a65f8c0b5e}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="68"/>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="71"/>
<source>Actual power consumption</source>
<extracomment>The name of the ParamType (ThingClass: mtec, EventType: actualPowerConsumption, ID: {c67c79cf-7369-409f-b170-16c4ece9d25a})
----------
The name of the StateType ({c67c79cf-7369-409f-b170-16c4ece9d25a}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="74"/>
<source>Actual power consumption changed</source>
<extracomment>The name of the EventType ({c67c79cf-7369-409f-b170-16c4ece9d25a}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="77"/>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="80"/>
<source>Connected</source>
<extracomment>The name of the ParamType (ThingClass: mtec, EventType: connected, ID: {8d64954a-855d-44ea-8bc9-88a71ab47b6b})
----------
The name of the StateType ({8d64954a-855d-44ea-8bc9-88a71ab47b6b}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="83"/>
<source>Connected changed</source>
<extracomment>The name of the EventType ({8d64954a-855d-44ea-8bc9-88a71ab47b6b}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="86"/>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="89"/>
<source>Control of the heat source by an external control [100%]</source>
<extracomment>The name of the ParamType (ThingClass: mtec, EventType: externalSetValueScaling, ID: {087c0296-705b-483a-b1e9-7ce08202c035})
----------
The name of the StateType ({087c0296-705b-483a-b1e9-7ce08202c035}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="92"/>
<source>Control of the heat source by an external control [100%] changed</source>
<extracomment>The name of the EventType ({087c0296-705b-483a-b1e9-7ce08202c035}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="95"/>
<source>IP address</source>
<extracomment>The name of the ParamType (ThingClass: mtec, Type: thing, ID: {f1c43b1e-cffe-4d30-bda0-c23ed648dd71})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="98"/>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="101"/>
<source>M-Tec</source>
<extracomment>The name of the vendor ({04d3fa7c-e469-4a79-a119-155426e5a846})
----------
The name of the plugin MTec ({07cd316b-1e2c-40cf-8358-88d7407506ae})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="104"/>
<source>MTec</source>
<extracomment>The name of the ThingClass ({451e38d8-50d5-4ae9-8d9f-21af9347128d})</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="107"/>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="110"/>
<source>Request external heat source</source>
<extracomment>The name of the ParamType (ThingClass: mtec, EventType: requestExternalHeatSource, ID: {90b17788-ce63-47e3-b97d-1b025a41ce35})
----------
The name of the StateType ({90b17788-ce63-47e3-b97d-1b025a41ce35}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="113"/>
<source>Request external heat source changed</source>
<extracomment>The name of the EventType ({90b17788-ce63-47e3-b97d-1b025a41ce35}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="116"/>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="119"/>
<source>Status</source>
<extracomment>The name of the ParamType (ThingClass: mtec, EventType: status, ID: {9bf5f8d6-116a-4399-a728-51470a3a5620})
----------
The name of the StateType ({9bf5f8d6-116a-4399-a728-51470a3a5620}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../build-nymea-plugins-modbus-Desktop-Debug/mtec/plugininfo.h" line="122"/>
<source>Status changed</source>
<extracomment>The name of the EventType ({9bf5f8d6-116a-4399-a728-51470a3a5620}) of ThingClass mtec</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -4,6 +4,7 @@ PLUGIN_DIRS = \
drexelundweiss \
energymeters \
modbuscommander \
mtec \
mypv \
sunspec \
unipi \