Skip to content

Instantly share code, notes, and snippets.

@esnya
Created August 14, 2023 10:50
Show Gist options
  • Save esnya/5b70a02056ade085fc565f0643998e1b to your computer and use it in GitHub Desktop.
Save esnya/5b70a02056ade085fc565f0643998e1b to your computer and use it in GitHub Desktop.
LighthouseのBaseStationを電源状態を取得したりonにしたりsleepにしたりできるやつ。
import asyncio
import logging
from enum import Enum
from typing import Optional
# pip install bleak
from bleak import BleakClient, BleakScanner, BLEDevice
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
CONTROL_SERVICE_UUID = "00001523-1212-efde-1523-785feabcd124"
POWER_CHARACTERISTIC_UUID = "00001525-1212-efde-1523-785feabcd124"
class PowerState(Enum):
SLEEP = 0x00
STANDBY = 0x02
ON = 0x0B
BOOTING = 0x09
async def on_device_detected(
device: BLEDevice, target_state: Optional[PowerState], timeout: float
):
async with BleakClient(
device, services=[CONTROL_SERVICE_UUID], timeout=timeout
) as client:
assert client.is_connected
logger.debug("Connected to %s", device)
service = client.services.get_service(CONTROL_SERVICE_UUID)
if service is None:
logger.debug("Control service not detected.")
return
logger.debug("Control service detected: %s", service)
ch = service.get_characteristic(POWER_CHARACTERISTIC_UUID)
if ch is None:
logger.warning("Power characteristic not detected.")
return
current_status = await client.read_gatt_char(POWER_CHARACTERISTIC_UUID)
current_status = PowerState(current_status[0])
if target_state is None:
logger.info("%s: %s", device.name, current_status)
return
await client.write_gatt_char(
POWER_CHARACTERISTIC_UUID, bytes([target_state.value])
)
logger.info("%s: %s -> %s", device.name, current_status, target_state)
async def main(target_state: Optional[PowerState] = None, timeout: float = 5.0):
async with BleakScanner(services=[CONTROL_SERVICE_UUID]) as scanner:
devices = await scanner.discover()
for device in devices:
await on_device_detected(device, target_state, timeout)
if __name__ == "__main__":
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument(
"--sleep", action="store_const", const=PowerState.SLEEP, dest="target_state"
)
parser.add_argument(
"--standby", action="store_const", const=PowerState.STANDBY, dest="target_state"
)
parser.add_argument(
"--on", action="store_const", const=PowerState.ON, dest="target_state"
)
parser.add_argument(
"--timeout", "-t", type=float, default=5.0, help="Timeout in seconds"
)
args = parser.parse_args()
asyncio.run(main(args.target_state, args.timeout))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment