コード例 #1
0
async def main(**kwargs):

    lib_kwargs = initialise_sys(kwargs)

    global GWY
    GWY = Gateway(lib_kwargs[CONFIG].pop(SERIAL_PORT, COM_PORT), **lib_kwargs)
    protocol, _ = GWY.create_client(process_gwy_message)
    mqtt_publish_schema()

    try:
        MQTT_CLIENT.loop_start()
        tasks = asyncio.create_task(GWY.start())

        await tasks

    except asyncio.CancelledError:
        msg = " - ended via: CancelledError (e.g. SIGINT)"
    except GracefulExit:
        msg = " - ended via: GracefulExit"
    except KeyboardInterrupt:
        msg = " - ended via: KeyboardInterrupt"
    except EvohomeError as err:
        msg = f" - ended via: EvohomeError: {err}"
    else:  # if no Exceptions raised, e.g. EOF when parsing
        msg = " - ended without error (e.g. EOF)"

    MQTT_CLIENT.loop_stop()
コード例 #2
0
async def main(serial_port, **config):

    # print(f"kwargs = {config}")

    if sys.platform == "win32":
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

    gwy = Gateway(serial_port, **config)

    colorama_init(autoreset=True)
    protocol, _ = gwy.create_client(process_message)

    schedule = config["set_schedule"] if config.get("set_schedule") else None
    try:
        task = asyncio.create_task(gwy.start())

        if config.get("get_schedule") is not None:
            zone = gwy.evo.zone_by_idx[config["get_schedule"]]
            schedule = await zone.get_schedule()

        elif config.get("set_schedule") is not None:
            zone = gwy.evo.zone_by_idx[schedule["zone_idx"]]
            await zone.set_schedule(schedule["schedule"])

        else:
            gwy.device_by_id[config["device_id"]]

        await gwy.shutdown()
        await task

    except asyncio.CancelledError:
        # print(" - exiting via: CancelledError (this is expected)")
        pass
    except GracefulExit:
        print(" - exiting via: GracefulExit")
    except KeyboardInterrupt:
        print(" - exiting via: KeyboardInterrupt")
    else:  # if no Exceptions raised, e.g. EOF when parsing
        print(" - exiting via: else-block (e.g. EOF when parsing)")

    if config.get("get_schedule") is not None:
        if schedule is None:
            print("Error: Failed to get the schedule.")
        else:
            result = {"zone_idx": config["get_schedule"], "schedule": schedule}
            print(json.dumps(result))  # , indent=4))

    elif config.get("set_schedule") is None:
        print(gwy.device_by_id[config["device_id"]])
コード例 #3
0
ファイル: client.py プロジェクト: skundrik/evohome_rf
async def main(serial_port, loop=None, **config):

    # loop=asyncio.get_event_loop() causes: 'NoneType' object has no attribute 'serial'
    print("Starting evohome_rf...")

    if sys.platform == "win32":  # is better than os.name
        # ERROR:asyncio:Cancelling an overlapped future failed
        # future: ... cb=[BaseProactorEventLoop._loop_self_reading()]
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

    gwy = None  # avoid 'possibly unbound' lint error
    try:
        gwy = Gateway(serial_port, loop=loop, **config)
        task = asyncio.create_task(gwy.start())
        # await asyncio.sleep(20)
        # print(await gwy.evo.zones[0].name)
        await task

    except asyncio.CancelledError:
        print(" - exiting via: CancelledError (this is expected)")
    except GracefulExit:
        print(" - exiting via: GracefulExit")
    except KeyboardInterrupt:
        print(" - exiting via: KeyboardInterrupt")
    else:  # if no Exceptions raised, e.g. EOF when parsing
        print(" - exiting via: else-block (e.g. EOF when parsing)")

    if gwy.evo is None:
        print(f"\r\nSchema[gateway] = {json.dumps(gwy.schema)}")
        print(f"\r\nParams[gateway] = {json.dumps(gwy.params)}")
        print(f"\r\nStatus[gateway] = {json.dumps(gwy.status)}")

    if __dev_mode__ and gwy.evo is not None:
        print(f"\r\nSchema[{gwy.evo.id}] = {json.dumps(gwy.evo.schema, indent=2)}")
        print(f"\r\nParams[{gwy.evo.id}] = {json.dumps(gwy.evo.params)}")
        print(f"\r\nStatus[{gwy.evo.id}] = {json.dumps(gwy.evo.status)}")

    elif gwy.evo is not None:
        print(f"\r\nSchema[{gwy.evo.id}] = {json.dumps(gwy.evo.schema, indent=2)}")
        print(f"\r\nParams[{gwy.evo.id}] = {json.dumps(gwy.evo.params, indent=2)}")
        print(f"\r\nStatus[{gwy.evo.id}] = {json.dumps(gwy.evo.status, indent=2)}")

    print("\r\nFinished evohome_rf.")
