controller initialization
This commit is contained in:
parent
b4f6a30007
commit
4c3dae7e21
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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!"
|
||||||
|
|
@ -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,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
|
||||||
|
|
@ -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()
|
|
||||||
Loading…
Reference in New Issue