예제 #1
0
async def test_start_from_async_stop_from_executor():
    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())
        run_event = asyncio.Event()

        class Acc(Accessory):
            @Accessory.run_at_interval(0)
            def run(self):  # pylint: disable=invalid-overridden-method
                run_event.set()

            def setup_message(self):
                pass

        acc = Acc(driver, "TestAcc")
        driver.add_accessory(acc)
        driver.start_service()
        await run_event.wait()
        assert not driver.loop.is_closed()
        await driver.loop.run_in_executor(None, driver.stop)
        await driver.aio_stop_event.wait()
예제 #2
0
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
예제 #3
0
async def test_start_stop_async_acc():
    """Verify run_at_interval closes the driver."""
    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())
        run_event = asyncio.Event()

        class Acc(Accessory):
            @Accessory.run_at_interval(0)
            async def run(self):
                run_event.set()

            def setup_message(self):
                pass

        acc = Acc(driver, "TestAcc")
        driver.add_accessory(acc)
        driver.start_service()
        await asyncio.sleep(0)
        await run_event.wait()
        assert not driver.loop.is_closed()
        await driver.async_stop()
        assert not driver.loop.is_closed()
예제 #4
0
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()
예제 #5
0
async def test_start_service_and_update_config():
    """Test starting service and updating the config."""
    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())
        acc = Accessory(driver, "TestAcc")
        driver.add_accessory(acc)
        await driver.async_start()

        assert driver.state.config_version == 2
        driver.config_changed()
        assert driver.state.config_version == 3
        driver.state.config_version = 65535
        driver.config_changed()
        assert driver.state.config_version == 1
        for _ in range(3):
            await asyncio.sleep(0)
        await driver.async_stop()
        await asyncio.sleep(0)
        assert not driver.loop.is_closed()
        assert driver.aio_stop_event.is_set()
예제 #6
0
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
예제 #7
0
def start_homekit(co2meter):
    # Start the accessory on port 51826
    driver = AccessoryDriver(port=51826)

    driver.add_accessory(accessory=CO2Sensor(
        co2meter=co2meter, driver=driver, display_name="CO2 Sensor"))

    # 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, driver.signal_handler)

    # Start it!
    driver.start()
예제 #8
0
def main(args):
    import logging
    import signal
    from pyhap.accessory_driver import AccessoryDriver

    logging.basicConfig(level=logging.INFO)

    driver = AccessoryDriver(port=args.port)
    accessory = MiFan(args, driver, 'Fanv2')
    driver.add_accessory(accessory=accessory)

    signal.signal(signal.SIGTERM, driver.signal_handler)
    driver.start()
예제 #9
0
파일: main.py 프로젝트: tim6her/Homekit-LMS
def homekit():
    # Start the accessory on port 51826
    driver = AccessoryDriver(port=51826)

    # Change `get_accessory` to `get_bridge` if you want to run a Bridge.
    driver.add_accessory(accessory=get_accessory(driver))

    # We want SIGTERM (kill) to be handled by the driver itself,
    # so that it can gracefully stop the accessory, server and advertising.
    signal.signal(signal.SIGTERM, driver.signal_handler)

    # Start it!
    driver.start()
예제 #10
0
def main():
    import logging
    import signal

    from pyhap.accessory_driver import AccessoryDriver

    logging.basicConfig(level=logging.INFO)

    driver = AccessoryDriver(port=51826)
    accessory = TV(driver, 'TV')
    driver.add_accessory(accessory=accessory)

    signal.signal(signal.SIGTERM, driver.signal_handler)
    driver.start()
예제 #11
0
파일: ahk.py 프로젝트: jarobey/happygarden
class GardenHub():
    hub_name = None
    driver = None
    bridge = None
    coup = None
    
    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 start(self):
        self.driver.start()
        print("Completed {0} start".format(__name__))
