controller initialization

This commit is contained in:
HappyZ 2019-05-04 15:23:41 -05:00
parent b4f6a30007
commit 4c3dae7e21
7 changed files with 179 additions and 84 deletions

31
controller.py Normal file
View File

@ -0,0 +1,31 @@
from libs.env import get_env_var
from libs.env import set_env_var
from libs.vacuum_controller import VacuumController
def export_ip_token(ip, token):
print("Exporting to environment variables")
set_env_var("MIROBO_IP", ip)
set_env_var("MIROBO_TOKEN", token)
print("Exporting to `.setup.sh` for later references")
with open(".setup.sh", "w") as f:
f.write("export MIROBO_IP={}\n".format(ip))
f.write("export MIROBO_TOKEN={}\n".format(token))
if __name__ == '__main__':
ip = get_env_var("MIROBO_IP")
token = get_env_var("MIROBO_TOKEN")
c = VacuumController(ip, token)
if not c.test_connection():
if ip is None or token is None:
c = VacuumController()
assert(c.test_connection())
export_ip_token(c.ip, c.token)

18
get_loc_est.py Normal file
View File

@ -0,0 +1,18 @@
import argparse
import subprocess
from libs.parser import get_slam_log
# args
parser = argparse.ArgumentParser(
description='Get Location Estimation from SLAM log on the vacuum'
)
parser.add_argument(
dest='filepath',
help='Specify output file path'
)
args, __ = parser.parse_known_args()
# fetch slam
get_slam_log(outputfile=args.filepath)

23
init_vacuum.sh Executable file
View File

@ -0,0 +1,23 @@
#!/bin/bash
REMOTE="root@${MIROBO_IP}"
EXP_FP="/mnt/data/exp"
REMOTE_EXP_FP="${REMOTE}:${EXP_FP}"
REMOTE_CMD="ssh -t ${REMOTE}"
echo "IP: ${MIROBO_IP}"
echo "EXP_FP: ${EXP_FP}"
echo "Create folder on vacuum.."
${REMOTE_CMD} mkdir -p ${EXP_FP}/libs
echo "Push files to vacuum to run.."
scp ./libs/__init__.py ${REMOTE_EXP_FP}
scp ./libs/parser.py ${REMOTE_EXP_FP}
scp ./get_loc_est.py ${REMOTE_EXP_FP}
echo "Install necessary packages"
${REMOTE_CMD} apt --yes install python3-minimal
echo "Done!"

13
libs/env.py Normal file
View File

@ -0,0 +1,13 @@
import os
def get_env_var(name):
return os.environ[name] if name in os.environ else None
def set_env_var(name, value):
os.environ[name] = value
def clear_env_var(name):
del os.environ[name]

0
libs/exceptions.py Normal file
View File

94
libs/vacuum_controller.py Normal file
View File

@ -0,0 +1,94 @@
import miio
import codecs
import socket
class VacuumController():
'''
controlling xiaomi vacuum
'''
def __init__(self, ip=None, token=None):
self.ip = ip
self.token = token
if self.ip is None:
self.finding_ip()
self.vacuum = miio.Vacuum(ip=self.ip, token=self.token)
if self.token is None:
self.get_token()
def _discover_devices(self, timeout=5):
ips = []
# broadcast magic handshake to find devices
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.settimeout(timeout)
s.sendto(
bytes.fromhex('21310020ffffffffffffffffffffffffffffffffffffffffffffffffffffffff'),
('<broadcast>', 54321)
)
while 1:
try:
__, addr = s.recvfrom(1024)
if addr[0] not in ips:
ips.append(addr[0])
except socket.timeout:
break # ignore timeouts on discover
except Exception as e:
print('Error while reading discover results: {}'.format(e))
break
return ips
def finding_ip(self):
'''
getting ip of vacuum
'''
ips = self._discover_devices()
if not ips:
print('Err: cannot find any vacuum IP')
exit(-1)
if len(ips) == 1:
self.ip = ips[0]
return
print('Found multiple IPs:')
for i, ip in enumerate(ips):
print(' {0}. {1}'.format(i+1, ip))
try:
selected = input('Please select one by typing number (1-{}): '.format(len(ips)))
self.ip = ips[int(selected)-1]
except KeyboardInterrupt:
print('User requested to exit')
exit(0)
except ValueError:
print('Err: Please enter only one number')
exit(-1)
except IndexError:
print('Err: Please enter one number between 1-{}'.format(len(ips)))
exit(-1)
except BaseException as e:
print('Err: {}'.format(e))
exit(-1)
def get_token(self):
'''
getting token by handshaking with vacuum
'''
print('Sending handshake to get token')
m = self.vacuum.do_discover()
self.vacuum.token = m.checksum
self.token = codecs.encode(m.checksum, 'hex')
def test_connection(self):
'''
test connection
'''
try:
s = self.vacuum.status()
print(s)
return True
except Exception as e:
print('Err: {}'.format(e))
return False

View File

@ -1,84 +0,0 @@
import miio
import codecs
import socket
def discover_devices():
timeout = 5
seen_addrs = [] # type: List[str]
addr = '<broadcast>'
# magic, length 32
helobytes = bytes.fromhex('21310020ffffffffffffffffffffffffffffffffffffffffffffffffffffffff')
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.settimeout(timeout)
s.sendto(helobytes, (addr, 54321))
while True:
try:
data, addr = s.recvfrom(1024)
if addr[0] not in seen_addrs:
seen_addrs.append(addr[0])
except socket.timeout:
break # ignore timeouts on discover
except Exception as ex:
print('Error while reading discover results:', ex)
break
return seen_addrs
def select_item(welcome_text, items):
print(welcome_text)
for i, item in enumerate(items):
print('{}. {}'.format(i+1, item))
try:
selected = input('Please select option by typing number (1-{}): '.format(len(items)))
result = items[int(selected)-1]
return result
except KeyboardInterrupt:
print('User requested to exit')
exit()
except ValueError:
print('Error! Please enter only one number')
exit()
except IndexError:
print('Error! Please enter one number between 1-{}'.format(len(items)))
exit()
ip_address = None
known_token = None
if not ip_address:
print('Address is not set. Trying to discover.')
seen_addrs = discover_devices()
if len(seen_addrs) == 0:
print('No devices discovered.')
exit()
elif len(seen_addrs) == 1:
ip_address = seen_addrs[0]
else:
ip_address = select_item('Choose device for connection:', seen_addrs)
vacuum = miio.Vacuum(ip=ip_address, token=known_token)
if not known_token:
print('Sending handshake to get token')
m = vacuum.do_discover()
vacuum.token = m.checksum
known_token = codecs.encode(m.checksum, 'hex')
else:
if len(known_token) == 16:
known_token = str(binascii.hexlify(bytes(known_token, encoding="utf8")))
print("ip_address: {}".format(ip_address))
print("known_token: {}".format(known_token))
try:
s = vacuum.status()
print(s)
except Exception as ex:
print('error while checking device:', ex)
exit()
vacuum.home()