diff --git a/ebus/__init__.py b/ebus/__init__.py
index e4e4539b0..081300bf8 100755
--- a/ebus/__init__.py
+++ b/ebus/__init__.py
@@ -4,22 +4,23 @@
# Copyright 2018- Martin Sinn m.sinn@gmx.de
# Copyright 2012-2013 KNX-User-Forum e.V. http://knx-user-forum.de/
#########################################################################
-# This file is part of SmartHomeNG.py.
-# Visit: https://github.com/smarthomeNG/
-# https://knx-user-forum.de/forum/supportforen/smarthome-py
+# This file is part of SmartHomeNG.
+# https://www.smarthomeNG.de
+# https://knx-user-forum.de/forum/supportforen/smarthome-py
#
-# SmartHomeNG.py is free software: you can redistribute it and/or modify
+# SmartHomeNG is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
-# SmartHomeNG.py is distributed in the hope that it will be useful,
+# SmartHomeNG 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with SmartHomeNG.py. If not, see .
+# along with SmartHomeNG. If not, see .
+#
#########################################################################
import logging
@@ -36,7 +37,7 @@ class eBus(SmartPlugin):
the update functions for the items
"""
- PLUGIN_VERSION = '1.5.1'
+ PLUGIN_VERSION = '1.6.0'
_items = []
@@ -58,6 +59,9 @@ def __init__(self, sh, *args, **kwargs):
returns the value in the datatype that is defined in the metadata.
"""
+ # Call init code of parent class (SmartPlugin)
+ super().__init__()
+
logger = logging.getLogger(__name__) # remove for shNG v1.6
self.host = self.get_parameter_value('host')
self.port = self.get_parameter_value('port')
@@ -95,7 +99,7 @@ def run(self):
"""
self.logger.debug("Run method called".format(self.get_fullname()))
self.alive = True
- self.scheduler_add('eBusd', self.refresh, prio=5, cycle=self._cycle, offset=2)
+ self.scheduler_add(self.get_fullname(), self.refresh, prio=5, cycle=self._cycle, offset=2)
def refresh(self):
@@ -113,7 +117,7 @@ def refresh(self):
value = self.request(request)
#if reading fails (i.e. at broadcast-commands) the value will not be updated
if 'command not found' not in str(value) and value is not None:
- item(value, 'eBus', 'refresh')
+ item(value, self.get_fullname(), 'refresh')
if not self.alive:
break
@@ -126,8 +130,13 @@ def request(self, request):
:type request: str
"""
if not self.connected:
- self.logger.info("eBusd not connected")
+ self.logger.info("eBusd not connected, try to connect")
+ self.connect()
+
+ if not self.connected:
+ self.logger.info("eBusd not connected, giving up")
return
+
self._lock.acquire()
try:
self._sock.send(request.encode())
@@ -165,7 +174,7 @@ def connect(self):
except Exception as e:
self._connection_attempts -= 1
if self._connection_attempts <= 0:
- self.logger.error('eBus: could not connect to ebusd at {0}:{1}: {2}'.format(self.host, self.port, e))
+ self.logger.error('eBus: could not connect to ebusd at {0}:{1}: {2}'.format(self.host, self.port, e))
self._connection_attempts = self._connection_errorlog
self._lock.release()
return
@@ -198,6 +207,7 @@ def stop(self):
"""
self.logger.debug("Stop method called".format(self.get_fullname()))
self.close()
+ self.scheduler_remove(self.get_fullname())
self.alive = False
@@ -209,7 +219,7 @@ def update_item(self, item, caller=None, source=None, dest=None):
:param source: if given it represents the source
:param dest: if given it represents the dest
"""
- if caller != 'eBus':
+ if caller != self.get_fullname():
value = str(int(item()))
cmd = item.conf['ebus_cmd']
request = "write -c " + cmd + " " + value + "\n"
diff --git a/ebus/README.md.old b/ebus/_pv_1_5_1/README.md
old mode 100755
new mode 100644
similarity index 100%
rename from ebus/README.md.old
rename to ebus/_pv_1_5_1/README.md
diff --git a/ebus/_pv_1_5_1/__init__.py b/ebus/_pv_1_5_1/__init__.py
new file mode 100644
index 000000000..e4e4539b0
--- /dev/null
+++ b/ebus/_pv_1_5_1/__init__.py
@@ -0,0 +1,223 @@
+#!/usr/bin/env python3
+# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
+#########################################################################
+# Copyright 2018- Martin Sinn m.sinn@gmx.de
+# Copyright 2012-2013 KNX-User-Forum e.V. http://knx-user-forum.de/
+#########################################################################
+# This file is part of SmartHomeNG.py.
+# Visit: https://github.com/smarthomeNG/
+# https://knx-user-forum.de/forum/supportforen/smarthome-py
+#
+# SmartHomeNG.py is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SmartHomeNG.py 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SmartHomeNG.py. If not, see .
+#########################################################################
+
+import logging
+import socket
+import threading
+import time
+
+from lib.model.smartplugin import *
+
+
+class eBus(SmartPlugin):
+ """
+ Main class of the Plugin. Does all plugin specific stuff and provides
+ the update functions for the items
+ """
+
+ PLUGIN_VERSION = '1.5.1'
+
+ _items = []
+
+ def __init__(self, sh, *args, **kwargs):
+ """
+ Initalizes the plugin. The parameters descriptions for this method are pulled from the entry in plugin.yaml.
+
+ :param sh: **Deprecated**: The instance of the smarthome object. For SmartHomeNG versions **beyond** 1.3: **Don't use it**!
+ :param *args: **Deprecated**: Old way of passing parameter values. For SmartHomeNG versions **beyond** 1.3: **Don't use it**!
+ :param **kwargs:**Deprecated**: Old way of passing parameter values. For SmartHomeNG versions **beyond** 1.3: **Don't use it**!
+
+ If you need the sh object at all, use the method self.get_sh() to get it. There should be almost no need for
+ a reference to the sh object any more.
+
+ The parameters *args and **kwargs are the old way of passing parameters. They are deprecated. They are imlemented
+ to support older plugins. Plugins for SmartHomeNG v1.4 and beyond should use the new way of getting parameter values:
+ use the SmartPlugin method get_parameter_value(parameter_name) instead. Anywhere within the Plugin you can get
+ the configured (and checked) value for a parameter by calling self.get_parameter_value(parameter_name). It
+ returns the value in the datatype that is defined in the metadata.
+ """
+
+ logger = logging.getLogger(__name__) # remove for shNG v1.6
+ self.host = self.get_parameter_value('host')
+ self.port = self.get_parameter_value('port')
+ self._cycle = self.get_parameter_value('cycle')
+
+ self._sock = False
+ self.connected = False
+ self._connection_attempts = 0
+ self._connection_errorlog = 60
+ self._lock = threading.Lock()
+ # self.refresh_cycle = self._cycle # not used
+
+
+ def parse_item(self, item):
+ """
+ Default plugin parse_item method. Is called when the plugin is initialized.
+ The plugin can, corresponding to its attribute keywords, decide what to do with
+ the item in future, like adding it to an internal array for future reference
+ :param item: The item to process.
+ :return: If the plugin needs to be informed of an items change you should return a call back function
+ like the function update_item down below. An example when this is needed is the knx plugin
+ where parse_item returns the update_item function when the attribute knx_send is found.
+ This means that when the items value is about to be updated, the call back function is called
+ with the item, caller, source and dest as arguments and in case of the knx plugin the value
+ can be sent to the knx with a knx write function within the knx plugin.
+ """
+ if 'ebus_type' in item.conf and 'ebus_cmd' in item.conf:
+ self._items.append(item)
+ return self.update_item
+
+
+ def run(self):
+ """
+ Run method for the plugin
+ """
+ self.logger.debug("Run method called".format(self.get_fullname()))
+ self.alive = True
+ self.scheduler_add('eBusd', self.refresh, prio=5, cycle=self._cycle, offset=2)
+
+
+ def refresh(self):
+ """
+ Refresh items with data from ebusd
+ """
+ for item in self._items:
+ time.sleep(1)
+ ebus_type = item.conf['ebus_type']
+ ebus_cmd = item.conf['ebus_cmd']
+ if ebus_cmd == "cycle":
+ request = ebus_type + " " + ebus_cmd + "\n" # build command
+ else:
+ request = "read" + " -c " + ebus_cmd + "\n" # build command
+ value = self.request(request)
+ #if reading fails (i.e. at broadcast-commands) the value will not be updated
+ if 'command not found' not in str(value) and value is not None:
+ item(value, 'eBus', 'refresh')
+ if not self.alive:
+ break
+
+
+ def request(self, request):
+ """
+ send request to ebusd deamon
+
+ :param request: Command to send to ebusd
+ :type request: str
+ """
+ if not self.connected:
+ self.logger.info("eBusd not connected")
+ return
+ self._lock.acquire()
+ try:
+ self._sock.send(request.encode())
+ self.logger.debug("REQUEST: {0}".format(request))
+ except Exception as e:
+ self._lock.release()
+ self.close()
+ self.logger.warning("error sending request: {0} => {1}".format(request, e))
+ return
+ try:
+ answer = self._sock.recv(256).decode()[:-2]
+ self.logger.debug("ANSWER: {0}".format(answer))
+ except socket.timeout:
+ self._lock.release()
+ self.logger.warning("error receiving answer: timeout")
+ return
+ except Exception as e:
+ self._lock.release()
+ self.close()
+ self.logger.warning("error receiving answer: {0}".format(e))
+ return
+ self._lock.release()
+ return answer
+
+
+ def connect(self):
+ """
+ Open socket connection to ebusd deamon
+ """
+ self._lock.acquire()
+ try:
+ self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self._sock.settimeout(2)
+ self._sock.connect((self.host, self.port))
+ except Exception as e:
+ self._connection_attempts -= 1
+ if self._connection_attempts <= 0:
+ self.logger.error('eBus: could not connect to ebusd at {0}:{1}: {2}'.format(self.host, self.port, e))
+ self._connection_attempts = self._connection_errorlog
+ self._lock.release()
+ return
+ self.logger.info('Connected to {0}:{1}'.format(self.host, self.port))
+ self.connected = True
+ self._connection_attempts = 0
+ self._lock.release()
+
+
+ def close(self):
+ """
+ Close socket connection
+ """
+ self.connected = False
+ try:
+ self._sock.shutdown(socket.SHUT_RDWR)
+ except:
+ pass
+ try:
+ self._sock.close()
+ self._sock = False
+ self.logger.info('Connection closed to {0}:{1}'.format(self.host, self.port))
+ except:
+ pass
+
+
+ def stop(self):
+ """
+ Stop method for the plugin
+ """
+ self.logger.debug("Stop method called".format(self.get_fullname()))
+ self.close()
+ self.alive = False
+
+
+ def update_item(self, item, caller=None, source=None, dest=None):
+ """
+ Write items values
+ :param item: item to be updated towards the plugin
+ :param caller: if given it represents the callers name
+ :param source: if given it represents the source
+ :param dest: if given it represents the dest
+ """
+ if caller != 'eBus':
+ value = str(int(item()))
+ cmd = item.conf['ebus_cmd']
+ request = "write -c " + cmd + " " + value + "\n"
+ set_answer = self.request(request)
+ #just check if set was no broadcast-message
+ if 'broadcast done' not in set_answer:
+ request = "read -c " + cmd + "\n"
+ answer = self.request(request)
+ #transfer value and answer to float for better comparsion
+ if float(answer) != float(value) or answer is None:
+ self.logger.warning("Failed to set parameter: value: {0} cmd: {1} answer {2}".format(value, request, answer))
diff --git a/ebus/_pv_1_5_1/plugin.yaml b/ebus/_pv_1_5_1/plugin.yaml
new file mode 100644
index 000000000..dbe420e78
--- /dev/null
+++ b/ebus/_pv_1_5_1/plugin.yaml
@@ -0,0 +1,79 @@
+# Metadata for the classic-plugin
+plugin:
+ # Global plugin attributes
+ type: interface # plugin type (gateway, interface, protocol, system, web)
+ description:
+ de: 'Unterstützt eBus Heizungen (z.B. Vailant, Wolf, Kromschroeder) - Dieses Plugin verbindet sich zu einem ebusd Deamon (http://www.cometvisu.de/wiki/Ebusd), welcher mit einer eBus Heizung kommuniziert. Voraussetzungen: Ein ebusd Deamon läuft auf dem Netzwerk. (Anmerkung: Der ebusd benötigt ein ebus-Interface um mit ihm zu kommunizieren.'
+ en: 'Supports eBus heating systems (e.g. Vailant, Wolf, Kromschroeder) - The plugin connects to a ebusd damon (http://www.cometvisu.de/wiki/Ebusd) which is communicating with eBus heatings. Requirements: running ebusd deamon on the network (note: ebusd also requires an ebus-interface)'
+ maintainer: '? (msinn)'
+ tester: Sandman60
+ state: ready
+# keywords: kwd1 kwd2 # keywords, where applicable
+# documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md # url of documentation (wiki) page
+# support: https://knx-user-forum.de/forum/supportforen/smarthome-py
+
+# Following entries are for Smart-Plugins:
+ version: 1.5.1 # Plugin version
+ sh_minversion: 1.5 # minimum shNG version to use this plugin
+ #sh_maxversion: # maximum shNG version to use this plugin (leave empty if latest)
+ multi_instance: False
+ restartable: unknown
+ classname: eBus # class containing the plugin
+
+
+parameters:
+ # Definition of parameters to be configured in etc/plugin.yaml
+
+ host:
+ type: ip
+ default: 127.0.0.1
+ description:
+ de: 'IP Adresse des ebusd Deamons'
+ en: 'ip address of ebusd deamon'
+
+ port:
+ type: int
+ valid_min: 0
+ default: 8888
+ description:
+ de: 'Port auf dem der ebusd Deamon lauscht'
+ en: 'port of ebusd deamon'
+
+ cycle:
+ type: int
+ valid_min: 0
+ default: 240
+ description:
+ de: 'Cycle Zeit zur Abfrage jedes Items'
+ en: 'cycle of each item'
+
+item_attributes:
+ # Definition of item attributes defined by this plugin
+
+ ebus_cmd:
+ type: str
+ description:
+ de: "ebus_cmd ist das Kommando, welches durch die Telnet Verbindung zum ebusd übertragen wird - z.B. 'cir2 heat_pump_curr', 'mv yield_sum' or 'short hw_load'"
+ en: "ebus_cmd is the command you use though the telnet-connection to ebusd - e.g. 'cir2 heat_pump_curr', 'mv yield_sum' or 'short hw_load'"
+
+ ebus_type:
+ type: str
+ default: 'get'
+ valid_list: ['get', 'set']
+ valid_list_description:
+ de: ['get', 'set']
+ en: ['Items will only be readable, i.e. sensors', 'Items are read/write. All "set"-items will be read cyclic too!']
+ description:
+ de: 'ebus_type legt fest, ob vom ebusd Deamon nur gelesen werden soll oder ob auch Daten an ebusd übertragen werden sollen.'
+ en: 'ebus_type determins, if data should only be read from the ebusd deamon or if data should be written to ebusd too.'
+
+
+item_structs: NONE
+ # Definition of item-structure templates for this plugin
+
+logic_parameters: NONE
+ # Definition of logic parameters defined by this plugin
+
+plugin_functions: NONE
+ # Definition of function interface of the plugin
+
diff --git a/ebus/plugin.yaml b/ebus/plugin.yaml
index 9519b28b0..1cc5e581e 100755
--- a/ebus/plugin.yaml
+++ b/ebus/plugin.yaml
@@ -3,17 +3,24 @@ plugin:
# Global plugin attributes
type: interface # plugin type (gateway, interface, protocol, system, web)
description:
- de: 'Unterstützt eBus Heizungen (z.B. Vailant, Wolf, Kromschroeder) - Dieses Plugin verbindet sich zu einem ebusd Deamon (http://www.cometvisu.de/wiki/Ebusd), welcher mit einer eBus Heizung kommuniziert. Voraussetzungen: Ein ebusd Deamon läuft auf dem Netzwerk. (Anmerkung: Der ebusd benötigt ein ebus-Interface um mit ihm zu kommunizieren.'
- en: 'Supports eBus heating systems (e.g. Vailant, Wolf, Kromschroeder) - The plugin connects to a ebusd damon (http://www.cometvisu.de/wiki/Ebusd) which is communicating with eBus heatings. Requirements: running ebusd deamon on the network (note: ebusd also requires an ebus-interface)'
+ de: >
+ Unterstützt eBus Heizungen (z.B. Vailant, Wolf, Kromschroeder)
+ Dieses Plugin verbindet sich zu einem ebusd Deamon (https://ebusd.de/),
+ welcher mit einer eBus Heizung kommuniziert.
+ Voraussetzungen: Ein ebusd Deamon läuft auf dem Netzwerk.
+ Anmerkung: Der ebusd benötigt ein ebus-Interface um mit ihm zu kommunizieren.
+ en: >
+ Supports eBus heating systems (e.g. Vailant, Wolf, Kromschroeder)
+ The plugin connects to a ebusd damon (https://ebusd.de/)
+ which is communicating with eBus heatings.
+ Requirements: running ebusd deamon on the network (note: ebusd also requires an ebus-interface)'
maintainer: '? (msinn)'
- tester: Sandman60
+ tester: android, z1marco
state: ready
-# keywords: kwd1 kwd2 # keywords, where applicable
-# documentation: https://github.com/smarthomeNG/plugins/blob/develop/mqtt/README.md # url of documentation (wiki) page
-# support: https://knx-user-forum.de/forum/supportforen/smarthome-py
+ support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1925957
# Following entries are for Smart-Plugins:
- version: 1.5.0 # Plugin version
+ version: 1.6.0 # Plugin version
sh_minversion: 1.5 # minimum shNG version to use this plugin
#sh_maxversion: # maximum shNG version to use this plugin (leave empty if latest)
multi_instance: False
diff --git a/ebus/user_doc.rst b/ebus/user_doc.rst
new file mode 100644
index 000000000..73ec8d1d1
--- /dev/null
+++ b/ebus/user_doc.rst
@@ -0,0 +1,99 @@
+.. index:: Plugins; ebus
+.. index:: ebus
+
+
+====
+ebus
+====
+
+Dieses Plugin verbindet sich zu einem ebus daemon und kann über diesen mit Geräten mit eBus Schnittstellen kommunizieren.
+
+Anforderungen
+=============
+
+Eine ebus Schnittstelle
+
+Notwendige Software
+-------------------
+
+Ein konfigurierter und funktionierender ebus Daemon der im Netzwerk erreichbar ist.
+
+Unterstützte Geräte
+-------------------
+
+Beispielsweise Geräte von Vaillant, Wolf, Kromschroeder und andere die über eine ebus Schnittstelle kommunizieren können.
+
+
+Konfiguration
+=============
+
+Die Plugin Parameter und die Informationen zur Item-spezifischen Konfiguration des Plugins sind
+unter :doc:`/plugins_doc/config/ebus` beschrieben.
+
+
+plugin.yaml
+-----------
+
+Zu den Informationen, welche Parameter in der ../etc/plugin.yaml konfiguriert werden können bzw. müssen, bitte
+bitte die Dokumentation :doc:`Dokumentation ` lesen, die aus
+den Metadaten der plugin.yaml erzeugt wurde (siehe oben).
+
+items.yaml
+----------
+
+Zu den Informationen, welche Attribute in der Item Konfiguration verwendet werden können bzw. müssen, bitte
+bitte die Dokumentation :doc:`Dokumentation ` lesen, die aus
+den Metadaten der plugin.yaml erzeugt wurde (siehe oben).
+
+logic.yaml
+----------
+
+Zu den Informationen, welche Konfigurationsmöglichkeiten für Logiken bestehen, bitte
+bitte die Dokumentation :doc:`Dokumentation ` lesen, die aus
+den Metadaten der plugin.yaml erzeugt wurde (siehe oben).
+
+Funktionen
+----------
+
+Zu den Informationen, welche Funktionen das Plugin bereitstellt (z.B. zur Nutzung in Logiken), bitte
+bitte die Dokumentation :doc:`Dokumentation ` lesen, die aus
+den Metadaten der plugin.yaml erzeugt wurde (siehe oben).
+
+Beispiele
+=========
+
+.. code:: yaml
+
+ ebus_geraet:
+
+ hk_pumpe_perc:
+ type: num
+ knx_dpt: 5
+ knx_send: 8/6/110
+ knx_reply: 8/6/110
+ ebus_cmd: cir2 heat_pump_curr
+ ebus_type: get
+ # akt. PWM-Wert Heizkreizpumpe
+
+ ernergie_summe:
+ type: num
+ knx_dpt: 12
+ knx_send: 8/6/22
+ knx_reply: 8/6/22
+ ebus_cmd: mv yield_sum
+ ebus_type: get
+ # Energieertrag
+
+ speicherladung:
+ type: bool
+ knx_dpt: 1
+ knx_listen: 8/7/1
+ ebus_cmd: short hw_load
+ ebus_type: set
+ # Quick - WW Speicherladung
+
+
+Web Interface
+=============
+
+Das Plugin hat derzeit kein Web Interface
\ No newline at end of file