Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
e69c64e
init heater support
YogevBokobza Mar 14, 2025
7af0768
refactoring
YogevBokobza Mar 24, 2025
16b3a2a
heater continue
YogevBokobza Mar 24, 2025
640d832
heater continue
YogevBokobza Mar 24, 2025
5550933
Update __init__.py and test_device_enum_helpers.py
YogevBokobza Mar 24, 2025
943fd7f
Update __init__.py
YogevBokobza Mar 24, 2025
fdba5e7
Update bridge.py, test_device_dataclasses.py, test_udp_datagram_parsi…
YogevBokobza Mar 24, 2025
ed41623
refactoring
YogevBokobza Apr 9, 2025
ceacb72
refactoring and support turn on and off for heater
YogevBokobza Apr 9, 2025
38b8e72
refactoring and add tests
YogevBokobza Apr 9, 2025
bb1a732
refactoring and add tests
YogevBokobza Apr 9, 2025
f6dd60f
refactoring
YogevBokobza Apr 9, 2025
bfe4ce4
add get_heater_state with tests
YogevBokobza Apr 9, 2025
50e03ac
fix linting
YogevBokobza Apr 9, 2025
d285140
Update messages.py
YogevBokobza Nov 24, 2025
aac2741
Update supported.md and get_heater_state_response.txt
YogevBokobza Nov 24, 2025
4aaf146
Update scripts.md
YogevBokobza Nov 24, 2025
5316d24
Update scripts.md
YogevBokobza Nov 24, 2025
8403531
Update usage_api.md
YogevBokobza Nov 24, 2025
d03fac7
Update messages.py
YogevBokobza Dec 21, 2025
bfe921c
Update bridge.py and __init__.py
YogevBokobza Dec 21, 2025
affca6a
Update test_device_dataclasses.py and test_a_heater_datagram_produces…
YogevBokobza Dec 21, 2025
71c9511
Merge branch 'TomerFi:dev' into add-heater-support
YogevBokobza Feb 1, 2026
2516c03
fix based on requested changes
YogevBokobza Feb 1, 2026
fe3cb7a
fix based on CodeRabbit
YogevBokobza Feb 1, 2026
9d30409
fix tests
YogevBokobza Feb 1, 2026
6b33ab7
Update control_device.py, test_api_tcp_client.py, test_datagram_state…
YogevBokobza Feb 1, 2026
661d359
Update scripts.md and test_api_tcp_client.py
YogevBokobza Feb 1, 2026
74f8f16
Update control_device.py
YogevBokobza Feb 1, 2026
6f6e711
Update test_udp_datagram_parsing.py
YogevBokobza Feb 1, 2026
7089f55
fix tests
YogevBokobza Feb 2, 2026
cc47a7f
Update test_udp_datagram_parsing.py
YogevBokobza Feb 2, 2026
9486641
Update test_udp_datagram_parsing.py
YogevBokobza Feb 2, 2026
39e81f6
Update scripts.md and control_device.py
YogevBokobza Feb 2, 2026
39b071a
Update docs/supported.md
YogevBokobza Feb 2, 2026
f84c13a
Update docs/usage_api.md
YogevBokobza Feb 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ body:
- Switcher Light SL02
- Switcher Light SL02 Mini
- Switcher Light SL03
- Switcher Heater
validations:
required: true

