Skip to content

Commit

Permalink
merge remote branch ha0y/master (support Alarm) #133
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexxIT committed Jan 31, 2021
2 parents 5012973 + 8014a17 commit 396d848
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 22 deletions.
2 changes: 1 addition & 1 deletion custom_components/xiaomi_gateway3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
_LOGGER = logging.getLogger(__name__)

DOMAINS = ['binary_sensor', 'climate', 'cover', 'light', 'remote', 'sensor',
'switch']
'switch', 'alarm_control_panel']

CONF_DEVICES = 'devices'
CONF_DEBUG = 'debug'
Expand Down
98 changes: 98 additions & 0 deletions custom_components/xiaomi_gateway3/alarm_control_panel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import logging

from homeassistant.components.alarm_control_panel import (
SUPPORT_ALARM_ARM_AWAY,
SUPPORT_ALARM_ARM_HOME,
SUPPORT_ALARM_ARM_NIGHT,
AlarmControlPanelEntity,
)
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_DISARMED,
)

from . import Gateway3Device
from .core.gateway3 import Gateway3
from .core.utils import DOMAIN

_LOGGER = logging.getLogger(__name__)

ALARM_STATES = [STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_NIGHT]


async def async_setup_entry(hass, config_entry, async_add_entities):
def setup(gateway: Gateway3, device: dict, attr: str):
async_add_entities([Gateway3Alarm(gateway, device, attr)], True)

gw: Gateway3 = hass.data[DOMAIN][config_entry.entry_id]
gw.add_setup('alarm_control_panel', setup)


async def async_unload_entry(hass, entry):
return True


class Gateway3Alarm(Gateway3Device, AlarmControlPanelEntity):
@property
def miio_did(self):
return self.device['init']['alarm_did']

@property
def should_poll(self):
return True

@property
def state(self):
return self._state

@property
def icon(self):
return "mdi:shield-home"

@property
def supported_features(self):
return (SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY |
SUPPORT_ALARM_ARM_NIGHT)

@property
def code_arm_required(self):
return False

async def async_added_to_hass(self):
pass

async def async_will_remove_from_hass(self) -> None:
pass

def alarm_disarm(self, code=None):
self.gw.miio.send('set_properties', [{
'did': self.miio_did, 'siid': 3, 'piid': 1, 'value': 0
}])

def alarm_arm_home(self, code=None):
self.gw.miio.send('set_properties', [{
'did': self.miio_did, 'siid': 3, 'piid': 1, 'value': 1
}])

def alarm_arm_away(self, code=None):
self.gw.miio.send('set_properties', [{
'did': self.miio_did, 'siid': 3, 'piid': 1, 'value': 2
}])

def alarm_arm_night(self, code=None):
self.gw.miio.send('set_properties', [{
'did': self.miio_did, 'siid': 3, 'piid': 1, 'value': 3
}])

def update(self, *args):
try:
resp = self.gw.miio.send('get_properties', [{
'did': self.miio_did, 'siid': 3, 'piid': 1
}])
state = resp[0]['value']
self._state = ALARM_STATES[state]
except:
pass
6 changes: 5 additions & 1 deletion custom_components/xiaomi_gateway3/core/gateway3.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,9 @@ def _get_devices(self, shell: TelnetShell):
"""Load devices info for Coordinator, Zigbee and Mesh."""

# 1. Read coordinator info
raw = shell.read_file('/data/miio/device.conf').decode()
m = re.search(r'did=(\d+)', raw)

raw = shell.read_file('/data/zigbee/coordinator.info')
device = json.loads(raw)
devices = [{
Expand All @@ -552,7 +555,8 @@ def _get_devices(self, shell: TelnetShell):
'mac': device['mac'],
'type': 'gateway',
'init': {
'firmware lock': shell.check_firmware_lock()
'firmware lock': shell.check_firmware_lock(),
'alarm_did': m[1]
}
}]

