Montamos la aspiradora Xiaomi

Entonces llegaron las vacaciones de A帽o Nuevo, y con ellos mucho tiempo libre, e incluso una aspiradora inteligente cay贸 en mis manos. Tan pronto como vi el control manual en la aplicaci贸n MiHome, inmediatamente me di cuenta de lo que quer铆a hacer: 隆controlaremos la aspiradora usando el gamepad Dualshock v4!

Paso 1, arrastrando el token, parpadeando (opcional)


Ponemos la aplicaci贸n parcheada MiHome, que nos mostrar谩 el token, luego seleccionamos el firmware ra铆z, descargamos, instalamos python-miio (pip install python-miio), intentamos instalar el firmware usando mirobo --ip %ip% --token %token% update-firmware %filename% y en este punto todo se rompi贸. La aspiradora se neg贸 desesperadamente a actualizarse, despu茅s de varias horas de buscar en Google, trat茅 de ver la salida de depuraci贸n de mirobo y lo y 隆he aqu铆! Debido al hecho de que tengo varios adaptadores instalados en mi computadora port谩til, intent贸 distribuir el firmware en la red del adaptador VirtualBox Host-Only. A continuaci贸n, acabo de subir el servidor de archivos y 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"}' este comando: 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"}' . El firmware se levant贸 en alg煤n lugar en 10 minutos, el acceso ssh funcion贸

Paso 2, intenta montar el robot


 import miio ip = '' token = '' bot = miio.vacuum.Vacuum(ip, token) bot.manual_start() bot.manual_control(0, 0.3, 2000) # move forward with max speed for 2 seconds bot.manual_control(90, 0, 1000) # rotate bot.manual_stop() 

En este punto, la aspiradora deber铆a decir Usando controles remotos (o algo similar dependiendo del firmware), mover y parar

Paso 3, conecta Dualshock


Despu茅s de un poco de investigaci贸n, se decidi贸 utilizar pygame.
Analizamos qu茅 botones / pegatinas son responsables de

 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 # Touchpad to exit if event.button == 13: flag = False elif event.type == pygame.JOYBUTTONUP: if mode == 'unk': print('Ready to go! Press X to start manual mode') if event.button == BUTTON_X: mode = 'manual' bot.manual_start() elif mode == 'manual': if event.button == BUTTON_TRIANGLE: bot.manual_stop() mode = 'unk' elif event.button == BUTTON_X: play_sound('http://192.168.1.43:8080/dejavu.mp3') # see ya later elif event.button == BUTTON_CIRCLE: # stop sound play_sound(';') if mode == 'manual': try: move_robot(bot, button, axis) # see ya in the next step except: bot.manual_start() pass time.sleep(0.01) 

Por ahora, en move_robot, solo puede imprimir (eje) y verificar que el joystick est茅 funcionando.
Luego, tenemos que hacer que el robot se monte cuando presionas los botones / palos, eleg铆 el palo izquierdo en el eje Y (arriba -1, abajo 1) para la velocidad y el palo derecho en el eje X para el 谩ngulo, result贸 as铆

 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 # Right stick X if axis[2] != 0: rot = -translate(axis[2], -1, 1, -90, 90) if abs(rot) < 8: rot = 0 # Left stick Y, -1 up, 1 down if axis[1] != 0: val = -translate(axis[1], -1, 1, to_min, to_max) if abs(val) < 0.07: val = 0 if rot or val: bot.manual_control(rot, val, 150) 

Ejecute el script, presione X en el controlador y el robot debe montar y girar
En esta etapa, tuve un problema: por alguna raz贸n, si presionas el joystick izquierdo hacia el final e intentas girar, no girar谩, primero tendr谩s que reducir la velocidad, si intentas reducir los valores de mapeo, por ejemplo, establece -0.29, 0.29, comenzar谩 a circular , hasta que cambie la posici贸n de la etiqueta izquierda, nunca descubr铆 cu谩l es el problema

Paso 4, agrega algo de m煤sica


Vamos por ssh a nuestro robot y vemos qu茅 lenguajes de script hay.

No hab铆a Python, pero no vi el punto de instalarlo, pero encontr茅 una perla, adecuada para nuestra peque帽a tarea.

A continuaci贸n, instale sox:

 sudo apt-get install sox, libsox-fmt-mp3 

y escribe un peque帽o servidor en la perla:

 #!/usr/bin/perl use IO::Socket::INET; $| = 1; my $socket = new IO::Socket::INET ( LocalHost => '0.0.0.0', LocalPort => '7777', Proto => 'tcp', Listen => 2, Reuse => 1 ); die "cannot create socket $!\n" unless $socket; print "server waiting for client connection on port 7777\n"; while(1) { my $client_socket = $socket->accept(); my $client_address = $client_socket->peerhost(); my $client_port = $client_socket->peerport(); print "connection from $client_address:$client_port\n"; my $data = ""; $client_socket->recv($data, 256); print "received data: $data\n"; my @urls = split /;/, $data; system("killall play > /dev/null"); $data = "ok"; $client_socket->send($data); shutdown($client_socket, 1); if ( $urls[0] ne "") { system("play -q -v 0.4 " . $urls[0] . " &"); } } $socket->close(); 

 sudo perl sound_server.pl 

en nuestra consola hacemos algo como

 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() 

Y a trav茅s de la aspiradora deber铆a jugar nuestro test.mp3 (en consecuencia, necesitamos elevar el servidor de archivos en nuestra m谩quina local).

Nuestra funci贸n play_sound () har谩 casi lo mismo, solo sendall (url + ';') ser谩, url es el argumento de la funci贸n.

Resultado


Source: https://habr.com/ru/post/es435064/


All Articles