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