FHEM - Hausautomations-Systeme > MQTT

Roomba Staubsaugerroboter

<< < (2/82) > >>

Beta-User:
Hmmm, vorher würde ich mal versuchen, an Readings zu kommen => autocreate am IO aktiv?
Falls der Sauger einen Homeassistant-Modus kennt: darüber könnte man uU. rausbekommen, welche messages wo erwartet werden ;) .

Prof. Dr. Peter Henning:
Schon wieder einen Schritt weiter. Ich habe jetzt eine Python-Anwendung, die die beiden Broker koppelt. Auch das globale autocreate und das autorcreate im MQTT2_SERVER sind aktiv, verbose 5 zeig tmir auch Daten des Roboters, aber readings werden noch keine angelegt.

--- Zitat ---2020.09.12 14:22:32 5: in:  PUBLISH: 0!(0)(28)/roomba/feedback/signal_rssi-40
2020.09.12 14:22:32 4:   MQTTBridge_127.0.0.1_41349  PUBLISH /roomba/feedback/signal_rssi:-40
2020.09.12 14:22:32 5: MQTTBridge: dispatch autocreate=complex\000\000/roomba/feedback/signal_rssi\000-40
2020.09.12 14:22:32 5: in:  PUBLISH: 0(31)(0)(27)/roomba/feedback/signal_snr49
2020.09.12 14:22:32 4:   MQTTBridge_127.0.0.1_41349  PUBLISH /roomba/feedback/signal_snr:49
2020.09.12 14:22:32 5: MQTTBridge: dispatch autocreate=complex\000\000/roomba/feedback/signal_snr\00049
2020.09.12 14:22:32 5: in:  PUBLISH: 0 (0)(22)/roomba/feedback/stateCharging
2020.09.12 14:22:32 4:   MQTTBridge_127.0.0.1_41349  PUBLISH /roomba/feedback/state:Charging
2020.09.12 14:22:32 5: MQTTBridge: dispatch autocreate=complex\000\000/roomba/feedback/state\000Charging
--- Ende Zitat ---

LG

pah

Prof. Dr. Peter Henning:
OK, diese Methode klappt schon mal.

Mit der Python-Anwendung im Hintergrund kann ich den Roomba jetzt prima steuern. Aus irgendeinem Grund wurden aber weder das zugehörige MQTT2_DEVICE, noch dessen Readings automatisch angelegt, habe ich alles manuell machen müssen.

Außerdem ist ein Problem mit dem paho-mqttt-Client in Python aufgetreten: Von den Kommandostrings musste ich immer noch ein führendes "b" sowie die "'" entfernen.

Das ist mir jetzt aber noch zu umständlich - es müsste auch mit einem MQTT2_CLIENT direkt auf den Roomba gehen.

LG

pah

Otto123:
Hallo pah,

ich habe mal mit Hilfe von ein paar Beiträgen einen Cloud Broker an MQTT2_CLIENT gekoppelt.

Durch Dein python Script solltest Du alle Infos haben, vielleicht hilft dieses Beispiel.
autocreate complex ist übrigens nicht unbedingt das Mittel der Wahl, Standard sollte simple sein.

Gruß Otto

Prof. Dr. Peter Henning:
Danke Dir.

Ich habe jetzt als Übergangslösung das mit den externen Python-Programmen gemacht. Bisher habe ich es nicht hinbekommen, dass beide Roombas in demselben Python-Programm verwaltet werden.
Lässt man aber 2 davon im Hintergrund laufen, funktioniert das astrein, für jeden Roboter gibt es auf FHEM-Seite ein MQTT2_DEVICE, mit dem ich ihn steuern kann.

Diese Lösung, also MQTT2_DEVICE <-> MQTT2_SERVER <-> Python-Programm <-> Roomba-MQTT-Server <-> Roomba-Gerät  habe ich unten beschrieben.


Die andere Lösung  wäre MQTT2_DEVICE <-> MQTT2_CLIENT <-> Roomba-MQTT-Server <-> Roomba-Gerät, diese habe ich noch nicht hinbekommen. Denn inzwischen kriege ich - erstaunlicherweise, das hatte zwischendrin ja schon geklappt - eine Verweigerung der Verbindung eines MQTT2_CLIENT mit einem der Roboter. Irgendetwas stimmt dabei an den Credentials nicht, ich muss wohl wirklich nach dem Zertifikat graben, das mit der anderen Methode irgendwie geholt wird (auch da gibt es zunächst beom Connect eine Fehlermeldung, bis TLS 1.3 eingeschaltet wird).