Expand Down
56 changes: 46 additions & 10 deletions docs/scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ options:
-c DEVICE_TYPE, --device-type DEVICE_TYPE
the type of the device
-k TOKEN, --token TOKEN
the token for communicating with the new switcher devices
the token for communicating with switcher token-based devices
-d DEVICE_ID, --device-id DEVICE_ID
the identification of the device
-l DEVICE_KEY, --device-key DEVICE_KEY
Expand Down Expand Up @@ -245,7 +245,7 @@ options:
-c DEVICE_TYPE, --device-type DEVICE_TYPE
the type of the device
-k TOKEN, --token TOKEN
the token for communicating with the new switcher devices
the token for communicating with switcher token-based devices
-d DEVICE_ID, --device-id DEVICE_ID
the identification of the device
-l DEVICE_KEY, --device-key DEVICE_KEY
Expand Down Expand Up @@ -385,7 +385,7 @@ options:
-c DEVICE_TYPE, --device-type DEVICE_TYPE
the type of the device
-k TOKEN, --token TOKEN
the token for communicating with the new switcher devices
the token for communicating with switcher token-based devices
-d DEVICE_ID, --device-id DEVICE_ID
the identification of the device
-l DEVICE_KEY, --device-key DEVICE_KEY
Expand Down Expand Up @@ -423,7 +423,7 @@ options:
-c DEVICE_TYPE, --device-type DEVICE_TYPE
the type of the device
-k TOKEN, --token TOKEN
the token for communicating with the new switcher devices
the token for communicating with switcher token-based devices
-d DEVICE_ID, --device-id DEVICE_ID
the identification of the device
-l DEVICE_KEY, --device-key DEVICE_KEY
Expand Down Expand Up @@ -451,13 +451,15 @@ python control_device.py stop_shutter -c "runners12" -k "zvVvd7JxtN7CgvkD1Psujw=
```shell title="scripts/control_device.py turn_off"
$ poetry run control_device turn_off --help

usage: control_device.py turn_off [-h] [-v] -c DEVICE_TYPE -d DEVICE_ID [-l DEVICE_KEY] -i IP_ADDRESS
usage: control_device.py turn_off [-h] [-v] -c DEVICE_TYPE [-k TOKEN] -d DEVICE_ID [-l DEVICE_KEY] -i IP_ADDRESS

options:
-h, --help show this help message and exit
-v, --verbose include the raw message
-c DEVICE_TYPE, --device-type DEVICE_TYPE
the type of the device
-k TOKEN, --token TOKEN
the token for communicating with switcher token-based devices
-d DEVICE_ID, --device-id DEVICE_ID
the identification of the device
-l DEVICE_KEY, --device-key DEVICE_KEY
Expand All @@ -470,21 +472,25 @@ example usage:
python control_device.py turn_off -c "touch" -d ab1c2d -i "111.222.11.22"

python control_device.py turn_off -c "touch" -d ab1c2d -l 18 -i "111.222.11.22"

python control_device.py turn_off -c "heater" -k "zvVvd7JxtN7CgvkD1Psujw==" -d f2239a -l 18 -i "192.168.50.98"
```

### Turn on

```shell title="scripts/control_device.py turn_on"
$ poetry run control_device turn_on --help

usage: control_device.py turn_on [-h] [-v] -c DEVICE_TYPE -d DEVICE_ID [-l DEVICE_KEY] -i IP_ADDRESS
usage: control_device.py turn_on [-h] [-v] -c DEVICE_TYPE [-k TOKEN] -d DEVICE_ID [-l DEVICE_KEY] -i IP_ADDRESS
[-t [TIMER]]

options:
-h, --help show this help message and exit
-v, --verbose include the raw message
-c DEVICE_TYPE, --device-type DEVICE_TYPE
the type of the device
-k TOKEN, --token TOKEN
the token for communicating with switcher token-based devices
-d DEVICE_ID, --device-id DEVICE_ID
the identification of the device
-l DEVICE_KEY, --device-key DEVICE_KEY
Expand All @@ -501,6 +507,10 @@ python control_device.py turn_on -c "touch" -d ab1c2d -i "111.222.11.22"
python control_device.py turn_on -c "touch" -d ab1c2d -l 18 -i "111.222.11.22"

python control_device.py turn_on -c "touch" -d ab1c2d -i "111.222.11.22" -t 15

python control_device.py turn_on -c "heater" -k "zvVvd7JxtN7CgvkD1Psujw==" -d f2239a -l 18 -i "192.168.50.98"

python control_device.py turn_on -c "heater" -k "zvVvd7JxtN7CgvkD1Psujw==" -d f2239a -l 18 -i "192.168.50.98" -t 15
```

### Turn off light
Expand All @@ -516,7 +526,7 @@ options:
-c DEVICE_TYPE, --device-type DEVICE_TYPE
the type of the device
-k TOKEN, --token TOKEN
the token for communicating with the new switcher devices
the token for communicating with switcher token-based devices
-d DEVICE_ID, --device-id DEVICE_ID
the identification of the device
-l DEVICE_KEY, --device-key DEVICE_KEY
Expand Down Expand Up @@ -566,7 +576,7 @@ options:
-c DEVICE_TYPE, --device-type DEVICE_TYPE
the type of the device
-k TOKEN, --token TOKEN
the token for communicating with the new switcher devices
the token for communicating with switcher token-based devices
-d DEVICE_ID, --device-id DEVICE_ID
the identification of the device
-l DEVICE_KEY, --device-key DEVICE_KEY
Expand Down Expand Up @@ -616,7 +626,7 @@ options:
-c DEVICE_TYPE, --device-type DEVICE_TYPE
the type of the device
-k TOKEN, --token TOKEN
the token for communicating with the new switcher devices
the token for communicating with switcher token-based devices
-d DEVICE_ID, --device-id DEVICE_ID
the identification of the device
-l DEVICE_KEY, --device-key DEVICE_KEY
Expand Down Expand Up @@ -652,7 +662,7 @@ options:
-c DEVICE_TYPE, --device-type DEVICE_TYPE
the type of the device
-k TOKEN, --token TOKEN
the token for communicating with the new switcher devices
the token for communicating with switcher token-based devices
-d DEVICE_ID, --device-id DEVICE_ID
the identification of the device
-l DEVICE_KEY, --device-key DEVICE_KEY
Expand All @@ -675,6 +685,32 @@ python control_device.py turn_on_shutter_child_lock -c "runners11" -k "zvVvd7Jxt
python control_device.py turn_on_shutter_child_lock -c "runners12" -k "zvVvd7JxtN7CgvkD1Psujw==" -d ab1c2d -i "111.222.11.22"
```

### Get heater state

```shell title="scripts/control_device.py get_heater_state"
$ poetry run control_device get_heater_state --help