예제 #12
0
async def test_we_can_connect():
    """Test we can start, connect, and stop."""
    loop = asyncio.get_event_loop()
    with patch("pyhap.accessory_driver.Zeroconf"), patch(
        "pyhap.accessory_driver.AccessoryDriver.persist"
    ):
        driver = AccessoryDriver(loop=loop)

    driver.add_accessory(Accessory(driver, "TestAcc"))

    addr_info = ("0.0.0.0", None)
    server = hap_server.HAPServer(addr_info, driver)
    await server.async_start(loop)
    sock = server.server.sockets[0]
    assert server.connections == {}
    _, port = sock.getsockname()
    _, writer = await asyncio.open_connection("127.0.0.1", port)
    assert server.connections != {}
    server.async_stop()
    writer.close()
예제 #13
0
def main(cfg, reset, setup_systemd):
    # init logging
    logging.basicConfig(level=logging.INFO)

    if reset:
        # remove accessory.state
        os.remove('accessory.state')

    if setup_systemd:
        systmd()

    # create config if necessary
    if not os.path.exists(os.path.join(cfg, 'bridge.cfg')):
        create_cfg(cfg)

    # start the accessory driver on port 51826
    driver = AccessoryDriver(port=51826)

    # create bridge
    bridge = MqttBridge(cfg, driver, 'MQTT')

    # load accs
    loader = cfg_loader.CfgLoader(driver, cfg)
    accs = loader.load_accessories(reset)
    for acc in accs:
        bridge.add_accessory(acc)

    loader.save_accessories()

    # add the bridge
    driver.add_accessory(accessory=bridge)

    signal.signal(signal.SIGTERM, driver.signal_handler)

    # start HomeKit
    driver.start()
    print('Returned')
    return 0
예제 #14
0
    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...')
예제 #15
0
LED_DMA = 10  # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 200  # Set to 0 for darkest and 255 for brightest
LED_INVERT = False  # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL = 0  # set to '1' for GPIOs 13, 19, 41, 45 or 53
LED_STRIP = ws.SK6812W_STRIP
strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT,
                          LED_BRIGHTNESS, LED_CHANNEL, LED_STRIP)
strip.begin()


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


# Start the accessory on port 51828
driver = AccessoryDriver(port=51828, persist_file='main.state')

# Change `get_accessory` to `get_bridge` if you want to run a Bridge.
driver.add_accessory(accessory=get_bridge(driver))

# 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, driver.signal_handler)

# Start it!
driver.start()
예제 #16
0
                          maxNr=140,
                          minNr=20,
                          minDevPerc=2.0)
    bridge.add_sampler(sampler, conf.itstore)


if __name__ == "__main__":
    logger = logging.getLogger()
    hand = logging.StreamHandler()
    hand.setLevel(logging.INFO)
    logger.addHandler(hand)  # use console
    logger.addHandler(
        logging.FileHandler(filename='p1DSMR_Hap.log',
                            mode='w',
                            encoding='utf-8'))
    logger.setLevel(logging.DEBUG)
    logger.critical("### running %s dd %s ###" %
                    (__file__, time.strftime("%y%m%d %H:%M:%S")))

    driver = AccessoryDriver(port=51826)
    bridge = fsBridge(driver, 'fsBridge')

    add_p1DSMR_to_bridge(bridge, config="p1DSMR.json")
    driver.add_accessory(accessory=bridge)

    signal.signal(signal.SIGTERM, driver.signal_handler)

    driver.start()

    logger.info('bye')
예제 #17
0
파일: camera_main.py 프로젝트: ignalex/pi
            # [480, 270, 30],
            # [320, 240, 30],
            # [320, 180, 30],
        ],
    },
    "audio": {
        "codecs": [{
            'type': 'OPUS',
            'samplerate': 24,
        }, {
            'type': 'AAC-eld',
            'samplerate': 16
        }],
    },
    "srtp": True,

    # hard code the address if auto-detection does not work as desired: e.g. "192.168.1.226"
    "address": util.get_local_address(),
    "start_stream_cmd": FFMPEG_CMD
}