Also, was geht bisher:

1. Auf dem FHEM-Server per

--- Code: ---pip install paho-mqtt
pip install pillow
pip install six
pip install git+https://github.com/NickWaterton/Roomba980-Python.git
--- Ende Code ---
eine lokale Installation geholt.

2. Mit dem Kommando

--- Code: ---python3 ~/Roomba980-Python/roomba/getpasswd.py
--- Ende Code ---
die jeweiligen Credentials meiner beiden Roomba geholt. Ergibt jeweils etwas wie

--- Zitat ---Received: {
 "robotname": "Feger", 
 "sku": "R981040", 
 "nc": 0, 
 "ver": "3", 
 "proto": "mqtt", 
 "ip": "192.168.0.xx", 
 "hostname": "Roomba-31xxxxxxxxxx0", 
 "sw": "v2.4.8-44", 
 "mac": "70:66:xxxxxxxxxxx:6F", 
 "cap": {
   "carpetBoost": 1, 
   "pp": 1, 
   "langOta": 1, 
   "binFullDetect": 1, 
   "ota": 2, 
   "maps": 1, 
   "pose": 1, 
   "eco": 1, 
   "multiPass": 2, 
   "edge": 1, 
   "svcConf": 1
 }
}
Roomba (Feger) IP address is: 192.168.0.XX
blid is: 3###########0
Password=> :######################A <= Yes, all this string.
Use these credentials in roomba.py
--- Ende Zitat ---

3. Ein Python-Programm gebaut, z.B. ~/Roomba980-Python/roomba/fhemfeger.py als

--- Code: ---from __future__ import print_function
from roomba import Roomba
import paho.mqtt.client as mqtt
import time
import json

broker = 'localhost'    #ip of FHEM mqtt broker
user = ''         
password = '' 

#roombaName = 'roombaFeger'
#address = '192.168.0.xx'
#blid = '3xxxxxxxxxxxx0'
#roombaPassword = ':1:1xxxxxxxxxxxxxbh'

def broker_on_connect(client, userdata, flags, rc):
    print("Broker Connected with result code "+str(rc))
    #subscribe to roomba feedback
    if rc == 0:
        mqttc.subscribe(brokerCommand)
        mqttc.subscribe(brokerSetting)

def broker_on_message(mosq, obj, msg):
    if roombaName in msg.topic:
        #publish to roomba
        if "command" in msg.topic:
            pl = str(msg.payload).strip('b\'')
            print("Received COMMAND: %s" % pl)
            myroomba.send_command( pl )
        elif "setting" in msg.topic:
            print("Received SETTING: %s" % str(msg.payload))
            cmd = str(msg.payload).split()
            myroomba.set_preference(cmd[0], cmd[1])

def broker_on_publish(mosq, obj, mid):
    pass

def broker_on_subscribe(mosq, obj, mid, granted_qos):
    print("Broker Subscribed: %s %s" % (str(mid), str(granted_qos)))

def broker_on_disconnect(mosq, obj, rc):
    print("Broker disconnected")

def broker_on_log(mosq, obj, level, string):
    print(string)


mqttc = None
if broker is not None:
    brokerCommand = "/roomba/command/" + roombaName
    brokerSetting = "/roomba/setting/" + roombaName
    brokerFeedback = "/roomba/feedback/" + roombaName

    #connect to broker
 mqttc = mqtt.Client()
    #Assign event callbacks
    mqttc.on_message = broker_on_message
    mqttc.on_connect = broker_on_connect
    mqttc.on_disconnect = broker_on_disconnect
    mqttc.on_publish = broker_on_publish
    mqttc.on_subscribe = broker_on_subscribe

    try:
        mqttc.username_pw_set(user, password)  #put your own mqtt user and password here if you are using them, otherwise comment out
        mqttc.connect(broker, 1883, 60) #Ping MQTT broker every 60 seconds if no data is published from this script.

    except Exception as e:
        print("Unable to connect to MQTT Broker: %s" % e)
        mqttc = None

myroomba = Roomba(address, blid, roombaPassword, topic="#", continuous=True, clean=False, cert_name = "./ca-certificates.crt")

#all these are optional, if you don't include them, the defaults will work just fine
#if you are using maps
myroomba.enable_map(enable=True, mapSize="(800,1650,-300,-50,2,0)", mapPath="./", iconPath="./")  #enable live maps, class default is no maps


if broker is not None:
    myroomba.set_mqtt_client(mqttc, brokerFeedback)

