So kamen die Neujahrsferien und mit ihnen viel Freizeit, und sogar ein intelligenter Staubsauger fiel mir in die Hände. Sobald ich die manuelle Steuerung in der MiHome-Anwendung sah, wurde mir sofort klar, was ich tun wollte: Wir werden den Staubsauger mit dem Dualshock v4-Gamepad steuern!
Schritt 1, Ziehen des Tokens, Blinken (optional)
Wir setzen die gepatchte MiHome-Anwendung ein, die uns das Token anzeigt, wählen dann die Root-Firmware aus, laden sie herunter, installieren python-miio (pip install python-miio) und versuchen, die Firmware mit
mirobo --ip %ip% --token %token% update-firmware %filename%
zu installieren
mirobo --ip %ip% --token %token% update-firmware %filename%
und zu diesem Zeitpunkt ist alles kaputt gegangen. Der Staubsauger weigerte sich verzweifelt, aktualisiert zu werden. Nach mehreren Stunden Googeln versuchte ich, die Debug-Ausgabe von mirobo zu sehen und siehe da! Aufgrund der Tatsache, dass auf meinem Laptop mehrere Adapter installiert sind, versuchte er, die Firmware im Netzwerk des VirtualBox Host-Only-Adapters zu verteilen. Als nächstes habe ich gerade den Dateiserver hochgefahren und diesen Befehl ausgeführt:
mirobo --ip=%ip% --token=%token% raw-command miIO.ota '{"mode":"normal", "install":"1", "app_url":"http://%my_ip:port%/%filename%.pkg", "file_md5":"%md5%","proc":"dnld install"}'
. Die Firmware ist in 10 Minuten irgendwo hochgekommen, der SSH-Zugriff hat funktioniert
Schritt 2, versuchen Sie den Roboter zu fahren
import miio ip = '' token = '' bot = miio.vacuum.Vacuum(ip, token) bot.manual_start() bot.manual_control(0, 0.3, 2000)
Zu diesem Zeitpunkt sollte der Staubsauger sagen: Mit Fernbedienungen (oder ähnlichem, abhängig von der Firmware) zucken und anhalten
Schritt 3, Dualshock anschließen
Nach ein wenig Recherche wurde entschieden, Pygame zu verwenden
Wir schauen uns an, wofür Knöpfe / Aufkleber verantwortlich sind BUTTON_SQUARE = 0 BUTTON_X = 1 BUTTON_CIRCLE = 2 BUTTON_TRIANGLE = 3 def init_joystick(): pygame.init() pygame.joystick.init() controller = pygame.joystick.Joystick(0) controller.init() return controller def main(): controller = init_joystick() bot = miio.vacuum.Vacuum(ip, token) modes = ['manual', 'home', 'spot', 'cleaning', 'unk'] mode = 'unk' axis = [0.00 for _ in range(6)] flag = True button = [False for _ in range(14)] print('Press start to start!') while flag: for event in pygame.event.get(): if event.type == pygame.JOYAXISMOTION: axis[event.axis] = round(event.value,2) elif event.type == pygame.JOYBUTTONDOWN: button[event.button] = True
Im Moment können Sie in move_robot einfach drucken (Achse) und überprüfen, ob der Joystick funktioniert.
Als nächstes müssen wir den Roboter fahren lassen, wenn Sie die Knöpfe / Sticks drücken. Ich habe den linken Stick auf der Y-Achse (oben -1, unten 1) für die Geschwindigkeit und den rechten Stick auf der X-Achse für den Winkel gewählt. Es stellte sich so heraus
def translate(value, leftMin, leftMax, rightMin, rightMax): leftSpan = leftMax - leftMin rightSpan = rightMax - rightMin valueScaled = float(value - leftMin) / float(leftSpan) return rightMin + (valueScaled * rightSpan) def move_robot(bot, buttons, axis): rot = 0 val = 0 to_min, to_max = -0.3, 0.3
Führen Sie das Skript aus, drücken Sie X auf der Steuerung und der Roboter muss fahren und sich drehen
Zu diesem Zeitpunkt hatte ich ein Problem: Wenn Sie aus irgendeinem Grund den linken Steuerknüppel bis zum Ende nach vorne drücken und versuchen, ihn zu drehen, dreht er sich nicht. Sie müssen zuerst langsamer werden. Wenn Sie versuchen, die Zuordnungswerte zu reduzieren, z. B. -0,29, 0,29, beginnt der Kreis Bis sich die Position des linken Aufklebers ändert, habe ich nie herausgefunden, wo das Problem liegt
Schritt 4, fügen Sie etwas Musik hinzu
Wir fahren mit ssh zu unserem Roboter und sehen, welche Skriptsprachen es gibt.
Es gab kein Python, aber ich sah keinen Sinn darin, es zu installieren, aber ich fand eine Perle, die für unsere kleine Aufgabe geeignet war.
Als nächstes installieren Sie Sox:
sudo apt-get install sox, libsox-fmt-mp3
und schreibe einen kleinen Server auf die Perle:
sudo perl sound_server.pl
In unserer Konsole machen wir so etwas
import socket ip = '' s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((ip, 7777)) s.sendall(b'http://%local_ip%:%local_port%/test.mp3;') s.close()
Und durch den Staubsauger sollte unsere test.mp3 abgespielt werden (dementsprechend müssen wir den Dateiserver auf unserem lokalen Computer anheben).
Unsere Funktion play_sound () macht fast dasselbe, nur sendall (url + ';') wird es sein, url ist das Funktionsargument.
Ergebnis