added drexel und weiss
This commit is contained in:
commit
28542347a2
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*.pro.user
|
||||
builddir
|
||||
doc/html
|
||||
296
debian/changelog
vendored
Normal file
296
debian/changelog
vendored
Normal file
@ -0,0 +1,296 @@
|
||||
nymea-plugins (0.17.0) xenial; urgency=medium
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* FlowerCare: Add a refresh rate setting
|
||||
* Packaging: Fix dpkg clean target
|
||||
* Simulation: Add a simulated barcode scanner device
|
||||
|
||||
[ Bernhard Trinnes ]
|
||||
* Http commander: Add http server
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* DaylightSensor: Update README.md
|
||||
* dweet.io: Update README
|
||||
* Kodi: Automatically redetect Kodi when its IP address changes
|
||||
* Various Plugins: Spelling fixes in README files
|
||||
* Tasmota: Add Blinds support
|
||||
|
||||
[ Federico Leoni ]
|
||||
* Update Tasmota readme
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* PhilipsHue: Fix the timeout setting
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Mon, 09 Dec 2019 10:09:05 +0100
|
||||
|
||||
nymea-plugins (0.16.0) xenial; urgency=medium
|
||||
|
||||
[ Bernhard Trinnes ]
|
||||
* New Plugin: CoinMarketCap
|
||||
* New plugin: Sonos
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* All Plugins: Devicemanager api rework
|
||||
* Fix hertz wording
|
||||
* New plugin: Shelly
|
||||
* EQ-3: Some fixes for Eqiva Bluetooth Smart Radiator Thermostats
|
||||
* PhilipsHue: Fix light intensity conversion to lux for the motion
|
||||
sensor
|
||||
* Anel: Add anel plugin to main plugin package
|
||||
* NetworkDetector: Improve packaging and error handling
|
||||
* Nuimo: Make it work with Bluez 5.48 (except battery service)
|
||||
* Kodi: Fix active player not updating properly in some circumstances
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Tue, 22 Oct 2019 01:09:57 +0200
|
||||
|
||||
nymea-plugins (0.15.2) xenial; urgency=medium
|
||||
|
||||
[ Bernhard Trinnes ]
|
||||
* Denon Plug-In: Add heos devices
|
||||
|
||||
[ George Yatsev ]
|
||||
* Tasmota: Add support for 3ch devices
|
||||
|
||||
[ Bernhard Trinnes ]
|
||||
* TcpCommander: Fixed input and output device class
|
||||
* New plug-in: systemmonitor
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* PhilipsHue: Make use of the new alert interface
|
||||
|
||||
[ Bernhard Trinnes ]
|
||||
* New plugin: One-Wire
|
||||
* GPIO Plug-In: add counter device
|
||||
* Senic: Fixed device clean up on a failed device setup
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* Remove Plugin: UniPi
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Thu, 19 Sep 2019 12:28:02 +0200
|
||||
|
||||
nymea-plugins (0.15.1) xenial; urgency=medium
|
||||
|
||||
[ Bernhard Trinnes ]
|
||||
* New Plugin: WS2812FX
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* Tasmota: Use new powerswitch interface
|
||||
|
||||
[ Bernhard Trinnes ]
|
||||
* Add plug-in bose soundtouch
|
||||
* New plugin: generic interfaces
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* Kodi: Add support for media browsing
|
||||
|
||||
[ Bernhard Trinnes ]
|
||||
* Fix senic
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* Fix hue outdoorsensor
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Mon, 02 Sep 2019 18:02:07 +0200
|
||||
|
||||
nymea-plugins (0.15.0) xenial; urgency=medium
|
||||
|
||||
|
||||
[ Simon Stürz ]
|
||||
* All Plugins: Update docs mechanism
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* NetworkDetector: Change grace period to be a setting instead of a
|
||||
param
|
||||
* Philips Hue: Add support for the hue indoor motion sensor
|
||||
* All Plugins: Update according to new DeviceManager API
|
||||
* Use the new nymea-plugininfocompiler for building
|
||||
* GenericElements: Fix toggle button writable state
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Mon, 22 Jul 2019 12:17:16 +0200
|
||||
|
||||
nymea-plugins (0.12.3) xenial; urgency=medium
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* FlowerCare: Drop unneeded name parameter
|
||||
* PhilipsHue: Improve discovery and fix reconfigure
|
||||
* PhilipsHue: Drop deprecated old-style Hue Remote button events
|
||||
* WeMo: Fix discovery if device has been renamed
|
||||
* TexasInstruments: Fix Package dependencies
|
||||
* PhilipsHue: Work around a bug in Osram LIGHTIFY RGBW LED stripes
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Fri, 28 Jun 2019 12:45:50 +0200
|
||||
|
||||
nymea-plugins (0.12.2) xenial; urgency=medium
|
||||
|
||||
[ Bernhard Trinnes ]
|
||||
* Removed plugins: Orderbutton, Plantcare and ws2812
|
||||
* renamed HTTP commander vendor, fixed segfault on device removed
|
||||
* Fix serialportcommander
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* OpenWeatherMap: Add daylightsensor and allow loading custom API keys
|
||||
|
||||
[ Simon Stürz ]
|
||||
* Update mail notifications plugin
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* Depend on pkg-config
|
||||
* Kodi, AvahiMonitor: Update to new ZeroConf API
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Wed, 19 Jun 2019 23:52:37 +0200
|
||||
|
||||
nymea-plugins (0.12.1) xenial; urgency=medium
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* Rename vendor "guh GmbH" to "nymea"
|
||||
* Don't use dpkg specific tools to set install path
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Thu, 02 May 2019 11:56:17 +0200
|
||||
|
||||
nymea-plugins (0.12.0) xenial; urgency=medium
|
||||
[ Michael Zanetti ]
|
||||
* aWATTar: Cleanup old unused code and use connectable interface
|
||||
|
||||
[ Simon Stürz ]
|
||||
* PhilipsHue plugin: Add Hue Outdoor sensor
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* All Plugins: Update to API changes in core.
|
||||
* Boblight: Build using internal plugins.pri
|
||||
* New plugin: Pushbullet
|
||||
* New Plugin: TexasInstruments, replaces MultiSensor plugin
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Fri, 12 Apr 2019 13:42:46 +0200
|
||||
|
||||
nymea-plugins (0.10.3) xenial; urgency=medium
|
||||
|
||||
[ Simon Stürz ]
|
||||
* Netatmo: Update API changes and improve refresh behavior
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* Simulation: Update ev charger to new interface spec
|
||||
* SonoffTasmota: Fix wrong IP settings in device setup
|
||||
* NetworkDetector: Don't fail the entire discovery if one of the scan
|
||||
targets fails
|
||||
* PhilipsHue: Enable reconfiguring Hue bridges (Re-pairing)
|
||||
* Elgato: Fix reading of color state
|
||||
* Simulation: Add missing unit to heating plugins
|
||||
* FlowerCare: Add unit to conductivity sensor
|
||||
* Simulation: Make use of thermostat interface
|
||||
* NetworkDetector: Improve monitoring, add a grace period parameter
|
||||
* EQ-3: Add support for the Eqiva Bluetooth thermostat
|
||||
* Update Plugins: Set deviceId in Descriptors on discovery
|
||||
* Flower Care: Fix temperature reading for negative values
|
||||
|
||||
[ Bernhard Trinnes ]
|
||||
* New Plugin: Serialport commander
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Wed, 06 Mar 2019 21:13:53 +0100
|
||||
|
||||
nymea-plugins (0.10.2) xenial; urgency=medium
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* Simulation: Make use of powersocket interface
|
||||
* New Plugin: Boblight
|
||||
|
||||
[ Simon Stürz ]
|
||||
* LG smart TV: General update (use of interfaces, improve connectivity
|
||||
with TV)
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* New Plugin: ANEL Elektronik NET-PwrCtrl
|
||||
* Networkdetector: Implement the presencesensor interface
|
||||
* New Plugin: Daylight sensor which works offline and without any
|
||||
hardware
|
||||
* Sumulation: Fix action simulation for simulated blinds
|
||||
* PhilipsHue: Fix hue tap button 4 param value typo
|
||||
* Kodi: Implement new media interfaces
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Thu, 17 Jan 2019 15:37:27 +0100
|
||||
|
||||
nymea-plugins (0.10.1) xenial; urgency=medium
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* Elgato/Avea: Fix handling white channel in set color action
|
||||
* New plugin: Generic MQTT client plugin (mqttclient)
|
||||
* PhilipsHue: Improve naming of hue devices using nymea's system name
|
||||
and syncing to bridge
|
||||
* New plugin: Sonoff-Tasmota devices plugin (tasmota)
|
||||
* Netatmo: fix after upstream API change, make use of new interfaces
|
||||
|
||||
[ Simon Stürz ]
|
||||
* New plugin: UniPi
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Wed, 12 Dec 2018 14:44:58 +0100
|
||||
|
||||
nymea-plugins (0.10.0) xenial; urgency=medium
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* Elgato/Avea: Fix handling white channel in set color action
|
||||
* New plugin: Generic MQTT client plugin (mqttclient)
|
||||
* PhilipsHue: Improve naming of hue devices using nymea's system name
|
||||
and syncing to bridge
|
||||
* New plugin: Sonoff-Tasmota devices plugin (tasmota)
|
||||
* Netatmo: fix after upstream API change, make use of new interfaces
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Sun, 09 Dec 2018 18:56:19 +0100
|
||||
|
||||
nymea-plugins (0.9.39) xenial; urgency=medium
|
||||
|
||||
[ Jenkins ]
|
||||
* Prepare for release
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* use system interface in snapdcontrol
|
||||
* update hue plugin
|
||||
* change networkdetector discovery to do parallel scans...
|
||||
* Make use of new heating/evcharger interfaces in the simulated
|
||||
devices plugin
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Tue, 20 Nov 2018 14:32:38 +0100
|
||||
|
||||
nymea-plugins (0.9.38) xenial; urgency=medium
|
||||
|
||||
[ Jenkins ]
|
||||
* Prepare for release
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* add some nicer curves to simulated values
|
||||
* gateway now inherits connectable
|
||||
* add simple blind simulation
|
||||
* implement fingerprint interface in simulation plugin
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Mon, 29 Oct 2018 14:19:53 +0100
|
||||
|
||||
nymea-plugins (0.9.37) xenial; urgency=medium
|
||||
|
||||
[ Jenkins ]
|
||||
* Prepare for release
|
||||
|
||||
[ Michael Zanetti ]
|
||||
* Update all plugins using the new nymea-generateplugininfo
|
||||
|
||||
-- Jenkins <jenkins@nymea.io> Wed, 10 Oct 2018 04:38:16 +0200
|
||||
|
||||
nymea-plugins (0.9.36) bionic; urgency=medium
|
||||
|
||||
* Bump version to be in line with core
|
||||
|
||||
-- Michael Zanetti <michael.zanetti@nymea.io> Wed, 10 Oct 2018 04:00:57 +0200
|
||||
|
||||
nymea-plugins (0.2.0) bionic; urgency=medium
|
||||
|
||||
* rename to nymea
|
||||
|
||||
-- Michael Zanetti <michael.zanetti@nymea.io> Wed, 10 Oct 2018 04:00:00 +0200
|
||||
|
||||
guh-plugins (0.1.0) xenial; urgency=medium
|
||||
|
||||
* Add metapackages
|
||||
|
||||
-- Simon Stürz <simon.stuerz@guh.io> Tue, 03 Oct 2017 17:07:31 +0200
|
||||
|
||||
guh-plugins (0.1) UNRELEASED; urgency=medium
|
||||
|
||||
* Initial release. (Closes: #XXXXXX)
|
||||
|
||||
-- Michael Zanetti <michael.zanetti@guh.io> Tue, 11 Jul 2017 15:23:34 +0200
|
||||
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@ -0,0 +1 @@
|
||||
9
|
||||
63
debian/control
vendored
Normal file
63
debian/control
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
Source: nymea-plugins-modbus
|
||||
Section: utils
|
||||
Priority: options
|
||||
Maintainer: Michael Zanetti <michael.zanetti@guh.io>
|
||||
Build-depends: libboblight-dev,
|
||||
debhelper (>= 0.0.0),
|
||||
libnymea1-dev (>= 0.17),
|
||||
libnymea-mqtt-dev,
|
||||
libqt5serialport5-dev,
|
||||
libqt5websockets5-dev,
|
||||
nymea-dev-tools:native,
|
||||
pkg-config,
|
||||
python:any,
|
||||
qtbase5-dev,
|
||||
qtconnectivity5-dev,
|
||||
libow-dev,
|
||||
Standards-Version: 3.9.3
|
||||
|
||||
|
||||
Package: nymea-plugin-drexelundweiss
|
||||
Architecture: any
|
||||
Section: libs
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
nymea-plugins-translations,
|
||||
Description: nymea.io plugin for Drexel & Weiss heat pumps
|
||||
The nymea daemon is a plugin based IoT (Internet of Things) server. The
|
||||
server works like a translator for devices, things and services and
|
||||
allows them to interact.
|
||||
With the powerful rule engine you are able to connect any device available
|
||||
in the system and create individual scenes and behaviors for your environment.
|
||||
.
|
||||
This package will install the nymea.io plugin for Drexel & Weiss heat pumps
|
||||
|
||||
|
||||
Package: nymea-plugins-translations
|
||||
Section: misc
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}
|
||||
Replaces: guh-plugins-translations
|
||||
Description: Translation files for nymea plugins - translations
|
||||
The nymea daemon is a plugin based IoT (Internet of Things) server. The
|
||||
server works like a translator for devices, things and services and
|
||||
allows them to interact.
|
||||
With the powerful rule engine you are able to connect any device available
|
||||
in the system and create individual scenes and behaviors for your environment.
|
||||
.
|
||||
This package provides the translation files for all nymea plugins.
|
||||
|
||||
|
||||
Package: nymea-plugins-modbus
|
||||
Section: libs
|
||||
Architecture: all
|
||||
Depends: nymea-plugin-drexelundweiss,
|
||||
Description: Plugins for nymea IoT server - the modbus plugin collection
|
||||
The nymea daemon is a plugin based IoT (Internet of Things) server. The
|
||||
server works like a translator for devices, things and services and
|
||||
allows them to interact.
|
||||
With the powerful rule engine you are able to connect any device available
|
||||
in the system and create individual scenes and behaviors for your environment.
|
||||
.
|
||||
This package will install the nymea modbus plugins.
|
||||
|
||||
77
debian/copyright
vendored
Normal file
77
debian/copyright
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: nymea-plugins
|
||||
Upstream-Contact: Simon Stürz <simon.stuerz@guh.io>
|
||||
Copyright: 2014-2017, guh GmbH
|
||||
Download: http://www.github.com/guh/guh-plugins
|
||||
Source: https://github.com/guh/guh-plugins.git
|
||||
|
||||
|
||||
License: GPL-2+
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License can be found in `/usr/share/common-licenses/GPL-2'.
|
||||
|
||||
License: LGPL-2.1
|
||||
On Debian systems, the complete text of the GNU Lesser General
|
||||
Public License can be found in `/usr/share/common-licenses/LGPL-2.1'.
|
||||
|
||||
License: LGPL-3
|
||||
On Debian systems, the complete text of the GNU Lesser General
|
||||
Public License can be found in `/usr/share/common-licenses/LGPL-3'.
|
||||
|
||||
|
||||
Files: translations/*
|
||||
License: LGPL-2.1
|
||||
Copyright: 2016-2017, Simon Stürz <simon.stuerz@guh.io>
|
||||
|
||||
Files: debian/*
|
||||
License: GPL-2+
|
||||
Copyright: 2017, Michael Zanetti <michael.zanetti@guh.io>
|
||||
2017, Simon Stürz <simon.stuerz@guh.io>
|
||||
|
||||
Files: denon/*
|
||||
orderbutton/*
|
||||
ws2812/*
|
||||
tcpcommander/*
|
||||
License: LGPL-2.1
|
||||
Copyright: 2016, Bernhard Trinnes <bernhard.trinnes@guh.io>
|
||||
|
||||
Files: plantcare/*
|
||||
unipi/*
|
||||
License: LGPL-2.1
|
||||
Copyright: 2016-2018, Simon Stürz <simon.stuerz@guh.io>
|
||||
2016-2018, Bernhard Trinnes <bernhard.trinnes@guh.io>
|
||||
|
||||
Files: avahimonitor/*
|
||||
awattar/*
|
||||
dollhouse/*
|
||||
elgato/*
|
||||
elro/*
|
||||
eq-3/*
|
||||
genericelements/*
|
||||
gpio/*
|
||||
leynew/*
|
||||
lgsmarttv/*
|
||||
mailnotification/*
|
||||
netatmo/*
|
||||
networkdetector/*
|
||||
osdomotics/*
|
||||
senic/*
|
||||
udpcommander/*
|
||||
unitec/*
|
||||
wemo/*
|
||||
License: LGPL-2.1
|
||||
Copyright: 2014-2017, Simon Stürz <simon.stuerz@guh.io>
|
||||
|
||||
|
||||
Files: wakeonlan/*
|
||||
commandlauncher/*
|
||||
conrad/*
|
||||
datetime/*
|
||||
intertechno/*
|
||||
kodi/*
|
||||
lircd/*
|
||||
openweathermap/*
|
||||
philipshue/*
|
||||
License: LGPL-2.1
|
||||
Copyright: 2014-2017, Simon Stürz <simon.stuerz@guh.io>
|
||||
2014-2017, Michael Zanetti <michael.zanetti@guh.io>
|
||||
1
debian/nymea-plugin-drexelundweiss.install.in
vendored
Normal file
1
debian/nymea-plugin-drexelundweiss.install.in
vendored
Normal file
@ -0,0 +1 @@
|
||||
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_deviceplugindrexelundweiss.so
|
||||
25
debian/rules
vendored
Executable file
25
debian/rules
vendored
Executable file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
|
||||
|
||||
PREPROCESS_FILES := $(wildcard debian/*.in)
|
||||
|
||||
$(PREPROCESS_FILES:.in=): %: %.in
|
||||
sed 's,/@DEB_HOST_MULTIARCH@,$(DEB_HOST_MULTIARCH:%=/%),g' $< > $@
|
||||
|
||||
%:
|
||||
dh $@ --parallel
|
||||
|
||||
override_dh_auto_build:
|
||||
dh_auto_build
|
||||
make lrelease
|
||||
|
||||
override_dh_install: $(PREPROCESS_FILES:.in=)
|
||||
dh_install --fail-missing
|
||||
|
||||
override_dh_auto_clean:
|
||||
dh_auto_clean
|
||||
find -name *plugininfo.h -exec rm {} \;
|
||||
find -name *.qm -exec rm {} \;
|
||||
rm -rf $(PREPROCESS_FILES:.in=)
|
||||
|
||||
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@ -0,0 +1 @@
|
||||
3.0 (native)
|
||||
0
drexelundweiss/README.md
Normal file
0
drexelundweiss/README.md
Normal file
635
drexelundweiss/deviceplugindrexelundweiss.cpp
Normal file
635
drexelundweiss/deviceplugindrexelundweiss.cpp
Normal file
@ -0,0 +1,635 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 "deviceplugindrexelundweiss.h"
|
||||
#include "plugininfo.h"
|
||||
#include "modbusdegisterdefinition.h"
|
||||
|
||||
DevicePluginDrexelUndWeiss::DevicePluginDrexelUndWeiss()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DevicePluginDrexelUndWeiss::~DevicePluginDrexelUndWeiss()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::init()
|
||||
{
|
||||
connect(this, &DevicePluginDrexelUndWeiss::configValueChanged, this, &DevicePluginDrexelUndWeiss::onPluginConfigurationChanged);
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::discoverDevices(DeviceDiscoveryInfo *info)
|
||||
{
|
||||
// Create the list of available serial interfaces
|
||||
QList<DeviceDescriptor> deviceDescriptors;
|
||||
|
||||
if (info->deviceClassId() == modbusConnectionDeviceClassId) {
|
||||
Q_FOREACH(QSerialPortInfo port, QSerialPortInfo::availablePorts()) {
|
||||
if (m_usedSerialPorts.contains(port.systemLocation())){
|
||||
//device already in use
|
||||
qCDebug(dcDrexelUndWeiss()) << "Found serial port that is already used:" << port.portName();
|
||||
} else {
|
||||
//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);
|
||||
ParamList parameters;
|
||||
parameters.append(Param(modbusConnectionDeviceSerialPortParamTypeId, port.systemLocation()));
|
||||
descriptor.setParams(parameters);
|
||||
info->addDeviceDescriptor(descriptor);
|
||||
}
|
||||
}
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->deviceClassId() == x2luDeviceClassId) {
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->deviceClassId() == x2wpDeviceClassId) {
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
info->finish(Device::DeviceErrorDeviceClassNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::setupDevice(DeviceSetupInfo *info)
|
||||
{
|
||||
Device *device = info->device();
|
||||
|
||||
if (device->deviceClassId() == modbusConnectionDeviceClassId) {
|
||||
|
||||
QString serialPort = device->paramValue(modbusConnectionDeviceSerialPortParamTypeId).toString();
|
||||
int baudRate = device->paramValue(modbusConnectionDeviceBaudRateParamTypeId).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);
|
||||
|
||||
|
||||
m_modbusRTUMasters.insert(device, modbus);
|
||||
m_usedSerialPorts.append(serialPort);
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == x2luDeviceClassId) {
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == x2wpDeviceClassId) {
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
return;
|
||||
}
|
||||
info->finish(Device::DeviceErrorDeviceClassNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::postSetupDevice(Device *device)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == modbusConnectionDeviceClassId) {
|
||||
// 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);
|
||||
}
|
||||
|
||||
if ((device->deviceClassId() == x2luDeviceClassId) || (device->deviceClassId() == x2wpDeviceClassId)) {
|
||||
Device *parentDevice = myDevices().findById(device->parentId());
|
||||
if (!parentDevice) {
|
||||
qWarning(dcDrexelUndWeiss()) << "Could not find the parent device";
|
||||
return;
|
||||
}
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(parentDevice);
|
||||
if (!modbus){
|
||||
qCWarning(dcDrexelUndWeiss()) << "No modbus interface available";
|
||||
}
|
||||
updateStates(device);
|
||||
// Update states
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::executeAction(DeviceActionInfo *info)
|
||||
{
|
||||
Device *device = info->device();
|
||||
Action action = info->action();
|
||||
|
||||
if (device->deviceClassId() == modbusConnectionDeviceClassId) {
|
||||
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(device);
|
||||
if (!modbus){
|
||||
qCWarning(dcDrexelUndWeiss()) << "No modbus interface available";
|
||||
info->finish(Device::DeviceErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
if (action.actionTypeId() == modbusConnectionDiscoverDevicesActionTypeId) {
|
||||
int slave = action.param(modbusConnectionDiscoverDevicesActionSlaveAddressParamTypeId).value().toInt();
|
||||
discoverModbusSlaves(modbus, slave);
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
return;
|
||||
}
|
||||
info->finish(Device::DeviceErrorActionTypeNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == x2luDeviceClassId) {
|
||||
Device *parentDevice = myDevices().findById(device->parentId());
|
||||
if (!parentDevice) {
|
||||
qWarning(dcDrexelUndWeiss()) << "Could not find the parent device";
|
||||
info->finish(Device::DeviceErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(parentDevice);
|
||||
int slave = device->paramValue(x2luDeviceSlaveAddressParamTypeId).toInt();
|
||||
if (!modbus){
|
||||
qCWarning(dcDrexelUndWeiss()) << "No modbus interface available";
|
||||
info->finish(Device::DeviceErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
if (action.actionTypeId() == x2luVentilationModeActionTypeId) {
|
||||
QString mode = action.param(x2luVentilationModeActionVentilationModeParamTypeId).value().toString();
|
||||
int data = 0;
|
||||
|
||||
if (mode == "Manual level 0") {
|
||||
data = VentialtionMode::ManuellStufe0;
|
||||
} else if(mode == "Manual level 1") {
|
||||
data = VentialtionMode::ManuellStufe1;
|
||||
} else if(mode == "Manual level 2") {
|
||||
data = VentialtionMode::ManuellStufe2;
|
||||
}else if(mode == "Manual level 3") {
|
||||
data = VentialtionMode::ManuellStufe3;
|
||||
} else if(mode == "Automatic") {
|
||||
data = VentialtionMode::Automatikbetrieb;
|
||||
} else if(mode == "Party") {
|
||||
data = VentialtionMode::Party;
|
||||
}
|
||||
m_pendingActions.insert(modbus->writeHoldingRegister(slave, ModbusRegisterX2::Betriebsart, data), info);
|
||||
return;
|
||||
}
|
||||
info->finish(Device::DeviceErrorActionTypeNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == x2wpDeviceClassId) {
|
||||
Device *parentDevice = myDevices().findById(device->parentId());
|
||||
if (!parentDevice) {
|
||||
qWarning(dcDrexelUndWeiss()) << "Could not find modbus interface";
|
||||
info->finish(Device::DeviceErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(parentDevice);
|
||||
int slave = device->paramValue(x2wpDeviceSlaveAddressParamTypeId).toInt();
|
||||
if (!modbus){
|
||||
qCWarning(dcDrexelUndWeiss()) << "No modbus master available";
|
||||
info->finish(Device::DeviceErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
if (action.actionTypeId() == x2wpTargetTemperatureActionTypeId) {
|
||||
qreal targetTemp = (action.param(x2wpTargetTemperatureActionTargetTemperatureParamTypeId).value().toDouble());
|
||||
int data = static_cast<int>(qRound(targetTemp * 1000));
|
||||
m_pendingActions.insert(modbus->writeHoldingRegister(slave,ModbusRegisterX2::RaumSoll, data), info);
|
||||
return;
|
||||
}
|
||||
if (action.actionTypeId() == x2wpTargetWaterTemperatureActionTypeId) {
|
||||
qreal targetWaterTemp = action.param(x2wpTargetWaterTemperatureActionTargetWaterTemperatureParamTypeId).value().toDouble();
|
||||
int data = static_cast<int>(qRound(targetWaterTemp * 1000));
|
||||
m_pendingActions.insert(modbus->writeHoldingRegister(slave, ModbusRegisterX2::BrauchwasserSolltermperatur, data), info);
|
||||
return;
|
||||
}
|
||||
info->finish(Device::DeviceErrorActionTypeNotFound);
|
||||
return;
|
||||
}
|
||||
info->finish(Device::DeviceErrorDeviceClassNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginDrexelUndWeiss::deviceRemoved(Device *device)
|
||||
{
|
||||
if (device->deviceClassId() == modbusConnectionDeviceClassId) {
|
||||
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.take(device);
|
||||
if (!modbus){
|
||||
qCWarning(dcDrexelUndWeiss()) << "No modbus interface available";
|
||||
return;
|
||||
}
|
||||
m_usedSerialPorts.removeAll(modbus->serialPort());
|
||||
modbus->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::onRefreshTimer()
|
||||
{
|
||||
foreach (Device *device, myDevices()) {
|
||||
|
||||
if (device->deviceClassId() == modbusConnectionDeviceClassId) {
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(device);
|
||||
|
||||
if (!modbus) {
|
||||
qCWarning(dcDrexelUndWeiss()) << "No modbus master available";
|
||||
return;
|
||||
}
|
||||
} else if (device->deviceClassId() == x2luDeviceClassId || device->deviceClassId() == x2wpDeviceClassId){
|
||||
updateStates(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::updateStates(Device *device)
|
||||
{
|
||||
if (device->deviceClassId() == x2luDeviceClassId) {
|
||||
Device *parent = myDevices().findById(device->parentId());
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(parent);
|
||||
int slave = device->paramValue(x2luDeviceSlaveAddressParamTypeId).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());
|
||||
ModbusRTUMaster *modbus = m_modbusRTUMasters.value(parent);
|
||||
int slave = device->paramValue(x2wpDeviceSlaveAddressParamTypeId).toInt();
|
||||
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::Waermepumpe);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::RaumSoll);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::Raum);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::TemperaturWarmwasserspeicherUnten);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::BrauchwasserSolltermperatur);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::Auszenluft);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::Summenstoerung);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::LeistungKompressor);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::LeistungWarmwasser);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::LeistungRaumheizung);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::LeistungLuftvorwaermung);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::EnergieKompressor);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::EnergieWarmwasser);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::EnergieRaumheizung);
|
||||
modbus->readHoldingRegister(slave, ModbusRegisterX2::EnergieLuftvorerwarrmung);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginDrexelUndWeiss::onPluginConfigurationChanged(const ParamTypeId ¶mTypeId, const QVariant &value)
|
||||
{
|
||||
// Check refresh schedule
|
||||
if (paramTypeId == drexelUndWeissPluginUpdateIntervalParamTypeId) {
|
||||
if (m_refreshTimer) {
|
||||
int refreshTime = value.toInt();
|
||||
m_refreshTimer->stop();
|
||||
m_refreshTimer->startTimer(refreshTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::onConnectionStateChanged(bool status)
|
||||
{
|
||||
Q_UNUSED(status)
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::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)
|
||||
{
|
||||
Q_UNUSED(slaveAddress)
|
||||
Q_UNUSED(modbusRegister)
|
||||
Q_UNUSED(value)
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::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) {
|
||||
switch (modbusRegister) {
|
||||
case ModbusRegisterX2::Waermepumpe:
|
||||
device->setStateValue(x2wpPowerStateTypeId, value);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::RaumSoll:
|
||||
device->setStateValue(x2wpTargetTemperatureStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::Raum:
|
||||
device->setStateValue(x2wpTemperatureStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::TemperaturWarmwasserspeicherUnten:
|
||||
device->setStateValue(x2wpWaterTemperatureStateTypeId, value/1000.00);
|
||||
break;
|
||||
case ModbusRegisterX2::BrauchwasserSolltermperatur:
|
||||
device->setStateValue(x2wpTargetWaterTemperatureStateTypeId, value/1000.00);
|
||||
break;
|
||||
case ModbusRegisterX2::Auszenluft:
|
||||
device->setStateValue(x2wpOutsideAirTemperatureStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::Summenstoerung:
|
||||
if (value != 0) {
|
||||
//get actual error
|
||||
} else {
|
||||
device->setStateValue(x2wpErrorStateTypeId, "No Error");
|
||||
}
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungAbluftventilator:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Exhaust fan");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungBoilerfuehlerElektroheizstab:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Boiler sensor electric heating element");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungBoilerfuehlerSolar:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Boiler sensor solar");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungBoilerfuehlerWaermepumpe:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Boiler sensor heat pump");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungBoileruebertemperatur:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Boiler overtemperature");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungCO2Sensor:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "CO2-Sensor");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungDruckverlustAbluftZuGrosz:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Pressure loss exhaust air too big");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungDruckverlustZuluftZuGrosz:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Pressure loss supply air too large");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungDurchflussmengeHeizgkreis:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Flow rate of heating circuit");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungDurchflussmengeSolekreis:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Flow rate brine circuit");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTeilnehmerNichtErreichbar:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Participant not available");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTemperaturfuehlerAuszenluft:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Temperature sensor outside air");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTemperaturfuehlerHeizkreisVorlauf:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Temperature sensor heating circuit flow");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTemperaturfuehlerRaum:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Temperature sensor room");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTemperaturfuehlerSolarkollektor:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Temperature sensor solar collector");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTemperaturfuehlerSole:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Temperature sensor brine");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungTemperaturfuehlerSoleAuszenluft:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Temperature sensor brine outside air");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungWaermepumpeHochdruck:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Heat pump high pressure");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungWaermepumpeNiederdruck:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Heat pump low pressure");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungWertNichtZulaessig:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Value not allowed");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::StoerungZuluftventilator:
|
||||
if (value != 0)
|
||||
device->setStateValue(x2wpErrorStateTypeId, "Supply air fan");
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::LeistungKompressor:
|
||||
device->setStateValue(x2wpPowerCompressorStateTypeId, value/1000.00);
|
||||
break;
|
||||
case ModbusRegisterX2::LeistungWarmwasser:
|
||||
device->setStateValue(x2wpPowerWaterHeatingStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::LeistungRaumheizung:
|
||||
device->setStateValue(x2wpPowerRoomHeatingStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::LeistungLuftvorwaermung:
|
||||
device->setStateValue(x2wpPowerAirPreheatingStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::EnergieKompressor:
|
||||
device->setStateValue(x2wpEnergyCompressorStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::EnergieWarmwasser:
|
||||
device->setStateValue(x2wpEnergyWaterHeatingStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::EnergieRaumheizung:
|
||||
device->setStateValue(x2wpEnergyRoomHeatingStateTypeId, value/1000.00);
|
||||
break;
|
||||
|
||||
case ModbusRegisterX2::EnergieLuftvorerwarrmung:
|
||||
device->setStateValue(x2wpEnergyAirPreheatingStateTypeId, value/1000.00);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (device->deviceClassId() == x2wpDeviceClassId && device->paramValue(x2wpDeviceSlaveAddressParamTypeId) == slaveAddress) {
|
||||
|
||||
switch (modbusRegister) {
|
||||
case ModbusRegisterX2::Betriebsart:
|
||||
if (value == VentialtionMode::ManuellStufe0) {
|
||||
device->setStateValue(x2luVentilationModeStateTypeId, "Manual level 0");
|
||||
} else if (value == VentialtionMode::ManuellStufe1) {
|
||||
device->setStateValue(x2luVentilationModeStateTypeId, "Manual level 1");
|
||||
} else if (value == VentialtionMode::ManuellStufe2) {
|
||||
device->setStateValue(x2luVentilationModeStateTypeId, "Manual level 2");
|
||||
} else if (value == VentialtionMode::ManuellStufe3) {
|
||||
device->setStateValue(x2luVentilationModeStateTypeId, "Manual level 3");
|
||||
} else if (value == VentialtionMode::Automatikbetrieb) {
|
||||
device->setStateValue(x2luVentilationModeStateTypeId, "Automatic");
|
||||
} else if (value == VentialtionMode::Party) {
|
||||
device->setStateValue(x2luVentilationModeStateTypeId, "Party");
|
||||
}
|
||||
break;
|
||||
case ModbusRegisterX2::AktiveLuefterstufe:
|
||||
device->setStateValue(x2luActiveVentilationLevelStateTypeId, value);
|
||||
break;
|
||||
case ModbusRegisterX2::CO2:
|
||||
device->setStateValue(x2luCo2StateTypeId, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (modbusRegister == ModbusRegisterX2::Geraetetyp) {
|
||||
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());
|
||||
ParamList params;
|
||||
|
||||
//modbus->readHoldingRegister(slaveAddress, ModbusRegisterX2::SoftwareVersion);
|
||||
//params.append(Param(x2wpDeviceSofwareVersionParamTypeId, data));
|
||||
params.append(Param(x2wpDeviceSlaveAddressParamTypeId, slaveAddress));
|
||||
descriptor.setParams(params);
|
||||
deviceDescriptors.append(descriptor);
|
||||
emit autoDevicesAppeared(deviceDescriptors);
|
||||
break;
|
||||
}
|
||||
case DeviceType::X2_LU: {
|
||||
qDebug(dcDrexelUndWeiss()) << "Discovered X2 ventilation unit";
|
||||
QList<DeviceDescriptor> deviceDescriptors;
|
||||
DeviceDescriptor descriptor(x2luDeviceClassId, "X2 LU", "Drexel und Weiss", parentDevice->id());
|
||||
ParamList params;
|
||||
|
||||
//modbus->readHoldingRegister(slaveAddress, ModbusRegisterX2::SoftwareVersion);
|
||||
//params.append(Param(x2luDeviceSofwareVersionParamTypeId, data));
|
||||
params.append(Param(x2luDeviceSlaveAddressParamTypeId, slaveAddress));
|
||||
descriptor.setParams(params);
|
||||
deviceDescriptors.append(descriptor);
|
||||
emit autoDevicesAppeared(deviceDescriptors);
|
||||
break;
|
||||
}
|
||||
case DeviceType::AerosilentBianco:
|
||||
//Just a test
|
||||
qDebug(dcDrexelUndWeiss()) << "Discovered Aerosilent Bianco";
|
||||
break;
|
||||
default:
|
||||
qDebug(dcDrexelUndWeiss()) << "Unkown Devicetype" << value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::onReceivedInputRegister(int slaveAddress, int modbusRegister, int value)
|
||||
{
|
||||
Q_UNUSED(slaveAddress)
|
||||
Q_UNUSED(modbusRegister)
|
||||
Q_UNUSED(value)
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::onWriteRequestFinished(QUuid requestId, bool success)
|
||||
{
|
||||
DeviceActionInfo *info = m_pendingActions.take(requestId);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
if (success) {
|
||||
info->finish(Device::DeviceErrorNoError);
|
||||
} else {
|
||||
info->finish(Device::DeviceErrorHardwareFailure);
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDrexelUndWeiss::discoverModbusSlaves(ModbusRTUMaster *modbus, int slaveAddress)
|
||||
{
|
||||
foreach (Device *device, myDevices()) {
|
||||
if (device->deviceClassId() == x2luDeviceClassId) {
|
||||
if (device->paramValue(x2luDeviceSlaveAddressParamTypeId).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";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
modbus->readHoldingRegister(slaveAddress, ModbusRegisterX2::Geraetetyp);
|
||||
}
|
||||
80
drexelundweiss/deviceplugindrexelundweiss.h
Normal file
80
drexelundweiss/deviceplugindrexelundweiss.h
Normal file
@ -0,0 +1,80 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by copyright law, and
|
||||
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||
* of use of nymea GmbH, available under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software Foundation; version 3.
|
||||
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this project.
|
||||
* If not, see <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;
|
||||
|
||||
public slots:
|
||||
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
|
||||
374
drexelundweiss/deviceplugindrexelundweiss.json
Normal file
374
drexelundweiss/deviceplugindrexelundweiss.json
Normal file
@ -0,0 +1,374 @@
|
||||
{
|
||||
"name": "DrexelUndWeiss",
|
||||
"displayName": "Drexel und Weiss",
|
||||
"id": "68d78ce6-82d0-4a5b-b901-7c3b843ef63c",
|
||||
"paramTypes":[
|
||||
{
|
||||
"id": "ecc8e0f1-5fac-4ea9-b5ef-459d75c4fe78",
|
||||
"name": "updateInterval",
|
||||
"displayName": "Update interval",
|
||||
"type": "int",
|
||||
"unit": "Seconds",
|
||||
"defaultValue": 15
|
||||
}
|
||||
],
|
||||
"vendors": [
|
||||
{
|
||||
"name": "DrexelUndWeiss",
|
||||
"displayName": "Drexel und Weiss",
|
||||
"id": "9f476e8b-7e95-448e-b03b-874747e8fb1f",
|
||||
"deviceClasses": [
|
||||
{
|
||||
"name": "modbusConnection",
|
||||
"displayName": "Modbus Connection",
|
||||
"id": "06d04eec-ab5d-479a-b9e6-8c89efc18a8b",
|
||||
"createMethods": ["discovery", "user"],
|
||||
"interfaces": ["gateway"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "ed49f7d8-ab18-4c37-9b80-1004b75dcb91",
|
||||
"name": "serialPort",
|
||||
"displayName": "Serial port",
|
||||
"type": "QString",
|
||||
"inputType": "TextLine",
|
||||
"defaultValue": "ttyAMA0"
|
||||
},
|
||||
{
|
||||
"id": "d0c04612-cc3e-4d38-b4c9-708e28dc4eb3",
|
||||
"name": "baudRate",
|
||||
"displayName": "Baudrate",
|
||||
"type": "int",
|
||||
"defaultValue": 9600
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "181ce6e2-9c55-45c6-b329-adf379679e07a",
|
||||
"name": "connected",
|
||||
"displayName": "connected",
|
||||
"displayNameEvent": "connection status changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "b9a24ecc-4433-4f31-99ba-596033bda421",
|
||||
"name": "discoverDevices",
|
||||
"displayName": "Discover devices",
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "22413a22-31d4-4b8c-b855-8a29da5946bc",
|
||||
"name": "slaveAddress",
|
||||
"displayName": "Slave address",
|
||||
"type": "int",
|
||||
"minValue": 0,
|
||||
"maxValue": 250,
|
||||
"defaultValue": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "x2lu",
|
||||
"displayName": "X2 LU",
|
||||
"id": "0de8e21e-392a-4790-a78a-b1a7eaa7571b",
|
||||
"createMethods": ["auto"],
|
||||
"interfaces": ["co2sensor", "connectable"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "22413a22-31d4-4b8c-b855-8a29da5946bc",
|
||||
"name": "slaveAddress",
|
||||
"displayName": "Slave address",
|
||||
"type": "int",
|
||||
"minValue": 0,
|
||||
"maxValue": 250,
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "91ef76cf-6c53-4a8a-a278-6f6e2ef68cc6",
|
||||
"name": "sofwareVersion",
|
||||
"displayName": "Software version",
|
||||
"type": "QString",
|
||||
"inputType": "TextLine",
|
||||
"defaultValue": "-"
|
||||
}
|
||||
],
|
||||
"stateTypes":[
|
||||
{
|
||||
"id": "181ce6e2-9c55-45c6-b329-adf379679e07a",
|
||||
"name": "connected",
|
||||
"displayName": "connected",
|
||||
"displayNameEvent": "connection status changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "0a6b44c8-e7af-4148-92ff-682ae717f3a8",
|
||||
"name": "co2",
|
||||
"displayName": "CO2",
|
||||
"displayNameEvent": "CO2 changed",
|
||||
"unit": "PartsPerMillion",
|
||||
"type": "double",
|
||||
"defaultValue": 350
|
||||
},
|
||||
{
|
||||
"id": "4269d9d0-ddff-4e7a-9d7a-bf9a7db50f98",
|
||||
"name": "ventilationMode",
|
||||
"displayName": "Ventilation mode",
|
||||
"displayNameEvent": "Ventilation mode changed",
|
||||
"displayNameAction": "Change ventilation mode",
|
||||
"type": "QString",
|
||||
"defaultValue": "Manual level 0",
|
||||
"possibleValues": [
|
||||
"Manual level 0",
|
||||
"Manual level 1",
|
||||
"Manual level 2",
|
||||
"Manual level 3",
|
||||
"Automatic",
|
||||
"Party"
|
||||
],
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "1f26a013-7836-4f3e-b369-7ce07310fc59",
|
||||
"name": "activeVentilationLevel",
|
||||
"displayName": "Ventilation level",
|
||||
"displayNameEvent": "Ventilation level changed",
|
||||
"type": "int",
|
||||
"defaultValue": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "x2wp",
|
||||
"displayName": "X2 WP",
|
||||
"id": "e548f962-92db-4110-8279-10fbcde35f93",
|
||||
"createMethods": ["auto"],
|
||||
"interfaces": ["thermostat", "heating", "temperaturesensor", "connectable"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "22413a22-31d4-4b8c-b855-8a29da5946bc",
|
||||
"name": "slaveAddress",
|
||||
"displayName": "Slave address",
|
||||
"type": "int",
|
||||
"minValue": 0,
|
||||
"maxValue": 250,
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "91ef76cf-6c53-4a8a-a278-6f6e2ef68cc6",
|
||||
"name": "sofwareVersion",
|
||||
"displayName": "Software version",
|
||||
"type": "QString",
|
||||
"inputType": "TextLine",
|
||||
"defaultValue": "-"
|
||||
}
|
||||
],
|
||||
"stateTypes":[
|
||||
|
||||
{
|
||||
"id": "181ce6e2-9c55-45c6-b329-adf379679e07a",
|
||||
"name": "connected",
|
||||
"displayName": "connected",
|
||||
"displayNameEvent": "connection status changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "f2ce8389-c33f-4f10-8484-f2e993841762",
|
||||
"name": "power",
|
||||
"displayName": "Power",
|
||||
"displayNameEvent": "Power changed",
|
||||
"displayNameAction": "Change power",
|
||||
"type": "bool",
|
||||
"defaultValue": 0,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "3ab2d609-1686-4fd7-84e3-580c8e0537d0",
|
||||
"name": "temperature",
|
||||
"displayName": "Room temperature",
|
||||
"displayNameEvent": "Room temperature changed",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "77a96b57-fa0a-4946-af5b-39c3b66d9422",
|
||||
"name": "waterTemperature",
|
||||
"displayName": "Water temperature",
|
||||
"displayNameEvent": "Water temperature changed",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "32378843-5478-4b86-9c0e-ccbf978c02be",
|
||||
"name": "outsideAirTemperature",
|
||||
"displayName": "Outside air temperature",
|
||||
"displayNameEvent": "Outside air temperature changed",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "fb98754d-0fba-4163-9b74-3e5a07d71421",
|
||||
"name": "targetTemperature",
|
||||
"displayName": "Target room temperature",
|
||||
"displayNameEvent": "Target room temperature changed",
|
||||
"displayNameAction": "Change room target temperature",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"minValue": 14.00,
|
||||
"maxValue": 26.00,
|
||||
"defaultValue": 22.00,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "fb021cac-1236-4324-a45c-8d89ad069052",
|
||||
"name": "targetWaterTemperature",
|
||||
"displayName": "Target water temperature",
|
||||
"displayNameEvent": "Target water temperature changed",
|
||||
"displayNameAction": "Change water target temperature",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"minValue": 20.00,
|
||||
"maxValue": 55.00,
|
||||
"defaultValue": 46.00,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "5c125ddd-a0db-40fe-9998-2afea6c727f1",
|
||||
"name": "heatPumpMode",
|
||||
"displayName": "Heat pump mode",
|
||||
"displayNameEvent": "Heat pump mode changed",
|
||||
"type": "QString",
|
||||
"defaultValue": "Heat pump off",
|
||||
"possibleValues": [
|
||||
"Restart interlock" ,
|
||||
"Heat pump off",
|
||||
"Lead time brine pump",
|
||||
"Fan run-up time",
|
||||
"Open hot gas valve",
|
||||
"Open LPG valve",
|
||||
"Start compressor",
|
||||
"Minimum runtime heat pump",
|
||||
"Heat pump on",
|
||||
"Draw off refrigerant",
|
||||
"Vacuum during defrosting",
|
||||
"Defrost",
|
||||
"Drain after defrosting"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "8d6e52ef-992d-47ac-90a8-9dba95ab200e",
|
||||
"name": "error",
|
||||
"displayName": "Error",
|
||||
"displayNameEvent": "Error occured",
|
||||
"type": "QString",
|
||||
"defaultValue": "No error",
|
||||
"possibleValues": [
|
||||
"No error",
|
||||
"Exhaust fan" ,
|
||||
"Boiler sensor electric heating element",
|
||||
"Boiler sensor solar",
|
||||
"Boiler sensor heat pump",
|
||||
"Boiler overtemperature",
|
||||
"CO2-Sensor",
|
||||
"Pressure loss exhaust air too big",
|
||||
"Pressure loss supply air too large",
|
||||
"Flow rate of heating circuit",
|
||||
"Flow rate brine circuit",
|
||||
"Participant not available",
|
||||
"Temperature sensor outside air",
|
||||
"Temperature sensor heating circuit flow",
|
||||
"Temperature sensor room",
|
||||
"Temperature sensor solar collector",
|
||||
"Temperature sensor brine",
|
||||
"Temperature sensor brine outside air",
|
||||
"Heat pump high pressure",
|
||||
"Heat pump low pressure",
|
||||
"Value not allowed",
|
||||
"Supply air fan"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "7287943a-ea6d-4c92-abbd-f55f6c7ee9e5",
|
||||
"name": "powerCompressor",
|
||||
"displayName": "Power consumption compressor",
|
||||
"displayNameEvent": "Power consumption compressor changed",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "59beeff5-89c1-4996-9e07-48d53d74684d",
|
||||
"name": "powerAirPreheating",
|
||||
"displayName": "Power consumption air preheating",
|
||||
"displayNameEvent": "Power consumption air preheating changed",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "c4237da0-0ead-42b8-b192-6a681509dc90",
|
||||
"name": "powerRoomHeating",
|
||||
"displayName": "Power consumption room heating",
|
||||
"displayNameEvent": "Power consumption room heating changed",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "21dfc736-f35c-469f-be57-afc1976d8328",
|
||||
"name": "powerWaterHeating",
|
||||
"displayName": "Power consumption water heating",
|
||||
"displayNameEvent": "Power consumption water heating changed",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "b423657b-4e59-41cd-89a3-4f5cb1c3a271",
|
||||
"name": "energyCompressor",
|
||||
"displayName": "Energy compressor",
|
||||
"displayNameEvent": "Energy compressor changed",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "0816ca6d-a178-4a2a-8183-c26a794fb0ca",
|
||||
"name": "energyAirPreheating",
|
||||
"displayName": "Energy air preheating",
|
||||
"displayNameEvent": "Energy air preheating changed",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "cb189b75-3634-4674-a847-f29ca322d4be",
|
||||
"name": "energyWaterHeating",
|
||||
"displayName": "Energy water heating",
|
||||
"displayNameEvent": "Energy water heating changed",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "4495618e-5a43-46ac-9f76-32aae3f3e954",
|
||||
"name": "energyRoomHeating",
|
||||
"displayName": "Energy room heating",
|
||||
"displayNameEvent": "Energy room heating changed",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
16
drexelundweiss/drexelundweiss.pro
Normal file
16
drexelundweiss/drexelundweiss.pro
Normal file
@ -0,0 +1,16 @@
|
||||
include(../plugins.pri)
|
||||
|
||||
QT += \
|
||||
serialport \
|
||||
serialbus \
|
||||
|
||||
SOURCES += \
|
||||
deviceplugindrexelundweiss.cpp \
|
||||
modbusrtumaster.cpp \
|
||||
|
||||
HEADERS += \
|
||||
deviceplugindrexelundweiss.h \
|
||||
modbusrtumaster.h \
|
||||
modbusdegisterdefinition.h
|
||||
|
||||
|
||||
248
drexelundweiss/modbusdegisterdefinition.h
Normal file
248
drexelundweiss/modbusdegisterdefinition.h
Normal file
@ -0,0 +1,248 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 MODBUSDEGISTERDEFINITION
|
||||
#define MODBUSDEGISTERDEFINITION
|
||||
|
||||
#endif // MODBUSDEGISTERDEFINITION
|
||||
|
||||
enum ModbusRegisterX2 {
|
||||
AbsenkungderLuefterstufe1 = 5328,
|
||||
AktiveLuefterstufe = 1066,
|
||||
AnforderungDerVentilatorenDurchWaermepumpe = 1292,
|
||||
AnforderungDerVentilatorenDurchZonenregelung = 1336,
|
||||
AnforderungDisbalance = 1338,
|
||||
AnforderungBeschattung = 1218,
|
||||
AnforderungBrauchwasserheizungElektoheizstab = 1038,
|
||||
AnforderungBrauchwasserheizungWaermepumpe = 1036,
|
||||
AnforderungBypassklappe = 1216,
|
||||
AnforderungFrostschutz = 1146,
|
||||
AnforderungLST3EXT = 228,
|
||||
AnforderungRaumHeizstufe1 = 1032,
|
||||
AnforderungRaumHeizstufe2 = 1034,
|
||||
AnforderungSoleFuerAuszenlufterwaermung = 1198,
|
||||
AnforderungSoleFuerWaermepumpe = 1196,
|
||||
AnforderungSoleKuehlung = 1320,
|
||||
Auszenluft = 202,
|
||||
AuszenluftfuehlerVorhanden = 5304 ,
|
||||
Beschattungsfunktion = 5336,
|
||||
Betriebsart = 5002,
|
||||
BetriebsstundenAbluftventilator = 902,
|
||||
BetriebsstundenBeschattung = 964,
|
||||
BetriebsstundenBypassklappe = 932,
|
||||
BetriebsstundenFeinstaub = 928,
|
||||
BetriebsstundenFrostschutzeinrichtung = 940,
|
||||
BetriebsstundenGrobstaub = 926,
|
||||
BetriebsstundenHeizstufe1 = 912,
|
||||
BetriebsstundenHeizstufe2 = 914,
|
||||
BetriebsstundenHeizung = 938,
|
||||
BetriebsstundenLuefterstufe0 = 962,
|
||||
BetriebsstundenLuefterstufe1 = 904,
|
||||
BetriebsstundenLuefterstufe2 = 906,
|
||||
BetriebsstundenLuefterstufe3 = 908,
|
||||
BetriebsstundenReduzierteLuefterstufe = 944,
|
||||
BetriebsstundenSoleKreis = 934,
|
||||
BetriebsstundenSoleKreisAuszenluft = 970,
|
||||
BetriebsstundenZuluftventilator = 900,
|
||||
Brandmeldealarm = 838,
|
||||
BrandmeldeanlageVorhanden = 5068,
|
||||
CO2 = 230,
|
||||
CO2Messung = 1048,
|
||||
CO2SensorVorhanden = 5054,
|
||||
Datum = 5210,
|
||||
DrehzahlAbluftventilator = 1094,
|
||||
DrehzahlZuluftventilator = 1092,
|
||||
ErhoehungDerLuefterstufe3 = 5330,
|
||||
FeinstaubfilterVorhanden = 5034,
|
||||
FeinstaubfilterWechseln = 7004,
|
||||
FeinstaubfilterStandzeit = 5032,
|
||||
FunktionHeizungPlus = 5492,
|
||||
Geraetetyp = 5000,
|
||||
GesamtBefoerderteKubikmeter = 946,
|
||||
GesamtBefoerderteLuftmengeSeitFilterwechsel = 960,
|
||||
GrobstaubfilterVorhanden = 5154,
|
||||
GrobstaubfilterWechseln = 7002,
|
||||
GrobstaubfilterBetriebsartFiltereberwachung = 5164,
|
||||
GrobstaubfilterMaximalesFoerdervolumen = 5166,
|
||||
GrobstaubfilterStandzeit = 5030,
|
||||
IstDrehzahlAbluftventilator = 1186,
|
||||
IstDrehzahlZuluftventilator = 1184,
|
||||
KontaktBrandmeldealarm = 238,
|
||||
KuehlungVorhanden = 5192,
|
||||
MaximalZulaessigeDrehzahlAbluftventilator = 5270,
|
||||
MaximalZulaessigeDrehzahlZuluftventilator = 5268,
|
||||
PelletofenVorhanden = 5168,
|
||||
PelletofenAnlaufverzoegerung = 5282,
|
||||
PelletofenMindestlaufzeit = 5284,
|
||||
Raum = 200,
|
||||
RaumSoll = 5016,
|
||||
RaumtemperaturBeschattung = 5338,
|
||||
RelaiskontaktEXT = 252,
|
||||
Revisionstuere = 226,
|
||||
SollVolumenstromAbluft = 1084,
|
||||
SollVolumenstromLuefterstufe = 5060,
|
||||
SollVolumenstromZuluft = 1082,
|
||||
SollwertErhoehungFunktionHeizungPlus = 5496,
|
||||
StoerungAbluftventilator = 826,
|
||||
StoerungBoilerfuehlerElektroheizstab = 828,
|
||||
StoerungBoilerfuehlerSolar = 844,
|
||||
StoerungBoilerfuehlerWaermepumpe = 830,
|
||||
StoerungBoileruebertemperatur = 810,
|
||||
StoerungCO2Sensor = 832,
|
||||
StoerungDruckverlustAbluftZuGrosz = 854,
|
||||
StoerungDruckverlustZuluftZuGrosz = 852,
|
||||
StoerungDurchflussmengeHeizgkreis = 848,
|
||||
StoerungDurchflussmengeSolekreis = 846,
|
||||
StoerungTeilnehmerNichtErreichbar = 856,
|
||||
StoerungTemperaturfuehlerAuszenluft = 806,
|
||||
StoerungTemperaturfuehlerHeizkreisVorlauf = 850,
|
||||
StoerungTemperaturfuehlerRaum = 804,
|
||||
StoerungTemperaturfuehlerSolarkollektor = 842,
|
||||
StoerungTemperaturfuehlerSole = 812,
|
||||
StoerungTemperaturfuehlerSoleAuszenluft = 7504,
|
||||
StoerungWaermepumpeHochdruck = 818,
|
||||
StoerungWaermepumpeNiederdruck = 820,
|
||||
StoerungWertNichtZulaessig = 840,
|
||||
StoerungZuluftventilator = 824,
|
||||
Summenstoerung = 800,
|
||||
Summenstoerung2 = 7500,
|
||||
SoftwareVersion = 1156,
|
||||
Tag = 1174,
|
||||
TemperaturAuszenluftBeschattung = 5340,
|
||||
TemperaturAuszenluftBypassKuehlungAus = 5452,
|
||||
TemperaturAuszenluftBypassKuehlungEin = 5450,
|
||||
TemperaturAuszenluftBypassOeffnen = 5084,
|
||||
TemperaturAuszenluftBypassSchlieszen = 5086,
|
||||
TemperaturAuszenluftFrostschutz= 5206,
|
||||
TemperaturAuszenluftFrostschutzAus = 5090,
|
||||
TemperaturAuszenluftFrostschutzEin = 5088,
|
||||
TemperaturAuszenluftKuehlungAus = 5200,
|
||||
TemperaturAuszenluftKuelungEin = 5198,
|
||||
TemperaturAuszenluftReduktionLuftmenge10Prozent = 5422,
|
||||
TemperaturAuszenluftReduktionLuftmenge20Prozent = 5424,
|
||||
TemperaturSole = 216,
|
||||
TemperaturSoleNachAuszenluftvorwaermung = 206,
|
||||
TemperaturschwelleAuszenluftHeizenKuehlen = 5186,
|
||||
TimeOutSolltemperaturRaum = 7508,
|
||||
TimeOutTemperaturfuehlerAuszenluft = 7510,
|
||||
TimeoutTemperaturfuehlerHeizkreisVorlauf = 7512,
|
||||
TimeoutTemperaturfuehlerRaum = 7506,
|
||||
Uhrzeit = 5212,
|
||||
UhrzeitundDatumVerschicken = 5442,
|
||||
VolumenstrombalanceZuluftAbluft = 5026,
|
||||
VorlaufNiedertemperaturHeizkreis = 240,
|
||||
ZeitspanneFunktionHeizung = 5494,
|
||||
ZeitspanneFunktionParty = 5038,
|
||||
HochdruckWaermepumpe = 222,
|
||||
NiederdruckWaermepumpe = 224, //nicht vorhanden, vorhanden
|
||||
HystereseSolareRaumheizungAus = 5302,
|
||||
KontaktEVU = 232,
|
||||
MaximalZulaessigeVorlauftemperaturHeizung = 5202,
|
||||
MinimalZulaessigeRuecklauftemperaturPassiveKuehlung = 5204,
|
||||
MinimaleBrauchwassertemperaturSolareRaumheizungEin = 5300,
|
||||
RaumtemperaturPassiveKuehlungEin = 5182,
|
||||
RelaiskontaktExt = 262,
|
||||
SolaranlageVorhanden = 5190,
|
||||
SolaranlageAusschaltschwelleSolarpumpe = 5180,
|
||||
SolaranlageEinschaltschwelleSolarpumpe =5178,
|
||||
SolaranlageMaximaleLadetemperatur = 5176,
|
||||
SolareRaumheizungVorhanden = 5306,
|
||||
StatusWaermepumpe = 1314,
|
||||
StatusWaermepumpeRestzeit = 1316, // in seconds
|
||||
EVUAnlageVorhanden = 5146,
|
||||
EVUSperreBrauchwasserAktiv = 1270,
|
||||
EVUSperreElektroheizstabAktiv = 1274,
|
||||
EVUSperreRaumheizungAktiv = 1272,
|
||||
BrauchwasserSolltermperatur = 5064,
|
||||
BrauchwassertemperaturRaumheizungssperre = 5130,
|
||||
FunktionBadPlus = 5036,
|
||||
ElektroheizstabVorhanden = 5126,
|
||||
EnergieKompressor = 4500,
|
||||
EnergieLuftvorerwarrmung = 4506,
|
||||
EnergieRaumheizung = 4502,
|
||||
EnergieWarmwasser = 4504,
|
||||
LeistungKompressor = 4000,
|
||||
LeistungLuftvorwaermung = 4006 ,
|
||||
LeistungRaumheizung = 4002,
|
||||
LeistungWarmwasser = 4004,
|
||||
TemperaturBoilerSolar = 244,
|
||||
TemperaturSolarkollektor = 242,
|
||||
TemperaturWarmwasserspeicherOben = 212,
|
||||
TemperaturWarmwasserspeicherUnten = 214,
|
||||
Waermepumpe = 1044,
|
||||
ZentralgeraetAdresse = 5436
|
||||
};
|
||||
|
||||
|
||||
enum DeviceType {
|
||||
NotDefined,
|
||||
AerosilentPrimus = 1,
|
||||
AerosilentTopo,
|
||||
AerosilentMicro,
|
||||
AerosmartS,
|
||||
AerosmartM,
|
||||
AerosmartL,
|
||||
AerosmartXls,
|
||||
AerosilentCentro,
|
||||
TermosmartSc,
|
||||
X2_LU = 25,
|
||||
X2_WP = 26,
|
||||
AerosmartMono,
|
||||
Vbox120,
|
||||
AerosilentBianco,
|
||||
X2Plus,
|
||||
AerosilentBusiness,
|
||||
CentralDevice,
|
||||
AerosilentStratos,
|
||||
ZoneControl,
|
||||
Vbox300
|
||||
};
|
||||
|
||||
enum HeatPumpStatus {
|
||||
Wiedereinschaltsperre,
|
||||
Waermepumpeaus,
|
||||
VorlaufzeitSolepumpe,
|
||||
VorlaufzeitVentilatoren,
|
||||
OeffnenHeissgasventil,
|
||||
OeffnenFluessiggasventil,
|
||||
StartKompressor,
|
||||
MindestlaufzeitWaermepumpe,
|
||||
WaermepumpeEin,
|
||||
KaeltemittleAbsaugen,
|
||||
BeimAbtauenAbsaugen,
|
||||
AbtauenEin,
|
||||
NachAbtauenAbtropfen
|
||||
};
|
||||
|
||||
enum VentialtionMode {
|
||||
ManuellStufe0 = 0,
|
||||
ManuellStufe1,
|
||||
ManuellStufe2,
|
||||
ManuellStufe3,
|
||||
Automatikbetrieb,
|
||||
Party
|
||||
};
|
||||
362
drexelundweiss/modbusrtumaster.cpp
Normal file
362
drexelundweiss/modbusrtumaster.cpp
Normal file
@ -0,0 +1,362 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 "modbusrtumaster.h"
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
#include <QSerialPortInfo>
|
||||
|
||||
ModbusRTUMaster::ModbusRTUMaster(QString serialPort, int baudrate, QSerialPort::Parity parity, int dataBits, int stopBits, QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
m_modbusRtuSerialMaster = new QModbusRtuSerialMaster(this);
|
||||
m_modbusRtuSerialMaster->setConnectionParameter(QModbusDevice::SerialPortNameParameter, serialPort);
|
||||
m_modbusRtuSerialMaster->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, baudrate);
|
||||
m_modbusRtuSerialMaster->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, dataBits);
|
||||
m_modbusRtuSerialMaster->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, stopBits);
|
||||
m_modbusRtuSerialMaster->setConnectionParameter(QModbusDevice::SerialParityParameter, parity);
|
||||
//m_modbusRtuSerialMaster->setTimeout(100);
|
||||
//m_modbusRtuSerialMaster->setNumberOfRetries(1);
|
||||
connect(m_modbusRtuSerialMaster, &QModbusTcpClient::stateChanged, this, &ModbusRTUMaster::onModbusStateChanged);
|
||||
connect(m_modbusRtuSerialMaster, &QModbusRtuSerialMaster::errorOccurred, this, &ModbusRTUMaster::onModbusErrorOccurred);
|
||||
|
||||
m_reconnectTimer = new QTimer(this);
|
||||
m_reconnectTimer->setSingleShot(true);
|
||||
connect(m_reconnectTimer, &QTimer::timeout, this, &ModbusRTUMaster::onReconnectTimer);
|
||||
}
|
||||
|
||||
|
||||
ModbusRTUMaster::~ModbusRTUMaster()
|
||||
{
|
||||
if (!m_modbusRtuSerialMaster) {
|
||||
m_modbusRtuSerialMaster->disconnectDevice();
|
||||
m_modbusRtuSerialMaster->deleteLater();
|
||||
}
|
||||
if (!m_reconnectTimer) {
|
||||
m_reconnectTimer->stop();
|
||||
m_reconnectTimer->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
bool ModbusRTUMaster::connectDevice()
|
||||
{
|
||||
qDebug(dcDrexelUndWeiss()) << "Setting up TCP connecion";
|
||||
|
||||
if (!m_modbusRtuSerialMaster)
|
||||
return false;
|
||||
|
||||
return m_modbusRtuSerialMaster->connectDevice();
|
||||
}
|
||||
|
||||
QString ModbusRTUMaster::serialPort()
|
||||
{
|
||||
return m_modbusRtuSerialMaster->connectionParameter(QModbusDevice::SerialPortNameParameter).toString();
|
||||
}
|
||||
|
||||
void ModbusRTUMaster::onReplyFinished()
|
||||
{
|
||||
QModbusReply *reply = qobject_cast<QModbusReply *>(sender());
|
||||
if (!reply)
|
||||
return;
|
||||
reply->deleteLater();
|
||||
|
||||
int modbusAddress = 0;
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
|
||||
for (int i = 0; i < static_cast<int>(unit.valueCount()); i++) {
|
||||
//qCDebug(dcUniPi()) << "Start Address:" << unit.startAddress() << "Register Type:" << unit.registerType() << "Value:" << unit.value(i);
|
||||
modbusAddress = unit.startAddress() + i;
|
||||
|
||||
switch (unit.registerType()) {
|
||||
case QModbusDataUnit::RegisterType::Coils:
|
||||
emit receivedCoil(reply->serverAddress(), modbusAddress, unit.value(i));
|
||||
break;
|
||||
case QModbusDataUnit::RegisterType::DiscreteInputs:
|
||||
emit receivedDiscreteInput(reply->serverAddress(), modbusAddress, unit.value(i));
|
||||
break;
|
||||
case QModbusDataUnit::RegisterType::InputRegisters:
|
||||
emit receivedInputRegister(reply->serverAddress(), modbusAddress, unit.value(i));
|
||||
break;
|
||||
case QModbusDataUnit::RegisterType::HoldingRegisters:
|
||||
emit receivedHoldingRegister(reply->serverAddress(), modbusAddress, unit.value(i));
|
||||
break;
|
||||
case QModbusDataUnit::RegisterType::Invalid:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (reply->error() == QModbusDevice::ProtocolError) {
|
||||
qCWarning(dcDrexelUndWeiss()) << "Read response error:" << reply->errorString() << reply->rawResult().exceptionCode();
|
||||
} else {
|
||||
qCWarning(dcDrexelUndWeiss()) << "Read response error:" << reply->error();
|
||||
}
|
||||
}
|
||||
|
||||
void ModbusRTUMaster::onReplyErrorOccured(QModbusDevice::Error error)
|
||||
{
|
||||
qCWarning(dcDrexelUndWeiss()) << "Modbus replay error:" << error;
|
||||
QModbusReply *reply = qobject_cast<QModbusReply *>(sender());
|
||||
if (!reply)
|
||||
return;
|
||||
reply->finished(); //to make sure it will be deleted
|
||||
}
|
||||
|
||||
void ModbusRTUMaster::onReconnectTimer()
|
||||
{
|
||||
if(!m_modbusRtuSerialMaster->connectDevice()) {
|
||||
m_reconnectTimer->start(10000);
|
||||
}
|
||||
}
|
||||
|
||||
bool ModbusRTUMaster::readCoil(int slaveAddress, int registerAddress)
|
||||
{
|
||||
if (!m_modbusRtuSerialMaster)
|
||||
return false;
|
||||
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::Coils, registerAddress, 1);
|
||||
|
||||
if (QModbusReply *reply = m_modbusRtuSerialMaster->sendReadRequest(request, slaveAddress)) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, &ModbusRTUMaster::onReplyFinished);
|
||||
connect(reply, &QModbusReply::errorOccurred, this, &ModbusRTUMaster::onReplyErrorOccured);
|
||||
QTimer::singleShot(200, reply, SLOT(deleteLater()));
|
||||
} else {
|
||||
delete reply; // broadcast replies return immediately
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcDrexelUndWeiss()) << "Read error: " << m_modbusRtuSerialMaster->errorString();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QUuid ModbusRTUMaster::writeCoil(int slaveAddress, int registerAddress, bool value)
|
||||
{
|
||||
QUuid requestId = QUuid::createUuid();
|
||||
if (!m_modbusRtuSerialMaster)
|
||||
return requestId;
|
||||
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::Coils, registerAddress, 1);
|
||||
request.setValue(0, static_cast<uint16_t>(value));
|
||||
|
||||
if (QModbusReply *reply = m_modbusRtuSerialMaster->sendWriteRequest(request, slaveAddress)) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, [requestId, this] {
|
||||
|
||||
QModbusReply *reply = qobject_cast<QModbusReply *>(sender());
|
||||
if (!reply)
|
||||
return;
|
||||
reply->deleteLater();
|
||||
|
||||
int modbusAddress = 0;
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
emit writeRequestFinished(requestId, true);
|
||||
|
||||
for (int i = 0; i < static_cast<int>(unit.valueCount()); i++) {
|
||||
//qCDebug(dcUniPi()) << "Start Address:" << unit.startAddress() << "Register Type:" << unit.registerType() << "Value:" << unit.value(i);
|
||||
modbusAddress = unit.startAddress() + i;
|
||||
|
||||
switch (unit.registerType()) {
|
||||
case QModbusDataUnit::RegisterType::Coils:
|
||||
emit receivedCoil(reply->serverAddress(), modbusAddress, unit.value(i));
|
||||
break;
|
||||
case QModbusDataUnit::RegisterType::DiscreteInputs:
|
||||
emit receivedDiscreteInput(reply->serverAddress(), modbusAddress, unit.value(i));
|
||||
break;
|
||||
case QModbusDataUnit::RegisterType::InputRegisters:
|
||||
emit receivedInputRegister(reply->serverAddress(), modbusAddress, unit.value(i));
|
||||
break;
|
||||
case QModbusDataUnit::RegisterType::HoldingRegisters:
|
||||
emit receivedHoldingRegister(reply->serverAddress(), modbusAddress, unit.value(i));
|
||||
break;
|
||||
case QModbusDataUnit::RegisterType::Invalid:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (reply->error() == QModbusDevice::ProtocolError) {
|
||||
emit writeRequestFinished(requestId, false);
|
||||
qCWarning(dcDrexelUndWeiss()) << "Read response error:" << reply->errorString() << reply->rawResult().exceptionCode();
|
||||
} else {
|
||||
emit writeRequestFinished(requestId, false);
|
||||
qCWarning(dcDrexelUndWeiss()) << "Read response error:" << reply->error();
|
||||
}
|
||||
});
|
||||
connect(reply, &QModbusReply::errorOccurred, this, &ModbusRTUMaster::onReplyErrorOccured);
|
||||
QTimer::singleShot(200, reply, SLOT(deleteLater()));
|
||||
} else {
|
||||
delete reply; // broadcast replies return immediately
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcDrexelUndWeiss()) << "Read error: " << m_modbusRtuSerialMaster->errorString();
|
||||
}
|
||||
return requestId;
|
||||
}
|
||||
|
||||
QUuid ModbusRTUMaster::writeHoldingRegister(int slaveAddress, int registerAddress, int value)
|
||||
{
|
||||
QUuid requestId = QUuid::createUuid();
|
||||
if (!m_modbusRtuSerialMaster){
|
||||
qCWarning(dcDrexelUndWeiss()) << "Modbus RTU interface not available";
|
||||
return requestId;
|
||||
}
|
||||
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, registerAddress, 1);
|
||||
request.setValue(0, static_cast<uint16_t>(value));
|
||||
|
||||
if (QModbusReply *reply = m_modbusRtuSerialMaster->sendWriteRequest(request, slaveAddress)) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, [requestId, this] {
|
||||
|
||||
QModbusReply *reply = qobject_cast<QModbusReply *>(sender());
|
||||
if (!reply)
|
||||
return;
|
||||
reply->deleteLater();
|
||||
|
||||
int modbusAddress = 0;
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
emit writeRequestFinished(requestId, true);
|
||||
|
||||
for (int i = 0; i < static_cast<int>(unit.valueCount()); i++) {
|
||||
//qCDebug(dcUniPi()) << "Start Address:" << unit.startAddress() << "Register Type:" << unit.registerType() << "Value:" << unit.value(i);
|
||||
modbusAddress = unit.startAddress() + i;
|
||||
|
||||
switch (unit.registerType()) {
|
||||
case QModbusDataUnit::RegisterType::Coils:
|
||||
emit receivedCoil(reply->serverAddress(), modbusAddress, unit.value(i));
|
||||
break;
|
||||
case QModbusDataUnit::RegisterType::DiscreteInputs:
|
||||
emit receivedDiscreteInput(reply->serverAddress(), modbusAddress, unit.value(i));
|
||||
break;
|
||||
case QModbusDataUnit::RegisterType::InputRegisters:
|
||||
emit receivedInputRegister(reply->serverAddress(), modbusAddress, unit.value(i));
|
||||
break;
|
||||
case QModbusDataUnit::RegisterType::HoldingRegisters:
|
||||
emit receivedHoldingRegister(reply->serverAddress(), modbusAddress, unit.value(i));
|
||||
break;
|
||||
case QModbusDataUnit::RegisterType::Invalid:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (reply->error() == QModbusDevice::ProtocolError) {
|
||||
emit writeRequestFinished(requestId, false);
|
||||
qCWarning(dcDrexelUndWeiss()) << "Read response error:" << reply->errorString() << reply->rawResult().exceptionCode();
|
||||
} else {
|
||||
emit writeRequestFinished(requestId, false);
|
||||
qCWarning(dcDrexelUndWeiss()) << "Read response error:" << reply->error();
|
||||
}
|
||||
});
|
||||
connect(reply, &QModbusReply::errorOccurred, this, &ModbusRTUMaster::onReplyErrorOccured);
|
||||
QTimer::singleShot(200, reply, SLOT(deleteLater()));
|
||||
} else {
|
||||
delete reply; // broadcast replies return immediately
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcDrexelUndWeiss()) << "Read error: " << m_modbusRtuSerialMaster->errorString();
|
||||
}
|
||||
return requestId;
|
||||
}
|
||||
|
||||
bool ModbusRTUMaster::readDiscreteInput(int slaveAddress, int registerAddress)
|
||||
{
|
||||
if (!m_modbusRtuSerialMaster)
|
||||
return false;
|
||||
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::DiscreteInputs, registerAddress, 1);
|
||||
|
||||
if (QModbusReply *reply = m_modbusRtuSerialMaster->sendReadRequest(request, slaveAddress)) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, &ModbusRTUMaster::onReplyFinished);
|
||||
connect(reply, &QModbusReply::errorOccurred, this, &ModbusRTUMaster::onReplyErrorOccured);
|
||||
QTimer::singleShot(200, reply, SLOT(deleteLater()));
|
||||
} else {
|
||||
delete reply; // broadcast replies return immediately
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcDrexelUndWeiss()) << "Read error: " << m_modbusRtuSerialMaster->errorString();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModbusRTUMaster::readInputRegister(int slaveAddress, int registerAddress)
|
||||
{
|
||||
if (!m_modbusRtuSerialMaster)
|
||||
return false;
|
||||
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::InputRegisters, registerAddress, 1);
|
||||
|
||||
if (QModbusReply *reply = m_modbusRtuSerialMaster->sendReadRequest(request, slaveAddress)) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, &ModbusRTUMaster::onReplyFinished);
|
||||
connect(reply, &QModbusReply::errorOccurred, this, &ModbusRTUMaster::onReplyErrorOccured);
|
||||
QTimer::singleShot(200, reply, SLOT(deleteLater()));
|
||||
} else {
|
||||
delete reply; // broadcast replies return immediately
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcDrexelUndWeiss()) << "Read error: " << m_modbusRtuSerialMaster->errorString();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModbusRTUMaster::readHoldingRegister(int slaveAddress, int registerAddress)
|
||||
{
|
||||
if (!m_modbusRtuSerialMaster)
|
||||
return false;
|
||||
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, registerAddress, 1);
|
||||
|
||||
if (QModbusReply *reply = m_modbusRtuSerialMaster->sendReadRequest(request, slaveAddress)) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, &ModbusRTUMaster::onReplyFinished);
|
||||
connect(reply, &QModbusReply::errorOccurred, this, &ModbusRTUMaster::onReplyErrorOccured);
|
||||
QTimer::singleShot(200, reply, SLOT(deleteLater()));
|
||||
} else {
|
||||
delete reply; // broadcast replies return immediately
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcDrexelUndWeiss()) << "Read error: " << m_modbusRtuSerialMaster->errorString();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ModbusRTUMaster::onModbusErrorOccurred(QModbusDevice::Error error)
|
||||
{
|
||||
qCWarning(dcDrexelUndWeiss()) << "An error occured" << error;
|
||||
}
|
||||
|
||||
|
||||
void ModbusRTUMaster::onModbusStateChanged(QModbusDevice::State state)
|
||||
{
|
||||
bool connected = (state != QModbusDevice::UnconnectedState);
|
||||
if (!connected) {
|
||||
//try to reconnect in 10 seconds
|
||||
m_reconnectTimer->start(10000);
|
||||
}
|
||||
emit connectionStateChanged(connected);
|
||||
}
|
||||
78
drexelundweiss/modbusrtumaster.h
Normal file
78
drexelundweiss/modbusrtumaster.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 MODBUSRTUMASTER_H
|
||||
#define MODBUSRTUMASTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtSerialBus>
|
||||
#include <QSerialPort>
|
||||
#include <QTimer>
|
||||
#include <QUuid>
|
||||
|
||||
class ModbusRTUMaster : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ModbusRTUMaster(QString serialPort, int baudrate, QSerialPort::Parity parity, int dataBits, int stopBits, QObject *parent = nullptr);
|
||||
~ModbusRTUMaster();
|
||||
|
||||
bool connectDevice();
|
||||
|
||||
bool readCoil(int slaveAddress, int registerAddress);
|
||||
bool readDiscreteInput(int slaveAddress, int registerAddress);
|
||||
bool readInputRegister(int slaveAddress, int registerAddress);
|
||||
bool readHoldingRegister(int slaveAddress, int registerAddress);
|
||||
|
||||
QUuid writeCoil(int slaveAddress, int registerAddress, bool status);
|
||||
QUuid writeHoldingRegister(int slaveAddress, int registerAddress, int data);
|
||||
|
||||
QString serialPort();
|
||||
|
||||
private:
|
||||
QModbusRtuSerialMaster *m_modbusRtuSerialMaster;
|
||||
QTimer *m_reconnectTimer = nullptr;
|
||||
|
||||
private slots:
|
||||
void onReplyFinished();
|
||||
void onReplyErrorOccured(QModbusDevice::Error error);
|
||||
void onReconnectTimer();
|
||||
|
||||
void onModbusErrorOccurred(QModbusDevice::Error error);
|
||||
void onModbusStateChanged(QModbusDevice::State state);
|
||||
|
||||
signals:
|
||||
void connectionStateChanged(bool status);
|
||||
void receivedCoil(int slaveAddress, int modbusRegister, bool value);
|
||||
void receivedDiscreteInput(int slaveAddress, int modbusRegister, bool value);
|
||||
void receivedHoldingRegister(int slaveAddress, int modbusRegister, int value);
|
||||
void receivedInputRegister(int slaveAddress, int modbusRegister, int value);
|
||||
|
||||
void writeRequestFinished(QUuid requestId, bool success);
|
||||
};
|
||||
|
||||
#endif // MODBUSRTUMASTER_H
|
||||
@ -0,0 +1 @@
|
||||
<クdハ<>箆!ソ`。スン
|
||||
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1">
|
||||
</TS>
|
||||
45
nymea-plugins-modbus.pro
Normal file
45
nymea-plugins-modbus.pro
Normal file
@ -0,0 +1,45 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
PLUGIN_DIRS = \
|
||||
drexelundweiss \
|
||||
|
||||
|
||||
message(============================================)
|
||||
message("Qt version:" $$[QT_VERSION])
|
||||
|
||||
plugininfo.depends = FORCE
|
||||
for (entry, PLUGIN_DIRS):plugininfo.commands += test -d $${entry} || mkdir -p $${entry}; cd $${entry} && qmake -o Makefile $$PWD/$${entry}/$${entry}.pro && cd ..;
|
||||
for (entry, PLUGIN_DIRS):plugininfo.commands += make -C $${entry} plugininfo.h;
|
||||
QMAKE_EXTRA_TARGETS += plugininfo
|
||||
|
||||
# Translations:
|
||||
# make lupdate to update .ts files
|
||||
lupdate.depends = FORCE plugininfo
|
||||
for (entry, PLUGIN_DIRS):lupdate.commands += make -C $${entry} lupdate;
|
||||
QMAKE_EXTRA_TARGETS += lupdate
|
||||
|
||||
# make lrelease to build .qm from .ts
|
||||
lrelease.depends = FORCE
|
||||
for (entry, PLUGIN_DIRS):lrelease.commands += lrelease $$files($$PWD/$${entry}/translations/*.ts, true);
|
||||
for (entry, PLUGIN_DIRS):lrelease.commands += rsync -a $$PWD/$${entry}/translations/*.qm $$OUT_PWD/translations/;
|
||||
QMAKE_EXTRA_TARGETS += lrelease
|
||||
|
||||
# For Qt-Creator's code model: Add CPATH to INCLUDEPATH explicitly
|
||||
INCLUDEPATH += $$(CPATH)
|
||||
|
||||
# Verify if building only a selection of plugins
|
||||
contains(CONFIG, selection) {
|
||||
# Check each plugin if the subdir exists
|
||||
for(plugin, PLUGINS) {
|
||||
contains(PLUGIN_DIRS, $${plugin}) {
|
||||
SUBDIRS*= $${plugin}
|
||||
} else {
|
||||
error("Invalid plugin passed. There is no subdirectory with the name $${plugin}.")
|
||||
}
|
||||
}
|
||||
message("Building plugin selection: $${SUBDIRS}")
|
||||
} else {
|
||||
SUBDIRS *= $${PLUGIN_DIRS}
|
||||
message("Building all plugins")
|
||||
}
|
||||
|
||||
17
plugins.pri
Normal file
17
plugins.pri
Normal file
@ -0,0 +1,17 @@
|
||||
isEmpty(PLUGIN_PRI) {
|
||||
exists($$[QT_INSTALL_PREFIX]/include/nymea/plugin.pri) {
|
||||
include($$[QT_INSTALL_PREFIX]/include/nymea/plugin.pri)
|
||||
} else {
|
||||
message("plugin.pri not found. Either install libnymea1-dev or use the PLUGIN_PRI argument to point to it.")
|
||||
message("For building this project without nymea installed system-wide, you will want to export those variables in addition:")
|
||||
message("PKG_CONFIG_PATH=/path/to/build-nymea/libnymea/pkgconfig/")
|
||||
message("CPATH=/path/to/nymea/libnymea/")
|
||||
message("LIBRARY_PATH=/path/to/build-nymea/libnymea/")
|
||||
message("PATH=/path/to/build-nymea/tools/nymea-plugininfocompiler:$PATH")
|
||||
message("LD_LIBRARY_PATH=/path/to/build-nymea/libnymea/")
|
||||
error("plugin.pri not found. Cannot continue")
|
||||
}
|
||||
} else {
|
||||
# message("Using $$PLUGIN_PRI")
|
||||
include($$PLUGIN_PRI)
|
||||
}
|
||||
Reference in New Issue
Block a user