# Start the accessory on port 51826
driver = AccessoryDriver(port=51826)
acc = camera.Camera(options, driver, "Camera")
driver.add_accessory(accessory=acc)

# We want KeyboardInterrupts and SIGTERM (terminate) to be handled by the driver itself,
# so that it can gracefully stop the accessory, server and advertising.
signal.signal(signal.SIGTERM, driver.signal_handler)
# Start it!
driver.start()
예제 #18
0
def run():
    driver = AccessoryDriver(port=51826, persist_file='busy_home.state')
    driver.add_accessory(accessory=get_bridge(driver))
    signal.signal(signal.SIGTERM, driver.signal_handler)
    driver.start()
예제 #19
0
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')
bridge.add_accessory(trigger)

driver.add_accessory(bridge)

signal.signal(signal.SIGTERM, driver.signal_handler)

driver.start()

print('Bridge Ready')
            port = int(arg)
        if opt in ['-u', '--updates']:
            dev_updates = True

    logging.info("Bridge name: %s", bridge_name)

    loop = asyncio.get_event_loop()

    try:
        xknx = loop.run_until_complete(get_xknx(config_file, dev_updates))
    except Exception as e:
        logging.info('Exception for KNX: %s', e)
        logging.info('Exiting...')
        sys.exit(1)

    driver = AccessoryDriver(loop=loop,
                             port=port,
                             persist_file='homekit-knx-bridge.state')

    driver.add_accessory(
        accessory=get_bridge_from_config(driver, bridge_name, xknx))

    signal.signal(signal.SIGTERM, driver.signal_handler)

    driver.start()
    #driver.async_add_job(xknx.start())

    #driver.add_job(xknx.stop())
    #loop.run_until_complete(xknx.stop())
# driver.stop()
예제 #21
0
"""Demo script for starting."""
import logging
import signal

from pyhap.accessory_driver import AccessoryDriver
from py_maxcube import MaxBridge

logging.basicConfig(level=logging.INFO, format="[%(module)s] %(message)s")

driver = AccessoryDriver(port=51826)

driver.add_accessory(accessory=MaxBridge('192.168.1.247', 62910, driver, 'MaxBridge'))

# 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, driver.signal_handler)

# Start it!
driver.start()
예제 #22
0
"""An example of how to setup and start an Accessory.

This is:
1. Create the Accessory object you want.
2. Add it to an AccessoryDriver, which will advertise it on the local network,
    setup a server to answer client queries, etc.
"""
import logging
import signal

from pyhap.accessory_driver import AccessoryDriver
import pyhap.loader as loader

# The below package can be found in the HAP-python github repo under accessories/
from LightBulb import LightBulb

logging.basicConfig(level=logging.INFO)

# Start the accessory on port 51826
driver = AccessoryDriver(port=51826)

# Change `get_accessory` to `get_bridge` if you want to run a Bridge.
driver.add_accessory(accessory=LightBulb(driver, 'Deck Lights'))

# We want SIGTERM (kill) to be handled by the driver itself,
# so that it can gracefully stop the accessory, server and advertising.
signal.signal(signal.SIGTERM, driver.signal_handler)

# Start it!
driver.start()
예제 #23
0
                                 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


wh = WiHome()

driver = AccessoryDriver(port=51826, persist_file='wihome.state')
driver.add_accessory(accessory=get_bridge(driver, wihome=wh))
signal.signal(signal.SIGTERM, driver.signal_handler)
driver.start()
예제 #24
0
        self.char_on.set_value(value=v)
        self.setBulb(v)


def get_bridge(driver):
    bridge = Bridge(driver, 'Bridge')
    for lName in lampNames:
        lamp = Lamp(driver, lName)
        bridge.add_accessory(lamp)
    return bridge


