def __init__(self, hub_name, user, device, listen_address=None): logging.basicConfig(level=logging.INFO, format="[%(module)s] %(message)s") # Initialize my coup self.hub_name = hub_name coup = RemoteCoup(user, device) # Start the accessory on port 51826 if listen_address: self.driver = AccessoryDriver(port=51826, address=listen_address) else: self.driver = AccessoryDriver(port=51826) self.bridge = Bridge(self.driver, self.hub_name) # Setup run and coup lights while True: status = coup.get_status() if (status is None) or ('Coup' not in status) or ('Lights' not in status['Coup']): logger.error("Status has not been initialized or lights missing: Status = {0} at {1}".format(status, datetime.now())) else: for light in status['Coup']['Lights']: logger.info("Adding %s", light) runlight = RemoteGardenLight(self.driver, name=light, coup=coup) self.bridge.add_accessory(runlight) break time.sleep(5) # Change `get_accessory` to `get_bridge` if you want to run a Bridge. self.driver.add_accessory(accessory=self.bridge) # We want SIGTERM (terminate) to be handled by the driver itself, # so that it can gracefully stop the accessory, server and advertising. signal.signal(signal.SIGTERM, self.driver.signal_handler)
def get_bridge(driver): """Call this method to get a Bridge instead of a standalone accessory.""" bridge = Bridge(driver, 'Bridge') fifty_fifty = FiftyFiftyHomeKit(driver, 'Fifty fifty') bridge.add_accessory(fifty_fifty) return bridge
def main(): # init logger logger = logging.getLogger('homekit-flux-led') formatter = logging.Formatter('[%(levelname)s %(asctime)s]: %(message)s') ch = logging.StreamHandler() ch.setFormatter(formatter) logger.addHandler(ch) # parse cli-arguments parser = argparse.ArgumentParser() parser.add_argument( '-v', '--verbose', help='DEBUG logging mode', action='store_true', ) args = parser.parse_args() # set loggin level if args.verbose: logger.setLevel(logging.DEBUG) logger.info('Logging level: DEBUG') else: logger.setLevel(logging.INFO) logger.info('Logging level: INFO') # scan for bulbs logger.debug('Scanning for lightbulbs') scanner = BulbScanner() scanner.scan() logger.debug(f'Found lightbulbs:') logger.debug(scanner.found_bulbs) # initialize AccessoryServer logger.debug('Create HomeKit-AccessoryServer...') driver = AccessoryDriver() bridge = Bridge(driver, 'MagicHome') logger.debug('HomeKit-AccessoryServer created successful.') for bulb in scanner.found_bulbs: # add bulbs to bridge logger bridge.add_accessory( FluxLED( driver, bulb['id'], bulb['ipaddr'], logger=logger, ), ) # add bridge to the driver driver.add_accessory(bridge) try: # start the server logger.info('Start server...') driver.start() except KeyboardInterrupt: logger.info('Stopping server...') driver.stop()
def test_get_characteristic(mock_driver): bridge = Bridge(mock_driver, "Test Bridge") acc = Accessory(mock_driver, "Test Accessory", aid=2) assert acc.available is True assert bridge.aid == 1 assert bridge.get_characteristic(1, 2).display_name == "Identify" assert bridge.get_characteristic(2, 2) is None assert bridge.get_characteristic(3, 2) is None
def get_bridge(driver): bridge = Bridge(driver, 'Bridge') bridge.add_accessory(LightBulb(driver, 'Lightbulb')) bridge.add_accessory(FakeFan(driver, 'Big Fan')) bridge.add_accessory(GarageDoor(driver, 'Garage')) bridge.add_accessory(TemperatureSensor(driver, 'Sensor')) return bridge
def get_bridge(driver): """Call this method to get a Bridge instead of a standalone accessory.""" bridge = Bridge(driver, 'Bridge') temp_sensor = MotionSensor(driver, 'Motion Sendor 1') # temp_sensor2 = TemperatureSensor(driver, 'Sensor 1') bridge.add_accessory(temp_sensor) # bridge.add_accessory(temp_sensor2) return bridge
def get_bridge(driver): """Call this method to get a Bridge instead of a standalone accessory.""" bridge = Bridge(driver, 'Bridge') temp_valv1 = Valve("Valve1", -1, driver, 'MyValve1') temp_valv2 = Valve("Valve2", -1, driver, 'MyValve2') # temp_sensor = TemperatureSensor(driver, 'Sensor 2') # temp_sensor2 = TemperatureSensor(driver, 'Sensor 1') bridge.add_accessory(temp_valv1) bridge.add_accessory(temp_valv2) return bridge
def get_bridge(driver): """Call this method to get a Bridge instead of a standalone accessory.""" bridge = Bridge(driver, 'Bridge') # temp_sensor = TemperatureSensor(driver, 'Sensor 2') # temp_sensor2 = TemperatureSensor(driver, 'Sensor 1') # bridge.add_accessory(temp_sensor) # bridge.add_accessory(temp_sensor2) neopixel_one = NeoPixelLightStrip(driver, 'Pixel 1') bridge.add_accessory(neopixel_one) return bridge
def get_bridge(driver): """Call this method to get a Bridge instead of a standalone accessory.""" bridge = Bridge(driver, 'Bridge') # temp_sensor = TemperatureSensor(driver, 'CurrentTemperature') # bmp180_sensor = BMP180(driver, 'CurrentPressure') g201s_sensor = G201S(driver, 'SmartKettle') # bridge.add_accessory(temp_sensor) # bridge.add_accessory(bmp180_sensor) bridge.add_accessory(g201s_sensor) return bridge
def create_driver(loop, core_alarm): config = core_alarm.config.get('homekit', {}) use_bridge = core_alarm.sensors or config.get('use_bridge', False) driver = AccessoryDriver(loop=loop, port=config.get('port', 51001)) alarm = Alarm(driver, core_alarm, config) alarm.set_info_service(model=core_alarm.model, manufacturer='Jablotron', serial_number=core_alarm.serial_number, firmware_revision=core_alarm.firmware_version) if use_bridge: bridge = Bridge(driver, display_name='Jablotron Bridge') bridge.set_info_service(model=core_alarm.model, manufacturer='Jablotron', serial_number=core_alarm.serial_number, firmware_revision=core_alarm.firmware_version) bridge.add_accessory(alarm) for s in core_alarm.sensors.values(): bridge.add_accessory(create_sensor_accessory(driver, s)) driver.add_accessory(bridge) else: driver.add_accessory(alarm) return driver
def get_bridge(): """Call this method to get a Bridge instead of a standalone accessory.""" bridge = Bridge(display_name="Bridge") bridge.add_accessory( NodeMCUSwitch("Relay 1", URL="http://192.168.1.11", switchIndex=1)) bridge.add_accessory( NodeMCUSwitch("Relay 2", URL="http://192.168.1.11", switchIndex=2)) bridge.add_accessory( NodeMCUSwitch("Relay 3", URL="http://192.168.1.11", switchIndex=3)) bridge.add_accessory( NodeMCUSwitch("Relay 4", URL="http://192.168.1.11", switchIndex=4)) return bridge
def get_bridge(): """Call this method to get a Bridge instead of a standalone accessory.""" devices = json.loads(open("devices.json",'r').read()) bridge = json.loads(open("bridge.json",'r').read()) bridge = Bridge(display_name=bridge['name'],mac=util.generate_mac(), pincode=b"111-11-111") #bridge = Bridge(display_name="Bridge", mac=util.generate_mac(),pincode=b"203-23-999") #bridge.add_accessory(LightBulb("Luz",server=server_auth,device_id="F9-CB-E6-6D-F4-00")) #bridge.add_accessory(LightBulbDimmer("Luz",server=server_auth,device_id="F9-CB-E6-6D-F4-02")) i = 2 for device in devices: i += 1 if (device['service'] == "LIGHTBULB"): if(device['dimmer']): bridge.add_accessory(LightBulbDimmer(device['name'],aid=i ,server=server_auth,device_id=device['device_id'])) else: bridge.add_accessory(LightBulb(device['name'],aid=i ,server=server_auth,device_id=device['device_id'])) elif (device['service'] == "GARAGE_DOOR_OPENER"): bridge.add_accessory(GarageDoor(device['name'],aid=i ,server=server_auth,device_id=device['device_id'])) else: pass return bridge
def start_homekit(self): self.homekit_driver = HomekitDriver( address=os.environ["API_SERVER_HOST"], port=51826, persist_file="{}/data/bridge.state".format(storage_path)) self.homekit_bridge = Bridge(self.homekit_driver, 'Camera bridge') self.homekit_driver.add_accessory(accessory=self.homekit_bridge) self.homekit_worker = HomekitWorker(driver=self.homekit_driver) self.homekit_worker.start()
def test_bridge_add_accessory(mock_driver): bridge = Bridge(mock_driver, "Test Bridge") acc = Accessory(mock_driver, "Test Accessory", aid=2) bridge.add_accessory(acc) acc2 = Accessory(mock_driver, "Test Accessory 2") bridge.add_accessory(acc2) assert acc2.aid != STANDALONE_AID and acc2.aid != acc.aid
async def test_bridge_with_multiple_sync_run_at_interval_accessories(): with patch("pyhap.accessory_driver.HAPServer.async_stop", new_callable=AsyncMock), patch( "pyhap.accessory_driver.HAPServer.async_start", new_callable=AsyncMock ), patch("pyhap.accessory_driver.Zeroconf"), patch( "pyhap.accessory_driver.AccessoryDriver.persist"), patch( "pyhap.accessory_driver.AccessoryDriver.load"): driver = AccessoryDriver(loop=asyncio.get_event_loop()) bridge = Bridge(driver, "mybridge") acc = SyncIntervalAccessory(driver, "TestAcc", aid=2) acc2 = SyncIntervalAccessory(driver, "TestAcc2", aid=3) acc3 = SyncIntervalAccessory(driver, "TestAcc3", aid=4) bridge.add_accessory(acc) bridge.add_accessory(acc2) bridge.add_accessory(acc3) driver.add_accessory(bridge) driver.start_service() await asyncio.sleep(0.5) assert not driver.loop.is_closed() await driver.async_stop() assert acc.counter > 2 assert acc2.counter > 2 assert acc3.counter > 2
def test_bridge_n_add_accessory_dup_aid(mock_driver): bridge = Bridge(mock_driver, "Test Bridge") acc_1 = Accessory(mock_driver, "Test Accessory 1", aid=2) acc_2 = Accessory(mock_driver, "Test Accessory 2", aid=acc_1.aid) bridge.add_accessory(acc_1) with pytest.raises(ValueError): bridge.add_accessory(acc_2)
def test_handle_snapshot_encrypted_non_existant_accessory(driver): """Verify an encrypted snapshot with non-existant accessory.""" bridge = Bridge(driver, "Test Bridge") driver.add_accessory(bridge) handler = hap_handler.HAPServerHandler(driver, "peername") handler.is_encrypted = True response = hap_handler.HAPResponse() handler.response = response handler.request_body = b'{"image-height":360,"resource-type":"image","image-width":640,"aid":1411620844}' with pytest.raises(ValueError): handler.handle_resource()
def get_bridge(driver): """Call this method to get a Bridge instead of a standalone accessory.""" bridge = Bridge(driver, config['bridge_name']) bridge.set_info_service(manufacturer="Emsi") devices = config['devices'] for device in devices: password = devices[device].get('password') or b'D000000' bulb = Bulb(devices[device]['address'].encode(), password=password, verbose=config['verbose']).connect() name = devices[device].get('name') or device bridge.add_accessory(OortColorBulb(driver, name, bulb)) if devices[device]['color_switch'] == 'yes': bridge.add_accessory( OortColorBulbSwitch(driver, '{} color switch'.format(device), bulb)) return bridge
def get_bridge(driver): """Call this method to get a Bridge instead of a standalone accessory.""" bridge = Bridge(driver, 'Bridge') light_1 = LightBulb(driver, 'Red Light', pin=LedPin1) light_2 = LightBulb(driver, 'Blue Light', pin=LedPin2) bridge.add_accessory(light_1) bridge.add_accessory(light_2) temp = TemperatureSensor(driver, 'Temperature Humidity', pin=TempPin) bridge.add_accessory(temp) return bridge
async def test_bridge_run_stop(mock_driver): mock_driver.async_add_job = AsyncMock() bridge = Bridge(mock_driver, "Test Bridge") acc = Accessory(mock_driver, "Test Accessory", aid=2) assert acc.available is True bridge.add_accessory(acc) acc2 = Accessory(mock_driver, "Test Accessory 2") bridge.add_accessory(acc2) await bridge.run() assert mock_driver.async_add_job.called await bridge.stop()
def get_bridge(): """Call this method to get a Bridge instead of a standalone accessory.""" bridge = Bridge(display_name="Bridge", pincode=b"203-23-999") temp_sensor = TemperatureSensor("Termometer") temp_sensor2 = TemperatureSensor("Termometer2") bridge.add_accessory(temp_sensor) bridge.add_accessory(temp_sensor2) # Uncomment if you have RPi module and want a LED LightBulb service on pin 16. # from pyhap.accessories.LightBulb import LightBulb # bulb = LightBulb("Desk LED", pin=16) # bridge.add_accessory(bulb) return bridge
def get_bridge(driver): bridge = Bridge(driver, 'Bridge') Bright1 = BrightBulb(driver, 'Table Lamp') Outlet1 = Outlet(driver, 'Table Switch') Switch1 = Switch(driver, 'Laptop Charger') Bright1.uid = "BedroomTable Lamp" Outlet1.uid = "BedroomTable LaptopCharger" Switch1.uid = "BedroomTable Switch" bridge.add_accessory(Bright1) bridge.add_accessory(Outlet1) bridge.add_accessory(Switch1) return (bridge)
def get_bridge(_driver, wihome=None): bridge = Bridge(driver, 'Bridge') f = open('wihome.json') accs = json.loads(f.read()) f.close() for acc in accs: if acc['accessory'] == 'WiHomeSwitch': for inst in acc['instances']: bridge.add_accessory( WiHomeSwitch(_driver, inst['homekit_label'], wihome_instance=wihome, wihome_client=inst['wihome_client'], wihome_channel=inst['wihome_channel'])) elif acc['accessory'] == 'WiHomeGateOpener': for inst in acc['instances']: bridge.add_accessory( WiHomeGateOpener(_driver, inst['homekit_label'], wihome_instance=wihome, wihome_client=inst['wihome_client'])) elif acc['accessory'] == 'WiHomeGateOpenerSetup': for inst in acc['instances']: bridge.add_accessory( WiHomeGateOpenerSetup( _driver, inst['homekit_label'], wihome_instance=wihome, wihome_parameter=inst['wihome_parameter'], wihome_scaling_0=inst['wihome_scaling_0'], wihome_scaling_100=inst['wihome_scaling_100'], wihome_client=inst['wihome_client'])) return bridge
async def test_camera_snapshot_missing_accessory(driver): """Test camera snapshot that throws an exception.""" loop = MagicMock() transport = MagicMock() connections = {} bridge = Bridge(driver, "Test Bridge") driver.add_accessory(bridge) hap_proto = hap_protocol.HAPServerProtocol(loop, connections, driver) hap_proto.connection_made(transport) hap_proto.hap_crypto = MockHAPCrypto() hap_proto.handler.is_encrypted = True with patch.object(hap_proto.transport, "write") as writer: hap_proto.data_received( b'POST /resource HTTP/1.1\r\nHost: HASS\\032Bridge\\032BROZ\\0323BF435._hap._tcp.local\r\nContent-Length: 79\r\nContent-Type: application/hap+json\r\n\r\n{"image-height":360,"resource-type":"image","image-width":640,"aid":1411620844}' # pylint: disable=line-too-long ) await asyncio.sleep(0) assert hap_proto.response is None assert b"-70402" in writer.call_args_list[0][0][0] hap_proto.close()
async def test_bridge_run_stop(): with patch("pyhap.accessory_driver.HAPServer.async_stop", new_callable=AsyncMock), patch( "pyhap.accessory_driver.HAPServer.async_start", new_callable=AsyncMock ), patch("pyhap.accessory_driver.AsyncZeroconf"), patch( "pyhap.accessory_driver.AccessoryDriver.persist"), patch( "pyhap.accessory_driver.AccessoryDriver.load"): driver = AccessoryDriver(loop=asyncio.get_event_loop()) bridge = Bridge(driver, "Test Bridge") acc = TestAccessory(driver, "Test Accessory", aid=2) assert acc.available is True bridge.add_accessory(acc) acc2 = TestAccessory(driver, "Test Accessory 2") bridge.add_accessory(acc2) await bridge.run() await bridge.stop() assert acc.stopped is True assert acc2.stopped is True
def start(self): try: logging.basicConfig(level=logging.INFO) driver = AccessoryDriver(port=51827) bridge = Bridge(driver, 'Bridge') for device in self.settings.xcomfort.devices: if not device.add_to_homekit: continue print(f"[XComfort] Adding {device.name}") lamp = HomeKitXComfortLight(driver, device.name) bridge.add_accessory(lamp) for device in self.settings.easee.devices: if not device.add_to_homekit: continue print(f"[Easee] Adding {device.name}") charger = EaseeCharger(driver, device.name) bridge.add_accessory(charger) driver.add_accessory(accessory=bridge) signal.signal(signal.SIGTERM, driver.signal_handler) driver.start() except KeyboardInterrupt: print('Stopping...')
def test_mixing_service_char_callbacks_partial_failure(driver): bridge = Bridge(driver, "mybridge") acc = Accessory(driver, "TestAcc", aid=2) acc2 = UnavailableAccessory(driver, "TestAcc2", aid=3) service = Service(uuid1(), "Lightbulb") char_on = Characteristic("On", uuid1(), CHAR_PROPS) char_brightness = Characteristic("Brightness", uuid1(), CHAR_PROPS) service.add_characteristic(char_on) service.add_characteristic(char_brightness) def fail_callback(*_): raise ValueError service.setter_callback = fail_callback acc.add_service(service) bridge.add_accessory(acc) service2 = Service(uuid1(), "Lightbulb") char_on2 = Characteristic("On", uuid1(), CHAR_PROPS) char_brightness2 = Characteristic("Brightness", uuid1(), CHAR_PROPS) service2.add_characteristic(char_on2) service2.add_characteristic(char_brightness2) char_on2.setter_callback = fail_callback acc2.add_service(service2) bridge.add_accessory(acc2) char_on_iid = char_on.to_HAP()[HAP_REPR_IID] char_brightness_iid = char_brightness.to_HAP()[HAP_REPR_IID] char_on2_iid = char_on2.to_HAP()[HAP_REPR_IID] char_brightness2_iid = char_brightness2.to_HAP()[HAP_REPR_IID] driver.add_accessory(bridge) response = driver.set_characteristics( { HAP_REPR_CHARS: [ { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: True, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_brightness_iid, HAP_REPR_VALUE: 88, }, { HAP_REPR_AID: acc2.aid, HAP_REPR_IID: char_on2_iid, HAP_REPR_VALUE: True, }, { HAP_REPR_AID: acc2.aid, HAP_REPR_IID: char_brightness2_iid, HAP_REPR_VALUE: 12, }, ] }, "mock_addr", ) assert response == { HAP_REPR_CHARS: [ { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_STATUS: HAP_SERVER_STATUS.SERVICE_COMMUNICATION_FAILURE, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_brightness_iid, HAP_REPR_STATUS: HAP_SERVER_STATUS.SERVICE_COMMUNICATION_FAILURE, }, { HAP_REPR_AID: acc2.aid, HAP_REPR_IID: char_on2_iid, HAP_REPR_STATUS: HAP_SERVER_STATUS.SERVICE_COMMUNICATION_FAILURE, }, { HAP_REPR_AID: acc2.aid, HAP_REPR_IID: char_brightness2_iid, HAP_REPR_STATUS: 0, }, ] }
def test_service_callbacks(driver): bridge = Bridge(driver, "mybridge") acc = Accessory(driver, "TestAcc", aid=2) acc2 = UnavailableAccessory(driver, "TestAcc2", aid=3) service = Service(uuid1(), "Lightbulb") char_on = Characteristic("On", uuid1(), CHAR_PROPS) char_brightness = Characteristic("Brightness", uuid1(), CHAR_PROPS) service.add_characteristic(char_on) service.add_characteristic(char_brightness) mock_callback = MagicMock() service.setter_callback = mock_callback acc.add_service(service) bridge.add_accessory(acc) service2 = Service(uuid1(), "Lightbulb") char_on2 = Characteristic("On", uuid1(), CHAR_PROPS) char_brightness2 = Characteristic("Brightness", uuid1(), CHAR_PROPS) service2.add_characteristic(char_on2) service2.add_characteristic(char_brightness2) mock_callback2 = MagicMock() service2.setter_callback = mock_callback2 acc2.add_service(service2) bridge.add_accessory(acc2) char_on_iid = char_on.to_HAP()[HAP_REPR_IID] char_brightness_iid = char_brightness.to_HAP()[HAP_REPR_IID] char_on2_iid = char_on2.to_HAP()[HAP_REPR_IID] char_brightness2_iid = char_brightness2.to_HAP()[HAP_REPR_IID] driver.add_accessory(bridge) response = driver.set_characteristics( { HAP_REPR_CHARS: [ { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_on_iid, HAP_REPR_VALUE: True, }, { HAP_REPR_AID: acc.aid, HAP_REPR_IID: char_brightness_iid, HAP_REPR_VALUE: 88, }, { HAP_REPR_AID: acc2.aid, HAP_REPR_IID: char_on2_iid, HAP_REPR_VALUE: True, }, { HAP_REPR_AID: acc2.aid, HAP_REPR_IID: char_brightness2_iid, HAP_REPR_VALUE: 12, }, ] }, "mock_addr", ) assert response is None mock_callback2.assert_called_with({"On": True, "Brightness": 12}) mock_callback.assert_called_with({"On": True, "Brightness": 88}) get_chars = driver.get_characteristics([ "{}.{}".format(acc.aid, char_on_iid), "{}.{}".format(acc2.aid, char_on2_iid) ]) assert get_chars == { "characteristics": [ { "aid": acc.aid, "iid": char_on_iid, "status": 0, "value": True }, { "aid": acc2.aid, "iid": char_on2_iid, "status": -70402 }, ] } def _fail_func(): raise ValueError char_brightness.getter_callback = _fail_func get_chars = driver.get_characteristics([ "{}.{}".format(acc.aid, char_on_iid), "{}.{}".format(acc2.aid, char_on2_iid), "{}.{}".format(acc2.aid, char_brightness_iid), "{}.{}".format(acc.aid, char_brightness2_iid), ]) assert get_chars == { "characteristics": [ { "aid": acc.aid, "iid": char_on_iid, "status": 0, "value": True }, { "aid": acc2.aid, "iid": char_on2_iid, "status": -70402 }, { "aid": acc2.aid, "iid": char_brightness2_iid, "status": -70402 }, { "aid": acc.aid, "iid": char_brightness_iid, "status": -70402 }, ] }
def get_bridge(driver): """Call this method to get a Bridge instead of a standalone accessory.""" bridge = Bridge(driver, 'Bridge') music_dis = MusicStart(strip, driver, 'MusicDisplay') bridge.add_accessory(music_dis) return bridge
import pyhap.util as util from pyhap.accessory import Bridge from pyhap.accessory_driver import AccessoryDriver from accessories.air_quality_monitor import AirQualityMonitor from accessories.vacuum import Vacuum from accessories.air_fresh import AirFresh from accessories.presence import Presence from accessories.dummy_switch import DummySwitch logging.basicConfig(level=logging.DEBUG) driver = AccessoryDriver(port=54321, pincode=bytearray(b'111-11-111'), mac=util.generate_mac()) bridge = Bridge(driver, 'Bridge') air_quality = AirQualityMonitor(driver, 'Air Monitor', ip='192.168.1.1', token='XXX') bridge.add_accessory(air_quality) vacuum = Vacuum(driver, 'Vacuum', ip='192.168.1.2', token='XXX') bridge.add_accessory(vacuum) air_fresh = AirFresh(driver, 'Air Fresh', ip='192.168.1.3', token='XXX') bridge.add_accessory(air_fresh) nikolay_at_home = Presence(driver, 'Nikolay', hostname='192.168.1.4') bridge.add_accessory(nikolay_at_home) trigger = DummySwitch(driver, 'Trigger')