def test_put_characteristic(self): model_mixin.id_counter = 0 c = Controller() a = Accessory( 'test-dev-123', 'TestCo', 'Test Dev Pro', '00000', 1 ) a.add_service(LightBulbService()) manager = DeviceManager() manager._devices['00:00:00:00:00'] = Device(a) with mock.patch('homekit.controller.ble_impl.device.DeviceManager') as m1: with mock.patch('homekit.controller.ble_impl.DeviceManager') as m2: m1.return_value = manager m2.return_value = manager c.perform_pairing_ble('test-pairing', '00:00:00:00:00', '111-11-111') c.pairings['test-pairing'].list_accessories_and_characteristics() result = c.pairings['test-pairing'].put_characteristics([ (1, 10, True), ]) self.assertEqual(result, {}) self.assertTrue(a.services[1].characteristics[0].get_value()) result = c.pairings['test-pairing'].put_characteristics([ (1, 10, False), ]) self.assertEqual(result, {}) self.assertFalse(a.services[1].characteristics[0].get_value())
def test_pair_unpair(self): model_mixin.id_counter = 0 c = Controller() a = Accessory( 'test-dev-123', 'TestCo', 'Test Dev Pro', '00000', 1 ) a.add_service(LightBulbService()) manager = DeviceManager() device = manager._devices['00:00:00:00:00'] = Device(a) with mock.patch('homekit.controller.ble_impl.DeviceManager') as m1: with mock.patch('homekit.controller.ble_impl.device.DeviceManager') as m2: m1.return_value = manager m2.return_value = manager c.perform_pairing_ble('test-pairing', '00:00:00:00:00', '111-11-111') c.pairings['test-pairing'].list_accessories_and_characteristics() self.assertEqual(len(device.peers), 1) c.remove_pairing('test-pairing') self.assertEqual(len(device.peers), 0) self.assertNotIn('test-pairing', c.pairings)
def test_discovery(self): model_mixin.id_counter = 0 c = Controller() a = Accessory( 'test-dev-123', 'TestCo', 'Test Dev Pro', '00000', 1 ) a.add_service(LightBulbService()) manager = DeviceManager() manager._devices['00:00:00:00:00'] = Device(a) with mock.patch('homekit.controller.controller.DiscoveryDeviceManager') as m: m.return_value = manager self.assertEqual(c.discover_ble(0), [{ 'acid': 9, 'category': 'Thermostat', 'cn': 2, 'cv': 2, 'device_id': '99:99:99:99:99:99', 'flags': 'unpaired', 'gsn': 3985, 'mac': '00:00:00:00:00', 'name': 'Test', 'sf': 1, }])
def setup_accessories_from_file(path): """Load an collection of accessory defs from JSON data.""" with open(path, 'r') as accessories_data: accessories_json = json.load(accessories_data) accessories = [] for accessory_data in accessories_json: accessory = Accessory('Name', 'Mfr', 'Model', '0001', '0.1') accessory.services = [] accessory.aid = accessory_data['aid'] for service_data in accessory_data['services']: service = FakeService('public.hap.service.accessory-information') service.type = service_data['type'] service.iid = service_data['iid'] for char_data in service_data['characteristics']: char = FakeCharacteristic(1, '23', None) char.type = char_data['type'] char.iid = char_data['iid'] char.perms = char_data['perms'] char.format = char_data['format'] if 'description' in char_data: char.description = char_data['description'] if 'value' in char_data: char.value = char_data['value'] service.characteristics.append(char) accessory.services.append(service) accessories.append(accessory) return accessories
async def setup_test_component(hass, services): """Load a fake homekit accessory based on a homekit accessory model.""" domain = None for service in services: service_name = ServicesTypes.get_short(service.type) if service_name in HOMEKIT_ACCESSORY_DISPATCH: domain = HOMEKIT_ACCESSORY_DISPATCH[service_name] break assert domain, 'Cannot map test homekit services to homeassistant domain' config = {'discovery': {}} with mock.patch('homekit.Controller') as controller: fake_controller = controller.return_value = FakeController() await async_setup_component(hass, DOMAIN, config) accessory = Accessory('TestDevice', 'example.com', 'Test', '0001', '0.1') accessory.services.extend(services) pairing = fake_controller.add(accessory) discovery_info = { 'host': '127.0.0.1', 'port': 8080, 'properties': { 'md': 'TestDevice', 'id': '00:00:00:00:00:00', 'c#': 1, } } fire_service_discovered(hass, SERVICE_HOMEKIT, discovery_info) await hass.async_block_till_done() return Helper(hass, '.'.join((domain, 'testdevice')), pairing, accessory)
def test_get_characteristic_disconnected_read(self): model_mixin.id_counter = 0 c = Controller() a = Accessory( 'test-dev-123', 'TestCo', 'Test Dev Pro', '00000', 1 ) a.add_service(LightBulbService()) manager = DeviceManager() d = manager._devices['00:00:00:00:00'] = Device(a) with mock.patch('homekit.controller.ble_impl.device.DeviceManager') as m1: with mock.patch('homekit.controller.ble_impl.DeviceManager') as m2: m1.return_value = manager m2.return_value = manager c.perform_pairing_ble('test-pairing', '00:00:00:00:00', '111-11-111') c.pairings['test-pairing'].list_accessories_and_characteristics() # Establishes a secure session c.pairings['test-pairing'].get_characteristics([(1, 4)]) # Disconnect from virtual bluetooth device - BleSession doesn't know yet d.disconnect() # Further reads should throw an error self.assertRaises( exceptions.AccessoryDisconnectedError, c.pairings['test-pairing'].get_characteristics, [(1, 4)], )
def test_identify(self): model_mixin.id_counter = 0 c = Controller() a = Accessory( 'test-dev-123', 'TestCo', 'Test Dev Pro', '00000', 1 ) a.add_service(LightBulbService()) manager = DeviceManager() manager._devices['00:00:00:00:00'] = Device(a) with mock.patch('homekit.controller.ble_impl.device.DeviceManager') as m1: with mock.patch('homekit.controller.ble_impl.DeviceManager') as m2: m1.return_value = manager m2.return_value = manager c.perform_pairing_ble('test-pairing', '00:00:00:00:00', '111-11-111') c.pairings['test-pairing'].list_accessories_and_characteristics() self.assertIsNone(a.services[0].characteristics[0].value) c.pairings['test-pairing'].identify() self.assertTrue(a.services[0].characteristics[0].value)
def setUpClass(cls): # prepare config file for unpaired accessory server cls.config_file = tempfile.NamedTemporaryFile() cls.config_file.write("""{ "accessory_ltpk": "7986cf939de8986f428744e36ed72d86189bea46b4dcdc8d9d79a3e4fceb92b9", "accessory_ltsk": "3d99f3e959a1f93af4056966f858074b2a1fdec1c5fd84a51ea96f9fa004156a", "accessory_pairing_id": "12:34:56:00:01:0B", "accessory_pin": "010-22-020", "c#": 0, "category": "Lightbulb", "host_ip": "127.0.0.1", "host_port": 54321, "name": "unittestLight", "peers": { }, "unsuccessful_tries": 0 }""".encode()) cls.config_file.flush() # Make sure get_id() numbers are stable between tests model_mixin.id_counter = 0 cls.httpd = AccessoryServer(cls.config_file.name, None) cls.httpd.set_identify_callback(identify_callback) accessory = Accessory('Testlicht', 'lusiardi.de', 'Demoserver', '0001', '0.1') accessory.set_identify_callback(identify_callback) lightBulbService = LightBulbService() lightBulbService.set_on_set_callback(set_value) accessory.services.append(lightBulbService) cls.httpd.add_accessory(accessory) t = T(cls.httpd) t.start() time.sleep(10) cls.controller_file = tempfile.NamedTemporaryFile()
def test_get_characteristic_invalid_iid(self): model_mixin.id_counter = 0 c = Controller() a = Accessory( 'test-dev-123', 'TestCo', 'Test Dev Pro', '00000', 1 ) a.add_service(LightBulbService()) manager = DeviceManager() manager._devices['00:00:00:00:00'] = Device(a) with mock.patch('homekit.controller.ble_impl.device.DeviceManager') as m1: with mock.patch('homekit.controller.ble_impl.DeviceManager') as m2: m1.return_value = manager m2.return_value = manager c.perform_pairing_ble('test-pairing', '00:00:00:00:00', '111-11-111') c.pairings['test-pairing'].list_accessories_and_characteristics() result = c.pairings['test-pairing'].get_characteristics([ (2, 1), ]) self.assertEqual(result, { (2, 1): { "status": 6, "description": "Accessory was not able to perform the requested operation", } })
def setUpClass(cls): # prepare config file for paired accessory server, delete false for Windows, so we can close the file and open # it for reading after that cls.config_file = tempfile.NamedTemporaryFile(delete=False) cls.config_file.write("""{ "accessory_ltpk": "7986cf939de8986f428744e36ed72d86189bea46b4dcdc8d9d79a3e4fceb92b9", "accessory_ltsk": "3d99f3e959a1f93af4056966f858074b2a1fdec1c5fd84a51ea96f9fa004156a", "accessory_pairing_id": "12:34:56:00:01:0A", "accessory_pin": "031-45-154", "c#": 1, "category": "Lightbulb", "host_ip": "127.0.0.1", "host_port": 51842, "name": "unittestLight", "peers": { "decc6fa3-de3e-41c9-adba-ef7409821bfc": { "admin": true, "key": "d708df2fbf4a8779669f0ccd43f4962d6d49e4274f88b1292f822edc3bcf8ed8" }, "ABCDEFfa3-de3e-41c9-adba-ef7409821bfc": { "admin": false, "key": "d708df2fbf4a8779669f0ccd43f4962d6d49e4274f88b1292f822edc3bcf8ed8" } }, "unsuccessful_tries": 0 }""".encode()) cls.config_file.close() # Make sure get_id() numbers are stable between tests model_mixin.id_counter = 0 cls.logger = list() cls.httpd = AccessoryServer(cls.config_file.name, logger=cls.logger) cls.httpd.set_identify_callback(identify_callback) accessory = Accessory('Testlicht', 'lusiardi.de', 'Demoserver', '0001', '0.1') accessory.set_identify_callback(identify_callback) lightBulbService = LightBulbService() lightBulbService.set_on_set_callback(set_value) accessory.services.append(lightBulbService) cls.httpd.add_accessory(accessory) t = T(cls.httpd) t.start() time.sleep(5) cls.controller_file = tempfile.NamedTemporaryFile(delete=False) cls.controller_file.write("""{ "alias": { "Connection": "IP", "iOSDeviceLTPK": "d708df2fbf4a8779669f0ccd43f4962d6d49e4274f88b1292f822edc3bcf8ed8", "iOSPairingId": "decc6fa3-de3e-41c9-adba-ef7409821bfc", "AccessoryLTPK": "7986cf939de8986f428744e36ed72d86189bea46b4dcdc8d9d79a3e4fceb92b9", "AccessoryPairingID": "12:34:56:00:01:0A", "AccessoryPort": 51842, "AccessoryIP": "127.0.0.1", "iOSDeviceLTSK": "fa45f082ef87efc6c8c8d043d74084a3ea923a2253e323a7eb9917b4090c2fcc" } }""".encode()) cls.controller_file.close()
def setUpClass(cls): cls.config_file = tempfile.NamedTemporaryFile() cls.config_file.write("""{ "accessory_ltpk": "7986cf939de8986f428744e36ed72d86189bea46b4dcdc8d9d79a3e4fceb92b9", "accessory_ltsk": "3d99f3e959a1f93af4056966f858074b2a1fdec1c5fd84a51ea96f9fa004156a", "accessory_pairing_id": "12:34:56:00:01:0A", "accessory_pin": "031-45-154", "c#": 1, "category": "Lightbulb", "host_ip": "127.0.0.1", "host_port": 51842, "name": "unittestLight", "peers": { "decc6fa3-de3e-41c9-adba-ef7409821bfc": { "admin": true, "key": "d708df2fbf4a8779669f0ccd43f4962d6d49e4274f88b1292f822edc3bcf8ed8" } }, "unsuccessful_tries": 0 }""".encode()) cls.config_file.flush() cls.httpd = AccessoryServer(cls.config_file.name, None) cls.httpd.set_identify_callback(identify_callback) accessory = Accessory('Testlicht', 'lusiardi.de', 'Demoserver', '0001', '0.1') accessory.set_identify_callback(identify_callback) lightBulbService = LightBulbService() lightBulbService.set_on_set_callback(set_value) accessory.services.append(lightBulbService) cls.httpd.add_accessory(accessory) t = T(cls.httpd) t.start() time.sleep(5) cls.controller_file = tempfile.NamedTemporaryFile() cls.controller_file.write("""{ "alias": { "iOSDeviceLTPK": "d708df2fbf4a8779669f0ccd43f4962d6d49e4274f88b1292f822edc3bcf8ed8", "iOSPairingId": "decc6fa3-de3e-41c9-adba-ef7409821bfc", "AccessoryLTPK": "7986cf939de8986f428744e36ed72d86189bea46b4dcdc8d9d79a3e4fceb92b9", "AccessoryPairingID": "12:34:56:00:01:0A", "AccessoryPort": 51842, "AccessoryIP": "127.0.0.1", "iOSDeviceLTSK": "fa45f082ef87efc6c8c8d043d74084a3ea923a2253e323a7eb9917b4090c2fcc" } }""".encode()) cls.controller_file.flush()
def test_unpaired_identify(self): model_mixin.id_counter = 0 c = Controller() a = Accessory('test-dev-123', 'TestCo', 'Test Dev Pro', '00000', 1) a.add_service(LightBulbService()) manager = DeviceManager() manager._devices['00:00:00:00:00'] = Device(a) with mock.patch( 'homekit.controller.ble_impl.device.DeviceManager') as m: m.return_value = manager self.assertIsNone(a.services[0].characteristics[0].value) self.assertTrue(c.identify_ble('00:00:00:00:00')) self.assertTrue(a.services[0].characteristics[0].value)
def test_pair_malformed_pin(self): model_mixin.id_counter = 0 c = Controller() a = Accessory('test-dev-123', 'TestCo', 'Test Dev Pro', '00000', 1) a.add_service(LightBulbService()) manager = DeviceManager() manager._devices['00:00:00:00:00'] = Device(a) with mock.patch( 'homekit.controller.ble_impl.device.DeviceManager') as m: m.return_value = manager c.perform_pairing_ble('test-pairing', '00:00:00:00:00', '111-11-111') self.assertRaises(exceptions.MalformedPinError, c.perform_pairing_ble, 'alias2', '12:34:56:00:01:0B', '01022021')
def test_pair_success(self): model_mixin.id_counter = 0 c = Controller() a = Accessory('test-dev-123', 'TestCo', 'Test Dev Pro', '00000', 1) a.add_service(LightBulbService()) manager = DeviceManager() manager._devices['00:00:00:00:00'] = Device(a) with mock.patch( 'homekit.controller.ble_impl.device.DeviceManager') as m: m.return_value = manager c.perform_pairing_ble('test-pairing', '00:00:00:00:00', '111-11-111') self.assertEqual(c.pairings['test-pairing'].pairing_data['Connection'], 'BLE')
def test_unpaired_identify_already_paired(self): model_mixin.id_counter = 0 c = Controller() a = Accessory('test-dev-123', 'TestCo', 'Test Dev Pro', '00000', 1) a.add_service(LightBulbService()) manager = DeviceManager() manager._devices['00:00:00:00:00'] = Device(a) with mock.patch( 'homekit.controller.ble_impl.device.DeviceManager') as m: m.return_value = manager c.perform_pairing_ble('test-pairing', '00:00:00:00:00', '111-11-111') self.assertIsNone(a.services[0].characteristics[0].value) self.assertRaises(exceptions.AlreadyPairedError, c.identify_ble, '00:00:00:00:00')
async def setup_accessories_from_file(hass, path): """Load an collection of accessory defs from JSON data.""" accessories_fixture = await hass.async_add_executor_job( load_fixture, os.path.join('homekit_controller', path), ) accessories_json = json.loads(accessories_fixture) accessories = [] for accessory_data in accessories_json: accessory = Accessory('Name', 'Mfr', 'Model', '0001', '0.1') accessory.services = [] accessory.aid = accessory_data['aid'] for service_data in accessory_data['services']: service = FakeService('public.hap.service.accessory-information') service.type = service_data['type'] service.iid = service_data['iid'] for char_data in service_data['characteristics']: char = FakeCharacteristic(1, '23', None) char.type = char_data['type'] char.iid = char_data['iid'] char.perms = char_data['perms'] char.format = char_data['format'] if 'description' in char_data: char.description = char_data['description'] if 'value' in char_data: char.value = char_data['value'] if 'minValue' in char_data: char.minValue = char_data['minValue'] if 'maxValue' in char_data: char.maxValue = char_data['maxValue'] if 'valid-values' in char_data: char.valid_values = char_data['valid-values'] service.characteristics.append(char) accessory.services.append(service) accessories.append(accessory) return accessories
async def setup_accessories_from_file(hass, path): """Load an collection of accessory defs from JSON data.""" accessories_fixture = await hass.async_add_executor_job( load_fixture, os.path.join("homekit_controller", path) ) accessories_json = json.loads(accessories_fixture) accessories = [] for accessory_data in accessories_json: accessory = Accessory("Name", "Mfr", "Model", "0001", "0.1") accessory.services = [] accessory.aid = accessory_data["aid"] for service_data in accessory_data["services"]: service = FakeService("public.hap.service.accessory-information") service.type = service_data["type"] service.iid = service_data["iid"] for char_data in service_data["characteristics"]: char = FakeCharacteristic(1, "23", None) char.type = char_data["type"] char.iid = char_data["iid"] char.perms = char_data["perms"] char.format = char_data["format"] if "description" in char_data: char.description = char_data["description"] if "value" in char_data: char.value = char_data["value"] if "minValue" in char_data: char.minValue = char_data["minValue"] if "maxValue" in char_data: char.maxValue = char_data["maxValue"] if "valid-values" in char_data: char.valid_values = char_data["valid-values"] service.characteristics.append(char) accessory.services.append(service) accessories.append(accessory) return accessories
async def setup_test_component(hass, services, capitalize=False, suffix=None): """Load a fake homekit accessory based on a homekit accessory model. If capitalize is True, property names will be in upper case. If suffix is set, entityId will include the suffix """ domain = None for service in services: service_name = ServicesTypes.get_short(service.type) if service_name in HOMEKIT_ACCESSORY_DISPATCH: domain = HOMEKIT_ACCESSORY_DISPATCH[service_name] break assert domain, 'Cannot map test homekit services to homeassistant domain' accessory = Accessory('TestDevice', 'example.com', 'Test', '0001', '0.1') accessory.services.extend(services) pairing = await setup_test_accessories(hass, [accessory]) entity = 'testdevice' if suffix is None else 'testdevice_{}'.format(suffix) return Helper(hass, '.'.join((domain, entity)), pairing, accessory)
async def setup_test_component(hass, services, capitalize=False, suffix=None): """Load a fake homekit accessory based on a homekit accessory model. If capitalize is True, property names will be in upper case. If suffix is set, entityId will include the suffix """ domain = None for service in services: service_name = ServicesTypes.get_short(service.type) if service_name in HOMEKIT_ACCESSORY_DISPATCH: domain = HOMEKIT_ACCESSORY_DISPATCH[service_name] break assert domain, "Cannot map test homekit services to Home Assistant domain" accessory = Accessory("TestDevice", "example.com", "Test", "0001", "0.1") accessory.services.extend(services) config_entry, pairing = await setup_test_accessories(hass, [accessory]) entity = "testdevice" if suffix is None else "testdevice_{}".format(suffix) return Helper(hass, ".".join((domain, entity)), pairing, accessory, config_entry)
async def setup_test_component(hass, services, capitalize=False, suffix=None): """Load a fake homekit accessory based on a homekit accessory model. If capitalize is True, property names will be in upper case. If suffix is set, entityId will include the suffix """ domain = None for service in services: service_name = ServicesTypes.get_short(service.type) if service_name in HOMEKIT_ACCESSORY_DISPATCH: domain = HOMEKIT_ACCESSORY_DISPATCH[service_name] break assert domain, 'Cannot map test homekit services to homeassistant domain' fake_controller = await setup_platform(hass) accessory = Accessory('TestDevice', 'example.com', 'Test', '0001', '0.1') accessory.services.extend(services) pairing = fake_controller.add([accessory]) discovery_info = { 'host': '127.0.0.1', 'port': 8080, 'properties': { ('MD' if capitalize else 'md'): 'TestDevice', ('ID' if capitalize else 'id'): '00:00:00:00:00:00', ('C#' if capitalize else 'c#'): 1, } } fire_service_discovered(hass, SERVICE_HOMEKIT, discovery_info) await hass.async_block_till_done() entity = 'testdevice' if suffix is None else 'testdevice_{}'.format(suffix) return Helper(hass, '.'.join((domain, entity)), pairing, accessory)
if __name__ == '__main__': # setup logger logger = logging.getLogger('accessory') logger.setLevel(logging.INFO) ch = logging.StreamHandler() ch.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')) logger.addHandler(ch) logger.info('starting') try: httpd = AccessoryServer(os.path.expanduser('./demoserver.json'), logger) httpd.set_identify_callback(lambda) accessory = Accessory('Light', 'PheonixFi', 'Demoserver', '0001', '0.1') lightService = LightBulbService() # lightService.set_get_value_callback(); lightService.append_characteristic(BrightnessCharacteristic(12345678901)) # lightService.append_characteristic(HueCharacteristic(12345678902)) accessory.services.append(lightService) httpd.add_accessory(accessory) httpd.publish_device() print('published device and start serving') httpd.serve_forever() except KeyboardInterrupt:
def create_proxy(accessories_and_characteristics): """ Create a proxy in front of a set of accessories, services and characteristics. This allows to follow the communication of a controller and an accessory (e.g. an iPhone and some HomeKit IP camera). :param accessories_and_characteristics: the accessory data as described in the spec on page 73 and following. This contains all the data that will be used to create the proxy. :return: a list of `Accessory` instances whose services and characteristics are replaced by proxied versions. That means characteristic's callback functions for getting and setting values relay those calls to the proxied characteristics. """ accessories = [] logging.info('%<------ creating proxy ------') for accessory in accessories_and_characteristics: proxy_accessory = Accessory( '', '', '', '', '', ) aid = accessory['aid'] proxy_accessory.aid = aid logging.info('accessory with aid=%s', aid) proxy_accessory.services = [] accessories.append(proxy_accessory) for service in accessory['services']: service_iid = service['iid'] service_type = service['type'] short_type = ServicesTypes.get_short(service_type) logging.info(' %i.%i: >%s< (%s)', aid, service_iid, short_type, service_type) proxy_service = ProxyService(service_iid, service_type) proxy_accessory.add_service(proxy_service) for characteristic in service['characteristics']: characteristic_iid = characteristic['iid'] characteristic_type = characteristic['type'] short_type = CharacteristicsTypes.get_short( characteristic_type) characteristic_format = characteristic['format'] characteristic_value = characteristic.get('value') characteristic_perms = characteristic['perms'] logging.info(' %i.%i: %s >%s< (%s) [%s] %s', aid, characteristic_iid, characteristic_value, short_type, characteristic_type, ','.join(characteristic_perms), characteristic_format) proxy_characteristic = ProxyCharacteristic( characteristic_iid, characteristic_type, characteristic_format) proxy_service.append_characteristic(proxy_characteristic) if characteristic_value: proxy_characteristic.value = characteristic_value proxy_characteristic.perms = characteristic_perms proxy_characteristic.set_set_value_callback( generate_set_value_callback(accessory['aid'], proxy_characteristic)) proxy_characteristic.set_get_value_callback( generate_get_value_callback(accessory['aid'], proxy_characteristic)) logging.info('%<------ finished creating proxy ------') return accessories
import os.path from homekit import HomeKitServer from homekit.model import Accessory, LightBulbService def light_switched(newval): print('=======> light switched: {x}'.format(x=newval)) if __name__ == '__main__': try: httpd = HomeKitServer(os.path.expanduser('~/.homekit/demoserver.json')) accessory = Accessory('Testlicht') lightBulbService = LightBulbService() lightBulbService.set_on_set_callback(light_switched) accessory.services.append(lightBulbService) httpd.accessories.add_accessory(accessory) print(httpd.accessories.__str__()) httpd.publish_device() print('published device and start serving') httpd.serve_forever() except KeyboardInterrupt: pass print('unpublish device') httpd.unpublish_device() httpd.shutdown()
logger = logging.getLogger('accessory') logger.setLevel(logging.INFO) ch = logging.StreamHandler() ch.setFormatter( logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s')) logger.addHandler(ch) logger.info('starting') config_file = os.path.expanduser(args.file) # create a server and an accessory an run it unless ctrl+c was hit try: httpd = AccessoryServer(config_file, logger) accessory = Accessory('Testlicht', 'lusiardi.de', 'Demoserver', '0001', '0.1') lightBulbService = LightBulbService() lightBulbService.set_on_set_callback(light_switched) accessory.services.append(lightBulbService) httpd.add_accessory(accessory) httpd.publish_device() logger.info('published device and start serving') httpd.serve_forever() except KeyboardInterrupt: pass # unpublish the device and shut down logger.info('unpublish device') httpd.unpublish_device() httpd.shutdown()
def test_list_accessories_and_characteristics(self): model_mixin.id_counter = 0 c = Controller() a = Accessory( 'test-dev-123', 'TestCo', 'Test Dev Pro', '00000', 1 ) a.add_service(LightBulbService()) manager = DeviceManager() manager._devices['00:00:00:00:00'] = Device(a) with mock.patch('homekit.controller.ble_impl.device.DeviceManager') as m: with mock.patch('homekit.controller.ble_impl.DeviceManager') as m2: m.return_value = manager m2.return_value = manager c.perform_pairing_ble('test-pairing', '00:00:00:00:00', '111-11-111') accessories = c.pairings['test-pairing'].list_accessories_and_characteristics() self.assertEqual(accessories, [ { "aid": 1, "services": [ { "characteristics": [ { "iid": 3, "type": "00000014-0000-1000-8000-0026BB765291", "perms": [], "description": "", "format": "bool", "unit": "unknown", "range": None, "step": None }, { "iid": 4, "type": "00000020-0000-1000-8000-0026BB765291", "perms": [], "description": "", "format": "string", "unit": "unknown", "range": None, "step": None }, { "iid": 5, "type": "00000021-0000-1000-8000-0026BB765291", "perms": [], "description": "", "format": "string", "unit": "unknown", "range": None, "step": None }, { "iid": 6, "type": "00000023-0000-1000-8000-0026BB765291", "perms": [], "description": "", "format": "string", "unit": "unknown", "range": None, "step": None }, { "iid": 7, "type": "00000030-0000-1000-8000-0026BB765291", "perms": [], "description": "", "format": "string", "unit": "unknown", "range": None, "step": None }, { "iid": 8, "type": "00000052-0000-1000-8000-0026BB765291", "perms": [], "description": "", "format": "string", "unit": "unknown", "range": None, "step": None } ], "iid": 2, "type": "0000003E-0000-1000-8000-0026BB765291" }, { "characteristics": [ { "iid": 10, "type": "00000025-0000-1000-8000-0026BB765291", "perms": [], "description": "", "format": "bool", "unit": "unknown", "range": None, "step": None } ], "iid": 9, "type": "00000043-0000-1000-8000-0026BB765291" }, { "characteristics": [ { "iid": 12, "type": "0000004C-0000-1000-8000-0026BB765291", "perms": [], "description": "", "format": "data", "unit": "unknown", "range": None, "step": None }, { "iid": 13, "type": "0000004E-0000-1000-8000-0026BB765291", "perms": [], "description": "", "format": "data", "unit": "unknown", "range": None, "step": None }, { "description": "", "format": "data", "iid": 14, "perms": [], "range": None, "step": None, "type": "00000050-0000-1000-8000-0026BB765291", "unit": "unknown"} ], "iid": 11, "type": "00000055-0000-1000-8000-0026BB765291" } ] } ])