コード例 #4
0
ファイル: puzzle.py プロジェクト: martynwendon/evohome_rf
async def main(lib_kwargs, **kwargs):
    async def start(gwy) -> None:
        protocol_factory = create_protocol_factory(
            LocalProtocol, gwy, gwy.msg_transport._pkt_receiver)

        gwy.pkt_protocol, gwy.pkt_transport = create_pkt_stack(
            gwy,
            gwy.msg_transport._pkt_receiver,
            serial_port=gwy.serial_port,
            protocol_factory=protocol_factory,
        )
        gwy._tasks.append(
            gwy.msg_transport._set_dispatcher(gwy.pkt_protocol.send_data))

    print("\r\nclient.py: Starting evohome_rf (puzzler)...")

    if sys.platform == "win32":  # is better than os.name?
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

    colorama_init(autoreset=True)

    gwy = Gateway(lib_kwargs[CONFIG].pop(SERIAL_PORT, None), **lib_kwargs)
    await start(gwy)  # replaces asyncio.create_task(gwy.start())

    while gwy.pkt_protocol is None:
        await asyncio.sleep(0.05)

    if kwargs[COMMAND] == "cast":
        task = asyncio.create_task(puzzle_cast(gwy, gwy.pkt_protocol,
                                               **kwargs))
    else:  # kwargs[COMMAND] == "tune":
        task = asyncio.create_task(puzzle_tune(gwy, gwy.pkt_protocol,
                                               **kwargs))
    gwy._tasks.append(task)

    try:  # main code here
        await task  # await gather gwy_tasks

    except asyncio.CancelledError:
        msg = " - ended via: CancelledError (e.g. SIGINT)"
    except GracefulExit:
        msg = " - ended via: GracefulExit"
    except KeyboardInterrupt:
        msg = " - ended via: KeyboardInterrupt"
    except EvohomeError as err:
        msg = f" - ended via: EvohomeError: {err}"
    else:  # if no Exceptions raised, e.g. EOF when parsing
        msg = " - ended without error (e.g. EOF)"

    print(f"\r\nclient.py: Finished evohome_rf (puzzler).\r\n{msg}\r\n")
