mirror of
https://github.com/naruxde/revpipyload.git
synced 2025-11-08 15:13:52 +01:00
IOs des Core als einzelne Werte behandeln
Topic base/get/ioname sendet den angegebenen IO sofort per MQTT base/got/ioname Topic base/get sendet Zyklische Daten sofort Funktion SaveXMLRPCServer.isAlive in SaveXMLRPCServer.is_alive() umbenannt MqttServer läd RevPiModIO sofort neu bei reload_revpimodio sendinterval=0 deaktiviert zyklische Übertragung
This commit is contained in:
@@ -101,7 +101,7 @@ Init MqttServer class.
|
||||
Basis-Topic fuer Datenaustausch
|
||||
</dd><dt><i>sendinterval</i></dt>
|
||||
<dd>
|
||||
Prozessabbild alle n Sekunden senden
|
||||
Prozessabbild alle n Sekunden senden / 0 = aus
|
||||
</dd><dt><i>broker_address</i></dt>
|
||||
<dd>
|
||||
Adresse <class 'str'> des MQTT-Servers
|
||||
@@ -130,7 +130,7 @@ Per MQTT auch Outputs schreiben
|
||||
</dl><a NAME="MqttServer._evt_io" ID="MqttServer._evt_io"></a>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
MqttServer._evt_io</h3>
|
||||
<b>_evt_io</b>(<i>name, value</i>)
|
||||
<b>_evt_io</b>(<i>name, value, requested=False</i>)
|
||||
<p>
|
||||
Sendet Daten aus Events.
|
||||
</p><dl>
|
||||
@@ -140,6 +140,9 @@ IO-Name
|
||||
</dd><dt><i>value</i></dt>
|
||||
<dd>
|
||||
IO-Value
|
||||
</dd><dt><i>requested</i></dt>
|
||||
<dd>
|
||||
Wenn True, wird 'got' Topic verwendet
|
||||
</dd>
|
||||
</dl><a NAME="MqttServer._loadrevpimodio" ID="MqttServer._loadrevpimodio"></a>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
|
||||
@@ -104,7 +104,7 @@ Methods</h3>
|
||||
<td><a style="color:#0000FF" href="#SaveXMLRPCServer._dispatch">_dispatch</a></td>
|
||||
<td>Prueft ACL Level fuer angeforderte Methode.</td>
|
||||
</tr><tr>
|
||||
<td><a style="color:#0000FF" href="#SaveXMLRPCServer.isAlive">isAlive</a></td>
|
||||
<td><a style="color:#0000FF" href="#SaveXMLRPCServer.is_alive">is_alive</a></td>
|
||||
<td>Prueft ob der XML RPC Server laeuft.</td>
|
||||
</tr><tr>
|
||||
<td><a style="color:#0000FF" href="#SaveXMLRPCServer.register_function">register_function</a></td>
|
||||
@@ -152,10 +152,10 @@ Argumente fuer Methode
|
||||
<dd>
|
||||
Dispatched data
|
||||
</dd>
|
||||
</dl><a NAME="SaveXMLRPCServer.isAlive" ID="SaveXMLRPCServer.isAlive"></a>
|
||||
</dl><a NAME="SaveXMLRPCServer.is_alive" ID="SaveXMLRPCServer.is_alive"></a>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
SaveXMLRPCServer.isAlive</h3>
|
||||
<b>isAlive</b>(<i></i>)
|
||||
SaveXMLRPCServer.is_alive</h3>
|
||||
<b>is_alive</b>(<i></i>)
|
||||
<p>
|
||||
Prueft ob der XML RPC Server laeuft.
|
||||
</p><dl>
|
||||
|
||||
@@ -18,7 +18,7 @@ logsystem.PipeLogwriter?1(logfilename)
|
||||
logsystem.__author__?9
|
||||
logsystem.__copyright__?9
|
||||
logsystem.__license__?9
|
||||
mqttserver.MqttServer._evt_io?5(name, value)
|
||||
mqttserver.MqttServer._evt_io?5(name, value, requested=False)
|
||||
mqttserver.MqttServer._loadrevpimodio?5()
|
||||
mqttserver.MqttServer._on_connect?5(client, userdata, flags, rc)
|
||||
mqttserver.MqttServer._on_disconnect?5(client, userdata, rc)
|
||||
@@ -149,7 +149,7 @@ revpipyload.shared.ipaclmanager.__version__?9
|
||||
revpipyload.shared.ipaclmanager.refullmatch?4(regex, string)
|
||||
xrpcserver.SaveXMLRPCRequestHandler.parse_request?4()
|
||||
xrpcserver.SaveXMLRPCServer._dispatch?5(method, params)
|
||||
xrpcserver.SaveXMLRPCServer.isAlive?4()
|
||||
xrpcserver.SaveXMLRPCServer.is_alive?4()
|
||||
xrpcserver.SaveXMLRPCServer.register_function?4(acl_level, function, name=None)
|
||||
xrpcserver.SaveXMLRPCServer.start?4()
|
||||
xrpcserver.SaveXMLRPCServer.stop?4()
|
||||
|
||||
@@ -22,7 +22,7 @@ class MqttServer(Thread):
|
||||
"""Init MqttServer class.
|
||||
|
||||
@param basetopic Basis-Topic fuer Datenaustausch
|
||||
@param sendinterval Prozessabbild alle n Sekunden senden
|
||||
@param sendinterval Prozessabbild alle n Sekunden senden / 0 = aus
|
||||
@param broker_address Adresse <class 'str'> des MQTT-Servers
|
||||
@param port Portnummer <class 'int'> des MQTT-Servers
|
||||
@param tls_set TLS fuer Verbindung zum MQTT-Server verwenden
|
||||
@@ -35,9 +35,9 @@ class MqttServer(Thread):
|
||||
"""
|
||||
if not isinstance(basetopic, str):
|
||||
raise ValueError("parameter topic must be <class 'str'>")
|
||||
if not (isinstance(sendinterval, int) and sendinterval > 0):
|
||||
if not (isinstance(sendinterval, int) and sendinterval >= 0):
|
||||
raise ValueError(
|
||||
"parameter sendinterval must be <class 'int'> and > 0"
|
||||
"parameter sendinterval must be <class 'int'> and >= 0"
|
||||
)
|
||||
if not (isinstance(broker_address, str) and broker_address != ""):
|
||||
raise ValueError(
|
||||
@@ -80,9 +80,12 @@ class MqttServer(Thread):
|
||||
|
||||
# Topics konfigurieren
|
||||
self._mqtt_evt_io = join(basetopic, "event/{0}")
|
||||
self._mqtt_got_io = join(basetopic, "got/{0}")
|
||||
self._mqtt_io = join(basetopic, "io/{0}")
|
||||
self._mqtt_ioget = join(basetopic, "get/#")
|
||||
self._mqtt_ioset = join(basetopic, "set/#")
|
||||
self._mqtt_pictory = join(basetopic, "pictory")
|
||||
self._mqtt_senddata = join(basetopic, "get")
|
||||
self._mqtt_sendpictory = join(basetopic, "needpictory")
|
||||
|
||||
self._mq = Client(client_id)
|
||||
@@ -96,13 +99,22 @@ class MqttServer(Thread):
|
||||
self._mq.on_connect = self._on_connect
|
||||
self._mq.on_message = self._on_message
|
||||
|
||||
def _evt_io(self, name, value):
|
||||
def _evt_io(self, name, value, requested=False):
|
||||
"""Sendet Daten aus Events.
|
||||
|
||||
@param name IO-Name
|
||||
@param value IO-Value"""
|
||||
@param value IO-Value
|
||||
@param requested Wenn True, wird 'got' Topic verwendet
|
||||
|
||||
"""
|
||||
if requested:
|
||||
topic = self._mqtt_got_io.format(name)
|
||||
else:
|
||||
topic = self._mqtt_evt_io.format(name)
|
||||
|
||||
if isinstance(value, bytes):
|
||||
value = int.from_bytes(value, "little")
|
||||
self._mq.publish(self._mqtt_evt_io.format(name), int(value))
|
||||
self._mq.publish(topic, int(value))
|
||||
|
||||
def _loadrevpimodio(self):
|
||||
"""Instantiiert das RevPiModIO Modul.
|
||||
@@ -147,6 +159,26 @@ class MqttServer(Thread):
|
||||
io.reg_event(self._evt_io)
|
||||
self._exported_ios.append(io)
|
||||
|
||||
# RevPiLED Ausgang zerlegen und exportieren
|
||||
if self._rpi.core._ioled.export:
|
||||
lst_coreio = [
|
||||
self._rpi.core.a1green, self._rpi.core.a1red,
|
||||
self._rpi.core.a2green, self._rpi.core.a2red,
|
||||
]
|
||||
|
||||
# Connect-IOs anhängen
|
||||
if type(self._rpi.core) == revpimodio2.device.Connect:
|
||||
lst_coreio += [
|
||||
self._rpi.core.a3green, self._rpi.core.a3red,
|
||||
self._rpi.core.wd,
|
||||
self._rpi.core.x2in, self._rpi.core.x2out,
|
||||
]
|
||||
|
||||
# Events registrieren
|
||||
for io in lst_coreio:
|
||||
io.reg_event(self._evt_io)
|
||||
self._exported_ios.append(io)
|
||||
|
||||
proginit.logger.debug("created revpimodio2 object")
|
||||
|
||||
def _on_connect(self, client, userdata, flags, rc):
|
||||
@@ -158,6 +190,8 @@ class MqttServer(Thread):
|
||||
)
|
||||
else:
|
||||
# Subscribe piCtory Anforderung
|
||||
client.subscribe(self._mqtt_ioget)
|
||||
client.subscribe(self._mqtt_senddata)
|
||||
client.subscribe(self._mqtt_sendpictory)
|
||||
if self._write_outputs:
|
||||
client.subscribe(self._mqtt_ioset)
|
||||
@@ -176,11 +210,32 @@ class MqttServer(Thread):
|
||||
# piCtory Konfiguration senden
|
||||
self._send_pictory_conf()
|
||||
|
||||
elif msg.topic == self._mqtt_senddata:
|
||||
# Alle zyklischen Daten senden
|
||||
self._evt_data.set()
|
||||
|
||||
else:
|
||||
lst_topic = msg.topic.split("/")
|
||||
if len(lst_topic) < 2:
|
||||
proginit.logger.info(
|
||||
"wrong topic format - need ./get/ioname or ./set/ioname"
|
||||
)
|
||||
return
|
||||
|
||||
# Aktion und IO auswerten
|
||||
ioget = lst_topic[-2].lower() == "get"
|
||||
ioset = lst_topic[-2].lower() == "set"
|
||||
ioname = lst_topic[-1]
|
||||
coreio = ioname.find(".") != -1
|
||||
|
||||
try:
|
||||
# IO holen
|
||||
if coreio:
|
||||
coreio = ioname.split(".")[-1]
|
||||
io = getattr(self._rpi_write.core, coreio)
|
||||
if not isinstance(io, revpimodio2.io.IOBase):
|
||||
raise RuntimeError()
|
||||
else:
|
||||
io = self._rpi_write.io[ioname]
|
||||
io_needbytes = type(io.value) == bytes
|
||||
except Exception:
|
||||
@@ -189,17 +244,28 @@ class MqttServer(Thread):
|
||||
)
|
||||
return
|
||||
|
||||
# Check Output exists and is an Output
|
||||
if io.type != revpimodio2.OUT:
|
||||
proginit.logger.error(
|
||||
"can not write to inputs with MQTT"
|
||||
)
|
||||
elif not io.export:
|
||||
# Aktion verarbeiten
|
||||
if not io.export:
|
||||
proginit.logger.error(
|
||||
"io '{0}' is not marked as export in piCtory for MQTT use"
|
||||
"".format(ioname)
|
||||
)
|
||||
|
||||
elif ioget:
|
||||
# Daten je nach IO Type aus Prozessabbild laden
|
||||
if io.type == revpimodio2.OUT:
|
||||
io._parentdevice.syncoutputs()
|
||||
else:
|
||||
io._parentdevice.readprocimg()
|
||||
|
||||
# Publish Wert von IO
|
||||
self._evt_io(io.name, io.value, requested=True)
|
||||
|
||||
elif ioset and io.type != revpimodio2.OUT:
|
||||
proginit.logger.error(
|
||||
"can not write to inputs with MQTT"
|
||||
)
|
||||
elif ioset:
|
||||
|
||||
# Convert MQTT Payload to valid Output-Value
|
||||
value = msg.payload.decode("utf8")
|
||||
@@ -241,6 +307,12 @@ class MqttServer(Thread):
|
||||
else:
|
||||
io._parentdevice.writeprocimg()
|
||||
|
||||
else:
|
||||
# Aktion nicht erkennbar
|
||||
proginit.logger.warning(
|
||||
"can not see get/set in topic '{0}'".format(msg.topic)
|
||||
)
|
||||
|
||||
def _send_pictory_conf(self):
|
||||
"""Sendet piCtory Konfiguration per MQTT."""
|
||||
try:
|
||||
@@ -260,6 +332,7 @@ class MqttServer(Thread):
|
||||
def reload_revpimodio(self):
|
||||
"""Fuehrt im naechsten Zyklus zum Reload."""
|
||||
self._reloadmodio = True
|
||||
self._evt_data.set()
|
||||
|
||||
def run(self):
|
||||
"""Startet die Uebertragung per MQTT."""
|
||||
@@ -280,6 +353,7 @@ class MqttServer(Thread):
|
||||
self._rpi.mainloop(blocking=False)
|
||||
|
||||
# mainloop
|
||||
send_cycledata = self._sendinterval > 0
|
||||
while not self.__exit:
|
||||
self._evt_data.clear()
|
||||
|
||||
@@ -291,6 +365,7 @@ class MqttServer(Thread):
|
||||
if self._send_events:
|
||||
self._rpi.mainloop(blocking=False)
|
||||
|
||||
if send_cycledata:
|
||||
# Werte laden, wenn nicht autorefresh
|
||||
if not self._send_events:
|
||||
self._rpi.readprocimg()
|
||||
@@ -302,7 +377,9 @@ class MqttServer(Thread):
|
||||
value = int.from_bytes(value, "little")
|
||||
self._mq.publish(self._mqtt_io.format(io.name), int(value))
|
||||
|
||||
self._evt_data.wait(self._sendinterval)
|
||||
self._evt_data.wait(
|
||||
10 if not send_cycledata else self._sendinterval
|
||||
)
|
||||
|
||||
# MQTT trennen
|
||||
self._mq.loop_stop()
|
||||
|
||||
@@ -387,7 +387,7 @@ class RevPiPyLoad():
|
||||
self.xml_ps = None
|
||||
proginit.logger.warning(
|
||||
"can not load revpimodio2 module. maybe its not installed "
|
||||
"or an old version (required at least 2.2.3). if you "
|
||||
"or an old version (required at least 2.2.4). if you "
|
||||
"like to use the process monitor feature, update/install "
|
||||
"revpimodio2: 'apt-get install python3-revpimodio2'"
|
||||
)
|
||||
@@ -453,7 +453,7 @@ class RevPiPyLoad():
|
||||
except Exception:
|
||||
proginit.logger.warning(
|
||||
"can not load revpimodio2 module. maybe its not installed "
|
||||
"or an old version (required at least 2.2.3). if you "
|
||||
"or an old version (required at least 2.2.4). if you "
|
||||
"like to use the mqtt feature, update/install "
|
||||
"revpimodio2: 'apt-get install python3-revpimodio2'"
|
||||
)
|
||||
|
||||
@@ -62,7 +62,7 @@ class SaveXMLRPCServer(SimpleXMLRPCServer):
|
||||
|
||||
return super()._dispatch(method, params)
|
||||
|
||||
def isAlive(self):
|
||||
def is_alive(self):
|
||||
"""Prueft ob der XML RPC Server laeuft.
|
||||
@return True, wenn Server noch laeuft"""
|
||||
return False if self.fut is None else self.fut.running()
|
||||
|
||||
2
setup.py
2
setup.py
@@ -31,7 +31,7 @@ setup(
|
||||
|
||||
scripts=["data/revpipyload"],
|
||||
|
||||
install_requires=["revpimodio2 >= 2.2.3"],
|
||||
install_requires=["revpimodio2 >= 2.2.4"],
|
||||
python_requires=">=3.2",
|
||||
|
||||
data_files=[
|
||||
|
||||
Reference in New Issue
Block a user