usage: control_device.py get_heater_state [-h] [-v] -c DEVICE_TYPE [-k TOKEN] -d DEVICE_ID [-l DEVICE_KEY] -i IP_ADDRESS

options:
-h, --help show this help message and exit
-v, --verbose include the raw message
-c DEVICE_TYPE, --device-type DEVICE_TYPE
the type of the device
-k TOKEN, --token TOKEN
the token for communicating with switcher token-based devices
-d DEVICE_ID, --device-id DEVICE_ID
the identification of the device
-l DEVICE_KEY, --device-key DEVICE_KEY
the login key of the device
-i IP_ADDRESS, --ip-address IP_ADDRESS
the ip address assigned to the device

example usage:

python control_device.py get_heater_state -c "heater" -k "zvVvd7JxtN7CgvkD1Psujw==" -d f2239a -i "192.168.50.98"
```

## Discover devices

Use to discover devices and their states.
Expand Down
36 changes: 19 additions & 17 deletions docs/supported.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
| Name | Link | Included from version |
|--------------------------|:-----------------------------------:|:---------------------:|
| Switcher V2 | [product][switcher-v2] | 1.x.x |
| Switcher Mini | [product][switcher-mini] | 1.x.x |
| Switcher Touch (V3) | [product][switcher-touch] | 1.x.x |
| Switcher V4 | [product][switcher-v4] | 1.x.x |
| Switcher Power Plug | [product][switcher-power-plug] | 2.x.x |
| Switcher Breeze | [product][switcher-breeze] | 3.x.x |
| Switcher Runner | [product][switcher-runner] | 3.x.x |
| Switcher Runner Mini | [product][switcher-runner-mini] | 3.x.x |
| Switcher Runner S11 | [product][switcher-runner-s11] | 4.x.x |
| Switcher Runner S12 | [product][switcher-runner-s12] | 4.1.x |
| Switcher Light SL01 | [product][switcher-light-sl01] | 4.2.x |
| Switcher Light SL01 Mini | [product][switcher-light-sl01-mini] | 4.2.x |
| Switcher Light SL02 | [product][switcher-light-sl02] | 4.3.x |
| Switcher Light SL02 Mini | [product][switcher-light-sl02-mini] | 4.3.x |
| Switcher Light SL03 | [product][switcher-light-sl03] | 4.4.x |
| Name | Link | Included from version | Requires token |
|--------------------------|:-----------------------------------:|:---------------------:|:------------------:|
| Switcher V2 | [product][switcher-v2] | 1.x.x | No |
| Switcher Mini | [product][switcher-mini] | 1.x.x | No |
| Switcher Touch (V3) | [product][switcher-touch] | 1.x.x | No |
| Switcher V4 | [product][switcher-v4] | 1.x.x | No |
| Switcher Power Plug | [product][switcher-power-plug] | 2.x.x | No |
| Switcher Breeze | [product][switcher-breeze] | 3.x.x | No |
| Switcher Runner | [product][switcher-runner] | 3.x.x | No |
| Switcher Runner Mini | [product][switcher-runner-mini] | 3.x.x | No |
| Switcher Runner S11 | [product][switcher-runner-s11] | 4.x.x | Yes |
| Switcher Runner S12 | [product][switcher-runner-s12] | 4.1.x | Yes |
| Switcher Light SL01 | [product][switcher-light-sl01] | 4.2.x | Yes |
| Switcher Light SL01 Mini | [product][switcher-light-sl01-mini] | 4.2.x | Yes |
| Switcher Light SL02 | [product][switcher-light-sl02] | 4.3.x | Yes |
| Switcher Light SL02 Mini | [product][switcher-light-sl02-mini] | 4.3.x | Yes |
| Switcher Light SL03 | [product][switcher-light-sl03] | 4.4.x | Yes |
| Switcher Heater | [product][switcher-heater] | 6.x.x | Yes |

!!!note
Newer Switcher devices, such as Runner S11, require a token. Get yours at: https://switcher.co.il/GetKey
Expand All @@ -34,3 +35,4 @@
[switcher-light-sl02]: https://switcher.co.il/%D7%9E%D7%95%D7%A6%D7%A8/switcher-light-sl02/
[switcher-light-sl02-mini]: https://switcher.co.il/%D7%9E%D7%95%D7%A6%D7%A8/switcher-light-slmini02/
[switcher-light-sl03]: https://switcher.co.il/%D7%9E%D7%95%D7%A6%D7%A8/switcher-light-sl03/
[switcher-heater]: https://switcher.co.il/%D7%9E%D7%95%D7%A6%D7%A8/switcher-heater/
20 changes: 20 additions & 0 deletions docs/usage_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,23 @@ asyncio.run(control_light(DeviceType.LIGHT_SL02, "111.222.11.22", "ab1c2d", "00"
asyncio.run(control_light(DeviceType.LIGHT_SL02_MINI, "111.222.11.22", "ab1c2d", "00", "zvVvd7JxtN7CgvkD1Psujw=="))
asyncio.run(control_light(DeviceType.LIGHT_SL03, "111.222.11.22", "ab1c2d", "00", "zvVvd7JxtN7CgvkD1Psujw=="))
```

