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_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_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 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 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)
Beispiel #6
0
    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)
Beispiel #7
0
    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')
Beispiel #8
0
    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')
Beispiel #9
0
    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')
    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_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"
                    }
                ]
            }
        ])
Beispiel #12
0
 def setUp(self):
     self.controller = Controller()
Beispiel #13
0
class TestController(unittest.TestCase):
    def __init__(self, methodName='runTest'):
        unittest.TestCase.__init__(self, methodName)

    def setUp(self):
        self.controller = Controller()

    @unittest.skipIf(not BLE_TRANSPORT_SUPPORTED, 'BLE no supported')
    def test_load_pairings_both_type(self):
        controller_file = tempfile.NamedTemporaryFile()
        controller_file.write("""{
            "alias_ip": {
                "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"
            },
            "alias_ble": {
                "Connection": "BLE",
                "iOSDeviceLTPK": "d708df2fbf4a8779669f0ccd43f4962d6d49e4274f88b1292f822edc3bcf8ed8",
                "iOSPairingId": "decc6fa3-de3e-41c9-adba-ef7409821bfc",
                "AccessoryLTPK": "7986cf939de8986f428744e36ed72d86189bea46b4dcdc8d9d79a3e4fceb92b9",
                "AccessoryPairingID": "12:34:56:00:01:0A",
                "AccessoryMAC": "FD:3C:D4:13:02:59",
                "iOSDeviceLTSK": "fa45f082ef87efc6c8c8d043d74084a3ea923a2253e323a7eb9917b4090c2fcc"
            }
        }""".encode())
        controller_file.flush()
        self.controller.load_data(controller_file.name)
        self.assertIsInstance(self.controller.get_pairings()['alias_ip'],
                              IpPairing)
        self.assertEqual(
            self.controller.get_pairings()
            ['alias_ip'].pairing_data['Connection'], 'IP')
        self.assertIsInstance(self.controller.get_pairings()['alias_ble'],
                              BlePairing)
        controller_file.close()

    @unittest.skipIf(not BLE_TRANSPORT_SUPPORTED, 'BLE no supported')
    def test_load_pairings_missing_type(self):
        controller_file = tempfile.NamedTemporaryFile()
        controller_file.write("""{
            "alias_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"
            },
            "alias_ble": {
                "Connection": "BLE",
                "iOSDeviceLTPK": "d708df2fbf4a8779669f0ccd43f4962d6d49e4274f88b1292f822edc3bcf8ed8",
                "iOSPairingId": "decc6fa3-de3e-41c9-adba-ef7409821bfc",
                "AccessoryLTPK": "7986cf939de8986f428744e36ed72d86189bea46b4dcdc8d9d79a3e4fceb92b9",
                "AccessoryPairingID": "12:34:56:00:01:0A",
                "AccessoryMAC": "FD:3C:D4:13:02:59",
                "iOSDeviceLTSK": "fa45f082ef87efc6c8c8d043d74084a3ea923a2253e323a7eb9917b4090c2fcc"
            }
        }""".encode())
        controller_file.flush()
        self.controller.load_data(controller_file.name)
        self.assertIsInstance(self.controller.get_pairings()['alias_ip'],
                              IpPairing)
        self.assertIsInstance(self.controller.get_pairings()['alias_ble'],
                              BlePairing)
        controller_file.close()

    def test_load_pairings_unknown_type(self):
        controller_file = tempfile.NamedTemporaryFile()
        controller_file.write("""{
             "alias_unknown": {
                 "Connection": "UNKNOWN"
             }
         }""".encode())
        controller_file.flush()
        self.controller.load_data(controller_file.name)
        self.assertEqual(0, len(self.controller.get_pairings()))
        controller_file.close()

    def test_load_pairings_invalid_json(self):
        controller_file = tempfile.NamedTemporaryFile()
        controller_file.write("""{
             "alias_unknown": {
                 "Connection": "UNKNOWN",
             }
         }""".encode())
        controller_file.flush()
        self.assertRaises(ConfigLoadingError, self.controller.load_data,
                          controller_file.name)
        controller_file.close()

    def test_load_pairings_missing_file(self):
        self.assertRaises(ConfigLoadingError, self.controller.load_data,
                          'test')

    def test_load_pairings_permissions(self):
        self.assertRaises(ConfigLoadingError, self.controller.load_data,
                          '/etc/shadow')

    def test_save_pairings_permissions(self):
        self.assertRaises(ConfigSavingError, self.controller.save_data,
                          '/root/shadow')

    def test_save_pairings_missing_file(self):
        self.assertRaises(ConfigSavingError, self.controller.save_data,
                          '/tmp/shadow/foo')