コード例 #5
0
async def main(lib_kwargs, **kwargs):
    async def start(gwy) -> None:
        protocol_factory = create_protocol_factory(LocalProtocol, gwy, None)

        gwy.pkt_protocol, gwy.pkt_transport = create_pkt_stack(
            gwy,
            None,
            packet_log=gwy._input_file,
            protocol_factory=protocol_factory,
        )
        if gwy.pkt_transport.get_extra_info(POLLER_TASK):
            gwy._tasks.append(gwy.pkt_transport.get_extra_info(POLLER_TASK))

    def setup_database(db_file: str):
        con = None
        try:
            con = sqlite3.connect(db_file)
        except sqlite3.Error as err:
            print(err)

        try:
            cur = con.cursor()
            cur.execute(SQL_CREATE_TABLE)
        except sqlite3.Error as err:
            print(err)

        return con

    def process_packet(pkt) -> None:
        global last_pkt

        def insert_pkt(pkt):
            global counter

            data_fields = (
                pkt.dtm,  # dtm
                pkt.packet[0:3],  # rssi
                pkt.packet[4:6],  # verb
                pkt.packet[7:10],  # seqn
                pkt.packet[11:20],  # dev0
                pkt.packet[21:30],  # dev1
                pkt.packet[31:40],  # dev2
                pkt.packet[41:45],  # code
                pkt.packet[46:49],  # len
                pkt.packet[50:],  # payload
            )

            try:
                # cur = con.cursor()
                cur.execute(SQL_UPSERT_ROW, data_fields)

            except sqlite3.Error as err:
                print(err)

            else:
                counter += 1
                if counter == 1000:
                    counter = 0

                    con.commit()
                    msg, hdr = f"{pkt.dtm} {pkt}", f"{Style.BRIGHT}{Fore.CYAN}"
                    print(f"{hdr}{msg[:CONSOLE_COLS]}")

            return cur.lastrowid

        if not pkt.is_valid:
            # msg, hdr = f"{pkt.dtm} {pkt._pkt_str}", f"{Fore.MAGENTA}"
            # print(f"{hdr}{msg[:CONSOLE_COLS]}")
            return

        if last_pkt:
            if all((
                    pkt.packet[4:6] == "RP",
                    pkt.packet[11:20] == last_pkt.packet[21:30],
                    pkt.packet[21:30] == last_pkt.packet[11:20],
                    pkt.packet[41:45] == last_pkt.packet[41:45],
            )):
                insert_pkt(last_pkt)
            last_pkt = None

        elif pkt.packet[4:6] == "RQ" and pkt.packet[11:13] == "18":
            last_pkt = pkt
            return

        else:
            insert_pkt(pkt)

    print("\r\nclient.py: Starting evohome_rf (utils)...")

    if sys.platform == "win32":
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

    colorama_init(autoreset=True)
    con = setup_database(kwargs[DATABASE])
    cur = con.cursor()

    gwy = Gateway(None, **lib_kwargs)
    await start(gwy)  # replaces asyncio.create_task(gwy.start())

    while gwy.pkt_protocol is None:
        await asyncio.sleep(0.05)
    gwy.pkt_protocol.pkt_callback = process_packet

    try:  # main code here
        await asyncio.gather(*gwy._tasks)

    except asyncio.CancelledError:
        msg = " - ended via: CancelledError (e.g. SIGINT)"
    except GracefulExit:
        msg = " - ended via: GracefulExit"
    except (KeyboardInterrupt, SystemExit):
        msg = " - ended via: KeyboardInterrupt"
    except EvohomeError as err:
        msg = f" - ended via: EvohomeError: {err}"
    else:  # if no Exceptions raised, e.g. EOF when parsing
        msg = " - ended without error (e.g. EOF)"

    con.commit()

    print(f"\r\nclient.py: Finished evohome_rf (utils).\r\n{msg}\r\n")