## Heater excerpt

```python
import asyncio
from aioswitcher.api import Command, SwitcherApi
from aioswitcher.device import DeviceType

async def control_heater(device_type, device_ip, device_id, device_key, token) :
# for connecting to a device we need its type, id, login key, ip address and token
async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api:
# get the device's current state
await api.get_heater_state()
# turn the device on for 15 minutes
await api.control_device(Command.ON, 15)
# turn the device off
await api.control_device(Command.OFF)

asyncio.run(control_heater(DeviceType.HEATER, "111.222.11.22", "ab1c2d" , "00", "zvVvd7JxtN7CgvkD1Psujw=="))
```
48 changes: 45 additions & 3 deletions scripts/control_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"light02": DeviceType.LIGHT_SL02,
"light02mini": DeviceType.LIGHT_SL02_MINI,
"light03": DeviceType.LIGHT_SL03,
"heater": DeviceType.HEATER,
}

# shared parse
Expand All @@ -78,7 +79,7 @@
"--token",
default=None,
type=str,
help="the token for communicating with the new switcher devices",
help="the token for communicating with switcher token-based devices",
)
shared_parser.add_argument(
"-d",
Expand Down Expand Up @@ -582,6 +583,18 @@
help="the circuit number to turn on",
)

# get_heater_state parser
_get_heater_state_examples = """example usage:

poetry run control_device get_heater_state -c "heater" -k "zvVvd7JxtN7CgvkD1Psujw==" -d ab1c2d -i "111.222.11.22"\n """ # noqa E501
subparsers.add_parser(
"get_heater_state",
help="get the current state of a heater device",
epilog=_get_heater_state_examples,
formatter_class=RawDescriptionHelpFormatter,
parents=[shared_parser],
)


def asdict(dc: object, verbose: bool = False) -> Dict[str, Any]:
"""Use as custom implementation of the asdict utility method."""
Expand Down Expand Up @@ -671,9 +684,10 @@ async def turn_on(
device_ip: str,
timer: int,
verbose: bool,
token: Union[str, None] = None,
) -> None:
"""Use to launch a turn_on request."""
async with SwitcherApi(device_type, device_ip, device_id, device_key) as api:
async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api:
printer.pprint(asdict(await api.control_device(Command.ON, timer), verbose))


Expand All @@ -683,9 +697,10 @@ async def turn_off(
device_key: str,
device_ip: str,
verbose: bool,
token: Union[str, None] = None,
) -> None:
"""Use to launch a turn_off request."""
async with SwitcherApi(device_type, device_ip, device_id, device_key) as api:
async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api:
printer.pprint(asdict(await api.control_device(Command.OFF), verbose))


Expand Down Expand Up @@ -889,6 +904,19 @@ async def turn_off_light(
printer.pprint(asdict(await api.set_light(DeviceState.OFF, index), verbose))


async def get_heater_state(
device_type: DeviceType,
device_id: str,
device_key: str,
device_ip: str,
verbose: bool,
token: Union[str, None] = None,
) -> None:
"""Use to launch a get_heater_state request."""
async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api:
printer.pprint(asdict(await api.get_heater_state(), verbose))


def main() -> None:
"""Run the device controller script."""
try:
Expand Down Expand Up @@ -918,6 +946,7 @@ def main() -> None:
args.ip_address,
args.timer,
args.verbose,
args.token,
)
)
elif args.action == "turn_off":
Expand All @@ -928,6 +957,7 @@ def main() -> None:
args.device_key,
args.ip_address,
args.verbose,
args.token,
)
)
elif args.action == "set_name":
Expand Down Expand Up @@ -1123,6 +1153,18 @@ def main() -> None:
)
)

elif args.action == "get_heater_state":
asyncio.run(
get_heater_state(
device_type,
args.device_id,
args.device_key,
args.ip_address,
args.verbose,
args.token,
)
)

except KeyboardInterrupt:
exit()

Expand Down
Loading
Loading