From 2e8383760b2f32e8d068a4b235b6379cd3f06c17 Mon Sep 17 00:00:00 2001 From: Marek Siarkowicz Date: Sat, 13 Jun 2015 00:06:19 +0200 Subject: First step of zik 2.0 feature implementation. --- ParrotZik.py | 204 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 114 insertions(+), 90 deletions(-) (limited to 'ParrotZik.py') diff --git a/ParrotZik.py b/ParrotZik.py index 514be50..6c1cd69 100644 --- a/ParrotZik.py +++ b/ParrotZik.py @@ -7,63 +7,111 @@ else: import ParrotProtocol from BeautifulSoup import BeautifulSoup -class ParrotZik(object): - def __init__(self, addr=None): - uuids = ["0ef0f502-f0ee-46c9-986c-54ed027807fb", - "8B6814D3-6CE7-4498-9700-9312C1711F63"] +def connect(addr=None): + uuids = ["0ef0f502-f0ee-46c9-986c-54ed027807fb", + "8B6814D3-6CE7-4498-9700-9312C1711F63"] + + if sys.platform == "darwin": + service_matches = lightblue.findservices( + name="Parrot RFcomm service", addr=addr) + else: + for uuid in uuids: + service_matches = bluetooth.find_service(uuid=uuid, + address=addr) + if service_matches: + break + + if len(service_matches) == 0: + print "Failed to find Parrot Zik RFCOMM service" + return ParrotZikBase(ParrotZikApi(None)) + + if sys.platform == "darwin": + first_match = service_matches[0] + port = first_match[1] + name = first_match[2] + host = first_match[0] + else: + first_match = service_matches[0] + port = first_match["port"] + name = first_match["name"] + host = first_match["host"] + + print "Connecting to \"%s\" on %s" % (name, host) + + if sys.platform == "darwin": + sock = lightblue.socket() + else: + sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM) + + sock.connect((host, port)) + + sock.send('\x00\x03\x00') + data = sock.recv(1024) + api = ParrotZikApi(sock) + if api.version.startswith('1'): + return ParrotZikVersion1(api) + else: + return ParrotZikVersion2(api) + + +class ParrotZikApi(object): + def __init__(self, socket): + self.sock = socket - if sys.platform == "darwin": - service_matches = lightblue.findservices( - name="Parrot RFcomm service", addr=addr) - else: - for uuid in uuids: - service_matches = bluetooth.find_service(uuid=uuid, - address=addr) - if service_matches: - break - - if len(service_matches) == 0: - print "Failed to find Parrot Zik RFCOMM service" - self.sock = "" - return + @property + def version(self): + data = self.get("/api/software/version/get") + try: + return data.answer.software["version"] + except KeyError: + return data.answer.software['sip6'] - if sys.platform == "darwin": - first_match = service_matches[0] - port = first_match[1] - name = first_match[2] - host = first_match[0] - else: - first_match = service_matches[0] - port = first_match["port"] - name = first_match["name"] - host = first_match["host"] + def get(self, message): + message = ParrotProtocol.getRequest(message) + return self.send_message(message) - print "Connecting to \"%s\" on %s" % (name, host) + def set(self, message, arg): + message = ParrotProtocol.setRequest(message, str(arg).lower()) + return self.send_message(message) + def send_message(self, message): + try: + self.sock.send(str(message)) + except Exception: + self.sock = "" + return if sys.platform == "darwin": - self.sock = lightblue.socket() + data = self.sock.recv(30) else: - self.sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM) + data = self.sock.recv(7) + data = self.sock.recv(1024) + data = BeautifulSoup(data) + return data - self.sock.connect((host, port)) + def close(self): + self.sock.close() - self.sock.send('\x00\x03\x00') - data = self.sock.recv(1024) +class ParrotZikBase(object): + def __init__(self, api): + self.api = api self.BatteryLevel = 100 self.BatteryCharging = False + @property + def version(self): + return self.api.version + @property def battery_state(self): - data = self.get("/api/system/battery/get") + data = self.api.get("/api/system/battery/get") return data.answer.system.battery["state"] - @property - def battery_level(self): - data = self.get("/api/system/battery/get") + def get_battery_level(self, field_name): + data = self.api.get("/api/system/battery/get") try: - if data.answer.system.battery["level"] != '': - self.BatteryLevel = data.answer.system.battery["level"] + if data.answer.system.battery[field_name] != '': + self.BatteryLevel = data.answer.system.battery[field_name] if data.answer.system.battery["state"] == 'charging': self.BatteryCharging = True else: @@ -78,38 +126,30 @@ class ParrotZik(object): return self.BatteryLevel - @property - def version(self): - data = self.get("/api/software/version/get") - try: - return data.answer.software["version"] - except KeyError: - return data.answer.software['sip6'] - @property def friendly_name(self): - data = self.get("/api/bluetooth/friendlyname/get") + data = self.api.get("/api/bluetooth/friendlyname/get") return data.answer.bluetooth["friendlyname"] @property def auto_connect(self): - data = self.get("/api/system/auto_connection/enabled/get") + data = self.api.get("/api/system/auto_connection/enabled/get") return self._result_to_bool( data.answer.system.auto_connection["enabled"]) @auto_connect.setter def auto_connect(self, arg): - self.set("/api/system/auto_connection/enabled/set", arg) + self.api.get("/api/system/auto_connection/enabled/set", arg) @property def anc_phone_mode(self): - data = self.get("/api/system/anc_phone_mode/enabled/get") + data = self.api.get("/api/system/anc_phone_mode/enabled/get") return self._result_to_bool( data.answer.system.anc_phone_mode["enabled"]) @property def noise_cancel(self): - data = self.get("/api/audio/noise_cancellation/enabled/get") + data = self.api.get("/api/audio/noise_cancellation/enabled/get") try: return self._result_to_bool( data.answer.audio.noise_cancellation["enabled"]) @@ -118,24 +158,11 @@ class ParrotZik(object): @noise_cancel.setter def noise_cancel(self, arg): - self.set("/api/audio/noise_cancellation/enabled/set", arg) - - @property - def lou_reed_mode(self): - data = self.get("/api/audio/specific_mode/enabled/get") - try: - return self._result_to_bool( - data.answer.audio.specific_mode["enabled"]) - except TypeError: - return False - - @lou_reed_mode.setter - def lou_reed_mode(self, arg): - self.set("/api/audio/specific_mode/enabled/set", arg) + self.api.get("/api/audio/noise_cancellation/enabled/set", arg) @property def concert_hall(self): - data = self.get("/api/audio/sound_effect/enabled/get") + data = self.api.get("/api/audio/sound_effect/enabled/get") try: return self._result_to_bool( data.answer.audio.sound_effect["enabled"]) @@ -144,7 +171,7 @@ class ParrotZik(object): @concert_hall.setter def concert_hall(self, arg): - self.set("/api/audio/sound_effect/enabled/set", arg) + self.api.get("/api/audio/sound_effect/enabled/set", arg) def _result_to_bool(self, result): if result == "true": @@ -154,27 +181,24 @@ class ParrotZik(object): else: raise AssertionError(result) - def get(self, message): - message = ParrotProtocol.getRequest(message) - return self.send_message(message) - def set(self, message, arg): - message = ParrotProtocol.setRequest(message, str(arg).lower()) - return self.send_message(message) +class ParrotZikVersion1(ParrotZikBase): + @property + def battery_level(self): + return self.get_battery_level('level') - def send_message(self, message): - try: - self.sock.send(str(message)) - except Exception: - self.sock = "" - return - if sys.platform == "darwin": - data = self.sock.recv(30) - else: - data = self.sock.recv(7) - data = self.sock.recv(1024) - data = BeautifulSoup(data) - return data + @property + def lou_reed_mode(self): + data = self.api.get("/api/audio/specific_mode/enabled/get") + return self._result_to_bool( + data.answer.audio.specific_mode["enabled"]) - def close(self): - self.sock.close() + @lou_reed_mode.setter + def lou_reed_mode(self, arg): + self.api.get("/api/audio/specific_mode/enabled/set", arg) + + +class ParrotZikVersion2(ParrotZikBase): + @property + def battery_level(self): + return self.get_battery_level('percent') -- cgit v1.2.1