コード例 #6
0
ファイル: client.py プロジェクト: martynwendon/evohome_rf
async def main(lib_kwargs, **kwargs):
    def print_results(**kwargs):

        if kwargs[GET_FAULTS]:
            fault_log = gwy.system_by_id[kwargs[GET_FAULTS]]._fault_log.fault_log

            if fault_log is None:
                print("No fault log, or failed to get the fault log.")
            else:
                [print(f"{k:02X}", v) for k, v in fault_log.items()]

        if kwargs[GET_SCHED][0]:
            system_id, zone_idx = kwargs[GET_SCHED]
            zone = gwy.system_by_id[system_id].zone_by_idx[zone_idx]
            schedule = zone._schedule.schedule

            if schedule is None:
                print("Failed to get the schedule.")
            else:
                print("Schedule = \r\n", json.dumps(schedule))  # , indent=4))

        if kwargs[SET_SCHED][0]:
            system_id, _ = kwargs[GET_SCHED]

        # else:
        #     print(gwy.device_by_id[kwargs["device_id"]])

    def print_summary(gwy):
        if gwy.evo is None:
            print(f"Schema[gateway] = {json.dumps(gwy.schema)}\r\n")
            print(f"Params[gateway] = {json.dumps(gwy.params)}\r\n")
            print(f"Status[gateway] = {json.dumps(gwy.status)}")

        else:
            print(
                f"Schema[{repr(gwy.evo)}] = {json.dumps(gwy.evo.schema, indent=4)}\r\n"
            )
            print(
                f"Params[{repr(gwy.evo)}] = {json.dumps(gwy.evo.params, indent=4)}\r\n"
            )
            print(f"Status[{repr(gwy.evo)}] = {json.dumps(gwy.evo.status, indent=4)}")

    def process_message(msg) -> None:
        if kwargs[DEBUG_MODE]:
            dtm = f"{msg.dtm}"  # keep original timestamp
            print(f"{dtm} {msg}"[:CONSOLE_COLS])
            return

        dtm = msg.dtm if kwargs["long_dates"] else f"{msg.dtm:%H:%M:%S.%f}"[:-3]
        if msg.src.type == "18":
            print(f"{Style.BRIGHT}{COLORS.get(msg.verb)}{dtm} {msg}"[:CONSOLE_COLS])
        else:
            print(f"{COLORS.get(msg.verb)}{dtm} {msg}"[:CONSOLE_COLS])

    print("\r\nclient.py: Starting evohome_rf...")

    if sys.platform == "win32":
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

    gwy = Gateway(lib_kwargs[CONFIG].pop(SERIAL_PORT, None), **lib_kwargs)

    if kwargs[REDUCE_PROCESSING] < DONT_CREATE_MESSAGES:
        # no MSGs will be sent to STDOUT, so send PKTs instead
        colorama_init(autoreset=True)  # TODO: remove strip=True
        protocol, _ = gwy.create_client(process_message)

    try:  # main code here
        task = asyncio.create_task(gwy.start())

        if kwargs[COMMAND] == MONITOR:
            tasks = spawn_monitor_scripts(gwy, **kwargs)

        if kwargs[COMMAND] == EXECUTE:
            tasks = spawn_execute_scripts(gwy, **kwargs)
            await asyncio.gather(*tasks)

            cmds = (EXECUTE_CMD, SCAN_DISC, SCAN_FULL, SCAN_HARD, SCAN_XXXX)
            if not any(kwargs[k] for k in cmds):
                # await gwy.stop()
                task.cancel()

        await task

    except asyncio.CancelledError:
        msg = " - ended via: CancelledError (e.g. SIGINT)"
    except GracefulExit:
        msg = " - ended via: GracefulExit"
    except KeyboardInterrupt:
        msg = " - ended via: KeyboardInterrupt"
    except EvohomeError as err:
        msg = f" - ended via: EvohomeError: {err}"
    else:  # if no Exceptions raised, e.g. EOF when parsing
        msg = " - ended without error (e.g. EOF)"

    print("\r\nclient.py: Finished evohome_rf, results:\r\n")
    if kwargs[COMMAND] == EXECUTE:
        print_results(**kwargs)
    else:
        print_summary(gwy)

    print(f"\r\nclient.py: Finished evohome_rf.\r\n{msg}\r\n")
