Skip to content

Commit

Permalink
Refactor & improve support for gateway devices (#924)
Browse files Browse the repository at this point in the history
* re-structure gateway devices

* re-apply already merged commit

* black formatting

* fix isort and flake8

* fix black

* fix issort

* fix magnet sensor zigbee id

* update zigbee ids

* vibration sensitivity

Add command to set vibration sensitivity of vibration sensor

* fix issort

* simplify subdevice_model_map

* remove unnesesarry comment

* move imports to the top

* fix black

* Update miio/gateway/devices/subdevice.py

Co-authored-by: Teemu R. <tpr@iki.fi>

* Update miio/gateway/devices/subdevice.py

Co-authored-by: Teemu R. <tpr@iki.fi>

* fix black

* fix isort and flake8 wanting to move above GatewayException class

Co-authored-by: Teemu R. <tpr@iki.fi>
  • Loading branch information
starkillerOG and rytilahti authored Feb 7, 2021
1 parent 91ecc98 commit a8289a6
Show file tree
Hide file tree
Showing 14 changed files with 1,754 additions and 1,677 deletions.
1,677 changes: 0 additions & 1,677 deletions miio/gateway.py

This file was deleted.

8 changes: 8 additions & 0 deletions miio/gateway/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Xiaomi Gateway implementation using Miio protecol."""

# flake8: noqa
from .alarm import Alarm
from .gateway import Gateway
from .light import Light
from .radio import Radio
from .zigbee import Zigbee
85 changes: 85 additions & 0 deletions miio/gateway/alarm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"""Xiaomi Gateway Alarm implementation."""

from datetime import datetime

import click

from ..click_common import command, format_output
from .gatewaydevice import GatewayDevice


class Alarm(GatewayDevice):
"""Class representing the Xiaomi Gateway Alarm."""

@command(default_output=format_output("[alarm_status]"))
def status(self) -> str:
"""Return the alarm status from the device."""
# Response: 'on', 'off', 'oning'
return self._gateway.send("get_arming").pop()

@command(default_output=format_output("Turning alarm on"))
def on(self):
"""Turn alarm on."""
return self._gateway.send("set_arming", ["on"])

@command(default_output=format_output("Turning alarm off"))
def off(self):
"""Turn alarm off."""
return self._gateway.send("set_arming", ["off"])

@command()
def arming_time(self) -> int:
"""
Return time in seconds the alarm stays 'oning'
before transitioning to 'on'
"""
# Response: 5, 15, 30, 60
return self._gateway.send("get_arm_wait_time").pop()

@command(click.argument("seconds"))
def set_arming_time(self, seconds):
"""Set time the alarm stays at 'oning' before transitioning to 'on'."""
return self._gateway.send("set_arm_wait_time", [seconds])

@command()
def triggering_time(self) -> int:
"""Return the time in seconds the alarm is going off when triggered."""
# Response: 30, 60, etc.
return self._gateway.get_prop("alarm_time_len").pop()

@command(click.argument("seconds"))
def set_triggering_time(self, seconds):
"""Set the time in seconds the alarm is going off when triggered."""
return self._gateway.set_prop("alarm_time_len", seconds)

@command()
def triggering_light(self) -> int:
"""
Return the time the gateway light blinks
when the alarm is triggerd
"""
# Response: 0=do not blink, 1=always blink, x>1=blink for x seconds
return self._gateway.get_prop("en_alarm_light").pop()

@command(click.argument("seconds"))
def set_triggering_light(self, seconds):
"""Set the time the gateway light blinks when the alarm is triggerd."""
# values: 0=do not blink, 1=always blink, x>1=blink for x seconds
return self._gateway.set_prop("en_alarm_light", seconds)

@command()
def triggering_volume(self) -> int:
"""Return the volume level at which alarms go off [0-100]."""
return self._gateway.send("get_alarming_volume").pop()

@command(click.argument("volume"))
def set_triggering_volume(self, volume):
"""Set the volume level at which alarms go off [0-100]."""
return self._gateway.send("set_alarming_volume", [volume])

@command()
def last_status_change_time(self) -> datetime:
"""
Return the last time the alarm changed status.
"""
return datetime.fromtimestamp(self._gateway.send("get_arming_time").pop())
8 changes: 8 additions & 0 deletions miio/gateway/devices/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Xiaomi Gateway subdevice base class."""

# flake8: noqa
from .light import LightBulb
from .sensor import Vibration
from .switch import Switch

from .subdevice import SubDevice, SubDeviceInfo # isort:skip
40 changes: 40 additions & 0 deletions miio/gateway/devices/light.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""Xiaomi Zigbee lights."""

import click

from ...click_common import command
from .subdevice import SubDevice


class LightBulb(SubDevice):
"""Base class for subdevice light bulbs."""

@command()
def update(self):
"""Update all device properties."""
self._props["brightness"] = self.send("get_bright").pop()
self._props["color_temp"] = self.send("get_ct").pop()
if self._props["brightness"] > 0 and self._props["brightness"] <= 100:
self._props["status"] = "on"
else:
self._props["status"] = "off"

@command()
def on(self):
"""Turn bulb on."""
return self.send_arg("set_power", ["on"]).pop()

@command()
def off(self):
"""Turn bulb off."""
return self.send_arg("set_power", ["off"]).pop()

@command(click.argument("ctt", type=int))
def set_color_temp(self, ctt):
"""Set the color temperature of the bulb ctt_min-ctt_max."""
return self.send_arg("set_ct", [ctt]).pop()

@command(click.argument("brightness", type=int))
def set_brightness(self, brightness):
"""Set the brightness of the bulb 1-100."""
return self.send_arg("set_bright", [brightness]).pop()
15 changes: 15 additions & 0 deletions miio/gateway/devices/sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""Xiaomi Zigbee sensors."""

import click

from ...click_common import command
from .subdevice import SubDevice


class Vibration(SubDevice):
"""Base class for subdevice vibration sensor."""

@command(click.argument("vibration_level", type=int))
def set_vibration_sensitivity(self, vibration_level):
"""Set the sensitivity of the vibration sensor, low = 21, medium = 11, high = 1."""
return self.set_property("vibration_level", vibration_level).pop()
Loading

0 comments on commit a8289a6

Please sign in to comment.