# Start the accessory on port 51826
driver = AccessoryDriver(port=51826)
myBridge = get_bridge(driver)
driver.add_accessory(accessory=myBridge)
signal.signal(signal.SIGTERM, driver.signal_handler)


def message_delegate(message):
    asStr = str(message, 'utf-8')
    for _, accessory in myBridge.accessories.items():
        if accessory.display_name == asStr:
            accessory.flipBulb()


def onSwitchChanged(state):
    for lampName, isOn in state.items():
        for _, accessory in myBridge.accessories.items():
            if accessory.display_name == lampName:
                accState = bool(accessory.char_on.value)
예제 #25
0
파일: example.py 프로젝트: CodyMcC/hap-mqtt
test.add_service(service_loader.get_service("Switch"))

accessories = list()
accessories.append(BasicLight("outside", MQTTSERVER, driver, "flood_1", aid=1111))
accessories.append(BasicLight("outside", MQTTSERVER, driver, "flood_2", aid=2222))
accessories.append(BasicLight("outside", MQTTSERVER, driver, "flood_3", aid=3333))
accessories.append(BasicLight("outside", MQTTSERVER, driver, "flood_4", aid=4444))
accessories.append(TemperatureSensor(driver, "fake_temp"))


# accessories.append(test)
# MqttAccessories(TemperatureSensor(MQTTSERVER, driver, "Battery_1", aid=2323))
# MqttAccessories.accessories[2].add_service(service_loader.get_service("BatteryService"))


# Add the accessories and the topics to the mqtt bridge
for acc in accessories:
    mqtt_bridge.add_accessory(acc)
    try:
        mqtt_bridge.add_topic(acc.topic)
    except AttributeError:
        pass


driver.add_accessory(accessory=mqtt_bridge)
# driver.add_accessory(accessory=TemperatureSensor(driver, "fake_temp"))

signal.signal(signal.SIGTERM, driver.signal_handler)
driver.start()

예제 #26
0
import signal
import logging
import busio

from pyhap.accessory_driver import AccessoryDriver
from pyhap.const import CATEGORY_SWITCH
from adafruit_pca9685 import PCA9685
from board import SCL, SDA
from python_json_config import ConfigBuilder

from dusty.dusty import DustyBridge, DustySwitch

logging.basicConfig(level=logging.INFO, format="[%(module)s] %(message)s")
logger = logging.getLogger()

builder = ConfigBuilder()
config = builder.parse_config('config.json')

i2c = busio.I2C(SCL, SDA)
pca = PCA9685(i2c)
pca = PCA9685(i2c, reference_clock_speed=config.servo.reference_clock_speed)
pca.frequency = config.servo.frequency

driver = AccessoryDriver(port=config.dusty.port)
dusty_bridge = DustyBridge(driver, config.dusty.max_switches, pca, config)
driver.add_accessory(accessory=dusty_bridge)
signal.signal(signal.SIGTERM, driver.signal_handler)

driver.start()
예제 #27
0
def main(getter, setter, port):
    driver = AccessoryDriver(port=port)
    driver.add_accessory(accessory=AirConditioner(getter, setter, driver,
                                                  'ElectraAirConditioner'))
    signal.signal(signal.SIGTERM, driver.signal_handler)
    return driver
    def set_bulb(self, value):
        print("Setting bulb state to %s" % value)
        global isPowered
        isPowered = not isPowered
        if value:
            relay.off()
        else:
            relay.on()

    def stop(self):
        super().stop()


driver = AccessoryDriver(port=51826)
driver.add_accessory(accessory=HomekitDevice(driver, 'Light 1'))
signal.signal(signal.SIGTERM, driver.signal_handler)

driver.start()

dir = os.getcwd()


@app.route('/', methods=['GET', 'POST'])
def main():
    return render_template('index.html', isPowered=isPowered)


