devices to things
This commit is contained in:
parent
344239fe0d
commit
197c1e0019
@ -1,78 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 DEVICEPLUGINDREXELUNDWEISS_H
|
||||
#define DEVICEPLUGINDREXELUNDWEISS_H
|
||||
|
||||
#include "devices/devicemanager.h"
|
||||
#include "plugintimer.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include "modbusrtumaster.h"
|
||||
#include <QSerialPortInfo>
|
||||
|
||||
class DevicePluginDrexelUndWeiss : public DevicePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "deviceplugindrexelundweiss.json")
|
||||
Q_INTERFACES(DevicePlugin)
|
||||
|
||||
public:
|
||||
explicit DevicePluginDrexelUndWeiss();
|
||||
~DevicePluginDrexelUndWeiss() override;
|
||||
void init() override;
|
||||
|
||||
void discoverDevices(DeviceDiscoveryInfo *info) override;
|
||||
void setupDevice(DeviceSetupInfo *info) override;
|
||||
void postSetupDevice(Device *device) override;
|
||||
void deviceRemoved(Device *device) override;
|
||||
void executeAction(DeviceActionInfo *info) override;
|
||||
|
||||
private:
|
||||
QList<QString> m_usedSerialPorts;
|
||||
QHash<Device *, ModbusRTUMaster *> m_modbusRTUMasters;
|
||||
PluginTimer *m_refreshTimer = nullptr;
|
||||
QHash<QUuid, DeviceActionInfo *> m_pendingActions;
|
||||
|
||||
void updateStates(Device *device);
|
||||
void discoverModbusSlaves(ModbusRTUMaster *modbus, int slaveAddress);
|
||||
|
||||
private slots:
|
||||
void onRefreshTimer();
|
||||
void onPluginConfigurationChanged(const ParamTypeId ¶mTypeId, const QVariant &value);
|
||||
|
||||
void onConnectionStateChanged(bool status);
|
||||
void onReceivedCoil(int slaveAddress, int modbusRegister, bool value);
|
||||
void onReceivedDiscreteInput(int slaveAddress, int modbusRegister, bool value);
|
||||
void onReceivedHoldingRegister(int slaveAddress, int modbusRegister, int value);
|
||||
void onReceivedInputRegister(int slaveAddress, int modbusRegister, int value);
|
||||
|
||||
void onWriteRequestFinished(QUuid requestId, bool success);
|
||||
};
|
||||
|
||||
#endif // DEVICEPLUGINDREXELUNDWEISS_H
|
||||
BIN
drexelundweiss/drexelundweiss.png
Normal file
BIN
drexelundweiss/drexelundweiss.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 126 KiB |
@ -1,17 +1,15 @@
|
||||
include(../plugins.pri)
|
||||
|
||||
TARGET = $$qtLibraryTarget(nymea_deviceplugindrexelundweiss)
|
||||
|
||||
QT += \
|
||||
serialport \
|
||||
serialbus \
|
||||
|
||||
SOURCES += \
|
||||
deviceplugindrexelundweiss.cpp \
|
||||
integrationplugindrexelundweiss.cpp \
|
||||
modbusrtumaster.cpp \
|
||||
|
||||
HEADERS += \
|
||||
deviceplugindrexelundweiss.h \
|
||||
integrationplugindrexelundweiss.h \
|
||||
modbusrtumaster.h \
|
||||
modbusdegisterdefinition.h
|
||||
|
||||
|
||||
@ -1,55 +1,58 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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/>.
|
||||
* 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
|
||||
* 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 "deviceplugindrexelundweiss.h"
|
||||
#include "integrationplugindrexelundweiss.h"
|
||||
#include "plugininfo.h"
|
||||
#include "modbusdegisterdefinition.h"
|
||||
|
||||
DevicePluginDrexelUndWeiss::DevicePluginDrexelUndWeiss()
|
||||
IntegrationPluginDrexelUndWeiss::IntegrationPluginDrexelUndWeiss()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DevicePluginDrexelUndWeiss::~DevicePluginDrexelUndWeiss()
|
||||
IntegrationPluginDrexelUndWeiss::~IntegrationPluginDrexelUndWeiss()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::init()
|
||||
void IntegrationPluginDrexelUndWeiss::init()
|
||||
{
|
||||
connect(this, &DevicePluginDrexelUndWeiss::configValueChanged, this, &DevicePluginDrexelUndWeiss::onPluginConfigurationChanged);
|
||||
connect(this, &IntegrationPluginDrexelUndWeiss::configValueChanged, this, &IntegrationPluginDrexelUndWeiss::onPluginConfigurationChanged);
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::discoverDevices(DeviceDiscoveryInfo *info)
|
||||
void IntegrationPluginDrexelUndWeiss::discoverThings(ThingDiscoveryInfo *info)
|
||||
{
|
||||
// Create the list of available serial interfaces
|
||||
QList<DeviceDescriptor> deviceDescriptors;
|
||||
QList<ThingDescriptor> thingDescriptors;
|
||||
|
||||
if (info->deviceClassId() == modbusConnectionDeviceClassId) {
|
||||
if (info->thingClassId() == modbusConnectionThingClassId) {
|
||||
Q_FOREACH(QSerialPortInfo port, QSerialPortInfo::availablePorts()) {
|
||||
if (m_usedSerialPorts.contains(port.systemLocation())){
|
||||
//device already in use
|
||||
@ -58,87 +61,87 @@ void DevicePluginDrexelUndWeiss::discoverDevices(DeviceDiscoveryInfo *info)
|
||||
//Serial port is not yet used, create now a new one
|
||||
qCDebug(dcDrexelUndWeiss()) << "Found serial port:" << port.portName();
|
||||
QString description = port.manufacturer() + " " + port.description();
|
||||
DeviceDescriptor descriptor(info->deviceClassId(), port.portName(), description);
|
||||
ThingDescriptor descriptor(info->thingClassId(), port.portName(), description);
|
||||
ParamList parameters;
|
||||
parameters.append(Param(modbusConnectionDeviceSerialPortParamTypeId, port.systemLocation()));
|
||||
parameters.append(Param(modbusConnectionThingSerialPortParamTypeId, port.systemLocation()));
|
||||
descriptor.setParams(parameters);
|
||||
info->addDeviceDescriptor(descriptor);
|
||||
info->addThingDescriptor(descriptor);
|
||||
}
|
||||
}
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->deviceClassId() == x2luDeviceClassId) {
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
if (info->thingClassId() == x2luThingClassId) {
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->deviceClassId() == x2wpDeviceClassId) {
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
if (info->thingClassId() == x2wpThingClassId) {
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
info->finish(Device::DeviceErrorDeviceClassNotFound);
|
||||
info->finish(Thing::ThingErrorDeviceClassNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::setupDevice(DeviceSetupInfo *info)
|
||||
void IntegrationPluginDrexelUndWeiss::setupThing(ThingSetupInfo *info)
|
||||
{
|
||||
Device *device = info->device();
|
||||
Thing *thing = info->thing();
|
||||
|
||||
if (device->deviceClassId() == modbusConnectionDeviceClassId) {
|
||||
if (thing->thingClassId() == modbusConnectionThingClassId) {
|
||||
|
||||
QString serialPort = device->paramValue(modbusConnectionDeviceSerialPortParamTypeId).toString();
|
||||
int baudRate = device->paramValue(modbusConnectionDeviceBaudRateParamTypeId).toInt();
|
||||
QString serialPort = thing->paramValue(modbusConnectionThingSerialPortParamTypeId).toString();
|
||||
int baudRate = thing->paramValue(modbusConnectionThingBaudRateParamTypeId).toInt();
|
||||
|
||||
ModbusRTUMaster *modbus = new ModbusRTUMaster(serialPort, baudRate, QSerialPort::Parity::NoParity, 8, 1, this);
|
||||
connect(modbus, &ModbusRTUMaster::connectionStateChanged, this, &DevicePluginDrexelUndWeiss::onConnectionStateChanged);
|
||||
connect(modbus, &ModbusRTUMaster::receivedCoil, this, &DevicePluginDrexelUndWeiss::onReceivedCoil);
|
||||
connect(modbus, &ModbusRTUMaster::receivedDiscreteInput, this, &DevicePluginDrexelUndWeiss::onReceivedDiscreteInput);
|
||||
connect(modbus, &ModbusRTUMaster::receivedHoldingRegister, this, &DevicePluginDrexelUndWeiss::onReceivedHoldingRegister);
|
||||
connect(modbus, &ModbusRTUMaster::receivedInputRegister, this, &DevicePluginDrexelUndWeiss::onReceivedInputRegister);
|
||||
connect(modbus, &ModbusRTUMaster::connectionStateChanged, this, &IntegrationPluginDrexelUndWeiss::onConnectionStateChanged);
|
||||
connect(modbus, &ModbusRTUMaster::receivedCoil, this, &IntegrationPluginDrexelUndWeiss::onReceivedCoil);
|
||||
connect(modbus, &ModbusRTUMaster::receivedDiscreteInput, this, &IntegrationPluginDrexelUndWeiss::onReceivedDiscreteInput);
|
||||
connect(modbus, &ModbusRTUMaster::receivedHoldingRegister, this, &IntegrationPluginDrexelUndWeiss::onReceivedHoldingRegister);
|
||||
connect(modbus, &ModbusRTUMaster::receivedInputRegister, this, &IntegrationPluginDrexelUndWeiss::onReceivedInputRegister);
|
||||
|
||||
|
||||
m_modbusRTUMasters.insert(device, modbus);
|
||||
m_modbusRTUMasters.insert(thing, modbus);
|
||||
m_usedSerialPorts.append(serialPort);
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == x2luDeviceClassId) {
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
if (thing->thingClassId() == x2luThingClassId) {
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == x2wpDeviceClassId) {
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
if (thing->thingClassId() == x2wpThingClassId) {
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
info->finish(Device::DeviceErrorDeviceClassNotFound);
|
||||
info->finish(Thing::ThingErrorDeviceClassNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::postSetupDevice(Device *device)
|
||||
void IntegrationPluginDrexelUndWeiss::postSetupDevice(Thing *thing)
|
||||
{
|
||||
if (!m_refreshTimer) {
|
||||
// Refresh timer for TCP read
|
||||
int refreshTime = configValue(drexelUndWeissPluginUpdateIntervalParamTypeId).toInt();
|
||||
m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(refreshTime);
|
||||
connect(m_refreshTimer, &PluginTimer::timeout, this, &DevicePluginDrexelUndWeiss::onRefreshTimer);
|
||||
connect(m_refreshTimer, &PluginTimer::timeout, this, &IntegrationPluginDrexelUndWeiss::onRefreshTimer);
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == modbusConnectionDeviceClassId) {
|
||||
if (thing->thingClassId() == modbusConnectionThingClassId) {
|
||||
// read Register 5000 and emit auto-device
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(device);
|
||||
if (!modbus){
|
||||
qCWarning(dcDrexelUndWeiss()) << "No modbus master available";
|
||||
}
|
||||
device->setStateValue(modbusConnectionConnectedStateTypeId, true);
|
||||
thing->setStateValue(modbusConnectionConnectedStateTypeId, true);
|
||||
}
|
||||
|
||||
if ((device->deviceClassId() == x2luDeviceClassId) || (device->deviceClassId() == x2wpDeviceClassId)) {
|
||||
Device *parentDevice = myDevices().findById(device->parentId());
|
||||
if ((thing->thingClassId() == x2luThingClassId) || (thing->thingClassId() == x2wpThingClassId)) {
|
||||
Device *parentDevice = myThings().findById(thing->parentId());
|
||||
if (!parentDevice) {
|
||||
qWarning(dcDrexelUndWeiss()) << "Could not find the parent device";
|
||||
return;
|
||||
@ -152,40 +155,40 @@ void DevicePluginDrexelUndWeiss::postSetupDevice(Device *device)
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::executeAction(DeviceActionInfo *info)
|
||||
void IntegrationPluginDrexelUndWeiss::executeAction(DeviceActionInfo *info)
|
||||
{
|
||||
Device *device = info->device();
|
||||
Thing *thing = info->device();
|
||||
Action action = info->action();
|
||||
|
||||
if (device->deviceClassId() == modbusConnectionDeviceClassId) {
|
||||
if (thing->thingClassId() == modbusConnectionThingClassId) {
|
||||
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(device);
|
||||
if (!modbus){
|
||||
qCWarning(dcDrexelUndWeiss()) << "No modbus interface available";
|
||||
info->finish(Device::DeviceErrorHardwareFailure);
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
if (action.actionTypeId() == modbusConnectionDiscoverDevicesActionTypeId) {
|
||||
int slave = action.param(modbusConnectionDiscoverDevicesActionSlaveAddressParamTypeId).value().toInt();
|
||||
discoverModbusSlaves(modbus, slave);
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
} else {
|
||||
info->finish(Device::DeviceErrorActionTypeNotFound);
|
||||
info->finish(Thing::ThingErrorActionTypeNotFound);
|
||||
}
|
||||
} else if (device->deviceClassId() == x2luDeviceClassId) {
|
||||
Device *parentDevice = myDevices().findById(device->parentId());
|
||||
} else if (thing->thingClassId() == x2luThingClassId) {
|
||||
Device *parentDevice = myThings().findById(thing->parentId());
|
||||
if (!parentDevice) {
|
||||
qWarning(dcDrexelUndWeiss()) << "Could not find the parent device";
|
||||
info->finish(Device::DeviceErrorHardwareFailure);
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(parentDevice);
|
||||
int slave = device->paramValue(x2luDeviceSlaveAddressParamTypeId).toInt();
|
||||
int slave = thing->paramValue(x2luThingSlaveAddressParamTypeId).toInt();
|
||||
if (!modbus){
|
||||
qCWarning(dcDrexelUndWeiss()) << "No modbus interface available";
|
||||
info->finish(Device::DeviceErrorHardwareFailure);
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -209,20 +212,20 @@ void DevicePluginDrexelUndWeiss::executeAction(DeviceActionInfo *info)
|
||||
m_pendingActions.insert(modbus->writeHoldingRegister(slave, ModbusRegisterX2::Betriebsart, data), info);
|
||||
return;
|
||||
} else {
|
||||
info->finish(Device::DeviceErrorActionTypeNotFound);
|
||||
info->finish(Thing::ThingErrorActionTypeNotFound);
|
||||
}
|
||||
} else if (device->deviceClassId() == x2wpDeviceClassId) {
|
||||
Device *parentDevice = myDevices().findById(device->parentId());
|
||||
} else if (thing->thingClassId() == x2wpThingClassId) {
|
||||
Device *parentDevice = myThings().findById(thing->parentId());
|
||||
if (!parentDevice) {
|
||||
qWarning(dcDrexelUndWeiss()) << "Could not find modbus interface";
|
||||
info->finish(Device::DeviceErrorHardwareFailure);
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(parentDevice);
|
||||
int slave = device->paramValue(x2wpDeviceSlaveAddressParamTypeId).toInt();
|
||||
int slave = thing->paramValue(x2wpThingSlaveAddressParamTypeId).toInt();
|
||||
if (!modbus){
|
||||
qCWarning(dcDrexelUndWeiss()) << "No modbus master available";
|
||||
info->finish(Device::DeviceErrorHardwareFailure);
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -237,17 +240,17 @@ void DevicePluginDrexelUndWeiss::executeAction(DeviceActionInfo *info)
|
||||
m_pendingActions.insert(modbus->writeHoldingRegister(slave, ModbusRegisterX2::BrauchwasserSolltermperatur, data), info);
|
||||
return;
|
||||
} else {
|
||||
info->finish(Device::DeviceErrorActionTypeNotFound);
|
||||
info->finish(Thing::ThingErrorActionTypeNotFound);
|
||||
}
|
||||
} else {
|
||||
info->finish(Device::DeviceErrorDeviceClassNotFound);
|
||||
info->finish(Thing::ThingErrorDeviceClassNotFound);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginDrexelUndWeiss::deviceRemoved(Device *device)
|
||||
void IntegrationPluginDrexelUndWeiss::deviceRemoved(Thing *thing)
|
||||
{
|
||||
if (device->deviceClassId() == modbusConnectionDeviceClassId) {
|
||||
if (thing->thingClassId() == modbusConnectionThingClassId) {
|
||||
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.take(device);
|
||||
if (!modbus){
|
||||
@ -259,39 +262,39 @@ void DevicePluginDrexelUndWeiss::deviceRemoved(Device *device)
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::onRefreshTimer()
|
||||
void IntegrationPluginDrexelUndWeiss::onRefreshTimer()
|
||||
{
|
||||
foreach (Device *device, myDevices()) {
|
||||
foreach (Thing *thing, myThings()) {
|
||||
|
||||
if (device->deviceClassId() == modbusConnectionDeviceClassId) {
|
||||
if (thing->thingClassId() == modbusConnectionThingClassId) {
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(device);
|
||||
|
||||
if (!modbus) {
|
||||
qCWarning(dcDrexelUndWeiss()) << "No modbus master available";
|
||||
return;
|
||||
}
|
||||
} else if (device->deviceClassId() == x2luDeviceClassId || device->deviceClassId() == x2wpDeviceClassId){
|
||||
} else if (thing->thingClassId() == x2luThingClassId || thing->thingClassId() == x2wpThingClassId){
|
||||
updateStates(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::updateStates(Device *device)
|
||||
void IntegrationPluginDrexelUndWeiss::updateStates(Thing *thing)
|
||||
{
|
||||
if (device->deviceClassId() == x2luDeviceClassId) {
|
||||
Device *parent = myDevices().findById(device->parentId());
|
||||
if (thing->thingClassId() == x2luThingClassId) {
|
||||
Device *parent = myThings().findById(thing->parentId());
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(parent);
|
||||
int slave = device->paramValue(x2luDeviceSlaveAddressParamTypeId).toInt();
|
||||
int slave = thing->paramValue(x2luThingSlaveAddressParamTypeId).toInt();
|
||||
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::AktiveLuefterstufe);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::Betriebsart); // Ventilation mode
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::CO2);
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == x2wpDeviceClassId) {
|
||||
Device *parent = myDevices().findById(device->parentId());
|
||||
if (thing->thingClassId() == x2wpThingClassId) {
|
||||
Device *parent = myThings().findById(thing->parentId());
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(parent);
|
||||
int slave = device->paramValue(x2wpDeviceSlaveAddressParamTypeId).toInt();
|
||||
int slave = thing->paramValue(x2wpThingSlaveAddressParamTypeId).toInt();
|
||||
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::Waermepumpe);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::RaumSoll);
|
||||
@ -312,7 +315,7 @@ void DevicePluginDrexelUndWeiss::updateStates(Device *device)
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginDrexelUndWeiss::onPluginConfigurationChanged(const ParamTypeId ¶mTypeId, const QVariant &value)
|
||||
void IntegrationPluginDrexelUndWeiss::onPluginConfigurationChanged(const ParamTypeId ¶mTypeId, const QVariant &value)
|
||||
{
|
||||
// Check refresh schedule
|
||||
if (paramTypeId == drexelUndWeissPluginUpdateIntervalParamTypeId) {
|
||||
@ -324,226 +327,226 @@ void DevicePluginDrexelUndWeiss::onPluginConfigurationChanged(const ParamTypeId
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::onConnectionStateChanged(bool status)
|
||||
void IntegrationPluginDrexelUndWeiss::onConnectionStateChanged(bool status)
|
||||
{
|
||||
Q_UNUSED(status)
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::onReceivedCoil(int slaveAddress, int modbusRegister, bool value)
|
||||
void IntegrationPluginDrexelUndWeiss::onReceivedCoil(int slaveAddress, int modbusRegister, bool value)
|
||||
{
|
||||
Q_UNUSED(slaveAddress)
|
||||
Q_UNUSED(modbusRegister)
|
||||
Q_UNUSED(value)
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::onReceivedDiscreteInput(int slaveAddress, int modbusRegister, bool value)
|
||||
void IntegrationPluginDrexelUndWeiss::onReceivedDiscreteInput(int slaveAddress, int modbusRegister, bool value)
|
||||
{
|
||||
Q_UNUSED(slaveAddress)
|
||||
Q_UNUSED(modbusRegister)
|
||||
Q_UNUSED(value)
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::onReceivedHoldingRegister(int slaveAddress, int modbusRegister, int value)
|
||||
void IntegrationPluginDrexelUndWeiss::onReceivedHoldingRegister(int slaveAddress, int modbusRegister, int value)
|
||||
{
|
||||
ModbusRTUMaster *modbus = static_cast<ModbusRTUMaster *>(sender());
|
||||
|
||||
if (m_modbusRTUMasters.values().contains(modbus) ){
|
||||
Device *parentDevice = m_modbusRTUMasters.key(static_cast<ModbusRTUMaster *>(modbus));
|
||||
|
||||
foreach(Device *device, myDevices().filterByParentDeviceId(parentDevice->id())) {
|
||||
if (device->deviceClassId() == x2luDeviceClassId && device->paramValue(x2luDeviceSlaveAddressParamTypeId) == slaveAddress) {
|
||||
foreach(Thing *thing, myThings().filterByParentDeviceId(parentthing->id())) {
|
||||
if (thing->thingClassId() == x2luThingClassId && thing->paramValue(x2luThingSlaveAddressParamTypeId) == slaveAddress) {
|
||||
switch (modbusRegister) {
|
||||
case ModbusRegisterX2::Waermepumpe:
|
||||
device->setStateValue(x2wpPowerStateTypeId, value);
|
||||
thing->setStateValue(x2wpPowerStateTypeId, value);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::RaumSoll:
|
||||
device->setStateValue(x2wpTargetTemperatureStateTypeId, value/1000.00);
|
||||
thing->setStateValue(x2wpTargetTemperatureStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::Raum:
|
||||
device->setStateValue(x2wpTemperatureStateTypeId, value/1000.00);
|
||||
thing->setStateValue(x2wpTemperatureStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::TemperaturWarmwasserspeicherUnten:
|
||||
device->setStateValue(x2wpWaterTemperatureStateTypeId, value/1000.00);
|
||||
thing->setStateValue(x2wpWaterTemperatureStateTypeId, value/1000.00);
|
||||
break;
|
||||
case ModbusRegisterX2::BrauchwasserSolltermperatur:
|
||||
device->setStateValue(x2wpTargetWaterTemperatureStateTypeId, value/1000.00);
|
||||
thing->setStateValue(x2wpTargetWaterTemperatureStateTypeId, value/1000.00);
|
||||
break;
|
||||
case ModbusRegisterX2::Auszenluft:
|
||||
device->setStateValue(x2wpOutsideAirTemperatureStateTypeId, value/1000.00);
|
||||
thing->setStateValue(x2wpOutsideAirTemperatureStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::Summenstoerung:
|
||||
if (value != 0) {
|
||||
//get actual error
|
||||
} else {
|
||||
device->setStateValue(x2wpErrorStateTypeId, "No Error");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "No Error");
|
||||
}
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungAbluftventilator:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Exhaust fan");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Exhaust fan");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungBoilerfuehlerElektroheizstab:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Boiler sensor electric heating element");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Boiler sensor electric heating element");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungBoilerfuehlerSolar:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Boiler sensor solar");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Boiler sensor solar");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungBoilerfuehlerWaermepumpe:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Boiler sensor heat pump");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Boiler sensor heat pump");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungBoileruebertemperatur:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Boiler overtemperature");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Boiler overtemperature");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungCO2Sensor:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "CO2-Sensor");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "CO2-Sensor");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungDruckverlustAbluftZuGrosz:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Pressure loss exhaust air too big");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Pressure loss exhaust air too big");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungDruckverlustZuluftZuGrosz:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Pressure loss supply air too large");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Pressure loss supply air too large");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungDurchflussmengeHeizgkreis:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Flow rate of heating circuit");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Flow rate of heating circuit");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungDurchflussmengeSolekreis:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Flow rate brine circuit");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Flow rate brine circuit");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTeilnehmerNichtErreichbar:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Participant not available");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Participant not available");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTemperaturfuehlerAuszenluft:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Temperature sensor outside air");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Temperature sensor outside air");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTemperaturfuehlerHeizkreisVorlauf:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Temperature sensor heating circuit flow");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Temperature sensor heating circuit flow");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTemperaturfuehlerRaum:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Temperature sensor room");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Temperature sensor room");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTemperaturfuehlerSolarkollektor:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Temperature sensor solar collector");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Temperature sensor solar collector");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTemperaturfuehlerSole:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Temperature sensor brine");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Temperature sensor brine");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTemperaturfuehlerSoleAuszenluft:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Temperature sensor brine outside air");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Temperature sensor brine outside air");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungWaermepumpeHochdruck:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Heat pump high pressure");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Heat pump high pressure");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungWaermepumpeNiederdruck:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Heat pump low pressure");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Heat pump low pressure");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungWertNichtZulaessig:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Value not allowed");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Value not allowed");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungZuluftventilator:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Supply air fan");
|
||||
thing->setStateValue(x2wpErrorStateTypeId, "Supply air fan");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::LeistungKompressor:
|
||||
device->setStateValue(x2wpPowerCompressorStateTypeId, value/1000.00);
|
||||
thing->setStateValue(x2wpPowerCompressorStateTypeId, value/1000.00);
|
||||
break;
|
||||
case ModbusRegisterX2::LeistungWarmwasser:
|
||||
device->setStateValue(x2wpPowerWaterHeatingStateTypeId, value/1000.00);
|
||||
thing->setStateValue(x2wpPowerWaterHeatingStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::LeistungRaumheizung:
|
||||
device->setStateValue(x2wpPowerRoomHeatingStateTypeId, value/1000.00);
|
||||
thing->setStateValue(x2wpPowerRoomHeatingStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::LeistungLuftvorwaermung:
|
||||
device->setStateValue(x2wpPowerAirPreheatingStateTypeId, value/1000.00);
|
||||
thing->setStateValue(x2wpPowerAirPreheatingStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::EnergieKompressor:
|
||||
device->setStateValue(x2wpEnergyCompressorStateTypeId, value/1000.00);
|
||||
thing->setStateValue(x2wpEnergyCompressorStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::EnergieWarmwasser:
|
||||
device->setStateValue(x2wpEnergyWaterHeatingStateTypeId, value/1000.00);
|
||||
thing->setStateValue(x2wpEnergyWaterHeatingStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::EnergieRaumheizung:
|
||||
device->setStateValue(x2wpEnergyRoomHeatingStateTypeId, value/1000.00);
|
||||
thing->setStateValue(x2wpEnergyRoomHeatingStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::EnergieLuftvorerwarrmung:
|
||||
device->setStateValue(x2wpEnergyAirPreheatingStateTypeId, value/1000.00);
|
||||
thing->setStateValue(x2wpEnergyAirPreheatingStateTypeId, value/1000.00);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (device->deviceClassId() == x2wpDeviceClassId && device->paramValue(x2wpDeviceSlaveAddressParamTypeId) == slaveAddress) {
|
||||
} else if (thing->thingClassId() == x2wpThingClassId && thing->paramValue(x2wpThingSlaveAddressParamTypeId) == slaveAddress) {
|
||||
|
||||
switch (modbusRegister) {
|
||||
case ModbusRegisterX2::Betriebsart:
|
||||
if (value == VentialtionMode::ManuellStufe0) {
|
||||
device->setStateValue(x2luVentilationModeStateTypeId, "Manual level 0");
|
||||
thing->setStateValue(x2luVentilationModeStateTypeId, "Manual level 0");
|
||||
} else if (value == VentialtionMode::ManuellStufe1) {
|
||||
device->setStateValue(x2luVentilationModeStateTypeId, "Manual level 1");
|
||||
thing->setStateValue(x2luVentilationModeStateTypeId, "Manual level 1");
|
||||
} else if (value == VentialtionMode::ManuellStufe2) {
|
||||
device->setStateValue(x2luVentilationModeStateTypeId, "Manual level 2");
|
||||
thing->setStateValue(x2luVentilationModeStateTypeId, "Manual level 2");
|
||||
} else if (value == VentialtionMode::ManuellStufe3) {
|
||||
device->setStateValue(x2luVentilationModeStateTypeId, "Manual level 3");
|
||||
thing->setStateValue(x2luVentilationModeStateTypeId, "Manual level 3");
|
||||
} else if (value == VentialtionMode::Automatikbetrieb) {
|
||||
device->setStateValue(x2luVentilationModeStateTypeId, "Automatic");
|
||||
thing->setStateValue(x2luVentilationModeStateTypeId, "Automatic");
|
||||
} else if (value == VentialtionMode::Party) {
|
||||
device->setStateValue(x2luVentilationModeStateTypeId, "Party");
|
||||
thing->setStateValue(x2luVentilationModeStateTypeId, "Party");
|
||||
}
|
||||
break;
|
||||
case ModbusRegisterX2::AktiveLuefterstufe:
|
||||
device->setStateValue(x2luActiveVentilationLevelStateTypeId, value);
|
||||
thing->setStateValue(x2luActiveVentilationLevelStateTypeId, value);
|
||||
break;
|
||||
case ModbusRegisterX2::CO2:
|
||||
device->setStateValue(x2luCo2StateTypeId, value);
|
||||
thing->setStateValue(x2luCo2StateTypeId, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -553,30 +556,30 @@ void DevicePluginDrexelUndWeiss::onReceivedHoldingRegister(int slaveAddress, int
|
||||
switch (value) {
|
||||
case DeviceType::X2_WP: {
|
||||
qDebug(dcDrexelUndWeiss()) << "Discovered X2 heat pump";
|
||||
QList<DeviceDescriptor> deviceDescriptors;
|
||||
DeviceDescriptor descriptor(x2wpDeviceClassId, "X2 WP", "Drexel und Weiss", parentDevice->id());
|
||||
QList<ThingDescriptor> thingDescriptors;
|
||||
ThingDescriptor descriptor(x2wpThingClassId, "X2 WP", "Drexel und Weiss", parentthing->id());
|
||||
ParamList params;
|
||||
|
||||
//modbus->readHoldingRegister(slaveAddress, ModbusRegisterX2::SoftwareVersion);
|
||||
//params.append(Param(x2wpDeviceSofwareVersionParamTypeId, data));
|
||||
params.append(Param(x2wpDeviceSlaveAddressParamTypeId, slaveAddress));
|
||||
//params.append(Param(x2wpThingSofwareVersionParamTypeId, data));
|
||||
params.append(Param(x2wpThingSlaveAddressParamTypeId, slaveAddress));
|
||||
descriptor.setParams(params);
|
||||
deviceDescriptors.append(descriptor);
|
||||
emit autoDevicesAppeared(deviceDescriptors);
|
||||
thingDescriptors.append(descriptor);
|
||||
emit autoDevicesAppeared(thingDescriptors);
|
||||
break;
|
||||
}
|
||||
case DeviceType::X2_LU: {
|
||||
qDebug(dcDrexelUndWeiss()) << "Discovered X2 ventilation unit";
|
||||
QList<DeviceDescriptor> deviceDescriptors;
|
||||
DeviceDescriptor descriptor(x2luDeviceClassId, "X2 LU", "Drexel und Weiss", parentDevice->id());
|
||||
QList<ThingDescriptor> thingDescriptors;
|
||||
ThingDescriptor descriptor(x2luThingClassId, "X2 LU", "Drexel und Weiss", parentthing->id());
|
||||
ParamList params;
|
||||
|
||||
//modbus->readHoldingRegister(slaveAddress, ModbusRegisterX2::SoftwareVersion);
|
||||
//params.append(Param(x2luDeviceSofwareVersionParamTypeId, data));
|
||||
params.append(Param(x2luDeviceSlaveAddressParamTypeId, slaveAddress));
|
||||
//params.append(Param(x2luThingSofwareVersionParamTypeId, data));
|
||||
params.append(Param(x2luThingSlaveAddressParamTypeId, slaveAddress));
|
||||
descriptor.setParams(params);
|
||||
deviceDescriptors.append(descriptor);
|
||||
emit autoDevicesAppeared(deviceDescriptors);
|
||||
thingDescriptors.append(descriptor);
|
||||
emit autoDevicesAppeared(thingDescriptors);
|
||||
break;
|
||||
}
|
||||
case DeviceType::AerosilentBianco:
|
||||
@ -590,38 +593,38 @@ void DevicePluginDrexelUndWeiss::onReceivedHoldingRegister(int slaveAddress, int
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::onReceivedInputRegister(int slaveAddress, int modbusRegister, int value)
|
||||
void IntegrationPluginDrexelUndWeiss::onReceivedInputRegister(int slaveAddress, int modbusRegister, int value)
|
||||
{
|
||||
Q_UNUSED(slaveAddress)
|
||||
Q_UNUSED(modbusRegister)
|
||||
Q_UNUSED(value)
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::onWriteRequestFinished(QUuid requestId, bool success)
|
||||
void IntegrationPluginDrexelUndWeiss::onWriteRequestFinished(QUuid requestId, bool success)
|
||||
{
|
||||
DeviceActionInfo *info = m_pendingActions.take(requestId);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
if (success) {
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
} else {
|
||||
info->finish(Device::DeviceErrorHardwareFailure);
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::discoverModbusSlaves(ModbusRTUMaster *modbus, int slaveAddress)
|
||||
void IntegrationPluginDrexelUndWeiss::discoverModbusSlaves(ModbusRTUMaster *modbus, int slaveAddress)
|
||||
{
|
||||
foreach (Device *device, myDevices()) {
|
||||
if (device->deviceClassId() == x2luDeviceClassId) {
|
||||
if (device->paramValue(x2luDeviceSlaveAddressParamTypeId).toInt() == slaveAddress) {
|
||||
foreach (Thing *thing, myThings()) {
|
||||
if (thing->thingClassId() == x2luThingClassId) {
|
||||
if (thing->paramValue(x2luThingSlaveAddressParamTypeId).toInt() == slaveAddress) {
|
||||
qWarning(dcDrexelUndWeiss()) << "Device with slave address" << slaveAddress << "already added";
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (device->deviceClassId() == x2wpDeviceClassId) {
|
||||
if (device->paramValue(x2wpDeviceSlaveAddressParamTypeId).toInt() == slaveAddress) {
|
||||
qWarning(dcDrexelUndWeiss()) << "Device with slave address" << slaveAddress << "already added";
|
||||
if (thing->thingClassId() == x2wpThingClassId) {
|
||||
if (thing->paramValue(x2wpThingSlaveAddressParamTypeId).toInt() == slaveAddress) {
|
||||
qWarning(dcDrexelUndWeiss()) << "Thing with slave address" << slaveAddress << "already added";
|
||||
return;
|
||||
}
|
||||
}
|
||||
81
drexelundweiss/integrationplugindrexelundweiss.h
Normal file
81
drexelundweiss/integrationplugindrexelundweiss.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 INTEGRATIONPLUGINDREXELUNDWEISS_H
|
||||
#define INTEGRATIONPLUGINDREXELUNDWEISS_H
|
||||
|
||||
#include "integrations/integrationplugin.h"
|
||||
#include "plugintimer.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include "modbusrtumaster.h"
|
||||
#include <QSerialPortInfo>
|
||||
|
||||
class DevicePluginDrexelUndWeiss : public IntegrationPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationplugindrexelundweiss.json")
|
||||
Q_INTERFACES(IntegrationPlugin)
|
||||
|
||||
public:
|
||||
explicit DevicePluginDrexelUndWeiss();
|
||||
~DevicePluginDrexelUndWeiss() override;
|
||||
void init() override;
|
||||
|
||||
void discoverThings(ThingDiscoveryInfo *info) override;
|
||||
void setupThing(ThingSetupInfo *info) override;
|
||||
void postSetupThing(Thing *thing) override;
|
||||
void thingRemoved(Thing *thing) override;
|
||||
void executeAction(ThingActionInfo *info) override;
|
||||
|
||||
private:
|
||||
QList<QString> m_usedSerialPorts;
|
||||
QHash<Thing *, ModbusRTUMaster *> m_modbusRTUMasters;
|
||||
PluginTimer *m_refreshTimer = nullptr;
|
||||
QHash<QUuid, ThingActionInfo *> m_pendingActions;
|
||||
|
||||
void updateStates(Device *device);
|
||||
void discoverModbusSlaves(ModbusRTUMaster *modbus, int slaveAddress);
|
||||
|
||||
private slots:
|
||||
void onRefreshTimer();
|
||||
void onPluginConfigurationChanged(const ParamTypeId ¶mTypeId, const QVariant &value);
|
||||
|
||||
void onConnectionStateChanged(bool status);
|
||||
void onReceivedCoil(int slaveAddress, int modbusRegister, bool value);
|
||||
void onReceivedDiscreteInput(int slaveAddress, int modbusRegister, bool value);
|
||||
void onReceivedHoldingRegister(int slaveAddress, int modbusRegister, int value);
|
||||
void onReceivedInputRegister(int slaveAddress, int modbusRegister, int value);
|
||||
|
||||
void onWriteRequestFinished(QUuid requestId, bool success);
|
||||
};
|
||||
|
||||
#endif // INTEGRATIONPLUGINDREXELUNDWEISS_H
|
||||
@ -17,7 +17,7 @@
|
||||
"name": "DrexelUndWeiss",
|
||||
"displayName": "Drexel und Weiss",
|
||||
"id": "9f476e8b-7e95-448e-b03b-874747e8fb1f",
|
||||
"deviceClasses": [
|
||||
"thingClasses": [
|
||||
{
|
||||
"name": "modbusConnection",
|
||||
"displayName": "Modbus Connection",
|
||||
13
drexelundweiss/meta.json
Normal file
13
drexelundweiss/meta.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"title": "Drexel und Weiss",
|
||||
"tagline": "Connect to Drexel und Weiss HVAC systems.",
|
||||
"icon": "drexelundweiss.png",
|
||||
"stability": "community",
|
||||
"offline": true,
|
||||
"technologies": [
|
||||
"network"
|
||||
],
|
||||
"categories": [
|
||||
"heating"
|
||||
]
|
||||
}
|
||||
@ -1,29 +1,32 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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/>.
|
||||
* 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
|
||||
* 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 MODBUSDEGISTERDEFINITION
|
||||
#define MODBUSDEGISTERDEFINITION
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "modbusrtumaster.h"
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
|
||||
@ -1,29 +1,32 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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/>.
|
||||
* 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
|
||||
* 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 MODBUSRTUMASTER_H
|
||||
#define MODBUSRTUMASTER_H
|
||||
|
||||
@ -1,87 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 DEVICEPLUGINMYPV_H
|
||||
#define DEVICEPLUGINMYPV_H
|
||||
|
||||
#include "devices/deviceplugin.h"
|
||||
#include "plugintimer.h"
|
||||
#include "modbustcpmaster.h"
|
||||
|
||||
#include <QUdpSocket>
|
||||
|
||||
class DevicePluginMyPv: public DevicePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "devicepluginmypv.json")
|
||||
Q_INTERFACES(DevicePlugin)
|
||||
|
||||
|
||||
public:
|
||||
explicit DevicePluginMyPv();
|
||||
|
||||
void discoverDevices(DeviceDiscoveryInfo *info) override;
|
||||
void setupDevice(DeviceSetupInfo *info) override;
|
||||
void postSetupDevice(Device *device) override;
|
||||
void deviceRemoved(Device *device) override;
|
||||
void executeAction(DeviceActionInfo *info) override;
|
||||
|
||||
private:
|
||||
|
||||
enum ElwaModbusRegisters {
|
||||
Power= 1000,
|
||||
WaterTemperature = 1001,
|
||||
TargetWaterTemperature = 1002,
|
||||
Status = 1003,
|
||||
ManuelStart = 1012
|
||||
};
|
||||
|
||||
enum ElwaStatus {
|
||||
Heating = 2,
|
||||
Standby = 3,
|
||||
Boosted = 4,
|
||||
HeatFinished = 5,
|
||||
Setup = 9,
|
||||
ErrorOvertempFuseBlown = 201,
|
||||
ErrorOvertempMeasured = 202,
|
||||
ErrorOvertempElectronics = 203,
|
||||
ErrorHardwareFault = 204,
|
||||
ErrorTempSensor = 205
|
||||
};
|
||||
|
||||
PluginTimer *m_refreshTimer = nullptr;
|
||||
QHash<Device *, ModbusTCPMaster *> m_modbusTcpMasters;
|
||||
|
||||
void update(Device *device);
|
||||
|
||||
private slots:
|
||||
void onRefreshTimer();
|
||||
};
|
||||
|
||||
#endif // DEVICEPLUGINMYPV_H
|
||||
|
||||
@ -1,43 +1,46 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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/>.
|
||||
* 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
|
||||
* 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 "plugininfo.h"
|
||||
#include "devicepluginmypv.h"
|
||||
#include "integrationpluginmypv.h"
|
||||
|
||||
#include <QUdpSocket>
|
||||
#include <QHostAddress>
|
||||
|
||||
DevicePluginMyPv::DevicePluginMyPv()
|
||||
IntegrationPluginMyPv::IntegrationPluginMyPv()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginMyPv::discoverDevices(DeviceDiscoveryInfo *info)
|
||||
void IntegrationPluginMyPv::discoverThings(ThingDiscoveryInfo *info)
|
||||
{
|
||||
QUdpSocket *searchSocket = new QUdpSocket(this);
|
||||
|
||||
@ -59,7 +62,7 @@ void DevicePluginMyPv::discoverDevices(DeviceDiscoveryInfo *info)
|
||||
}
|
||||
|
||||
QTimer::singleShot(2000, this, [this, searchSocket, info](){
|
||||
QList<DeviceDescriptor> descriptorList;
|
||||
QList<ThingDescriptor> descriptorList;
|
||||
while(searchSocket->hasPendingDatagrams()) {
|
||||
char buffer[1024];
|
||||
QHostAddress senderAddress;
|
||||
@ -93,8 +96,8 @@ void DevicePluginMyPv::discoverDevices(DeviceDiscoveryInfo *info)
|
||||
QByteArray serialNumber = data.mid(8, 16);
|
||||
|
||||
bool existing = false;
|
||||
foreach (Device *existingDev, myDevices()) {
|
||||
if (existingDev->deviceClassId() == info->deviceClassId() && existingDev->paramValue(elwaDeviceIpAddressParamTypeId).toString() == address.toString()) {
|
||||
foreach (Thing *existingThing, myThings()) {
|
||||
if (existingThing->thingClassId() == info->thingClassId() && existingThing->paramValue(elwaThingIpAddressParamTypeId).toString() == address.toString()) {
|
||||
existing = true;
|
||||
}
|
||||
}
|
||||
@ -102,24 +105,24 @@ void DevicePluginMyPv::discoverDevices(DeviceDiscoveryInfo *info)
|
||||
qCDebug(dcMypv()) << "Already have device" << senderAddress << "in configured devices. Skipping...";
|
||||
continue;
|
||||
}
|
||||
DeviceDescriptor deviceDescriptors(info->deviceClassId(), "AC ELWA-E", address.toString());
|
||||
ThingDescriptor thingDescriptors(info->thingClassId(), "AC ELWA-E", address.toString());
|
||||
ParamList params;
|
||||
params << Param(elwaDeviceIpAddressParamTypeId, address.toString());
|
||||
params << Param(elwaDeviceSerialNumberParamTypeId, serialNumber);
|
||||
deviceDescriptors.setParams(params);
|
||||
descriptorList << deviceDescriptors;
|
||||
params << Param(elwaThingIpAddressParamTypeId, address.toString());
|
||||
params << Param(elwaThingSerialNumberParamTypeId, serialNumber);
|
||||
thingDescriptors.setParams(params);
|
||||
descriptorList << thingDescriptors;
|
||||
}
|
||||
info->addDeviceDescriptors(descriptorList);;
|
||||
info->addThingDescriptors(descriptorList);;
|
||||
searchSocket->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
void DevicePluginMyPv::setupDevice(DeviceSetupInfo *info)
|
||||
void IntegrationPluginMyPv::setupThing(ThingSetupInfo *info)
|
||||
{
|
||||
Device *device = info->device();
|
||||
Thing *thing = info->thing();
|
||||
|
||||
if(device->deviceClassId() == elwaDeviceClassId) {
|
||||
QHostAddress address = QHostAddress(device->paramValue(elwaDeviceIpAddressParamTypeId).toString());
|
||||
if(thing->thingClassId() == elwaThingClassId) {
|
||||
QHostAddress address = QHostAddress(thing->paramValue(elwaThingIpAddressParamTypeId).toString());
|
||||
ModbusTCPMaster *modbusTcpMaster = new ModbusTCPMaster(address, 502, this);
|
||||
|
||||
if (!modbusTcpMaster->createInterface()) {
|
||||
@ -127,134 +130,134 @@ void DevicePluginMyPv::setupDevice(DeviceSetupInfo *info)
|
||||
|
||||
return;
|
||||
}
|
||||
m_modbusTcpMasters.insert(device, modbusTcpMaster);
|
||||
m_modbusTcpMasters.insert(thing, modbusTcpMaster);
|
||||
} else {
|
||||
Q_ASSERT_X(false, "setupDevice", QString("Unhandled deviceClassId: %1").arg(device->deviceClassId().toString()).toUtf8());
|
||||
Q_ASSERT_X(false, "setupDevice", QString("Unhandled deviceClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginMyPv::postSetupDevice(Device *device)
|
||||
void IntegrationPluginMyPv::postSetupThing(Thing *thing)
|
||||
{
|
||||
if (device->deviceClassId() == elwaDeviceClassId) {
|
||||
update(device);
|
||||
if (thing->thingClassId() == elwaThingClassId) {
|
||||
update(thing);
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginMyPv::deviceRemoved(Device *device)
|
||||
void IntegrationPluginMyPv::thingRemoved(Thing *thing)
|
||||
{
|
||||
if (device->deviceClassId() == elwaDeviceClassId) {
|
||||
ModbusTCPMaster *modbusTCPMaster = m_modbusTcpMasters.take(device);
|
||||
if (thing->thingClassId() == elwaThingClassId) {
|
||||
ModbusTCPMaster *modbusTCPMaster = m_modbusTcpMasters.take(thing);
|
||||
modbusTCPMaster->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginMyPv::executeAction(DeviceActionInfo *info)
|
||||
void IntegrationPluginMyPv::executeAction(ThingActionInfo *info)
|
||||
{
|
||||
Device *device = info->device();
|
||||
Thing *thing = info->thing();
|
||||
Action action = info->action();
|
||||
|
||||
if (device->deviceClassId() == elwaDeviceClassId) {
|
||||
if (thing->thingClassId() == elwaThingClassId) {
|
||||
|
||||
ModbusTCPMaster *modbusTCPMaster = m_modbusTcpMasters.value(device);
|
||||
ModbusTCPMaster *modbusTCPMaster = m_modbusTcpMasters.value(thing);
|
||||
if (action.actionTypeId() == elwaHeatingPowerActionTypeId) {
|
||||
int heatingPower = action.param(elwaHeatingPowerActionHeatingPowerParamTypeId).value().toInt();
|
||||
|
||||
if(!modbusTCPMaster->setRegister(0xff, ElwaModbusRegisters::Power, heatingPower)){
|
||||
return info->finish(Device::DeviceErrorHardwareFailure);
|
||||
return info->finish(Thing::ThingErrorHardwareFailure);
|
||||
}
|
||||
return;
|
||||
} else if (action.actionTypeId() == elwaPowerActionTypeId) {
|
||||
bool power = action.param(elwaHeatingPowerActionHeatingPowerParamTypeId).value().toBool();
|
||||
if(power) {
|
||||
if(!modbusTCPMaster->setRegister(0xff, ElwaModbusRegisters::ManuelStart, 1)){
|
||||
return info->finish(Device::DeviceErrorHardwareFailure);
|
||||
return info->finish(Thing::ThingErrorHardwareFailure);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8());
|
||||
}
|
||||
} else {
|
||||
Q_ASSERT_X(false, "executeAction", QString("Unhandled deviceClassId: %1").arg(device->deviceClassId().toString()).toUtf8());
|
||||
Q_ASSERT_X(false, "executeAction", QString("Unhandled deviceClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginMyPv::onRefreshTimer(){
|
||||
void IntegrationPluginMyPv::onRefreshTimer(){
|
||||
|
||||
foreach (Device *device, myDevices()) {
|
||||
update(device);
|
||||
foreach (Thing *thing, myThings()) {
|
||||
update(thing);
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginMyPv::update(Device *device) {
|
||||
if (device->deviceClassId() == elwaDeviceClassId)
|
||||
void IntegrationPluginMyPv::update(Thing *thing) {
|
||||
if (thing->thingClassId() == elwaThingClassId)
|
||||
{
|
||||
ModbusTCPMaster *modbusTCPMaster = m_modbusTcpMasters.value(device);
|
||||
ModbusTCPMaster *modbusTCPMaster = m_modbusTcpMasters.value(thing);
|
||||
|
||||
int data;
|
||||
if (modbusTCPMaster->getRegister(0xff, ElwaModbusRegisters::Status, &data)) {
|
||||
switch (data) {
|
||||
case Heating: {
|
||||
device->setStateValue(elwaStatusStateTypeId, "Heating");
|
||||
device->setStateValue(elwaPowerStateTypeId, true);
|
||||
thing->setStateValue(elwaStatusStateTypeId, "Heating");
|
||||
thing->setStateValue(elwaPowerStateTypeId, true);
|
||||
break;
|
||||
}
|
||||
case Standby:{
|
||||
device->setStateValue(elwaStatusStateTypeId, "Standby");
|
||||
device->setStateValue(elwaPowerStateTypeId, false);
|
||||
thing->setStateValue(elwaStatusStateTypeId, "Standby");
|
||||
thing->setStateValue(elwaPowerStateTypeId, false);
|
||||
break;
|
||||
}
|
||||
case Boosted:{
|
||||
device->setStateValue(elwaStatusStateTypeId, "Boosted");
|
||||
device->setStateValue(elwaPowerStateTypeId, true);
|
||||
thing->setStateValue(elwaStatusStateTypeId, "Boosted");
|
||||
thing->setStateValue(elwaPowerStateTypeId, true);
|
||||
break;
|
||||
}
|
||||
case HeatFinished:{
|
||||
device->setStateValue(elwaStatusStateTypeId, "Heat finished");
|
||||
device->setStateValue(elwaPowerStateTypeId, false);
|
||||
thing->setStateValue(elwaStatusStateTypeId, "Heat finished");
|
||||
thing->setStateValue(elwaPowerStateTypeId, false);
|
||||
break;
|
||||
}
|
||||
case Setup:{
|
||||
device->setStateValue(elwaStatusStateTypeId, "Setup");
|
||||
device->setStateValue(elwaPowerStateTypeId, false);
|
||||
thing->setStateValue(elwaStatusStateTypeId, "Setup");
|
||||
thing->setStateValue(elwaPowerStateTypeId, false);
|
||||
break;
|
||||
}
|
||||
case ErrorOvertempFuseBlown:{
|
||||
device->setStateValue(elwaStatusStateTypeId, "Error Overtemp Fuse blown");
|
||||
thing->setStateValue(elwaStatusStateTypeId, "Error Overtemp Fuse blown");
|
||||
break;
|
||||
}
|
||||
case ErrorOvertempMeasured:{
|
||||
device->setStateValue(elwaStatusStateTypeId, "Error Overtemp measured");
|
||||
thing->setStateValue(elwaStatusStateTypeId, "Error Overtemp measured");
|
||||
break;
|
||||
}
|
||||
case ErrorOvertempElectronics:{
|
||||
device->setStateValue(elwaStatusStateTypeId, "Error Overtemp Electronics");
|
||||
thing->setStateValue(elwaStatusStateTypeId, "Error Overtemp Electronics");
|
||||
break;
|
||||
}
|
||||
case ErrorHardwareFault:{
|
||||
device->setStateValue(elwaStatusStateTypeId, "Error Hardware Fault");
|
||||
thing->setStateValue(elwaStatusStateTypeId, "Error Hardware Fault");
|
||||
break;
|
||||
}
|
||||
case ErrorTempSensor:{
|
||||
device->setStateValue(elwaStatusStateTypeId, "Error Temp Sensor");
|
||||
thing->setStateValue(elwaStatusStateTypeId, "Error Temp Sensor");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
device->setStateValue(elwaStatusStateTypeId, "Unknown");
|
||||
thing->setStateValue(elwaStatusStateTypeId, "Unknown");
|
||||
}
|
||||
|
||||
device->setStateValue(elwaConnectedStateTypeId, true);
|
||||
thing->setStateValue(elwaConnectedStateTypeId, true);
|
||||
} else {
|
||||
device->setStateValue(elwaConnectedStateTypeId, false);
|
||||
thing->setStateValue(elwaConnectedStateTypeId, false);
|
||||
}
|
||||
|
||||
if (modbusTCPMaster->getRegister(0xff, ElwaModbusRegisters::WaterTemperature, &data)) {
|
||||
device->setStateValue(elwaTemperatureStateTypeId, data/10.00);
|
||||
thing->setStateValue(elwaTemperatureStateTypeId, data/10.00);
|
||||
}
|
||||
if (modbusTCPMaster->getRegister(0xff, ElwaModbusRegisters::TargetWaterTemperature, &data)) {
|
||||
device->setStateValue(elwaTargetWaterTemperatureStateTypeId, data/10.00);
|
||||
thing->setStateValue(elwaTargetWaterTemperatureStateTypeId, data/10.00);
|
||||
}
|
||||
if (modbusTCPMaster->getRegister(0xff, ElwaModbusRegisters::Power, &data)) {
|
||||
device->setStateValue(elwaHeatingPowerStateTypeId, data);
|
||||
thing->setStateValue(elwaHeatingPowerStateTypeId, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
90
mypv/integrationpluginmypv.h
Normal file
90
mypv/integrationpluginmypv.h
Normal file
@ -0,0 +1,90 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 INTEGRATIONPLUGINMYPV_H
|
||||
#define INTEGRATIONPLUGINMYPV_H
|
||||
|
||||
#include "integrations/integrationplugin.h"
|
||||
#include "plugintimer.h"
|
||||
#include "modbustcpmaster.h"
|
||||
|
||||
#include <QUdpSocket>
|
||||
|
||||
class IntegrationPluginMyPv: public IntegrationPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginmypv.json")
|
||||
Q_INTERFACES(IntegrationPlugin)
|
||||
|
||||
|
||||
public:
|
||||
explicit IntegrationPluginMyPv();
|
||||
|
||||
void discoverThings(ThingDiscoveryInfo *info) override;
|
||||
void setupThing(ThingSetupInfo *info) override;
|
||||
void postSetupThing(Thing *thing) override;
|
||||
void thingRemoved(Thing *thing) override;
|
||||
void executeAction(ThingActionInfo *info) override;
|
||||
|
||||
private:
|
||||
|
||||
enum ElwaModbusRegisters {
|
||||
Power= 1000,
|
||||
WaterTemperature = 1001,
|
||||
TargetWaterTemperature = 1002,
|
||||
Status = 1003,
|
||||
ManuelStart = 1012
|
||||
};
|
||||
|
||||
enum ElwaStatus {
|
||||
Heating = 2,
|
||||
Standby = 3,
|
||||
Boosted = 4,
|
||||
HeatFinished = 5,
|
||||
Setup = 9,
|
||||
ErrorOvertempFuseBlown = 201,
|
||||
ErrorOvertempMeasured = 202,
|
||||
ErrorOvertempElectronics = 203,
|
||||
ErrorHardwareFault = 204,
|
||||
ErrorTempSensor = 205
|
||||
};
|
||||
|
||||
PluginTimer *m_refreshTimer = nullptr;
|
||||
QHash<Thing *, ModbusTCPMaster *> m_modbusTcpMasters;
|
||||
|
||||
void update(Thing *thing);
|
||||
|
||||
private slots:
|
||||
void onRefreshTimer();
|
||||
};
|
||||
|
||||
#endif // INTEGRATIONPLUGINMYPV_H
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
"name": "myPV",
|
||||
"displayName": "my-PV",
|
||||
"id": "1f17597f-e0d0-459b-858d-ec9cbcd10b2c",
|
||||
"deviceClasses": [
|
||||
"thingClasses": [
|
||||
{
|
||||
"name": "elwa",
|
||||
"displayName": "AC Elwa E",
|
||||
13
mypv/meta.json
Normal file
13
mypv/meta.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"title": "my-PV",
|
||||
"tagline": "Control my-PV network enabled heating rods.",
|
||||
"icon": "mypv.png",
|
||||
"stability": "community",
|
||||
"offline": true,
|
||||
"technologies": [
|
||||
"network"
|
||||
],
|
||||
"categories": [
|
||||
"heating"
|
||||
]
|
||||
}
|
||||
@ -1,29 +1,32 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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/>.
|
||||
* 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
|
||||
* 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 "modbustcpmaster.h"
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
@ -1,29 +1,32 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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/>.
|
||||
* 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
|
||||
* 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 MODBUSTCPMASTER_H
|
||||
#define MODBUSTCPMASTER_H
|
||||
|
||||
BIN
mypv/mypv.png
Normal file
BIN
mypv/mypv.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
@ -1,19 +1,15 @@
|
||||
include(../plugins.pri)
|
||||
|
||||
TARGET = $$qtLibraryTarget(nymea_devicepluginmypv)
|
||||
|
||||
QT += \
|
||||
network \
|
||||
serialbus \
|
||||
|
||||
LIBS += -lmodbus
|
||||
|
||||
SOURCES += \
|
||||
devicepluginmypv.cpp \
|
||||
integrationpluginmypv.cpp \
|
||||
modbustcpmaster.cpp \
|
||||
|
||||
HEADERS += \
|
||||
devicepluginmypv.h \
|
||||
integrationpluginmypv.h \
|
||||
modbustcpmaster.h \
|
||||
|
||||
|
||||
|
||||
@ -1,207 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "devicepluginwallbe.h"
|
||||
#include "plugininfo.h"
|
||||
|
||||
#include "devices/devicemanager.h"
|
||||
#include "devices/device.h"
|
||||
#include "types/param.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QStringList>
|
||||
#include <QJsonDocument>
|
||||
#include <QNetworkInterface>
|
||||
|
||||
|
||||
DevicePluginWallbe::DevicePluginWallbe()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginWallbe::setupDevice(DeviceSetupInfo *info)
|
||||
{
|
||||
Device *device = info->device();
|
||||
qCDebug(dcWallbe) << "Setting up a new device:" << device->params();
|
||||
|
||||
QHostAddress address(device->paramValue(wallbeEcoDeviceIpParamTypeId).toString());
|
||||
|
||||
if (address.isNull()){
|
||||
qCWarning(dcWallbe) << "IP address is null";
|
||||
info->finish(Device::DeviceErrorSetupFailed, tr("IP address parameter not valid"));
|
||||
return;
|
||||
}
|
||||
|
||||
WallBe *wallbe = new WallBe(address, 502, this);
|
||||
m_connections.insert(device, wallbe);
|
||||
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginWallbe::discoverDevices(DeviceDiscoveryInfo *info)
|
||||
{
|
||||
if (info->deviceClassId() == wallbeEcoDeviceClassId){
|
||||
|
||||
Discover *discover = new Discover(QStringList("-xO" "-p 502"));
|
||||
connect(discover, &Discover::devicesDiscovered, this, [info, this](QList<Host> hosts){
|
||||
foreach (Host host, hosts) {
|
||||
DeviceDescriptor descriptor;
|
||||
foreach(Device *device, myDevices().filterByParam(wallbeEcoDeviceMacParamTypeId, host.macAddress())) {
|
||||
descriptor.setDeviceId(device->id());
|
||||
break;
|
||||
}
|
||||
descriptor.setTitle(host.hostName());
|
||||
ParamList params;
|
||||
params.append(Param(wallbeEcoDeviceIpParamTypeId, host.address()));
|
||||
params.append(Param(wallbeEcoDeviceMacParamTypeId, host.macAddress()));
|
||||
descriptor.setParams(params);
|
||||
info->addDeviceDescriptor(descriptor);
|
||||
}
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
Q_ASSERT_X(false, "discoverDevices", QString("Unhandled deviceClassId: %1").arg(info->deviceClassId().toString()).toUtf8());
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginWallbe::postSetupDevice(Device *device)
|
||||
{
|
||||
if (!m_pluginTimer) {
|
||||
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(120);
|
||||
connect(m_pluginTimer, &PluginTimer::timeout, this, [this] {
|
||||
foreach(Device *device, m_connections.keys()) {
|
||||
update(device);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (device->deviceClassId() == wallbeEcoDeviceClassId){
|
||||
update(device);
|
||||
return;
|
||||
}
|
||||
Q_ASSERT_X(false, "postSetupDevice", QString("Unhandled deviceClassId: %1").arg(device->deviceClassId().toString()).toUtf8());
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginWallbe::executeAction(DeviceActionInfo *info)
|
||||
{
|
||||
Device *device = info->device();
|
||||
Action action = info->action();
|
||||
|
||||
WallBe *wallbe = m_connections.value(device);
|
||||
if (!wallbe) {
|
||||
qCWarning(dcWallbe()) << "Wallbe object not available";
|
||||
info->finish(Device::DeviceErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == wallbeEcoDeviceClassId){
|
||||
|
||||
// check if this is the "set power" action
|
||||
if (action.actionTypeId() == wallbeEcoPowerActionTypeId) {
|
||||
|
||||
// get the param value of the charging action
|
||||
bool charging = action.param(wallbeEcoPowerActionPowerParamTypeId).value().toBool();
|
||||
qCDebug(dcWallbe) << "start Charging button" << device->name() << "set power to" << charging;
|
||||
wallbe->setChargingStatus(charging);
|
||||
// Set the "power" state
|
||||
device->setStateValue(wallbeEcoPowerStateTypeId, charging);
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
return;
|
||||
|
||||
} else if(action.actionTypeId() == wallbeEcoChargeCurrentActionTypeId){
|
||||
|
||||
uint16_t current = action.param(wallbeEcoChargeCurrentEventChargeCurrentParamTypeId).value().toUInt();
|
||||
qCDebug(dcWallbe) << "Charging power set to" << current;
|
||||
wallbe->setChargingCurrent(current);
|
||||
device->setStateValue(wallbeEcoChargeCurrentStateTypeId, current);
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
return;
|
||||
}
|
||||
Q_ASSERT_X(false, "executeAction", QString("Unhandled action: %1").arg(action.actionTypeId().toString()).toUtf8());
|
||||
}
|
||||
Q_ASSERT_X(false, "executeAction", QString("Unhandled deviceClassId: %1").arg(device->deviceClassId().toString()).toUtf8());
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginWallbe::deviceRemoved(Device *device)
|
||||
{
|
||||
m_address.removeOne(QHostAddress(device->paramValue(wallbeEcoDeviceIpParamTypeId).toString()));
|
||||
WallBe *wallbe = m_connections.take(device);
|
||||
if (wallbe) {
|
||||
qCDebug(dcWallbe) << "Remove device" << device->name();
|
||||
wallbe->deleteLater();
|
||||
}
|
||||
|
||||
if (myDevices().isEmpty()) {
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
|
||||
m_pluginTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginWallbe::update(Device *device)
|
||||
{
|
||||
WallBe * wallbe = m_connections.value(device);
|
||||
if(!wallbe->isAvailable())
|
||||
return;
|
||||
|
||||
device->setStateValue(wallbeEcoConnectedStateTypeId, true);
|
||||
|
||||
//EV state - 16 bit ASCII (8bit)
|
||||
switch (wallbe->getEvStatus()) {
|
||||
case 65:
|
||||
device->setStateValue(wallbeEcoEvStatusStateTypeId, "A - No car plugged in");
|
||||
break;
|
||||
case 66:
|
||||
device->setStateValue(wallbeEcoEvStatusStateTypeId, "B - Supply equipment not yet ready");
|
||||
break;
|
||||
case 67:
|
||||
device->setStateValue(wallbeEcoEvStatusStateTypeId, "C - Ready to charge");
|
||||
break;
|
||||
case 68:
|
||||
device->setStateValue(wallbeEcoEvStatusStateTypeId, "D - Ready to charge, ventilation needed");
|
||||
break;
|
||||
case 69:
|
||||
device->setStateValue(wallbeEcoEvStatusStateTypeId, "E - Short circuit detected");
|
||||
break;
|
||||
case 70:
|
||||
device->setStateValue(wallbeEcoEvStatusStateTypeId, "F - Supply equipment not available");
|
||||
break;
|
||||
default:
|
||||
device->setStateValue(wallbeEcoEvStatusStateTypeId, "F - Supply equipment not available");
|
||||
}
|
||||
|
||||
qCDebug(dcWallbe) << "EV State:" << device->stateValue(wallbeEcoEvStatusStateTypeId).toString();
|
||||
|
||||
// Extract Input Register 102 - load time - 32bit integer
|
||||
device->setStateValue(wallbeEcoChargeTimeStateTypeId, wallbe->getChargingTime());
|
||||
|
||||
// Read the charge current state
|
||||
device->setStateValue(wallbeEcoChargeCurrentStateTypeId, wallbe->getChargingCurrent());
|
||||
device->setStateValue(wallbeEcoPowerStateTypeId, wallbe->getChargingStatus());
|
||||
}
|
||||
@ -1,64 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 DEVICEPLUGINWALLBE_H
|
||||
#define DEVICEPLUGINWALLBE_H
|
||||
|
||||
#include "devices/deviceplugin.h"
|
||||
#include "wallbe.h"
|
||||
#include "host.h"
|
||||
#include "discover.h"
|
||||
#include "plugintimer.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
|
||||
class DevicePluginWallbe : public DevicePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "devicepluginwallbe.json")
|
||||
Q_INTERFACES(DevicePlugin)
|
||||
|
||||
public:
|
||||
explicit DevicePluginWallbe();
|
||||
|
||||
void discoverDevices(DeviceDiscoveryInfo *info) override;
|
||||
void setupDevice(DeviceSetupInfo *info) override;
|
||||
void postSetupDevice(Device *device) override;
|
||||
void executeAction(DeviceActionInfo *info) override;
|
||||
void deviceRemoved(Device *device) override;
|
||||
|
||||
private:
|
||||
QHash<Device *, WallBe *> m_connections;
|
||||
QList<QHostAddress> m_address;
|
||||
PluginTimer *m_pluginTimer = nullptr;
|
||||
|
||||
void update(Device *device);
|
||||
};
|
||||
|
||||
#endif // DEVICEPLUGINWALLBE_H
|
||||
@ -1,29 +1,32 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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/>.
|
||||
* 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
|
||||
* 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 <QHostAddress>
|
||||
#include <QNetworkInterface>
|
||||
|
||||
@ -1,29 +1,32 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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/>.
|
||||
* 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
|
||||
* 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 DISCOVER_H
|
||||
#define DISCOVER_H
|
||||
|
||||
@ -1,29 +1,32 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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/>.
|
||||
* 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
|
||||
* 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 "host.h"
|
||||
|
||||
|
||||
@ -1,29 +1,32 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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/>.
|
||||
* 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
|
||||
* 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 HOST_H
|
||||
#define HOST_H
|
||||
|
||||
209
wallbe/integrationpluginwallbe.cpp
Normal file
209
wallbe/integrationpluginwallbe.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "integrationpluginwallbe.h"
|
||||
#include "plugininfo.h"
|
||||
|
||||
#include "types/param.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QStringList>
|
||||
#include <QJsonDocument>
|
||||
#include <QNetworkInterface>
|
||||
|
||||
|
||||
IntegrationPluginWallbe::IntegrationPluginWallbe()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void IntegrationPluginWallbe::setupThing(ThingSetupInfo *info)
|
||||
{
|
||||
Thing *thing = info->thing();
|
||||
qCDebug(dcWallbe) << "Setting up a new device:" << thing->params();
|
||||
|
||||
QHostAddress address(thing->paramValue(wallbeEcoThingIpParamTypeId).toString());
|
||||
|
||||
if (address.isNull()){
|
||||
qCWarning(dcWallbe) << "IP address is null";
|
||||
info->finish(Thing::ThingErrorSetupFailed, tr("IP address parameter not valid"));
|
||||
return;
|
||||
}
|
||||
|
||||
WallBe *wallbe = new WallBe(address, 502, this);
|
||||
m_connections.insert(thing, wallbe);
|
||||
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
}
|
||||
|
||||
|
||||
void IntegrationPluginWallbe::discoverThings(ThingDiscoveryInfo *info)
|
||||
{
|
||||
if (info->thingClassId() == wallbeEcoThingClassId){
|
||||
|
||||
Discover *discover = new Discover(QStringList("-xO" "-p 502"));
|
||||
connect(discover, &Discover::devicesDiscovered, this, [info, this](QList<Host> hosts){
|
||||
foreach (Host host, hosts) {
|
||||
ThingDescriptor descriptor;
|
||||
foreach(Thing *thing, myThings().filterByParam(wallbeEcoThingMacParamTypeId, host.macAddress())) {
|
||||
descriptor.setThingId(thing->id());
|
||||
break;
|
||||
}
|
||||
descriptor.setTitle(host.hostName());
|
||||
ParamList params;
|
||||
params.append(Param(wallbeEcoThingIpParamTypeId, host.address()));
|
||||
params.append(Param(wallbeEcoThingMacParamTypeId, host.macAddress()));
|
||||
descriptor.setParams(params);
|
||||
info->addThingDescriptor(descriptor);
|
||||
}
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
return;
|
||||
}
|
||||
Q_ASSERT_X(false, "discoverThings", QString("Unhandled thingClassId: %1").arg(info->thingClassId().toString()).toUtf8());
|
||||
}
|
||||
|
||||
|
||||
void IntegrationPluginWallbe::postSetupThing(Thing *thing)
|
||||
{
|
||||
if (!m_pluginTimer) {
|
||||
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(120);
|
||||
connect(m_pluginTimer, &PluginTimer::timeout, this, [this] {
|
||||
foreach(Thing *thing, m_connections.keys()) {
|
||||
update(thing);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == wallbeEcoThingClassId){
|
||||
update(thing);
|
||||
} else {
|
||||
Q_ASSERT_X(false, "postSetupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IntegrationPluginWallbe::executeAction(ThingActionInfo *info)
|
||||
{
|
||||
Thing *thing = info->thing();
|
||||
Action action = info->action();
|
||||
|
||||
WallBe *wallbe = m_connections.value(thing);
|
||||
if (!wallbe) {
|
||||
qCWarning(dcWallbe()) << "Wallbe object not available";
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == wallbeEcoThingClassId){
|
||||
|
||||
// check if this is the "set power" action
|
||||
if (action.actionTypeId() == wallbeEcoPowerActionTypeId) {
|
||||
|
||||
// get the param value of the charging action
|
||||
bool charging = action.param(wallbeEcoPowerActionPowerParamTypeId).value().toBool();
|
||||
qCDebug(dcWallbe) << "start Charging button" << thing->name() << "set power to" << charging;
|
||||
wallbe->setChargingStatus(charging);
|
||||
// Set the "power" state
|
||||
thing->setStateValue(wallbeEcoPowerStateTypeId, charging);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
|
||||
} else if(action.actionTypeId() == wallbeEcoChargeCurrentActionTypeId){
|
||||
|
||||
uint16_t current = action.param(wallbeEcoChargeCurrentEventChargeCurrentParamTypeId).value().toUInt();
|
||||
qCDebug(dcWallbe) << "Charging power set to" << current;
|
||||
wallbe->setChargingCurrent(current);
|
||||
thing->setStateValue(wallbeEcoChargeCurrentStateTypeId, current);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
Q_ASSERT_X(false, "executeAction", QString("Unhandled action: %1").arg(action.actionTypeId().toString()).toUtf8());
|
||||
}
|
||||
Q_ASSERT_X(false, "executeAction", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
|
||||
}
|
||||
|
||||
|
||||
void IntegrationPluginWallbe::thingRemoved(Thing *thing)
|
||||
{
|
||||
m_address.removeOne(QHostAddress(thing->paramValue(wallbeEcoThingIpParamTypeId).toString()));
|
||||
WallBe *wallbe = m_connections.take(thing);
|
||||
if (wallbe) {
|
||||
qCDebug(dcWallbe) << "Remove device" << thing->name();
|
||||
wallbe->deleteLater();
|
||||
}
|
||||
|
||||
if (myThings().isEmpty()) {
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
|
||||
m_pluginTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginWallbe::update(Thing *thing)
|
||||
{
|
||||
WallBe * wallbe = m_connections.value(thing);
|
||||
if(!wallbe->isAvailable())
|
||||
return;
|
||||
|
||||
thing->setStateValue(wallbeEcoConnectedStateTypeId, true);
|
||||
|
||||
//EV state - 16 bit ASCII (8bit)
|
||||
switch (wallbe->getEvStatus()) {
|
||||
case 65:
|
||||
thing->setStateValue(wallbeEcoEvStatusStateTypeId, "A - No car plugged in");
|
||||
break;
|
||||
case 66:
|
||||
thing->setStateValue(wallbeEcoEvStatusStateTypeId, "B - Supply equipment not yet ready");
|
||||
break;
|
||||
case 67:
|
||||
thing->setStateValue(wallbeEcoEvStatusStateTypeId, "C - Ready to charge");
|
||||
break;
|
||||
case 68:
|
||||
thing->setStateValue(wallbeEcoEvStatusStateTypeId, "D - Ready to charge, ventilation needed");
|
||||
break;
|
||||
case 69:
|
||||
thing->setStateValue(wallbeEcoEvStatusStateTypeId, "E - Short circuit detected");
|
||||
break;
|
||||
case 70:
|
||||
thing->setStateValue(wallbeEcoEvStatusStateTypeId, "F - Supply equipment not available");
|
||||
break;
|
||||
default:
|
||||
thing->setStateValue(wallbeEcoEvStatusStateTypeId, "F - Supply equipment not available");
|
||||
}
|
||||
|
||||
qCDebug(dcWallbe) << "EV State:" << thing->stateValue(wallbeEcoEvStatusStateTypeId).toString();
|
||||
|
||||
// Extract Input Register 102 - load time - 32bit integer
|
||||
thing->setStateValue(wallbeEcoChargeTimeStateTypeId, wallbe->getChargingTime());
|
||||
|
||||
// Read the charge current state
|
||||
thing->setStateValue(wallbeEcoChargeCurrentStateTypeId, wallbe->getChargingCurrent());
|
||||
thing->setStateValue(wallbeEcoPowerStateTypeId, wallbe->getChargingStatus());
|
||||
}
|
||||
67
wallbe/integrationpluginwallbe.h
Normal file
67
wallbe/integrationpluginwallbe.h
Normal file
@ -0,0 +1,67 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 INTEGRATIONPLUGINWALLBE_H
|
||||
#define INTEGRATIONPLUGINWALLBE_H
|
||||
|
||||
#include "integrations/integrationplugin.h"
|
||||
#include "wallbe.h"
|
||||
#include "host.h"
|
||||
#include "discover.h"
|
||||
#include "plugintimer.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
|
||||
class IntegrationPluginWallbe : public IntegrationPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginwallbe.json")
|
||||
Q_INTERFACES(IntegrationPlugin)
|
||||
|
||||
public:
|
||||
explicit IntegrationPluginWallbe();
|
||||
|
||||
void discoverThings(ThingDiscoveryInfo *info) override;
|
||||
void setupThing(ThingSetupInfo *info) override;
|
||||
void postSetupThing(Thing *thing) override;
|
||||
void executeAction(ThingActionInfo *info) override;
|
||||
void thingRemoved(Thing *thing) override;
|
||||
|
||||
private:
|
||||
QHash<Thing *, WallBe *> m_connections;
|
||||
QList<QHostAddress> m_address;
|
||||
PluginTimer *m_pluginTimer = nullptr;
|
||||
|
||||
void update(Thing *thing);
|
||||
};
|
||||
|
||||
#endif // INTEGRATIONPLUGINWALLBE_H
|
||||
@ -7,7 +7,7 @@
|
||||
"displayName": "Petring",
|
||||
"name": "petring",
|
||||
"id": "831b4b87-0a6c-4d51-b055-967bb6e5fab5",
|
||||
"deviceClasses": [
|
||||
"thingClasses": [
|
||||
{
|
||||
"id": "e66c84f6-b398-47e9-8aeb-33840e7b4492",
|
||||
"displayName": "Wallbe eco 2.0",
|
||||
13
wallbe/meta.json
Normal file
13
wallbe/meta.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"title": "Wall-Be",
|
||||
"tagline": "Integrate Wall-Be EV-Charger into nymea-",
|
||||
"icon": "walllbe.png",
|
||||
"stability": "community",
|
||||
"offline": true,
|
||||
"technologies": [
|
||||
"network"
|
||||
],
|
||||
"categories": [
|
||||
"tool"
|
||||
]
|
||||
}
|
||||
@ -1,29 +1,32 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* 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/>.
|
||||
* 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
|
||||
* 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 WALLBE_H
|
||||
#define WALLBE_H
|
||||
|
||||
BIN
wallbe/wallbe.png
Normal file
BIN
wallbe/wallbe.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@ -1,19 +1,17 @@
|
||||
include(../plugins.pri)
|
||||
|
||||
TARGET = $$qtLibraryTarget(nymea_devicepluginwallbe)
|
||||
|
||||
QT += \
|
||||
network \
|
||||
serialbus \
|
||||
|
||||
SOURCES += \
|
||||
devicepluginwallbe.cpp \
|
||||
integrationpluginwallbe.cpp \
|
||||
wallbe.cpp \
|
||||
host.cpp \
|
||||
discover.cpp
|
||||
|
||||
HEADERS += \
|
||||
devicepluginwallbe.h \
|
||||
integrationpluginwallbe.h \
|
||||
wallbe.h \
|
||||
host.h \
|
||||
discover.h
|
||||
|
||||
Reference in New Issue
Block a user