#finally connect to Roomba - (required!)
myroomba.connect()

print("<CTRL C> to exit")
print("Subscribe to /roomba/feedback/" + roombaName + "/# to see published data")

try:
    if mqttc is not None:
        mqttc.loop_forever()
    else:
        while True:
            print("Roomba " + roombaName +" Data: %s" % json.dumps(myroomba.master_state, indent=2))
            time.sleep(5)

except (KeyboardInterrupt, SystemExit):
    print("System exit Received - Exiting program")
    myroomba.disconnect()
    if mqttc is not None:
        mqttc.disconnect()

--- Ende Code ---

4. Dieses Programm läuft auf dem FHEM-Server im Hintergrund als
--- Code: ---python3 ~/Roomba980-Python/roomba/fhemfeger.py > /dev/null 2> /dev/null
--- Ende Code ---
und schickt alle Messages von dem Roomba-MQTT-Server an den FHEM-MQTT-Server (mit Namen MQTTBridge). Der wiederum kennt für jeden der beiden Roomba ein Device.

5.Listing des einen Devices:

--- Code: ---DEVICETOPIC RoombaFeger
   FUUID      5f5cbe27-f33f-a726-8734-ab96da6c3ee99444
   IODev      MQTTBridge
   IODevName  RoombaFegerClient
   LASTInputDev MQTTBridge
   MQTTBridge_MSGCNT 2517
   MQTTBridge_TIME 2020-09-13 12:44:52
   MSGCNT     2517
   NAME       RoombaFeger
   NR         180
   STATE      Charging
   TYPE       MQTT2_DEVICE
   READINGS:
     2020-09-13 12:43:19   audio_active    False
     2020-09-13 12:43:19   battery         100
     2020-09-13 12:43:19   carpetBoost     False
     2020-09-12 15:46:56   lastCommand     dock
     2020-09-13 12:43:20   lastInitiator   manual
     2020-09-13 12:43:19   netinfo_dhcp    True
     2020-09-13 12:43:19   position_theta  173
     2020-09-13 12:43:19   position_x      -12
     2020-09-13 12:43:19   position_y      29
     2020-09-13 12:44:52   signal_rssi     -41
     2020-09-13 12:44:52   signal_snr      48
     2020-09-13 12:44:52   state           Charging
Attributes:
   IODev      MQTTBridge
   autocreate 1
   readingList /roomba/feedback/roombaFeger/state:.* state
/roomba/feedback/roombaFeger/signal_rssi:.* signal_rssi
/roomba/feedback/roombaFeger/signal_snr:.* signal_snr
/roomba/feedback/roombaFeger/netinfo_dhcp:.* netinfo_dhcp
/roomba/feedback/roombaFeger/audio_active:.* audio_active
/roomba/feedback/roombaFeger/batPct:.* battery
/roomba/feedback/roombaFeger/carpetBoost:.* carpetBoost
/roomba/feedback/roombaFegerr/astCommand_command:.* lastCommand
/roomba/feedback/roombaFeger/lastCommand_initiator:.* lastInitiator
/roomba/feedback/roombaFeger/pose_theta:.* position_theta
/roomba/feedback/roombaFeger/pose_point_x:.* position_x
/roomba/feedback/roombaFeger/pose_point_y:.* position_y

   setList    start /roomba/command/roombaFeger start
stop /roomba/command/roombaFeger stop
pause /roomba/command/roombaFeger pause
resume /roomba/command/roombaFeger resume
dock /roomba/command/roombaFeger dock
--- Ende Code ---

6. Ich habe es bisher nicht hinbekommen, die beiden unterschiedlichen Roombas in einem einzelnen Python-Programm abzudecken. Also werden ganz einfach zwei davon gestartet, es gibt zwei bach-Skripte in /opt/fhem, eins zum checken

--- Code: ---#!/bin/bash

statsauger=`ps -ef | grep fhemsauger | grep -v grep | awk '{print $2}'`
statfeger=`ps -ef | grep fhemfeger | grep -v grep | awk '{print $2}'`

if [ "$statsauger" == "" ] || [ "$statfeger" == "" ]; then
  echo -n "0"
else
  echo -n "1"
fi

--- Ende Code ---
und eins zum Starten der beiden Python-Programme

--- Code: ---#!/bin/bash

statsauger=`ps -ef | grep fhemsauger | grep -v grep | awk '{print $2}'`
statfeger=`ps -ef | grep fhemfeger | grep -v grep | awk '{print $2}'`