@app.route('/handle_data', methods=['POST'])
def handle_data():
예제 #29
0
        self.char_temp.set_value(random.randint(18, 26))


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)

    return bridge


def get_accessory(driver):
    """Call this method to get a standalone Accessory."""
    return TemperatureSensor(driver, 'MyTempSensor')


# Start the accessory on port 51826
driver = AccessoryDriver(port=51826)

# Change `get_accessory` to `get_bridge` if you want to run a Bridge.
driver.add_accessory(accessory=get_accessory(driver))

# 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, driver.signal_handler)

# Start it!
driver.start()
예제 #30
0
def main():  # noqa: C901 pylint: disable=too-many-branches, too-many-statements, too-many-locals
    parser = argparse.ArgumentParser(prog='vwsfriend', description='TBD')
    parser.add_argument(
        '--version',
        action='version',
        version=
        f'%(prog)s {__version__} (using WeConnect-python {__weconnect_version__})'
    )
    parser.add_argument('-u',
                        '--username',
                        help='Username of VWsFriend UI',
                        required=False)
    parser.add_argument('-p',
                        '--password',
                        help='Password of VWsFriend UI',
                        required=False)
    parser.add_argument('--host',
                        help='Host of VWsFriend UI',
                        type=str,
                        required=False,
                        default='0.0.0.0')  # nosec
    parser.add_argument('--port',
                        help='Port of VWsFriend UI',
                        type=int,
                        choices=range(1, 65535),
                        metavar="[1-65535]",
                        required=False,
                        default=4000)
    weConnectGroup = parser.add_argument_group('WeConnect')
    weConnectGroup.add_argument('--weconnect-username',
                                dest='weConnectUsername',
                                help='Username of Volkswagen id',
                                required=False)
    weConnectGroup.add_argument('--weconnect-password',
                                dest='weConnectPassword',
                                help='Password of Volkswagen id',
                                required=False)
    defaultNetRc = os.path.join(os.path.expanduser("~"), ".netrc")
    weConnectGroup.add_argument(
        '--netrc',
        help=f'File in netrc syntax providing login (default: {defaultNetRc}).'
        ' Netrc is only used when username and password are not provided  as arguments',
        default=None,
        required=False)
    weConnectGroup.add_argument('-i',
                                '--interval',
                                help='Query interval in seconds',
                                type=NumberRangeArgument(imin=180),
                                required=False,
                                default=300)
    defaultTemp = os.path.join(tempfile.gettempdir(), 'weconnect.token')
    weConnectGroup.add_argument(
        '--tokenfile',
        help=f'file to store token (default: {defaultTemp})',
        default=defaultTemp)
    weConnectGroup.add_argument(
        '--no-token-storage',
        dest='noTokenStorage',
        help='Do not store token on filesystem (this'
        ' will cause a new login for every invokation!)',
        action='store_true')

    parser.add_argument(
        '--config-dir',
        dest='configDir',
        help='directory to store configuration files (default: ./)',
        default='./')
    parser.add_argument(
        '--demo',
        help='folder containing demo scenario, see README for more information'
    )
    parser.add_argument('--privacy',
                        help='Options to control privacy of the cars users',
                        default=[],
                        required=False,
                        action='append',
                        type=Privacy,
                        choices=list(Privacy))
    dbGroup = parser.add_argument_group('Database & visualization')

    dbGroup.add_argument(
        '--with-database',
        dest='withDatabase',
        help='Connect VWsFriend to database for visualization',
        action='store_true')
    dbGroup.add_argument('--database-url',
                         dest='dbUrl',
                         help='Database to connect to',
                         default='sqlite:///vwsfrienddevel.db')

    abrpGroup = parser.add_argument_group('ABRP: A better route planner')
    abrpGroup.add_argument(
        '--with-abrp',
        dest='withABRP',
        help=
        'Connect VWsFriend to ABRP (you need to add userTokens in the UI!)',
        action='store_true')

    homekitGroup = parser.add_argument_group('Homekit')
    homekitGroup.add_argument('--with-homekit',
                              dest='withHomekit',
                              help='Provide Apple Homekit functionality',
                              action='store_true')

    loggingGroup = parser.add_argument_group('Logging')
    loggingGroup.add_argument(
        '-v',
        '--verbose',
        action="append_const",
        help='Logging level (verbosity)',
        const=-1,
    )
    loggingGroup.add_argument(
        '--logging-format',
        dest='loggingFormat',
        help='Logging format configured for python logging '
        '(default: %%(asctime)s:%%(levelname)s:%%(module)s:%%(message)s)',
        default='%(asctime)s:%(levelname)s:%(module)s:%(message)s')
    loggingGroup.add_argument(
        '--logging-date-format',
        dest='loggingDateFormat',
        help='Logging format configured for python logging '
        '(default: %%Y-%%m-%%dT%%H:%%M:%%S%%z)',
        default='%Y-%m-%dT%H:%M:%S%z')
    loggingGroup.add_argument(
        '--hide-repeated-log',
        dest='hideRepeatedLog',
        help='Hide repeated log messages from the same module',
        action='store_true')

    loggingMailGroup = parser.add_argument_group(
        'Logging to Email (Errors only)')
    loggingMailGroup.add_argument('--logging-mail-from',
                                  dest='loggingMailFrom',
                                  help='Mail address to send mails from',
                                  required=False)
    loggingMailGroup.add_argument(
        '--logging-mail-to',
        dest='loggingMailTo',
        help='Mail address to send mails to (can be used multiple times)',
        required=False,
        action='append')
    loggingMailGroup.add_argument('--logging-mail-host',
                                  dest='loggingMailHost',
                                  help='Mail server host',
                                  required=False)
    loggingMailGroup.add_argument('--logging-mail-credentials',
                                  dest='loggingMailCredentials',
                                  help='Mail server credentials',
                                  required=False,
                                  nargs=2)
    loggingMailGroup.add_argument('--logging-mail-subject',
                                  dest='loggingMailSubject',
                                  help='Mail subject',
                                  required=False,
                                  default='VWsFriend Log')
    loggingMailGroup.add_argument('--logging-mail-notls',
                                  dest='loggingMailnotls',
                                  help='Mail do not use TLS',
                                  required=False,
                                  action='store_true')
    loggingMailGroup.add_argument('--logging-mail-testmail',
                                  dest='loggingMailTestmail',
                                  help='Try to send Testmail at startup',
                                  required=False,
                                  action='store_true')

    args = parser.parse_args()

    logLevel = LOG_LEVELS.index(DEFAULT_LOG_LEVEL)
    for adjustment in args.verbose or ():
        logLevel = min(len(LOG_LEVELS) - 1, max(logLevel + adjustment, 0))

    logging.basicConfig(level=LOG_LEVELS[logLevel],
                        format=args.loggingFormat,
                        datefmt=args.loggingDateFormat)
    logging.getLogger("pyhap").setLevel(level=LOG_LEVELS[logLevel])
    if args.hideRepeatedLog:
        for handler in logging.root.handlers:
            handler.addFilter(DuplicateFilter())
    # logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

    if any(arg is not None for arg in [
            args.loggingMailFrom, args.loggingMailTo, args.loggingMailHost,
            args.loggingMailCredentials
    ]):
        if all(arg is not None for arg in [
                args.loggingMailFrom, args.loggingMailTo, args.loggingMailHost,
                args.loggingMailCredentials
        ]):
            secure = ()
            if args.loggingMailnotls:
                secure = None
            smtpHandler = logging.handlers.SMTPHandler(
                mailhost=args.loggingMailHost,
                fromaddr=args.loggingMailFrom,
                toaddrs=args.loggingMailTo,
                subject=args.loggingMailSubject,
                credentials=args.loggingMailCredentials,
                secure=secure)
            smtpHandler.setLevel(logging.INFO)
            smtpHandler.setFormatter(
                logging.Formatter("%(asctime)s %(levelname)-5s %(message)s"))
            LOG.addHandler(smtpHandler)
            if args.loggingMailTestmail:
                msg = f'vwsfriend {__version__} (using WeConnect-python {__weconnect_version__})'
                smtpHandler.emit(
                    logging.LogRecord('VWsFriend',
                                      logging.INFO,
                                      pathname=None,
                                      lineno=None,
                                      msg=msg,
                                      args=None,
                                      exc_info=None))
            smtpHandler.setLevel(logging.ERROR)
        else:
            LOG.error(
                'You need to provide all --logging-mail options to make mail work'
            )
            sys.exit(1)

    LOG.info('vwsfriend %s (using WeConnect-python %s)', __version__,
             __weconnect_version__)

    username = None
    password = None

    if args.username is not None and args.password is not None:
        username = args.username
        password = args.password
    else:
        if args.netrc is not None:
            netRcFilename = args.netrc
        else:
            netRcFilename = defaultNetRc
        try:
            secrets = netrc.netrc(file=args.netrc)
            username, _, password = secrets.authenticators("VWsFriend")
        except netrc.NetrcParseError as err:
            LOG.error('Authentification using .netrc failed: %s', err)
            sys.exit(1)
        except TypeError:
            LOG.error(
                'VWsFriend entry was not found in %s netrc-file. Create it or provide a username with --username and a password with --password'
                ' with --username', netRcFilename)
            sys.exit(1)
        except FileNotFoundError:
            LOG.error(
                '%s netrc-file was not found. Create it or provide a username with --username and a password with --password',
                netRcFilename)
            sys.exit(1)

    if args.weConnectUsername is not None and args.weConnectPassword is not None:
        weConnectUsername = args.weConnectUsername
        weConnectPassword = args.weConnectPassword
    else:
        if args.netrc is not None:
            netRcFilename = args.netrc
        else:
            netRcFilename = defaultNetRc
        try:
            secrets = netrc.netrc(file=args.netrc)
            weConnectUsername, _, weConnectPassword = secrets.authenticators(
                "volkswagen.de")
        except netrc.NetrcParseError as err:
            LOG.error('Authentification using .netrc failed: %s', err)
            sys.exit(1)
        except TypeError:
            weConnectUsername = username
            weConnectPassword = password
            LOG.warning(
                'volkswagen.de entry was not found in %s netrc-file. Create it or provide a username with --weconnect-username and a password with'
                ' --weconnect-password', netRcFilename)
        except FileNotFoundError:
            weConnectUsername = username
            weConnectPassword = password
            LOG.warning(
                '%s netrc-file was not found. Create it or provide a username with --weconnect-username and a password with --weconnect-password',
                netRcFilename)

    tokenfile = None
    if not args.noTokenStorage:
        tokenfile = args.tokenfile

    weConnect = None
    try:
        weConnect = weconnect.WeConnect(username=weConnectUsername,
                                        password=weConnectPassword,
                                        tokenfile=tokenfile,
                                        updateAfterLogin=False,
                                        loginOnInit=(args.demo is None),
                                        maxAgePictures=86400)

        connector = AgentConnector(weConnect=weConnect,
                                   dbUrl=args.dbUrl,
                                   interval=args.interval,
                                   withDB=args.withDatabase,
                                   withABRP=args.withABRP,
                                   configDir=args.configDir,
                                   privacy=args.privacy)

        driver = None
        if args.withHomekit:
            LOG.info('Starting up Homekit')
            # Start the accessory on port 51826
            driver = AccessoryDriver(
                pincode=None, persist_file=f'{args.configDir}/accessory.state')

            for characteristicKey, characteristic in CUSTOM_CHARACTERISTICS.items(
            ):
                driver.loader.char_types[characteristicKey] = characteristic

            bridge = VWsFriendBridge(
                driver=driver,
                weConnect=weConnect,
                accessoryConfigFile=f'{args.configDir}/accessory.config')
            driver.add_accessory(bridge)
            weConnectBridgeInitialized = False

            # Start it!
            hapThread = threading.Thread(target=driver.start)
            hapThread.start()

            # Enable status tracking:
            weConnect.enableTracker()

        ui = VWsFriendUI(weConnect=weConnect,
                         connector=connector,
                         homekitDriver=driver,
                         dbUrl=args.dbUrl,
                         configDir=args.configDir,
                         username=username,
                         password=password)
        ui.run(host=args.host, port=args.port)

        if args.demo is not None:
            utcDemoStart = datetime.utcnow().replace(tzinfo=timezone.utc,
                                                     microsecond=0)
            for file in sorted(os.listdir(args.demo)):
                fileNameRegex = r'(?P<number>\d+)_(?P<delay>\d+)s(_(?P<stage>[^\.]+))?.cache.json'
                match = re.search(fileNameRegex, file)
                if match is not None:
                    time.sleep(int(match.groupdict()['delay']))
                    stageFilePath = f'{args.demo}/{file}'
                    with open(stageFilePath, mode='r', encoding='utf8') as fp:
                        cacheString = fp.read()
                        cacheString = re.sub(
                            r'demodate\((?P<offset>[+-]?\d+)\)',
                            lambda m: str(utcDemoStart + timedelta(seconds=int(
                                m.groupdict()['offset']))).replace(
                                    '+00:00', 'Z'), cacheString)
                        cacheString = re.sub(
                            r'now\((?P<offset>[+-]?\d+)\)',
                            lambda m: str(datetime.now() + timedelta(
                                seconds=int(m.groupdict()['offset']))),
                            cacheString)
                        weConnect.fillCacheFromJsonString(cacheString,
                                                          maxAge=2147483647)
                        if args.withHomekit and not weConnectBridgeInitialized:
                            weConnectBridgeInitialized = True
                            bridge.update()
                        weConnect.update(updateCapabilities=True,
                                         updatePictures=False)
                        connector.commit()
                        if match.groupdict()['stage'] is not None:
                            LOG.info('Stage %s completed',
                                     match.groupdict()['stage'])
                        else:
                            LOG.info('Stage completed')
            LOG.info('Demo completed')
        else:
            starttime = time.time()
            permanentErrors = 0
            while True:
                try:
                    LOG.info('Updating data from WeConnect')
                    weConnect.update(updateCapabilities=True,
                                     updatePictures=True,
                                     force=True)
                    connector.commit()
                    if args.withHomekit and not weConnectBridgeInitialized:
                        weConnectBridgeInitialized = True
                        bridge.update()
                    sleeptime = args.interval - (
                        (time.time() - starttime) % args.interval)
                    permanentErrors = 0
                except weconnect.RetrievalError:
                    LOG.error(
                        'Retrieval error during update. Will try again after configured interval of %ds',
                        args.interval)
                except APICompatibilityError as e:
                    sleeptime = min((args.interval * pow(2, permanentErrors)),
                                    86400)
                    LOG.critical(
                        'There was a problem when communicating with WeConnect. If this problem persists please open a bug report: %s,'
                        ' will retry after %ds', e, sleeptime)
                    permanentErrors += 1
                #  Execute exactly every interval but if it misses its deadline only after the next interval
                time.sleep(sleeptime)

    except AuthentificationError as e:
        LOG.critical(
            'There was a problem when authenticating with WeConnect: %s', e)
    except APICompatibilityError as e:
        LOG.critical(
            'There was a problem when communicating with WeConnect.'
            ' If this problem persists please open a bug report: %s', e)
    finally:
        if weConnect is not None:
            weConnect.disconnect()