From 947a9f7d10bc3c54939cfa72dab27b2e64034318 Mon Sep 17 00:00:00 2001 From: Marek Siarkowicz Date: Mon, 15 Jun 2015 11:33:33 +0200 Subject: Create packet. --- parrot_zik/resource_manager.py | 176 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 parrot_zik/resource_manager.py (limited to 'parrot_zik/resource_manager.py') diff --git a/parrot_zik/resource_manager.py b/parrot_zik/resource_manager.py new file mode 100644 index 0000000..8b63e8c --- /dev/null +++ b/parrot_zik/resource_manager.py @@ -0,0 +1,176 @@ +import bluetooth +from operator import itemgetter +import sys + +from BeautifulSoup import BeautifulSoup + +from parrot_zik.message import Message + + +class ResourceManagerBase(object): + resources = [ + ] + + def __init__(self, socket, resource_values=None): + self.sock = socket + self.resource_values = resource_values or {} + + def get(self, resource): + try: + return self.resource_values[resource] + except KeyError: + return self.fetch(resource) + + def fetch(self, resource): + result = self.send_message(self._create_message(resource, 'get')) + self.resource_values[resource] = result + return result + + def toggle_on(self, resource): + self.send_message(self._create_message(resource, 'enable')) + self.fetch(resource) + + def toggle_off(self, resource): + self.send_message(self._create_message(resource, 'disable')) + self.fetch(resource) + + def set(self, resource, arg): + self.send_message(self._create_message(resource, 'set', arg)) + self.fetch(resource) + + def _create_message(self, resource, method, arg=None): + assert resource in self.resources, 'Unknown resource {}'.format(resource) + assert method in self.resources[resource], 'Unhandled method {} for {}'.format(method, resource) + return Message(resource, method, arg) + + def send_message(self, message): + try: + self.sock.send(str(message)) + return self.get_answer(message) + except bluetooth.btcommon.BluetoothError: + raise DeviceDisconnected + + def get_answer(self, message): + data = self.receive_message() + notifications = [] + while not data.answer: + if data.notify: + notifications.append(data.notify) + else: + raise AssertionError('Unknown response') + data = self.receive_message() + self.handle_notifications(notifications, message.resource) + return data.answer + + def handle_notifications(self, notifications, resource): + paths = map(itemgetter('path'), notifications) + clean_paths = set(map(self._clean_path, paths)) + for path in clean_paths: + if resource != path: + self.fetch(path) + + def _clean_path(self, path): + return path.rsplit('/', 1)[0].encode('utf-8') + + def receive_message(self): + if sys.platform == "darwin": + self.sock.recv(30) + else: + self.sock.recv(7) + return BeautifulSoup(self.sock.recv(1024)) + + def close(self): + self.sock.close() + + +class GenericResourceManager(ResourceManagerBase): + resources = { + '/api/software/version': ['get'], + } + + def __init__(self, sock): + super(GenericResourceManager, self).__init__(sock) + self.notifications = [] + + def handle_notification(self, notification): + self.notifications.append(notification) + + def get_resource_manager(self, resource_manager_class): + resource_manager = resource_manager_class(self.sock, self.resource_values) + resource_manager.handle_notifications(self.notifications, '/api/software/version') + return resource_manager + + @property + def api_version(self): + answer = self.get("/api/software/version") + try: + return answer.software["version"] + except KeyError: + return answer.software['sip6'] + + +class Version1ResourceManager(ResourceManagerBase): + resources = { + '/api/software/version': ['get'], + '/api/system/battery': ['get'], + '/api/bluetooth/friendlyname': ['get'], + '/api/system/auto_connection/enabled': ['get', 'set'], + '/api/system/anc_phone_mode/enabled': ['get', 'set'], + '/api/audio/specific_mode/enabled': ['get', 'set'], + '/api/audio/sound_effect/enabled': ['get', 'set'], + '/api/audio/noise_cancellation/enabled': ['get', 'set'], + } + +class Version2ResourceManager(ResourceManagerBase): + resources = { + '/api/account/username': ['get', 'set'], + '/api/appli_version': ['set'], + '/api/audio/counter': ['get'], + '/api/audio/equalizer/enabled': ['get', 'set'], + '/api/audio/equalizer/preset_id': ['set'], + '/api/audio/equalizer/preset_value': ['set'], + '/api/audio/noise_cancellation/enabled': ['get', 'set'], + '/api/audio/noise_control/enabled': ['get', 'set'], + '/api/audio/noise_control': ['get'], + '/api/audio/noise_control/phone_mode': ['get', 'set'], + '/api/audio/noise': ['get'], + '/api/audio/param_equalizer/value': ['set'], + '/api/audio/preset/bypass': ['get', 'set'], + '/api/audio/preset/': ['clear_all'], + '/api/audio/preset/counter': ['get'], + '/api/audio/preset/current': ['get'], + '/api/audio/preset': ['download', 'activate', 'save', 'remove', 'cancel_producer'], + '/api/audio/preset/synchro': ['start', 'stop'], + '/api/audio/smart_audio_tune': ['get', 'set'], + '/api/audio/sound_effect/angle': ['get', 'set'], + '/api/audio/sound_effect/enabled': ['get', 'set'], + '/api/audio/sound_effect': ['get'], + '/api/audio/sound_effect/room_size': ['get', 'set'], + '/api/audio/source': ['get'], + '/api/audio/specific_mode/enabled': ['get', 'set'], + '/api/audio/thumb_equalizer/value': ['get', 'set'], + '/api/audio/track/metadata': ['get', 'force'], + '/api/bluetooth/friendlyname': ['get', 'set'], + '/api/flight_mode': ['get', 'enable', 'disable'], + '/api/software/download_check_state': ['get'], + '/api/software/download_size': ['set'], + '/api/software/tts': ['get', 'enable', 'disable'], + '/api/software/version_checking': ['get'], + '/api/software/version': ['get'], + '/api/system/anc_phone_mode/enabled': ['get', 'set'], + '/api/system/auto_connection/enabled': ['get', 'set'], + '/api/system/auto_power_off': ['get', 'set'], + '/api/system/auto_power_off/presets_list': ['get'], + '/api/system/battery/forecast': ['get'], + '/api/system/battery': ['get'], + '/api/system/bt_address': ['get'], + '/api/system': ['calibrate'], + '/api/system/color': ['get'], + '/api/system/device_type': ['get'], + '/api/system/': ['factory_reset'], + '/api/system/head_detection/enabled': ['get', 'set'], + '/api/system/pi': ['get'], + } + +class DeviceDisconnected(Exception): + pass -- cgit v1.2.1 From b4ff541fd77d4076051e57b748fc5817e0cc1e25 Mon Sep 17 00:00:00 2001 From: Marek Siarkowicz Date: Mon, 15 Jun 2015 12:41:30 +0200 Subject: Make into proper package. --- parrot_zik/resource_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'parrot_zik/resource_manager.py') diff --git a/parrot_zik/resource_manager.py b/parrot_zik/resource_manager.py index 8b63e8c..8a9cd46 100644 --- a/parrot_zik/resource_manager.py +++ b/parrot_zik/resource_manager.py @@ -4,7 +4,7 @@ import sys from BeautifulSoup import BeautifulSoup -from parrot_zik.message import Message +from .message import Message class ResourceManagerBase(object): -- cgit v1.2.1 From 2340cbd0291f6f0f64615a3ed0cb5cfc062ec4f5 Mon Sep 17 00:00:00 2001 From: Marek Siarkowicz Date: Mon, 15 Jun 2015 15:32:31 +0200 Subject: Add more information to unknown response. --- parrot_zik/resource_manager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'parrot_zik/resource_manager.py') diff --git a/parrot_zik/resource_manager.py b/parrot_zik/resource_manager.py index 8a9cd46..4f90fb6 100644 --- a/parrot_zik/resource_manager.py +++ b/parrot_zik/resource_manager.py @@ -57,7 +57,8 @@ class ResourceManagerBase(object): if data.notify: notifications.append(data.notify) else: - raise AssertionError('Unknown response') + raise AssertionError('Unknown response "{}" for {}'.format( + data, message.request_string)) data = self.receive_message() self.handle_notifications(notifications, message.resource) return data.answer -- cgit v1.2.1 From 494e542c8eca97cb01f6e4495588a08136f482a0 Mon Sep 17 00:00:00 2001 From: Marek Siarkowicz Date: Mon, 15 Jun 2015 17:37:54 +0200 Subject: Migrate to newer wersion of beatifulsop. --- parrot_zik/resource_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'parrot_zik/resource_manager.py') diff --git a/parrot_zik/resource_manager.py b/parrot_zik/resource_manager.py index 4f90fb6..c2dae2f 100644 --- a/parrot_zik/resource_manager.py +++ b/parrot_zik/resource_manager.py @@ -2,7 +2,7 @@ import bluetooth from operator import itemgetter import sys -from BeautifulSoup import BeautifulSoup +from bs4 import BeautifulSoup from .message import Message -- cgit v1.2.1 From d6e3eb4ffb88959503cf41870dab72446ace6b46 Mon Sep 17 00:00:00 2001 From: Pavel Salomatov Date: Fri, 5 Feb 2016 15:41:47 +0300 Subject: Added functionality to change noise cancellation mode "Head detection" now initializes on startup --- parrot_zik/resource_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'parrot_zik/resource_manager.py') diff --git a/parrot_zik/resource_manager.py b/parrot_zik/resource_manager.py index c2dae2f..aa141cb 100644 --- a/parrot_zik/resource_manager.py +++ b/parrot_zik/resource_manager.py @@ -132,7 +132,7 @@ class Version2ResourceManager(ResourceManagerBase): '/api/audio/equalizer/preset_value': ['set'], '/api/audio/noise_cancellation/enabled': ['get', 'set'], '/api/audio/noise_control/enabled': ['get', 'set'], - '/api/audio/noise_control': ['get'], + '/api/audio/noise_control': ['get', 'set'], '/api/audio/noise_control/phone_mode': ['get', 'set'], '/api/audio/noise': ['get'], '/api/audio/param_equalizer/value': ['set'], -- cgit v1.2.1