if [ "$statsauger" == "" ]; then
  python3 /root/Roomba980-Python/roomba/fhemsauger.py > /dev/null 2> /dev/null &
fi

if [ "$statfeger" == "" ]; then
  python3 /root/Roomba980-Python/roomba/fhemfeger.py > /dev/null 2> /dev/null &
fi

--- Ende Code ---

7. Auf FHEM-Seite werden diese überwacht durch einen Dummy

--- Code: ---Internals:
   CFGFN     
   FUUID      5f5df29c-f33f-a726-2e25-be3150af0bbdd339
   NAME       RoombaBridge
   NR         1291
   STATE      on
   TYPE       dummy
   READINGS:
     2020-09-13 12:49:01   state           on
Attributes:
   devStateIcon off:ios-off .*:ios-on-green
   setList    start stop on off
   webCmd     start:stop
--- Ende Code ---
ein at zum periodischen checken

--- Code: ---Internals:
   CFGFN     
   COMMAND    {fhem("set RoombaBridge ".((`/opt/fhem/checkRoomba.sh` eq "1")?"on":"off"))}
   DEF        +*00:05:00 {fhem("set RoombaBridge ".((`/opt/fhem/checkRoomba.sh` eq "1")?"on":"off"))}
   FUUID      5f5df319-f33f-a726-6529-6a2067913cf0b841
   NAME       RoombaChecker
   NR         1323
   NTM        12:54:01
   PERIODIC   yes
   RELATIVE   yes
   REP        -1
   STATE      Next: 12:54:01
   TIMESPEC   00:05:00
   TRIGGERTIME 1599994441.07101
   TRIGGERTIME_FMT 2020-09-13 12:54:01
   TYPE       at
   READINGS:
     2020-09-13 12:49:01   state           Next: 12:54:01
Attributes:

--- Ende Code ---
und ein IF zum Abfangen der start/stop-Befehle für die Python-Skripte

--- Code: ---Internals:
   CFGFN     
   DEF        ([RoombaBridge] eq "start")
 ({system ("sudo /opt/fhem/startRoomba.sh")},
 {fhem("set RoombaBridge ".
  ((`/opt/fhem/checkRoomba.sh` eq "1")?"on":"off"))})
DOELSEIF ([RoombaBridge] eq "stop")
 ({system ("sudo /opt/fhem/stopRoomba.sh")},
{fhem("set RoombaBridge ".
  ((`/opt/fhem/checkRoomba.sh` eq "1")?"on":"off"))})
   FUUID      5f5df3a0-f33f-a726-7120-1bf01544cde3ae26
   MODEL      FHEM
   NAME       Roomba.IF
   NOTIFYDEV  RoombaBridge,global
   NR         1359
   NTFY_ORDER 50-Roomba.IF
   STATE      initialized
   TYPE       DOIF
   VERSION    22757 2020-09-11 16:21:17
   READINGS:
     2020-09-13 12:49:01   Device          RoombaBridge
     2020-09-13 12:27:47   cmd             0
     2020-09-13 12:49:01   e_RoombaBridge_STATE on
     2020-09-13 12:27:47   mode            enabled
     2020-09-13 12:27:47   state           initialized
   Regex:
     accu:
     cond:
       RoombaBridge:
         0:
           &STATE     ^RoombaBridge$
         1:
           &STATE     ^RoombaBridge$
   condition:
     0          ::InternalDoIf($hash,'RoombaBridge','STATE') eq "start"
     1          ::InternalDoIf($hash,'RoombaBridge','STATE') eq "stop"
   do:
     0:
       0          {system ("sudo /opt/fhem/startRoomba.sh")},  {fhem("set RoombaBridge ".   ((`/opt/fhem/checkRoomba.sh` eq "1")?"on":"off"))}
     1:
       0          {system ("sudo /opt/fhem/stopRoomba.sh")}, {fhem("set RoombaBridge ".   ((`/opt/fhem/checkRoomba.sh` eq "1")?"on":"off"))}
     2:
   helper:
     DEVFILTER  ^global$|^RoombaBridge$
     NOTIFYDEV  global|RoombaBridge
     event      on
     globalinit 1
     last_timer 0
     sleeptimer -1
     triggerDev RoombaBridge
     triggerEvents:
       on
     triggerEventsState:
       state: on
   internals:
     all         RoombaBridge:STATE
   readings:
   trigger:
   uiTable:
Attributes:
   do         always
--- Ende Code ---

LG

pah

Navigation

[0] Themen-Index

[#] Nächste Seite

[*] Vorherige Sete

Zur normalen Ansicht wechseln