Beispiel #14
0
class TestControllerIpPaired(unittest.TestCase):
    @classmethod
    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()

        # 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(5)
        cls.controller_file = tempfile.NamedTemporaryFile()
        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.flush()

    def __init__(self, methodName='runTest'):
        unittest.TestCase.__init__(self, methodName)

    @classmethod
    def tearDownClass(cls):
        cls.httpd.unpublish_device()
        cls.httpd.shutdown()
        cls.config_file.close()

    def setUp(self):
        self.controller = Controller()

    def tearDown(self):
        self.controller.shutdown()

    def test_01_1_discover(self):
        result = self.controller.discover(5)
        found = None
        for device in result:
            if '12:34:56:00:01:0A' == device['id']:
                found = device
        self.assertIsNotNone(found)

    def test_02_pair_alias_exists(self):
        """Try to pair the test accessory"""
        self.controller.load_data(self.controller_file.name)
        self.assertRaises(AlreadyPairedError, self.controller.perform_pairing,
                          'alias', '12:34:56:00:01:0B', '010-22-020')

    def test_02_paired_identify_wrong_method(self):
        """Try to identify an already paired accessory via the controller's method for unpaired accessories."""
        self.assertRaises(AlreadyPairedError, self.controller.identify,
                          '12:34:56:00:01:0A')

    def test_03_get_accessories(self):
        self.controller.load_data(self.controller_file.name)
        pairing = self.controller.get_pairings()['alias']
        result = pairing.list_accessories_and_characteristics()
        for characteristic in result[0]['services'][0]['characteristics']:
            if characteristic['format'] == 'bool':
                self.assertNotIn('maxDataLen', characteristic)
                self.assertNotIn('maxLen', characteristic)
        self.assertEqual(1, len(result))
        result = result[0]
        self.assertIn('aid', result)
        self.assertIn('services', result)

    def test_04_1_get_characteristic(self):
        self.controller.load_data(self.controller_file.name)
        pairing = self.controller.get_pairings()['alias']
        result = pairing.get_characteristics([(1, 4)])
        self.assertIn((1, 4), result)
        self.assertIn('value', result[(1, 4)])
        self.assertEqual('lusiardi.de', result[(1, 4)]['value'])
        self.assertEqual(['value'], list(result[(1, 4)].keys()))

    def test_04_2_get_characteristics(self):
        self.controller.load_data(self.controller_file.name)
        pairing = self.controller.get_pairings()['alias']
        result = pairing.get_characteristics([(1, 4), (1, 10)])
        self.assertIn((1, 4), result)
        self.assertIn('value', result[(1, 4)])
        self.assertEqual('lusiardi.de', result[(1, 4)]['value'])
        self.assertIn((1, 10), result)
        self.assertIn('value', result[(1, 10)])
        self.assertEqual(False, result[(1, 10)]['value'])

    def test_04_3_get_characteristic_with_events(self):
        """This tests the include_events flag on get_characteristics"""
        self.controller.load_data(self.controller_file.name)
        pairing = self.controller.get_pairings()['alias']
        result = pairing.get_characteristics([(1, 4)], include_events=True)
        self.assertIn((1, 4), result)
        self.assertIn('value', result[(1, 4)])
        self.assertEqual('lusiardi.de', result[(1, 4)]['value'])
        self.assertIn('ev', result[(1, 4)])

    def test_04_4_get_characteristic_with_type(self):
        """This tests the include_type flag on get_characteristics"""
        self.controller.load_data(self.controller_file.name)
        pairing = self.controller.get_pairings()['alias']
        result = pairing.get_characteristics([(1, 4)], include_type=True)
        self.assertIn((1, 4), result)
        self.assertIn('value', result[(1, 4)])
        self.assertEqual('lusiardi.de', result[(1, 4)]['value'])
        self.assertIn('type', result[(1, 4)])
        self.assertEqual('20', result[(1, 4)]['type'])

    def test_04_5_get_characteristic_with_perms(self):
        """This tests the include_perms flag on get_characteristics"""
        self.controller.load_data(self.controller_file.name)
        pairing = self.controller.get_pairings()['alias']
        result = pairing.get_characteristics([(1, 4)], include_perms=True)
        self.assertIn((1, 4), result)
        self.assertIn('value', result[(1, 4)])
        self.assertEqual('lusiardi.de', result[(1, 4)]['value'])
        self.assertIn('perms', result[(1, 4)])
        self.assertEqual(['pr'], result[(1, 4)]['perms'])
        result = pairing.get_characteristics([(1, 3)], include_perms=True)
        self.assertEqual(['pw'], result[(1, 3)]['perms'])

    def test_04_4_get_characteristic_with_meta(self):
        """This tests the include_meta flag on get_characteristics"""
        self.controller.load_data(self.controller_file.name)
        pairing = self.controller.get_pairings()['alias']
        result = pairing.get_characteristics([(1, 4)], include_meta=True)
        self.assertIn((1, 4), result)
        self.assertIn('value', result[(1, 4)])
        self.assertEqual('lusiardi.de', result[(1, 4)]['value'])
        self.assertIn('format', result[(1, 4)])
        self.assertEqual('string', result[(1, 4)]['format'])
        self.assertIn('maxLen', result[(1, 4)])
        self.assertEqual(64, result[(1, 4)]['maxLen'])

    def test_05_1_put_characteristic(self):
        """"""
        global value
        self.controller.load_data(self.controller_file.name)
        pairing = self.controller.get_pairings()['alias']
        result = pairing.put_characteristics([(1, 10, 'On')])
        self.assertEqual(result, {})
        self.assertEqual(1, value)
        result = pairing.put_characteristics([(1, 10, 'Off')])
        self.assertEqual(result, {})
        self.assertEqual(0, value)

    def test_05_2_put_characteristic_do_conversion(self):
        """"""
        global value
        self.controller.load_data(self.controller_file.name)
        pairing = self.controller.get_pairings()['alias']
        result = pairing.put_characteristics([(1, 10, 'On')],
                                             do_conversion=True)
        self.assertEqual(result, {})
        self.assertEqual(1, value)
        result = pairing.put_characteristics([(1, 10, 'Off')],
                                             do_conversion=True)
        self.assertEqual(result, {})
        self.assertEqual(0, value)

    def test_05_2_put_characteristic_do_conversion_wrong_value(self):
        """Tests that values that are not convertible to boolean cause a HomeKitTypeException"""
        self.controller.load_data(self.controller_file.name)
        pairing = self.controller.get_pairings()['alias']
        self.assertRaises(FormatError,
                          pairing.put_characteristics, [(1, 10, 'Hallo Welt')],
                          do_conversion=True)

    def test_06_list_pairings(self):
        """Gets the listing of registered controllers of the device. Count must be 1."""
        self.controller.load_data(self.controller_file.name)
        pairing = self.controller.get_pairings()['alias']
        result = pairing.list_pairings()
        self.assertEqual(1, len(result))
        result = result[0]
        self.assertIn('controllerType', result)
        self.assertEqual(result['controllerType'], 'admin')
        self.assertIn('publicKey', result)
        self.assertIn('permissions', result)
        self.assertEqual(result['permissions'], 1)
        self.assertIn('pairingId', result)

    def test_07_paired_identify(self):
        """Tests the paired variant of the identify method."""
        global identify
        self.controller.load_data(self.controller_file.name)
        pairing = self.controller.get_pairings()['alias']
        result = pairing.identify()
        self.assertTrue(result)
        self.assertEqual(1, identify)
        identify = 0

    def test_99_remove_pairing(self):
        """Tests that a removed pairing is not present in the list of pairings anymore."""
        self.controller.load_data(self.controller_file.name)
        self.controller.remove_pairing('alias')
        pairings = self.controller.get_pairings()
        self.assertNotIn('alias', pairings)