Expand Down
1 change: 1 addition & 0 deletions custom_components/xiaomi_gateway3/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
['8.0.2155', None, 'cloud', None], # {"cloud_link":0}
[None, None, 'pair', 'remote'],
[None, None, 'firmware lock', 'switch'], # firmware lock
[None, None, 'alarm', 'alarm_control_panel'],
]
}, {
# on/off, power measurement
Expand Down
39 changes: 39 additions & 0 deletions custom_components/xiaomi_gateway3/core/xiaomi_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,45 @@ async def get_devices(self, server: str):

return None

async def request_miot_api(self, server: str, api: str, params: list):
"""Request MIoT API, for gateway alarm control. By Haoyu, 2021"""
assert server in SERVERS, "Wrong server: " + server
baseurl = 'https://api.io.mi.com/app' if server == 'cn' \
else f"https://{server}.api.io.mi.com/app"

url = '/miotspec' + api
data = json.dumps({'params': params}, separators=(',', ':'))

nonce = gen_nonce()
signed_nonce = gen_signed_nonce(self.auth['ssecurity'], nonce)
signature = gen_signature(url, signed_nonce, nonce, data)

try:
r = await self.session.post(baseurl + url, cookies={
'userId': self.auth['user_id'],
'serviceToken': self.auth['service_token'],
'locale': 'en_US'
}, headers={
'User-Agent': UA,
'x-xiaomi-protocal-flag-cli': 'PROTOCAL-HTTP2'
}, data={
'signature': signature,
'_nonce': nonce,
'data': data
}, timeout=10)

resp = await r.json(content_type=None)
_LOGGER.debug(f"Response from MIoT API {api}: {resp}")
assert resp['code'] == 0, resp
return resp['result']

except asyncio.TimeoutError:
_LOGGER.error(f"Timeout while requesting MIoT api {api}")
except:
_LOGGER.exception(f"Can't request MIoT API {api}")

return None


def get_random_string(length: int):
seq = string.ascii_uppercase + string.digits
Expand Down
40 changes: 20 additions & 20 deletions custom_components/xiaomi_gateway3/translations/zh-Hans.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"config": {
"error": {
"no_servers": "请选择至少一个服务器",
"cant_login": "无法登陆,检查用户名和密码",
"cant_login": "无法登录,请检查用户名和密码",
"cant_connect": "无法连接到网络",
"wrong_model": "网关型号不支持"
},
Expand All @@ -15,19 +15,19 @@
},
"cloud": {
"title": "添加小米云账号",
"description": "选择你设备所属的服务器",
"description": "选择设备所属的服务器",
"data": {
"username": "邮箱/小米ID",
"username": "邮箱/小米 ID",
"password": "密码",
"servers": "服务器"
}
},
"token": {
"description": "[获得](https://github.com/Maxmudjon/com.xiaomi-miio/blob/master/docs/obtain_token.md) 米家 token。\n注意:网关固件版本高于 **1.4.6_0043** 版以上,请参考 [焊接方法](https://github.com/AlexxIT/XiaomiGateway3/wiki) 后才能支持",
"description": "需要[获取](https://github.com/Maxmudjon/com.xiaomi-miio/blob/master/docs/obtain_token.md)米家 token。\n注意:若网关固件版本高于 **1.4.6_0043** ,需要先[焊接](https://github.com/AlexxIT/XiaomiGateway3/wiki)才能支持。",
"data": {
"host": "主机",
"token": "Token",
"ble": "支持的 BLE 设备",
"ble": "支持 BLE 设备",
"zha": "Zigbee Home Automation 模式"
}
}
Expand All @@ -45,32 +45,32 @@
"user": {
"title": "网关设定",
"data": {
"host": "主机端",
"token": "密钥",
"host": "主机",
"token": "Token",
"ble": "支持 BLE 设备",
"stats": "Zigbee 和 BLE 效能数据",
"debug": "Debug",
"debug": "调试信息",
"buzzer": "关闭蜂鸣器 [PRO]",
"parent": "统计上端装置 [PRO]",
"zha": "模式 [PRO]"
},
"description": "您必须了解风险后,才建议变更 **PRO** 选项"
"description": "如果您不清楚了解带有 **PRO** 选项的作用,建议不要更改它们。"
}
}
},
"device_automation": {
"trigger_type": {
"button": "按下按钮",
"button_1": " 1 个按钮按下",
"button_2": " 2 个按钮按下",
"button_3": " 3 个按钮按下",
"button_4": " 4 个按钮按下",
"button_5": " 5 个按钮按下",
"button_6": " 6 个按钮按下",
"button_both": "同时按下按钮",
"button_both_12": "第 1 与第 2 个按钮同时按下",
"button_both_13": "第 1 与第 3 个按钮同时按下",
"button_both_23": "第 2 与第 3 个按钮同时按下"
"button": "按下按键",
"button_1": "按下第 1 ",
"button_2": "按下第 2 ",
"button_3": "按下第 3 ",
"button_4": "按下第 4 ",
"button_5": "按下第 5 ",
"button_6": "按下第 6 ",
"button_both": "两键同时按下",
"button_both_12": "同时按下第 1、2 键",
"button_both_13": "同时按下第 1、3 键",
"button_both_23": "同时按下第 2、3 键"
}
}
}

0 comments on commit 396d848

Please sign in to comment.