File: discover_devices.py

package info (click to toggle)
python-aioswitcher 4.0.2-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 13,528 kB
  • sloc: python: 4,324; makefile: 53
file content (139 lines) | stat: -rw-r--r-- 4,678 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#! python3

# Copyright Tomer Figenblat.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Python script for discovering Switcher devices."""

import asyncio
from argparse import ArgumentParser, RawDescriptionHelpFormatter
from dataclasses import asdict
from pprint import PrettyPrinter
from typing import List

from aioswitcher.bridge import (
    SWITCHER_UDP_PORT_TYPE1,
    SWITCHER_UDP_PORT_TYPE1_NEW_VERSION,
    SWITCHER_UDP_PORT_TYPE2,
    SWITCHER_UDP_PORT_TYPE2_NEW_VERSION,
    SwitcherBridge,
)
from aioswitcher.device import DeviceType, SwitcherBase

printer = PrettyPrinter(indent=4)

_examples = (
    """Executing this script will print a serialized version of the discovered Switcher
devices broadcasting on the local network for 60 seconds.
You can change the delay by passing an int argument: discover_devices.py 30

Switcher devices uses two protocol types:
    Protocol type 1 (UDP port 20002 or 10002), used by: """
    + ", ".join(d.value for d in DeviceType if d.protocol_type == 1)
    + """
    Protocol type 2 (UDP port 20003 or 10003), used by: """
    + ", ".join(d.value for d in DeviceType if d.protocol_type == 2)
    + """
You can change the scanned protocol type by passing an int argument: discover_devices.py -t 1

Note:
    WILL PRINT PRIVATE INFO SUCH AS DEVICE ID AND MAC.

Example output:
    Switcher devices broadcast a status message every approximately 4 seconds. This
    script listens for these messages and prints a serialized version of the to the
    standard output, for example (note the ``device_id`` and ``mac_address`` properties)::
    ```
        {   'auto_shutdown': '03:00:00',
            'device_id': 'aaaaaa',
            'device_state': <DeviceState.OFF: ('0000', 'off')>,
            'device_type': <DeviceType.V2_ESP: ('Switcher V2 (esp)', 'a7', <DeviceCategory.WATER_HEATER: 1>)>,
            'electric_current': 0.0,
            'ip_address': '192.168.1.33',
            'last_data_update': datetime.datetime(2021, 6, 13, 11, 11, 44, 883003),
            'mac_address': '12:A1:A2:1A:BC:1A',
            'name': 'My Switcher Boiler',
            'power_consumption': 0,
            'remaining_time': '00:00:00'}
    ```
Print all protocol types devices for 30 seconds:
    python discover_devices.py 30 -t all\n

Print only protocol type 1 devices:
    python discover_devices.py -t 1\n

Print only protocol type 2 devices:
    python discover_devices.py -t 2\n
"""  # noqa E501
)

parser = ArgumentParser(
    description="Discover and print info of Switcher devices",
    epilog=_examples,
    formatter_class=RawDescriptionHelpFormatter,
)
parser.add_argument(
    "delay",
    help="number of seconds to run, defaults to 60",
    type=int,
    nargs="?",
    default=60,
)
possible_types = ["1", "2", "all"]
parser.add_argument(
    "-t",
    "--type",
    required=False,
    choices=possible_types,
    help=f"set protocol type: {possible_types}",
    type=str,
)


async def print_devices(delay: int, ports: List[int]) -> None:
    """Run the Switcher bridge and register callback for discovered devices."""

    def on_device_found_callback(device: SwitcherBase) -> None:
        """Use as a callback printing found devices."""
        printer.pprint(asdict(device))
        print()

    async with SwitcherBridge(on_device_found_callback, broadcast_ports=ports):
        await asyncio.sleep(delay)


def main() -> None:
    """Run the device discovery script."""
    args = parser.parse_args()

    if args.type == "1":
        ports = [SWITCHER_UDP_PORT_TYPE1, SWITCHER_UDP_PORT_TYPE1_NEW_VERSION]
    elif args.type == "2":
        ports = [SWITCHER_UDP_PORT_TYPE2, SWITCHER_UDP_PORT_TYPE2_NEW_VERSION]
    else:
        ports = [
            SWITCHER_UDP_PORT_TYPE1,
            SWITCHER_UDP_PORT_TYPE1_NEW_VERSION,
            SWITCHER_UDP_PORT_TYPE2,
            SWITCHER_UDP_PORT_TYPE2_NEW_VERSION,
        ]

    try:
        asyncio.run(print_devices(args.delay, ports))
    except KeyboardInterrupt:
        exit()


if __name__ == "__main__":
    main()