eins vornweg - ich bin blutiger python-Neuling und bitte um Nachsicht, falls mein in Folge geschildertes Problem auf grundsätzliche Dummheit des Anwenders zurückzuführen ist

Ich habe es geschafft mein Gardena-Smart-Irrigation-System mittels websocket-Verbindung dazu zu bringen mir in Echtzeit Werte zu senden. Das klappt sehr gut. Da sich der Websocket bei Inaktivität disconnectet wird alle 150 sec. ein ping gesandt. Ausserdem wird der websocket nach 2h geschlossen - daher das rel-Konstrukt.
Nun möchte ich gerne mittels MQTT Befehle zu den Ventilen senden. Bisher passierte da gar nix. Nur durch Zufall habe ich einmal direkt während der Wertübermittlung des websockets eine Nachricht auf das topic MQTT_IN gesandt - und siehe da....die Nachricht kam an.
Nun meine Frage: wieso wird die MQTT-Nachricht nur direkt während der Wertübermittlung des websocket durchgeführt und ausserhalb dieser Übertragung passiert gar nichts wenn die MQTT-Nachricht gesandt wird?
MQTT während aktiver websocket Übertragung (der funktionale Teil dieses Codes wurde zu dem Zeitpunkt im Programm auskommentiert....es sollte nur das prizipielle Verhalten getestet werden):
Code: Alles auswählen
2024-08-31T13:13:13.304244150+02:00 ++Rcv decoded: fin=1 opcode=8 data=b'\x03\xe9Going away',
2024-08-31T13:13:13.304893903+02:00 ++Sent raw: b'\x88\x82@\x99\xa6\xf2Cq',
2024-08-31T13:13:13.305283017+02:00 ++Sent decoded: fin=1 opcode=8 data=b'\x03\xe8',
2024-08-31T13:13:13.308227385+02:00 msg {"id":"8ab391b8-0db6-42fd-b087-00xxxxxxxxxx","type":"COMMON","attributes":{"name":{"value":"Sensor Innenbeete"},"batteryLevel":{"value":76,"timestamp":"2024-08-24T19:04:22.000+00:00"},"batteryState":{"value":"UNKNOWN","timestamp":"2024-08-24T19:04:22.000+00:00"},"rfLinkLevel":{"value":100,"timestamp":"2024-08-31T09:04:25.000+00:00"},"serial":{"value":"00076841"},"modelType":{"value":"GARDENA smart Sensor"},"rfLinkState":{"value":"ONLINE"}}},
2024-08-31T13:13:13.308312161+02:00 msg {"id":"8ab391b8-0db6-42fd-b087-00xxxxxxxxxx","type":"SENSOR","attributes":{"soilHumidity":{"value":75,"timestamp":"2024-08-31T10:04:24.000+00:00"},"soilTemperature":{"value":21,"timestamp":"2024-08-31T10:04:25.000+00:00"}}},
2024-08-31T13:13:13.308355450+02:00 msg {"id":"8ab391b8-0db6-42fd-b087-00xxxxxxxxxx","type":"COMMON","attributes":{"name":{"value":"Sensor Innenbeete"},"batteryLevel":{"value":76,"timestamp":"2024-08-24T19:04:22.000+00:00"},"batteryState":{"value":"UNKNOWN","timestamp":"2024-08-24T19:04:22.000+00:00"},"rfLinkLevel":{"value":100,"timestamp":"2024-08-31T09:04:25.000+00:00"},"serial":{"value":"00076841"},"modelType":{"value":"GARDENA smart Sensor"},"rfLinkState":{"value":"ONLINE"}}},
[b]2024-08-31T13:13:13.308391847+02:00 ###geht los###,
2024-08-31T13:13:13.308444659+02:00 mqtt_in b'{\n "data":{\n "type": "VALVE_CONTROL",\n "id": "d1f51a16-b89a-41ce-a1d8-27692ef2af1e:5",\n "attributes": {\n "command": "START_SECONDS_TO_OVERRIDE",\n "seconds": 60\n }\n }\n }',
2024-08-31T13:13:13.308467524+02:00 ###geht los###,
2024-08-31T13:13:13.308489565+02:00 mqtt_in b'{\n "data":{\n "type": "VALVE_CONTROL",\n "id": "d1f51a16-b89a-41ce-a1d8-27692ef2af1e:5",\n "attributes": {\n "command": "START_SECONDS_TO_OVERRIDE",\n "seconds": 60\n }\n }\n }',
2024-08-31T13:13:13.308511574+02:00 ###geht los###,
2024-08-31T13:13:13.308595867+02:00 mqtt_in b'{\n "data":{\n "type": "VALVE_CONTROL",\n "id": "d1f51a16-b89a-41ce-a1d8-27692ef2af1e:5",\n "attributes": {\n "command": "START_SECONDS_TO_OVERRIDE",\n "seconds": 60\n }\n }\n }',[/b]
2024-08-31T13:13:13.308622184+02:00 msg {"id":"70cd0a17-3c76-437e-99xxxxxxxxxx","type":"SENSOR","attributes":{"soilHumidity":{"value":5,"timestamp":"2024-08-31T10:15:01.000+00:00"},"soilTemperature":{"value":20,"timestamp":"2024-08-31T08:15:02.000+00:00"}}},
2024-08-31T13:13:13.308645086+02:00 msg {"id":"70cd0a17-3c76-437e-99xxxxxxxxxx","type":"COMMON","attributes":{"name":{"value":"Sensor Aussenbeete"},"batteryLevel":{"value":76,"timestamp":"2024-06-29T15:14:44.000+00:00"},"batteryState":{"value":"UNKNOWN","timestamp":"2024-06-29T15:14:44.000+00:00"},"rfLinkLevel":{"value":80,"timestamp":"2024-08-31T09:15:01.000+00:00"},"serial":{"value":"00076993"},"modelType":{"value":"GARDENA smart Sensor"},"rfLinkState":{"value":"ONLINE"}}},
Code: Alles auswählen
2024-08-31T12:58:13.494757986+02:00 ++Rcv raw: b'\x8a\x00',
2024-08-31T12:58:13.494899785+02:00 ++Rcv decoded: fin=1 opcode=10 data=b'',
2024-08-31T13:00:43.459773605+02:00 Sending ping,
2024-08-31T13:00:43.460361370+02:00 ++Sent raw: b'\x89\x80\x95\xce\xce\xca',
2024-08-31T13:00:43.460741167+02:00 ++Sent decoded: fin=1 opcode=9 data=b'',
2024-08-31T13:00:43.497784480+02:00 ++Rcv raw: b'\x8a\x00',
2024-08-31T13:00:43.498089008+02:00 ++Rcv decoded: fin=1 opcode=10 data=b'',
2024-08-31T13:03:13.462573512+02:00 Sending ping,
2024-08-31T13:03:13.463146618+02:00 ++Sent raw: b'\x89\x80\x9d\xd3\xc8;',
2024-08-31T13:03:13.463542822+02:00 ++Sent decoded: fin=1 opcode=9 data=b'',
2024-08-31T13:03:13.500007019+02:00 ++Rcv raw: b'\x8a\x00',
2024-08-31T13:03:13.500256221+02:00 ++Rcv decoded: fin=1 opcode=10 data=b'',
2024-08-31T13:05:43.465400241+02:00 Sending ping,
2024-08-31T13:05:43.466025838+02:00 ++Sent raw: b'\x89\x80\xde\x99\xabe',
2024-08-31T13:05:43.466388601+02:00 ++Sent decoded: fin=1 opcode=9 data=b'',
2024-08-31T13:05:43.503160100+02:00 ++Rcv raw: b'\x8a\x00',
2024-08-31T13:05:43.503267470+02:00 ++Rcv decoded: fin=1 opcode=10 data=b'',
Denkanstösse und/oder Lösungsvorschläge sind herzlich willkommen!
Code: Alles auswählen
import websocket
import datetime
from threading import Thread
import time
import sys
import requests
import os
import json
import paho.mqtt.client as mqtt
import rel
# account specific values
CLIENT_ID = os.environ['CLIENT_ID']
CLIENT_SECRET = os.environ['CLIENT_SECRET']
API_KEY = os.environ['API_KEY']
#MQTT Broker
BROKER = os.environ['BROKER_IP']
BROKER_PORT = int(os.environ['BROKER_PORT'])
#MQTT Topics
MQTT_OUT = os.environ['MQTT_OUT']
MQTT_IN = os.environ['MQTT_IN']
MQTT_ERROR = os.environ['MQTT_ERROR']
# other constants
AUTHENTICATION_HOST = 'https://api.authentication.husqvarnagroup.dev'
SMART_HOST = 'https://api.smart.gardena.dev'
AUTH_TOKEN =''
class Client:
def on_message(self, any, message):
print("msg", message)
mclient.publish(MQTT_OUT, message)
def on_error(self, error, *args):
print("error", error)
mclient.publish(MQTT_ERROR, error)
def on_close(self, *args):
self.live = False
print("### closed ###")
sys.exit(0)
def on_open(self, any):
print("### connected ###")
self.live = True
def run(*args):
while self.live:
time.sleep(1)
Thread(target=run).start()
def format(response):
formatted = [response.url, "%s %s" % (response.status_code, response.reason)]
for k,v in response.headers.items():
formatted.append("%s: %s" % (k, v))
formatted.append("")
formatted.append(r.text)
return "\n".join(formatted)
class mqttClient:
def on_close(self,*args):
self.live = False
print("### closed ###")
sys.exit(0)
def on_connect(self, client: mqtt.Client, userdata, flags, rc, properties):
print("Connected with result code: "+str(rc))
mclient.subscribe(MQTT_IN, 0)
def on_subscribe(self, client: mqtt.Client, userdata, mid, reason_code_list, properties):
print("Subscribed: " + str(mid) + " " + str(reason_code_list)+" " + str(properties))
def on_message(self, client: mqtt.Client, userdata, msg): # hier wird garnichts ausgeführt
print("###geht los###")
print('mqtt_in', msg.payload)
jsPayload = json.loads(msg.payload)
jdata = jsPayload['data']
ServiceID = jdata['id']
headers = {
"Content-Type": "application/vnd.api+json",
"X-Api-Key": API_KEY,
"Authorization": "Bearer " + AUTH_TOKEN}
url = "https://api.smart.gardena.dev/v1/command/" + ServiceID
response = requests.put(url, data=msg.payload, headers= headers)
print(response)
if __name__ == "__main__":
payload = {'grant_type': 'client_credentials', 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET}
print("Logging into authentication system...")
r = requests.post(f'{AUTHENTICATION_HOST}/v1/oauth2/token', data=payload)
assert r.status_code == 200, format(r)
auth_token = r.json()["access_token"]
print("Logged in auth_token=(%s)" % auth_token)
headers = {
"Content-Type": "application/vnd.api+json",
"x-api-key": API_KEY,
"Authorization": "Bearer " + auth_token
}
print("### get locations ###")
r = requests.get(f'{SMART_HOST}/v1/locations', headers=headers)
assert r.status_code == 200, format(r)
assert len(r.json()["data"]) > 0, 'location missing - user has not setup system'
location_id = r.json()["data"][0]["id"]
print("LocationId=(%s)" % location_id)
payload = {
"data": {
"type": "WEBSOCKET",
"attributes": {
"locationId": location_id
},
"id": "does-not-matter"
}
}
print("getting websocket ID...")
r = requests.post(f'{SMART_HOST}/v1/websocket', json=payload, headers=headers)
assert r.status_code == 201, format(r)
print("Websocket ID obtained, connecting...")
response = r.json()
websocket_url = response["data"]["attributes"]["url"]
websocket.enableTrace(True)
mclient = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
MqttClient = mqttClient()
mclient.on_connect = MqttClient.on_connect
mclient.on_subscribe = MqttClient.on_subscribe
mclient.on_message = MqttClient.on_message
mclient.connect(BROKER,BROKER_PORT)
mclient.loop_start()
client = Client()
ws = websocket.WebSocketApp(
websocket_url,
on_message=client.on_message,
on_error=client.on_error,
on_close=client.on_close)
ws.on_open = client.on_open
ws.run_forever(dispatcher=rel, reconnect=5, ping_interval=150, ping_timeout=1)
rel.signal(2, rel.abort)
rel.dispatch()
Jens