コード例 #7
0
async def main(lib_kwargs, **kwargs):
    def print_results(**kwargs):

        if kwargs[GET_FAULTS]:
            fault_log = gwy.system_by_id[
                kwargs[GET_FAULTS]]._fault_log.fault_log

            if fault_log is None:
                print("No fault log, or failed to get the fault log.")
            else:
                [print(f"{k:02X}", v) for k, v in fault_log.items()]

        if kwargs[GET_SCHED][0]:
            system_id, zone_idx = kwargs[GET_SCHED]
            zone = gwy.system_by_id[system_id].zone_by_idx[zone_idx]
            schedule = zone._schedule.schedule

            if schedule is None:
                print("Failed to get the schedule.")
            else:
                print("Schedule = \r\n", json.dumps(schedule))  # , indent=4))

        if kwargs[SET_SCHED][0]:
            system_id, _ = kwargs[GET_SCHED]

        # else:
        #     print(gwy.device_by_id[kwargs["device_id"]])

    def print_summary(gwy):
        if gwy.evo is None:
            print(f"Schema[gateway] = {json.dumps(gwy.schema)}\r\n")
            print(f"Params[gateway] = {json.dumps(gwy.params)}\r\n")
            print(f"Status[gateway] = {json.dumps(gwy.status)}")
            return

        print(
            f"Schema[{repr(gwy.evo)}] = {json.dumps(gwy.evo.schema, indent=4)}\r\n"
        )
        print(
            f"Params[{repr(gwy.evo)}] = {json.dumps(gwy.evo.params, indent=4)}\r\n"
        )
        print(
            f"Status[{repr(gwy.evo)}] = {json.dumps(gwy.evo.status, indent=4)}\r\n"
        )

        orphans = {
            "orphans": {
                d.id: d.status
                for d in sorted(gwy.devices) if d not in gwy.evo.devices
            }
        }
        print(f"Status[gateway] = {json.dumps(orphans, indent=4)}")

        devices = {"devices": {d.id: d.schema for d in sorted(gwy.devices)}}
        print(f"Schema[devices] = {json.dumps(devices, indent=4)}")

    def process_message(msg) -> None:
        dtm = msg.dtm if kwargs["long_dates"] else f"{msg.dtm:%H:%M:%S.%f}"[:-3]
        if msg.src.type == "18":
            print(
                f"{Style.BRIGHT}{COLORS.get(msg.verb)}{dtm} {msg}"[:
                                                                   CONSOLE_COLS]
            )
        else:
            print(f"{COLORS.get(msg.verb)}{dtm} {msg}"[:CONSOLE_COLS])

    print("\r\nclient.py: Starting evohome_rf...")

    if sys.platform == "win32":
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

    serial_port, lib_kwargs = normalise_config_schema(lib_kwargs)
    gwy = Gateway(serial_port, **lib_kwargs)

    if kwargs[REDUCE_PROCESSING] < DONT_CREATE_MESSAGES:
        # no MSGs will be sent to STDOUT, so send PKTs instead
        colorama_init(autoreset=True)  # TODO: remove strip=True
        protocol, _ = gwy.create_client(process_message)

    try:  # main code here
        task = asyncio.create_task(gwy.start())

        if kwargs[COMMAND] == MONITOR:
            tasks = spawn_monitor_scripts(gwy, **kwargs)

        if kwargs[COMMAND] == EXECUTE:
            tasks = spawn_execute_scripts(gwy, **kwargs)
            await asyncio.gather(*tasks)

            cmds = (EXECUTE_CMD, SCAN_DISC, SCAN_FULL, SCAN_HARD, SCAN_XXXX)
            if not any(kwargs[k] for k in cmds):
                # await gwy.stop()
                task.cancel()

        if False:  # TODO: temp test code
            print("AAA")
            await asyncio.sleep(3)
            print("BBB")
            cmd = Command.get_zone_name("01:145038", "00")
            msg = await gwy.async_send_cmd(cmd)
            print("CCC")
            print(msg)
            print("ZZZ")

        await task

    except asyncio.CancelledError:
        msg = " - ended via: CancelledError (e.g. SIGINT)"
    except GracefulExit:
        msg = " - ended via: GracefulExit"
    except KeyboardInterrupt:
        msg = " - ended via: KeyboardInterrupt"
    except EvohomeError as err:
        msg = f" - ended via: EvohomeError: {err}"
    else:  # if no Exceptions raised, e.g. EOF when parsing
        msg = " - ended without error (e.g. EOF)"

    print("\r\nclient.py: Finished evohome_rf, results:\r\n")
    if kwargs[COMMAND] == EXECUTE:
        print_results(**kwargs)
    else:
        print_summary(gwy)

    # schema, msgs = gwy._get_state()
    # f = open("state_msgs.log", "w")
    # [
    #     f.write(f"{m.dtm.isoformat(sep='T')} {m._pkt}\r\n")
    #     for m in msgs.values()
    #     # if not m.is_expired
    # ]
    # f.close()

    # f = open("state_schema.json", "w")
    # f.write(json.dumps(schema, indent=4))
    # f.close()

    # # await gwy._set_state(schema, msgs)

    print(f"\r\nclient.py: Finished evohome_rf.\r\n{msg}\r\n")