Beispiel #15
0
 def setUp(self):
     self.controller = Controller()
     self.__class__.logger.clear()
Beispiel #16
0
                proxy_characteristic.set_get_value_callback(
                    generate_get_value_callback(accessory['aid'],
                                                proxy_characteristic))
    logging.info('%<------ finished creating proxy ------')
    return accessories


if __name__ == '__main__':
    args = setup_args_parser()

    setup_logging(args.loglevel)

    client_config_file = os.path.expanduser(args.client_data)
    server_config_file = os.path.expanduser(args.server_data)

    controller = Controller()
    try:
        controller.load_data(client_config_file)
    except Exception as e:
        logging.error(e, exc_info=True)
        sys.exit(-1)

    if args.alias not in controller.get_pairings():
        logging.error('"%s" is no known alias', args.alias)
        sys.exit(-1)

    try:
        pairing = controller.get_pairings()[args.alias]
        data = pairing.list_accessories_and_characteristics()
    except Exception as e:
        logging.error(e, exc_info=True)
Beispiel #17
0
class TestControllerIpUnpaired(unittest.TestCase):
    @classmethod
    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 __init__(self, methodName='runTest'):
        unittest.TestCase.__init__(self, methodName)
        self.controller_file = tempfile.NamedTemporaryFile()

    @classmethod
    def tearDownClass(cls):
        cls.httpd.unpublish_device()
        cls.httpd.shutdown()
        cls.config_file.close()

    def setUp(self):
        self.controller = Controller()

    def test_01_1_discover(self):
        """Try to discover the test accessory"""
        result = self.controller.discover()
        found = False
        for device in result:
            if '12:34:56:00:01:0B' == device['id']:
                found = True
        self.assertTrue(found)

    def test_01_2_unpaired_identify(self):
        """Try to trigger the identification of the test accessory"""
        global identify
        self.controller.identify('12:34:56:00:01:0B')
        self.assertEqual(1, identify)
        identify = 0

    def test_01_3_unpaired_identify_not_found(self):
        """Try to identify a non existing accessory. This should result in AccessoryNotFoundError"""
        self.assertRaises(AccessoryNotFoundError, self.controller.identify,
                          '12:34:56:00:01:0C')

    def test_02_pair(self):
        """Try to pair the test accessory"""
        self.controller.perform_pairing('alias', '12:34:56:00:01:0B',
                                        '010-22-020')
        pairings = self.controller.get_pairings()
        self.controller.save_data(self.controller_file.name)
        self.assertIn('alias', pairings)

    def test_02_pair_accessory_not_found(self):
        """"""
        self.assertRaises(AccessoryNotFoundError,
                          self.controller.perform_pairing, 'alias1',
                          '12:34:56:00:01:1B', '010-22-020')

    def test_02_pair_wrong_pin(self):
        """"""
        self.assertRaises(UnavailableError, self.controller.perform_pairing,
                          'alias2', '12:34:56:00:01:0B', '010-22-021')

    def test_02_pair_malformed_pin(self):
        """"""
        self.assertRaises(MalformedPinError, self.controller.perform_pairing,
                          'alias2', '12:34:56:00:01:0B', '01022021')