From e89edbd66f5450afb465f3a34a1a055a4f291184 Mon Sep 17 00:00:00 2001 From: chliny Date: Mon, 14 Jun 2021 23:32:52 +0800 Subject: [PATCH 01/14] merge to onefile && support ha 2021.4.6 --- ezviz/__init__.py | 1 + ezviz/manifest.json | 1 + ezviz/sensor.py | 334 +++++++++++++++++++++++++++++++----------- ezvizctrl/__init__.py | 297 ------------------------------------- 4 files changed, 252 insertions(+), 381 deletions(-) create mode 100755 ezviz/__init__.py delete mode 100755 ezvizctrl/__init__.py diff --git a/ezviz/__init__.py b/ezviz/__init__.py new file mode 100755 index 0000000..8b13789 --- /dev/null +++ b/ezviz/__init__.py @@ -0,0 +1 @@ + diff --git a/ezviz/manifest.json b/ezviz/manifest.json index a2720c3..732f591 100644 --- a/ezviz/manifest.json +++ b/ezviz/manifest.json @@ -2,6 +2,7 @@ "domain": "ezviz", "name": "ezviz", "documentation": "https://www.example.com", + "version":"0.0.1", "dependencies": [], "codeowners": [], "requirements": [] diff --git a/ezviz/sensor.py b/ezviz/sensor.py index f209c98..af4267e 100755 --- a/ezviz/sensor.py +++ b/ezviz/sensor.py @@ -26,9 +26,10 @@ # 定义三个可选项 # 格式:配置项名称:[OBJECT_ID, friendly_name, icon, 单位] OPTIONS = { - "privacyStatus": ["ezviz_privacyStatus", "遮蔽状态", "", ""], - "AlarmStatus": ["ezviz_AlarmStatus", "移动侦测", "", ""], - "alarmSoundMode": ["ezviz_alarmSoundMode", "报警音模式", "mdi:surround-sound", ""], + "sceneStatus": ["ezviz_sceneStatus", "遮蔽状态", "mdi:eye-off", ""], + "privacyStatus": ["ezviz_privacyStatus", "隐私状态", "mdi:looks", ""], + "pirStatus": ["ezviz_pirStatus", "红外状态", "mdi:camcorder-box", ""], + "alarmSoundMode": ["ezviz_alarmSoundMode", "告警模式", "mdi:surround-sound", ""], } ATTR_UPDATE_TIME = "更新时间" @@ -46,23 +47,24 @@ def setup_platform(hass, config, add_devices, discovery_info=None): """根据配置文件,setup_platform函数会自动被系统调用.""" _LOGGER.info("setup platform sensor.ezviz...") - + deviceSerial=config.get(CONF_Device_Serial) appKey= config.get(CONF_APP_KEY) appSecret= config.get(CONF_APP_SECRET) - # 定义一个新的数据对象,用于获取萤石API数据。 + # 定义一个新的数据对象 data = EZVIZData(hass,deviceSerial,appKey,appSecret) - + # 根据配置文件options中的内容,添加若干个设备 dev = [] for option in config[CONF_OPTIONS]: dev.append(EZVIZSensor(data, option)) add_devices(dev, True) - + data.regist() + class EZVIZSensor(Entity): """定义一个传感器的类,继承自HomeAssistant的Entity类.""" - + def __init__(self, data, option): """初始化.""" self._data = data @@ -74,32 +76,32 @@ def __init__(self, data, option): self._type = option self._state = None self._updatetime = None - + @property def name(self): """返回实体的名字.""" return self._object_id - + @property def registry_name(self): """返回实体的friendly_name属性.""" return self._friendly_name - + @property def state(self): """返回当前的状态.""" return self._state - + @property def icon(self): """返回icon属性.""" return self._icon - + @property def unit_of_measurement(self): """返回unit_of_measuremeng属性.""" return self._unit_of_measurement - + @property def device_state_attributes(self): """设置其它一些属性值.""" @@ -109,116 +111,280 @@ def device_state_attributes(self): # 增加updatetime作为属性,表示获取的时间 ATTR_UPDATE_TIME: self._updatetime } - + def update(self): # update只是从EZVIZData中获得数据,数据由EZVIZData维护。 self._updatetime = self._data.updatetime if self._type == "privacyStatus": self._state = self._data.privacyStatus + elif self._type == "sceneStatus": + self._state = self._data.sceneStatus elif self._type == "alarmSoundMode": - self._state = self._data.alarmSoundMode - elif self._type == "AlarmStatus": - self._state = self._data.AlarmStatus + self._state = self._data.alarmSoundMode + elif self._type == "pirStatus": + self._state = self._data.pirStatus class EZVIZData(object): """摄像头的数据,存储在这个类中.""" def __init__(self, hass, deviceSerial,appKey,appSecret): """初始化函数.""" - self._params = {"accessToken": "", - "deviceSerial": deviceSerial - } - self._apikey = {"appKey": appKey, - "appSecret": appSecret - } + + self.hass = hass + self.deviceSerial = deviceSerial + self.apikey = { + "appKey": appKey, + "appSecret": appSecret + } + self.ENTITYID = "ezviz.home" + self.access_Token = '' + self._privacyStatus = None - self._AlarmStatus = None + self._pirStatus = None + self._sceneStatus = None self._alarmSoundMode = None self._updatetime = None self.update(dt_util.now()) # 每隔TIME_BETWEEN_UPDATES,调用一次update() track_time_interval(hass, self.update, TIME_BETWEEN_UPDATES) - + @property def privacyStatus(self): """隐私状态""" return self._privacyStatus - + @property - def AlarmStatus(self): - """报警状态""" - return self._AlarmStatus - + def sceneStatus(self): + """遮蔽状态""" + return self._sceneStatus + + @property + def pirStatus(self): + """红外状态""" + return self._pirStatus + @property def alarmSoundMode (self): """提醒模式""" return self._alarmSoundMode - + @property def updatetime(self): """更新时间.""" return self._updatetime - + def update(self, now): """从远程更新信息.""" _LOGGER.info("Update the EZVIZ state...") - statusCode = requests.post('https://open.ys7.com/api/lapp/device/list',data=self._params).json()["code"] - if statusCode == "200": - _LOGGER.info('TOKEN_SUCCESS') - else: - response = requests.post('https://open.ys7.com/api/lapp/token/get',data=self._apikey).json() - #访问url - if response["code"] == "200": - _LOGGER.info('GET_TOKEN_SUCCESS') - self._params["accessToken"] = response['data']['accessToken'] - else: - _LOGGER.error("Error API return, code=%s, msg=%s",response['code'],response['msg']) - return #POST获取数据 - - result = requests.post('https://open.ys7.com/api/lapp/device/info',data=self._params).json() - if result is None: - _LOGGER.error("Request api Error") - return - elif result["code"] != "200": - _LOGGER.error("Error API return, code=%s, msg=%s", - result['code'],result['msg']) - return + params = {} + status_url = "https://open.ys7.com/api/lapp/device/status/get" + scene_url = "https://open.ys7.com/api/lapp/device/scene/switch/status" + result = self._post(status_url, params) + if result: + # 根据http返回的结果,更新数据 + all_result = result['data'] + _LOGGER.debug(all_result) - # 根据http返回的结果,更新数据 - all_result = result['data'] - # _LOGGER.error(all_result) + if all_result['privacyStatus'] == 1: + self._privacyStatus = '启用隐私' + elif all_result['privacyStatus'] == 0: + self._privacyStatus = '关闭隐私' + else: + self._privacyStatus = '不支持' - if all_result['defence'] == 1: - self._AlarmStatus = '布防' - else: - self._AlarmStatus = '撤防' - - if all_result['alarmSoundMode'] == 0: - self._alarmSoundMode = '短叫' - elif all_result['alarmSoundMode'] == 1: - self._alarmSoundMode = '长叫' - elif all_result['alarmSoundMode'] == 2: - self._alarmSoundMode = '静音' + if all_result['pirStatus'] == 1: + self._pirStatus = '启用' + elif all_result['pirStatus'] == 0: + self._pirStatus = '关闭' + else: + self._pirStatus = '不支持' + + if all_result['alarmSoundMode'] == 0: + self._alarmSoundMode = '短叫' + elif all_result['alarmSoundMode'] == 1: + self._alarmSoundMode = '长叫' + elif all_result['alarmSoundMode'] == 2: + self._alarmSoundMode = '静音' + else: + self._alarmSoundMode = '禁用或不支持' + + scene = self._post(scene_url, params) + if scene: + if scene['data']['enable'] == 1: + self._sceneStatus = '启用遮蔽' + else: + self._sceneStatus = '关闭遮蔽' + + self._updatetime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + # self._pirStatus= all_result['pirStatus'] + # self._privacyStatus= all_result['privacyStatus'] + # self._alarmSoundMode= all_result['alarmSoundMode'] + + def request_token(self) -> str: + #重新获取access_token + access_Token = "" + response = requests.post('https://open.ys7.com/api/lapp/token/get',data=self.apikey).json() + #访问url + if response["code"] == "200": + _LOGGER.info('GET_TOKEN_SUCCESS') + access_Token = response['data']['accessToken'] + attr = {'access_Token': access_Token} + self.hass.states.set(self.ENTITYID, 'OK', attributes=attr) else: - self._alarmSoundMode = '禁用或不支持' - - result = requests.post('https://open.ys7.com/api/lapp/device/scene/switch/status',data=self._params).json() - if result is None: - _LOGGER.error("Request api Error") + _LOGGER.error("Error API return, code=%s, msg=%s",response['code'],response['msg']) + return access_Token + + def Get_access_Token(self, isForce=False): + # 记录info级别的日志 + _LOGGER.info("Update the EZVIZ state...") + + if not self.access_Token: + entobj = self.hass.states.get(self.ENTITYID) + if entobj: + attr = entobj.attributes.copy() + self.access_Token = attr['access_Token'] + + if not self.access_Token: + self.access_Token = self.request_token() return - elif result["code"] != "200": - _LOGGER.error("Error API return, code=%s, msg=%s", - result['code'],result['msg']) + + if isForce: + self.access_Token = self.request_token() + _LOGGER.info('TOKEN_SUCCESS') + return + + def _post(self, url, data) -> dict: + # 获取access_Token + self.Get_access_Token() + if not self.access_Token: + _LOGGER.error("Request Token Error") return + default_data = { + "accessToken": self.access_Token, + "deviceSerial": self.deviceSerial + } + data.update(default_data) + ret = requests.post(url, data=data, timeout=5) + if not ret.ok: + _LOGGER.error("Request Error %s %s", url, str(data)) + return {} - # 根据http返回的结果,更新数据 - all_result = result['data'] - if all_result['enable'] == 1: - self._privacyStatus = '启用遮蔽' - else: - self._privacyStatus = '关闭遮蔽' + result = ret.json() + if not result: + _LOGGER.error("Request Empty Error %s %s", url, str(data)) + return {} - - self._updatetime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + code = result.get("code", "0") + if code != "200": + _LOGGER.error("Error API return, code=%s, msg=%s, url=%s", + code,result['msg'], url) + return {} + + return result + + + def Enable_privacy(self, call): + ctrl = {"enable": '1'} + url = 'https://open.ys7.com/api/lapp/device/scene/switch/set' + if self._post(url, ctrl): + # 更新传感器状态 + self.hass.states.set('sensor.ezviz_scenestatus', '启用遮蔽') + + def Disable_privacy(self, call): + ctrl = {"enable": '0'} + url = 'https://open.ys7.com/api/lapp/device/scene/switch/set' + if self._post(url, ctrl): + self.hass.states.set('sensor.ezviz_scenestatus', '关闭遮蔽') + + def Enable_alarm(self, call): + ctrl = {"isDefence": '1'} + url = 'https://open.ys7.com/api/lapp/device/defence/set' + if self._post(url, ctrl): + # 更新传感器状态 + self.hass.states.set('sensor.ezviz_alarmSoundstatus', '布防') + + def Disable_alarm(self, call): + ctrl = {"isDefence": '0'} + url = 'https://open.ys7.com/api/lapp/device/defence/set' + if self._post(url, ctrl): + self.hass.states.set('sensor.ezviz_alarmSoundstatus', '撤防') + + def move(self, direc) -> str: + ctrl = { + "channelNo": '1', + "direction": direc, + "speed": '1' + } + start_url = 'https://open.ys7.com/api/lapp/device/ptz/start' + if not self._post(start_url, ctrl): + _LOGGER.error("move failed") + return 'FAIL' + + # 等待0.2s后停止 + time.sleep(0.2) + ctrl = { + "channelNo": '1', + "direction": direc + } + + stop_url = 'https://open.ys7.com/api/lapp/device/ptz/stop' + if not self._post(stop_url, ctrl): + return 'FAIL' + return 'OK' + + def up(self, call): + self.move(0) + + def down(self, call): + self.move(1) + + def left(self, call): + self.move(2) + + def right(self, call): + self.move(3) + + def upleft(self, call): + self.move(4) + + def downleft(self,call): + self.move(5) + + def upright(self, call): + self.move(6) + + def downright(self, call): + self.move(7) + + def stop(self, call): + ctrl = { + "channelNo": '1' + } + url ='https://open.ys7.com/api/lapp/device/ptz/stop' + + trytimes = 2 + for idx in range(trytimes): + if self._post(url, ctrl): + break + return + + def regist(self): + # 注册服务 + DOMAIN = "ezviz" + self.hass.services.register(DOMAIN, 'enable_privacy', self.Enable_privacy) + self.hass.services.register(DOMAIN, 'disable_privacy', self.Disable_privacy) + self.hass.services.register(DOMAIN, 'enable_alarm', self.Enable_alarm) + self.hass.services.register(DOMAIN, 'disable_alarm', self.Disable_alarm) + self.hass.services.register(DOMAIN, 'up', self.up) + self.hass.services.register(DOMAIN, 'down', self.down) + self.hass.services.register(DOMAIN, 'left', self.left) + self.hass.services.register(DOMAIN, 'right', self.right) + self.hass.services.register(DOMAIN, 'upright', self.upright) + self.hass.services.register(DOMAIN, 'downright', self.downright) + self.hass.services.register(DOMAIN, 'upleft', self.upleft) + self.hass.services.register(DOMAIN, 'downleft', self.downleft) + self.hass.services.register(DOMAIN, 'stop', self.stop) + + return True diff --git a/ezvizctrl/__init__.py b/ezvizctrl/__init__.py deleted file mode 100755 index 1d78153..0000000 --- a/ezvizctrl/__init__.py +++ /dev/null @@ -1,297 +0,0 @@ -""" -用途:以服务方式控制萤石摄像头 -版本:V0.1 -依赖:ezviz/sensor.py控件 -""" - -import json -from urllib import request, parse -import logging -import requests -from time import sleep - -import voluptuous as vol -import homeassistant.helpers.config_validation as cv - - -_LOGGER = logging.getLogger(__name__) - -DOMAIN = "ezvizctrl" -ENTITYID = DOMAIN + ".home" - -# 预定义配置文件中的key值 -CONF_DEVICESERIAL = "deviceSerial" -CONF_APPKEY = "appKey" -CONF_APPSECRET = "appSecret" - - -# 在python中,__name__代表模块名字 -_LOGGER = logging.getLogger(__name__) - -# 配置文件的样式 -CONFIG_SCHEMA = vol.Schema( - { - DOMAIN: vol.Schema( - { - vol.Required(CONF_DEVICESERIAL): cv.string, - vol.Required(CONF_APPKEY): cv.string, - vol.Required(CONF_APPSECRET): cv.string, - }), - }, - extra=vol.ALLOW_EXTRA) - - -def setup(hass, config): - """配置文件加载后,setup被系统调用.""" - conf = config[DOMAIN] - deviceSerial = conf.get(CONF_DEVICESERIAL) - appKey = conf.get(CONF_APPKEY) - appSecret = conf.get(CONF_APPSECRET) - - access_Token = '' - attr = {"access_Token": access_Token,} - - hass.states.set(ENTITYID, 'OK', attributes=attr) - - def Get_access_Token(): - # 记录info级别的日志 - _LOGGER.info("Update the EZVIZ state...") - attr = hass.states.get(ENTITYID).attributes.copy() - access_Token = attr['access_Token'] - params = {"accessToken": access_Token, - "deviceSerial": deviceSerial - } - apikey = {"appKey": appKey, - "appSecret": appSecret - } - # 检查access_token是否有效 - statusCode = requests.post('https://open.ys7.com/api/lapp/device/list',data=params).json()["code"] - if statusCode == "200": - _LOGGER.info('TOKEN_SUCCESS') - else: - #重新获取access_token - response = requests.post('https://open.ys7.com/api/lapp/token/get',data=apikey).json() - #访问url - if response["code"] == "200": - _LOGGER.info('GET_TOKEN_SUCCESS') - access_Token = response['data']['accessToken'] - attr['access_Token'] = access_Token - hass.states.set(ENTITYID, 'OK', attributes=attr) - else: - _LOGGER.error("Error API return, code=%s, msg=%s",response['code'],response['msg']) - return - return access_Token - - def Enable_privacy(call): - # 获取access_Token - access_Token = Get_access_Token() - if access_Token is None: - _LOGGER.error("Request Token Error") - return - ctrl = {"accessToken": access_Token, - "deviceSerial": deviceSerial, - "enable": '1' - } - result = requests.post('https://open.ys7.com/api/lapp/device/scene/switch/set',data=ctrl).json() - if result is None: - _LOGGER.error("Request api Error") - return - elif result["code"] != "200": - _LOGGER.error("Error API return, code=%s, msg=%s", - result['code'],result['msg']) - return - # 更新传感器状态 - hass.states.set('sensor.ezviz_privacystatus', '启用遮蔽') - - def Disable_privacy(call): - # 获取access_Token - access_Token = Get_access_Token() - if access_Token is None: - _LOGGER.error("Request Token Error") - return - ctrl = {"accessToken": access_Token, - "deviceSerial": deviceSerial, - "enable": '0' - } - result = requests.post('https://open.ys7.com/api/lapp/device/scene/switch/set',data=ctrl).json() - if result is None: - _LOGGER.error("Request api Error") - return - elif result["code"] != "200": - _LOGGER.error("Error API return, code=%s, msg=%s", - result['code'],result['msg']) - return - hass.states.set('sensor.ezviz_privacystatus', '关闭遮蔽') - - def Enable_alarm(call): - # 获取access_Token - access_Token = Get_access_Token() - if access_Token is None: - _LOGGER.error("Request Token Error") - return - ctrl = {"accessToken": access_Token, - "deviceSerial": deviceSerial, - "isDefence": '1' - } - result = requests.post('https://open.ys7.com/api/lapp/device/defence/set',data=ctrl).json() - if result is None: - _LOGGER.error("Request api Error") - return - elif result["code"] != "200": - _LOGGER.error("Error API return, code=%s, msg=%s", - result['code'],result['msg']) - return - # 更新传感器状态 - hass.states.set('sensor.ezviz_alarmstatus', '布防') - - def Disable_alarm(call): - # 获取access_Token - access_Token = Get_access_Token() - if access_Token is None: - _LOGGER.error("Request Token Error") - return - ctrl = {"accessToken": access_Token, - "deviceSerial": deviceSerial, - "isDefence": '0' - } - result = requests.post('https://open.ys7.com/api/lapp/device/defence/set',data=ctrl).json() - if result is None: - _LOGGER.error("Request api Error") - return - elif result["code"] != "200": - _LOGGER.error("Error API return, code=%s, msg=%s", - result['code'],result['msg']) - return - # 更新传感器状态 - hass.states.set('sensor.ezviz_alarmstatus', '撤防') - - def move(direc): - # 获取access_Token - access_Token = Get_access_Token() - if access_Token is None: - _LOGGER.error("Request Token Error") - return - ctrl = {"accessToken": access_Token, - "deviceSerial": deviceSerial, - "channelNo": '1', - "direction": direc, - "speed": '1' - } - result = requests.post('https://open.ys7.com/api/lapp/device/ptz/start',data=ctrl).json() - if result is None: - _LOGGER.error("Request api Error") - return - elif result["code"] != "200": - _LOGGER.error("Error API return, code=%s, msg=%s", - result['code'],result['msg']) - return - # 等待0.2s后停止 - sleep(0.2) - ctrl = {"accessToken": access_Token, - "deviceSerial": deviceSerial, - "channelNo": '1', - "direction": direc - } - result = requests.post('https://open.ys7.com/api/lapp/device/ptz/stop',data=ctrl).json() - if result is None: - _LOGGER.error("Request api Error") - return - elif result["code"] != "200": - _LOGGER.error("Error API return, code=%s, msg=%s", - result['code'],result['msg']) - ##防止因为意外再次执行停止 - result = requests.post('https://open.ys7.com/api/lapp/device/ptz/stop',data=ctrl).json() - if result["code"] != "200": - _LOGGER.error("Error API return, code=%s, msg=%s", - result['code'],result['msg']) - return - return 'OK' - - def up(call): - result = move(0) - if result is None: - _LOGGER.error("move failed") - return - - def down(call): - result = move(1) - if result is None: - _LOGGER.error("move failed") - return - - def left(call): - result = move(2) - if result is None: - _LOGGER.error("move failed") - return - - def right(call): - result = move(3) - if result is None: - _LOGGER.error("move failed") - return - - def upleft(call): - result = move(4) - if result is None: - _LOGGER.error("move failed") - return - - def downleft(call): - result = move(5) - if result is None: - _LOGGER.error("move failed") - return - - def upright(call): - result = move(6) - if result is None: - _LOGGER.error("move failed") - return - - def downright(call): - result = move(7) - if result is None: - _LOGGER.error("move failed") - return - - def stop(call): - # 获取access_Token - access_Token = Get_access_Token() - if access_Token is None: - _LOGGER.error("Request Token Error") - return - ctrl = {"accessToken": access_Token, - "deviceSerial": deviceSerial, - "channelNo": '1' - } - result = requests.post('https://open.ys7.com/api/lapp/device/ptz/stop',data=ctrl).json() - if result is None: - _LOGGER.error("Request api Error") - return - elif result["code"] != "200": - _LOGGER.error("Error API return, code=%s, msg=%s", - result['code'],result['msg']) - ##防止因为意外再次执行停止 - result = requests.post('https://open.ys7.com/api/lapp/device/ptz/stop',data=ctrl).json() - if result["code"] != "200": - _LOGGER.error("Error API return, code=%s, msg=%s", - result['code'],result['msg']) - return - - # 注册服务 - hass.services.register(DOMAIN, 'Enable_privacy', Enable_privacy) - hass.services.register(DOMAIN, 'Disable_privacy', Disable_privacy) - hass.services.register(DOMAIN, 'Enable_alarm', Enable_alarm) - hass.services.register(DOMAIN, 'Disable_alarm', Disable_alarm) - hass.services.register(DOMAIN, 'up', up) - hass.services.register(DOMAIN, 'down', down) - hass.services.register(DOMAIN, 'left', left) - hass.services.register(DOMAIN, 'right', right) - hass.services.register(DOMAIN, 'upright', upright) - hass.services.register(DOMAIN, 'downright', downright) - hass.services.register(DOMAIN, 'upleft', upleft) - hass.services.register(DOMAIN, 'downleft', downleft) - hass.services.register(DOMAIN, 'stop', stop) - - return True From 1b11e36ff84c20a9fe7655b0248b357e4d997407 Mon Sep 17 00:00:00 2001 From: chliny Date: Mon, 14 Jun 2021 23:33:24 +0800 Subject: [PATCH 02/14] delete nouse import --- ezviz/sensor.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ezviz/sensor.py b/ezviz/sensor.py index af4267e..e84bdd5 100755 --- a/ezviz/sensor.py +++ b/ezviz/sensor.py @@ -1,11 +1,9 @@ -import json import time -from urllib import request, parse import logging from datetime import timedelta import voluptuous as vol import requests - + from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( ATTR_ATTRIBUTION, ATTR_FRIENDLY_NAME, TEMP_CELSIUS) @@ -13,7 +11,7 @@ import homeassistant.helpers.config_validation as cv from homeassistant.helpers.event import track_time_interval import homeassistant.util.dt as dt_util - + _LOGGER = logging.getLogger(__name__) TIME_BETWEEN_UPDATES = timedelta(seconds=60) From b4a00ed7f2495f2d08994d5138441032084b33cd Mon Sep 17 00:00:00 2001 From: chliny Date: Tue, 15 Jun 2021 00:43:52 +0800 Subject: [PATCH 03/14] add onlinestatus and defencestatus --- ezviz/sensor.py | 84 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 21 deletions(-) diff --git a/ezviz/sensor.py b/ezviz/sensor.py index e84bdd5..00df786 100755 --- a/ezviz/sensor.py +++ b/ezviz/sensor.py @@ -27,7 +27,9 @@ "sceneStatus": ["ezviz_sceneStatus", "遮蔽状态", "mdi:eye-off", ""], "privacyStatus": ["ezviz_privacyStatus", "隐私状态", "mdi:looks", ""], "pirStatus": ["ezviz_pirStatus", "红外状态", "mdi:camcorder-box", ""], - "alarmSoundMode": ["ezviz_alarmSoundMode", "告警模式", "mdi:surround-sound", ""], + "alarmSoundMode": ["ezviz_alarmSoundMode", "告警声音模式", "mdi:surround-sound", ""], + "defenceStatus":["ezviz_defenceStatus", "布防状态", "mdi:shield-home", ""], + "onlineStatus": ["ezviz_onlineStatus", "在线状态", "mdi:link", ""], } ATTR_UPDATE_TIME = "更新时间" @@ -122,6 +124,10 @@ def update(self): self._state = self._data.alarmSoundMode elif self._type == "pirStatus": self._state = self._data.pirStatus + elif self._type == "defenceStatus": + self._state = self._data.defenceStatus + elif self._type == "onlineStatus": + self._state = self._data.onlineStatus class EZVIZData(object): """摄像头的数据,存储在这个类中.""" @@ -141,6 +147,8 @@ def __init__(self, hass, deviceSerial,appKey,appSecret): self._pirStatus = None self._sceneStatus = None self._alarmSoundMode = None + self._defenceStatus = None + self._onlineStatus = None self._updatetime = None self.update(dt_util.now()) @@ -152,6 +160,16 @@ def privacyStatus(self): """隐私状态""" return self._privacyStatus + @property + def defenceStatus(self): + """布防状态""" + return self._defenceStatus + + @property + def onlineStatus(self): + """机器在线状态""" + return self._onlineStatus + @property def sceneStatus(self): """遮蔽状态""" @@ -178,7 +196,6 @@ def update(self, now): #POST获取数据 params = {} status_url = "https://open.ys7.com/api/lapp/device/status/get" - scene_url = "https://open.ys7.com/api/lapp/device/scene/switch/status" result = self._post(status_url, params) if result: # 根据http返回的结果,更新数据 @@ -208,6 +225,14 @@ def update(self, now): else: self._alarmSoundMode = '禁用或不支持' + self.get_sceneStatus() + self.get_deviceInfo() + + self._updatetime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + + def get_sceneStatus(self): + params = {} + scene_url = "https://open.ys7.com/api/lapp/device/scene/switch/status" scene = self._post(scene_url, params) if scene: if scene['data']['enable'] == 1: @@ -215,10 +240,25 @@ def update(self, now): else: self._sceneStatus = '关闭遮蔽' - self._updatetime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) - # self._pirStatus= all_result['pirStatus'] - # self._privacyStatus= all_result['privacyStatus'] - # self._alarmSoundMode= all_result['alarmSoundMode'] + def get_deviceInfo(self): + #布防开关(活动状态检测开关) + url = "https://open.ys7.com/api/lapp/device/info" + params = {} + ret = self._post(url, params) + retdata = ret.get("data", {}) + defence = retdata.get("defence", 0) + if defence == 0: + self._defenceStatus = "撤防" + else: + self._defenceStatus = "布防" + + #设备是否在线 + online = retdata.get("status", 0) + if online == 0: + self._onlineStatus = "离线" + else: + self._onlineStatus = "在线" + def request_token(self) -> str: #重新获取access_token @@ -235,9 +275,6 @@ def request_token(self) -> str: return access_Token def Get_access_Token(self, isForce=False): - # 记录info级别的日志 - _LOGGER.info("Update the EZVIZ state...") - if not self.access_Token: entobj = self.hass.states.get(self.ENTITYID) if entobj: @@ -283,31 +320,36 @@ def _post(self, url, data) -> dict: return result - def Enable_privacy(self, call): + def enable_sence(self, call): ctrl = {"enable": '1'} url = 'https://open.ys7.com/api/lapp/device/scene/switch/set' if self._post(url, ctrl): # 更新传感器状态 - self.hass.states.set('sensor.ezviz_scenestatus', '启用遮蔽') + self._sceneStatus = "启用遮蔽" + self.hass.states.set('sensor.ezviz_scenestatus', self._sceneStatus) - def Disable_privacy(self, call): + def disable_sence(self, call): ctrl = {"enable": '0'} url = 'https://open.ys7.com/api/lapp/device/scene/switch/set' if self._post(url, ctrl): - self.hass.states.set('sensor.ezviz_scenestatus', '关闭遮蔽') + self._sceneStatus = "关闭遮蔽" + self.hass.states.set('sensor.ezviz_scenestatus', self._sceneStatus) - def Enable_alarm(self, call): + def enable_defence(self, call): + #活动检测开关 ctrl = {"isDefence": '1'} url = 'https://open.ys7.com/api/lapp/device/defence/set' if self._post(url, ctrl): # 更新传感器状态 - self.hass.states.set('sensor.ezviz_alarmSoundstatus', '布防') + self._defenceStatus = "布防" + self.hass.states.set('sensor.ezviz_defenceStatus', '布防') - def Disable_alarm(self, call): + def disable_defence(self, call): ctrl = {"isDefence": '0'} url = 'https://open.ys7.com/api/lapp/device/defence/set' if self._post(url, ctrl): - self.hass.states.set('sensor.ezviz_alarmSoundstatus', '撤防') + self._defenceStatus = "撤防" + self.hass.states.set('sensor.ezviz_defenceStatus', '撤防') def move(self, direc) -> str: ctrl = { @@ -371,10 +413,10 @@ def stop(self, call): def regist(self): # 注册服务 DOMAIN = "ezviz" - self.hass.services.register(DOMAIN, 'enable_privacy', self.Enable_privacy) - self.hass.services.register(DOMAIN, 'disable_privacy', self.Disable_privacy) - self.hass.services.register(DOMAIN, 'enable_alarm', self.Enable_alarm) - self.hass.services.register(DOMAIN, 'disable_alarm', self.Disable_alarm) + self.hass.services.register(DOMAIN, 'enable_sence', self.enable_sence) + self.hass.services.register(DOMAIN, 'disable_sence', self.disable_sence) + self.hass.services.register(DOMAIN, 'enable_defence', self.enable_defence) + self.hass.services.register(DOMAIN, 'disable_defence', self.disable_defence) self.hass.services.register(DOMAIN, 'up', self.up) self.hass.services.register(DOMAIN, 'down', self.down) self.hass.services.register(DOMAIN, 'left', self.left) From fd921d17a6ed2d8c9365d7322c3cde47d4762a06 Mon Sep 17 00:00:00 2001 From: chliny Date: Tue, 15 Jun 2021 01:36:36 +0800 Subject: [PATCH 04/14] fix sceneStatus err --- ezviz/sensor.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ezviz/sensor.py b/ezviz/sensor.py index 00df786..50f1f51 100755 --- a/ezviz/sensor.py +++ b/ezviz/sensor.py @@ -326,14 +326,16 @@ def enable_sence(self, call): if self._post(url, ctrl): # 更新传感器状态 self._sceneStatus = "启用遮蔽" - self.hass.states.set('sensor.ezviz_scenestatus', self._sceneStatus) + self.hass.states.set('sensor.ezviz_sceneStatus', self._sceneStatus) + _LOGGER.info("enable sence") def disable_sence(self, call): ctrl = {"enable": '0'} url = 'https://open.ys7.com/api/lapp/device/scene/switch/set' if self._post(url, ctrl): self._sceneStatus = "关闭遮蔽" - self.hass.states.set('sensor.ezviz_scenestatus', self._sceneStatus) + self.hass.states.set('sensor.ezviz_sceneStatus', self._sceneStatus) + _LOGGER.info("disable sence") def enable_defence(self, call): #活动检测开关 From 40f51d752fbd77571b956af76763b09db2f42960 Mon Sep 17 00:00:00 2001 From: chliny Date: Tue, 15 Jun 2021 01:36:49 +0800 Subject: [PATCH 05/14] update log --- ezviz/sensor.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ezviz/sensor.py b/ezviz/sensor.py index 50f1f51..137a853 100755 --- a/ezviz/sensor.py +++ b/ezviz/sensor.py @@ -192,7 +192,7 @@ def updatetime(self): def update(self, now): """从远程更新信息.""" - _LOGGER.info("Update the EZVIZ state...") + _LOGGER.debug("Update the EZVIZ state...") #POST获取数据 params = {} status_url = "https://open.ys7.com/api/lapp/device/status/get" @@ -200,7 +200,6 @@ def update(self, now): if result: # 根据http返回的结果,更新数据 all_result = result['data'] - _LOGGER.debug(all_result) if all_result['privacyStatus'] == 1: self._privacyStatus = '启用隐私' @@ -287,7 +286,7 @@ def Get_access_Token(self, isForce=False): if isForce: self.access_Token = self.request_token() - _LOGGER.info('TOKEN_SUCCESS') + _LOGGER.debug('TOKEN_SUCCESS') return def _post(self, url, data) -> dict: @@ -345,6 +344,7 @@ def enable_defence(self, call): # 更新传感器状态 self._defenceStatus = "布防" self.hass.states.set('sensor.ezviz_defenceStatus', '布防') + _LOGGER.info("enable defence") def disable_defence(self, call): ctrl = {"isDefence": '0'} @@ -352,6 +352,7 @@ def disable_defence(self, call): if self._post(url, ctrl): self._defenceStatus = "撤防" self.hass.states.set('sensor.ezviz_defenceStatus', '撤防') + _LOGGER.info("disable defence") def move(self, direc) -> str: ctrl = { From 8449d51bc98f79da980341866c7f4d3b4509e567 Mon Sep 17 00:00:00 2001 From: chliny Date: Tue, 15 Jun 2021 01:47:22 +0800 Subject: [PATCH 06/14] Update README.md --- README.md | 142 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 73 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 24dec20..51d6117 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,9 @@ # 使用说明 -1、将下载的插件中两个文件夹复制到custom_components目录下
-2、key和secret请在萤石开发网站获取,具体可详见https://bbs.hassbian.com/thread-7062-1-1.html
-3、在configuration.yaml文件中添加以下内容启用插件
+1. 将下载的插件中的`ezviz`文件夹复制到`custom_components`目录下 +2. `key`和`secret`请在[萤石开发网站](https://bbs.hassbian.com/thread-7062-1-1.html)获取 +3. 在`configuration.yaml`文件中添加以下内容启用插件 -~~~ -ezvizctrl: - deviceSerial: ****设备序列号 - appKey: ****api接口里面的appkey - appSecret: ****api接口里面的appsecret +```yaml sensor: - platform: ezviz appKey: **** @@ -15,87 +11,95 @@ sensor: deviceSerial: *** scan_interval: 30 options: + - sceneStatus - privacyStatus - - AlarmStatus + - pirStatus - alarmSoundMode -~~~ -4、在configuration.yaml添加两个开关,用于修改移动侦测和遮蔽状态 -~~~ + - defenceStatus + - onlineStatus +``` + +4. 在`configuration.yaml`添加两个开关,用于修改移动侦测和遮蔽状态 +```yaml switch: - platform: template switches: - privacy: + sence: friendly_name: 镜头遮蔽 - value_template: "{{ is_state('sensor.ezviz_privacystatus', '启用遮蔽') }}" + value_template: "{{ is_state('sensor.ezviz_sceneStatus', '启用遮蔽') }}" turn_on: - service: ezvizctrl.enable_privacy + service: ezviz.enable_sence turn_off: - service: ezvizctrl.disable_privacy + service: ezviz.disable_sence icon_template: >- - {% if is_state('sensor.ezviz_privacystatus', '启用遮蔽') %} + {% if is_state('sensor.ezviz_sceneStatus', '启用遮蔽') %} mdi:eye-off {% else %} mdi:eye {% endif %} - platform: template switches: - alarm: - friendly_name: 移动侦测 - value_template: "{{ is_state('sensor.ezviz_alarmstatus', '布防') }}" + defence: + friendly_name: 布防状态(活动检测) + value_template: "{{ is_state('sensor.ezviz_defenceStatus', '布防') }}" turn_on: - service: ezvizctrl.enable_alarm + service: ezviz.enable_defence turn_off: - service: ezvizctrl.disable_alarm + service: ezviz.disable_defence icon_template: >- - {% if is_state('sensor.ezviz_alarmstatus', '布防') %} + {% if is_state('sensor.ezviz_defenceStatus', '布防') %} mdi:shield-home {% else %} mdi:shield-off {% endif %} -~~~ -5、在lovelace上面添加控制界面 -首先安装 radial-menu 插件,https://github.com/custom-cards/radial-menu -将如下代码,通过原始编辑器,在合适的位置添加进去 -~~~ -- cards: - - entities: - - switch.privacy - - switch.alarm - - sensor.ezviz_alarmsoundmode - show_header_toggle: false - title: 摄像机状态 - type: entities - - default_dismiss: false - default_open: true - icon: 'mdi:webcam' - items: - - entity: null - icon: 'mdi:arrow-up-thick' - name: 上 - tap_action: - action: call-service - service: ezvizctrl.up - - entity: null - icon: 'mdi:arrow-right-thick' - name: 右 - tap_action: - action: call-service - service: ezvizctrl.right - - entity: null - icon: 'mdi:arrow-down-thick' - name: 下 - tap_action: - action: call-service - service: ezvizctrl.down - - entity: null - icon: 'mdi:arrow-left-thick' - name: 左 - tap_action: - action: call-service - service: ezvizctrl.left - name: 家 - type: 'custom:radial-menu' - type: vertical-stack -~~~ -6、enjoyit +``` +5. 安装 [radial-menu](https://github.com/custom-cards/radial-menu) 插件 +6. 将如下代码,通过原始编辑器,在合适的位置添加进去 +```yaml + cards: + - type: entities + entities: + - entity: switch.sence + - entity: switch.defence + - entity: sensor.ezviz_alarmsoundmode + name: 告警声音模式 + - entity: sensor.ezviz_onlinestatus + name: 在线状态 + - entity: sensor.ezviz_privacystatus + name: 隐私状态 + show_header_toggle: false + title: 摄像机状态 + - default_dismiss: false + default_open: true + icon: 'mdi:webcam' + items: + - entity: null + icon: 'mdi:arrow-up-thick' + name: 上 + tap_action: + action: call-service + service: ezviz.up + - entity: null + icon: 'mdi:arrow-right-thick' + name: 右 + tap_action: + action: call-service + service: ezviz.right + - entity: null + icon: 'mdi:arrow-down-thick' + name: 下 + tap_action: + action: call-service + service: ezviz.down + - entity: null + icon: 'mdi:arrow-left-thick' + name: 左 + tap_action: + action: call-service + service: ezviz.left + name: 家 + type: 'custom:radial-menu' + + ``` +7. enjoyit From 7afc491eba35e6ea105256bdf7fc4fe6ec5d21b5 Mon Sep 17 00:00:00 2001 From: chliny Date: Sun, 20 Jun 2021 01:23:20 +0800 Subject: [PATCH 07/14] _post add retry --- ezviz/sensor.py | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/ezviz/sensor.py b/ezviz/sensor.py index 137a853..9b29c7d 100755 --- a/ezviz/sensor.py +++ b/ezviz/sensor.py @@ -300,8 +300,16 @@ def _post(self, url, data) -> dict: "deviceSerial": self.deviceSerial } data.update(default_data) - ret = requests.post(url, data=data, timeout=5) - if not ret.ok: + trytimes = 2 + ret = None + for tryidx in range(trytimes): + ret = requests.post(url, data=data, timeout=5) + if not ret.ok: + _LOGGER.warning("Request Error %s %s", url, str(data)) + continue + break + + if not ret or not ret.ok: _LOGGER.error("Request Error %s %s", url, str(data)) return {} @@ -355,25 +363,14 @@ def disable_defence(self, call): _LOGGER.info("disable defence") def move(self, direc) -> str: - ctrl = { - "channelNo": '1', - "direction": direc, - "speed": '1' - } - start_url = 'https://open.ys7.com/api/lapp/device/ptz/start' - if not self._post(start_url, ctrl): + if not self.start(direc): _LOGGER.error("move failed") return 'FAIL' # 等待0.2s后停止 time.sleep(0.2) - ctrl = { - "channelNo": '1', - "direction": direc - } - stop_url = 'https://open.ys7.com/api/lapp/device/ptz/stop' - if not self._post(stop_url, ctrl): + if not self.stop(direc): return 'FAIL' return 'OK' @@ -401,17 +398,22 @@ def upright(self, call): def downright(self, call): self.move(7) - def stop(self, call): + def start(self, direc) -> bool: ctrl = { - "channelNo": '1' + "channelNo": '1', + "direction": direc, + "speed": '1' } - url ='https://open.ys7.com/api/lapp/device/ptz/stop' + start_url = 'https://open.ys7.com/api/lapp/device/ptz/start' + return self._post(start_url, ctrl) - trytimes = 2 - for idx in range(trytimes): - if self._post(url, ctrl): - break - return + def stop(self, call) -> bool: + ctrl = { + "channelNo": '1', + "direction": call, + } + url = 'https://open.ys7.com/api/lapp/device/ptz/stop' + return self._post(url, ctrl) def regist(self): # 注册服务 From 2cb8dc03689bee3a5a81b155b0b6900fe3c70f16 Mon Sep 17 00:00:00 2001 From: chliny Date: Sun, 20 Jun 2021 02:14:03 +0800 Subject: [PATCH 08/14] requests_futures instead of requests --- ezviz/sensor.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/ezviz/sensor.py b/ezviz/sensor.py index 9b29c7d..6b226a9 100755 --- a/ezviz/sensor.py +++ b/ezviz/sensor.py @@ -2,7 +2,8 @@ import logging from datetime import timedelta import voluptuous as vol -import requests +from requests.exceptions import RequestException +from requests_futures.sessions import FuturesSession from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( @@ -150,6 +151,7 @@ def __init__(self, hass, deviceSerial,appKey,appSecret): self._defenceStatus = None self._onlineStatus = None self._updatetime = None + self.session = FuturesSession() self.update(dt_util.now()) # 每隔TIME_BETWEEN_UPDATES,调用一次update() @@ -262,7 +264,13 @@ def get_deviceInfo(self): def request_token(self) -> str: #重新获取access_token access_Token = "" - response = requests.post('https://open.ys7.com/api/lapp/token/get',data=self.apikey).json() + response_async = self.session.post('https://open.ys7.com/api/lapp/token/get',data=self.apikey) + try: + response = response_async.result().json() + except RequestException as ex: + _LOGGER.error(ex) + return "" + #访问url if response["code"] == "200": _LOGGER.info('GET_TOKEN_SUCCESS') @@ -303,7 +311,8 @@ def _post(self, url, data) -> dict: trytimes = 2 ret = None for tryidx in range(trytimes): - ret = requests.post(url, data=data, timeout=5) + ret_async = self.session.post(url, data=data, timeout=5) + ret = ret_async.result() if not ret.ok: _LOGGER.warning("Request Error %s %s", url, str(data)) continue From d8a07fcf52097e8f4237fa9f6da251520f580cd4 Mon Sep 17 00:00:00 2001 From: chliny Date: Sun, 20 Jun 2021 23:15:57 +0800 Subject: [PATCH 09/14] support motion alarm --- ezviz/sensor.py | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/ezviz/sensor.py b/ezviz/sensor.py index 6b226a9..25eea5c 100755 --- a/ezviz/sensor.py +++ b/ezviz/sensor.py @@ -1,6 +1,6 @@ import time +import datetime import logging -from datetime import timedelta import voluptuous as vol from requests.exceptions import RequestException from requests_futures.sessions import FuturesSession @@ -15,7 +15,7 @@ _LOGGER = logging.getLogger(__name__) -TIME_BETWEEN_UPDATES = timedelta(seconds=60) +TIME_BETWEEN_UPDATES = datetime.timedelta(seconds=60) # 配置文件中平台下的配置项 CONF_APP_KEY = 'appKey' @@ -31,6 +31,7 @@ "alarmSoundMode": ["ezviz_alarmSoundMode", "告警声音模式", "mdi:surround-sound", ""], "defenceStatus":["ezviz_defenceStatus", "布防状态", "mdi:shield-home", ""], "onlineStatus": ["ezviz_onlineStatus", "在线状态", "mdi:link", ""], + "motionStatus": ["ezviz_motionStatus", "人体感应事件", "mdi:walk", ""], } ATTR_UPDATE_TIME = "更新时间" @@ -129,6 +130,8 @@ def update(self): self._state = self._data.defenceStatus elif self._type == "onlineStatus": self._state = self._data.onlineStatus + elif self._type == "motionStatus": + self._state = self._data.motionStatus class EZVIZData(object): """摄像头的数据,存储在这个类中.""" @@ -150,6 +153,7 @@ def __init__(self, hass, deviceSerial,appKey,appSecret): self._alarmSoundMode = None self._defenceStatus = None self._onlineStatus = None + self._motionStatus = 0 self._updatetime = None self.session = FuturesSession() @@ -172,6 +176,11 @@ def onlineStatus(self): """机器在线状态""" return self._onlineStatus + @property + def motionStatus(self): + """是否有人体感应""" + return self._motionStatus + @property def sceneStatus(self): """遮蔽状态""" @@ -228,6 +237,7 @@ def update(self, now): self.get_sceneStatus() self.get_deviceInfo() + self.get_montionInfo() self._updatetime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) @@ -424,6 +434,34 @@ def stop(self, call) -> bool: url = 'https://open.ys7.com/api/lapp/device/ptz/stop' return self._post(url, ctrl) + #取间隔时间里的所有告警 + def get_alarminfo(self) -> list(): + startime = datetime.datetime.now() - TIME_BETWEEN_UPDATES + starttime_s = int(startime.timestamp() * 1000) + ctrl = { + "pageSize": 20, + "pageStart": 0, + "startTime": starttime_s, + "status": 2, #所有 + } + url = "https://open.ys7.com/api/lapp/alarm/device/list" + ret = self._post(url, ctrl) + if not ret: + return [] + + return ret.get("data", []) + + def get_montionInfo(self): + alarms = self.get_alarminfo() + for alarm in alarms: + _LOGGER.debug(alarm) + alarmType = alarm.get("alarmType", -1) + if alarmType in [10000, 15010]: + self._motionStatus = 1 + return + self._motionStatus = 0 + return + def regist(self): # 注册服务 DOMAIN = "ezviz" From 6bd5969b2af116f7ccc75218fc86e25261135bac Mon Sep 17 00:00:00 2001 From: chliny Date: Sun, 20 Jun 2021 23:20:54 +0800 Subject: [PATCH 10/14] update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 51d6117..81abeb3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # 使用说明 + 1. 将下载的插件中的`ezviz`文件夹复制到`custom_components`目录下 2. `key`和`secret`请在[萤石开发网站](https://bbs.hassbian.com/thread-7062-1-1.html)获取 3. 在`configuration.yaml`文件中添加以下内容启用插件 @@ -17,6 +18,7 @@ sensor: - alarmSoundMode - defenceStatus - onlineStatus + - motionStatus ``` 4. 在`configuration.yaml`添加两个开关,用于修改移动侦测和遮蔽状态 From 1d7ea8078af62927fbcf60af72013fea852e5f6f Mon Sep 17 00:00:00 2001 From: chliny Date: Sun, 20 Jun 2021 23:24:26 +0800 Subject: [PATCH 11/14] update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 81abeb3..cf91368 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,8 @@ switch: name: 在线状态 - entity: sensor.ezviz_privacystatus name: 隐私状态 + - entity: sensor.ezviz_motionstatus + name: 人体感应告警 show_header_toggle: false title: 摄像机状态 - default_dismiss: false From cb51fd431ce76de9b53d18b2a69a2bc25fb988df Mon Sep 17 00:00:00 2001 From: chliny Date: Tue, 29 Jun 2021 02:11:03 +0800 Subject: [PATCH 12/14] lint code --- ezviz/sensor.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/ezviz/sensor.py b/ezviz/sensor.py index 25eea5c..a2b0763 100755 --- a/ezviz/sensor.py +++ b/ezviz/sensor.py @@ -201,7 +201,7 @@ def updatetime(self): """更新时间.""" return self._updatetime - def update(self, now): + def update(self, _): """从远程更新信息.""" _LOGGER.debug("Update the EZVIZ state...") #POST获取数据 @@ -312,7 +312,7 @@ def _post(self, url, data) -> dict: self.Get_access_Token() if not self.access_Token: _LOGGER.error("Request Token Error") - return + return {} default_data = { "accessToken": self.access_Token, "deviceSerial": self.deviceSerial @@ -320,7 +320,7 @@ def _post(self, url, data) -> dict: data.update(default_data) trytimes = 2 ret = None - for tryidx in range(trytimes): + for _ in range(trytimes): ret_async = self.session.post(url, data=data, timeout=5) ret = ret_async.result() if not ret.ok: @@ -346,7 +346,7 @@ def _post(self, url, data) -> dict: return result - def enable_sence(self, call): + def enable_sence(self, _): ctrl = {"enable": '1'} url = 'https://open.ys7.com/api/lapp/device/scene/switch/set' if self._post(url, ctrl): @@ -355,7 +355,7 @@ def enable_sence(self, call): self.hass.states.set('sensor.ezviz_sceneStatus', self._sceneStatus) _LOGGER.info("enable sence") - def disable_sence(self, call): + def disable_sence(self, _): ctrl = {"enable": '0'} url = 'https://open.ys7.com/api/lapp/device/scene/switch/set' if self._post(url, ctrl): @@ -363,7 +363,7 @@ def disable_sence(self, call): self.hass.states.set('sensor.ezviz_sceneStatus', self._sceneStatus) _LOGGER.info("disable sence") - def enable_defence(self, call): + def enable_defence(self, _): #活动检测开关 ctrl = {"isDefence": '1'} url = 'https://open.ys7.com/api/lapp/device/defence/set' @@ -373,7 +373,7 @@ def enable_defence(self, call): self.hass.states.set('sensor.ezviz_defenceStatus', '布防') _LOGGER.info("enable defence") - def disable_defence(self, call): + def disable_defence(self, _): ctrl = {"isDefence": '0'} url = 'https://open.ys7.com/api/lapp/device/defence/set' if self._post(url, ctrl): @@ -393,28 +393,28 @@ def move(self, direc) -> str: return 'FAIL' return 'OK' - def up(self, call): + def up(self, _): self.move(0) - def down(self, call): + def down(self, _): self.move(1) - def left(self, call): + def left(self, _): self.move(2) - def right(self, call): + def right(self, _): self.move(3) - def upleft(self, call): + def upleft(self, _): self.move(4) - def downleft(self,call): + def downleft(self, _): self.move(5) - def upright(self, call): + def upright(self, _): self.move(6) - def downright(self, call): + def downright(self, _): self.move(7) def start(self, direc) -> bool: @@ -424,7 +424,7 @@ def start(self, direc) -> bool: "speed": '1' } start_url = 'https://open.ys7.com/api/lapp/device/ptz/start' - return self._post(start_url, ctrl) + return self._post(start_url, ctrl) != {} def stop(self, call) -> bool: ctrl = { @@ -432,10 +432,10 @@ def stop(self, call) -> bool: "direction": call, } url = 'https://open.ys7.com/api/lapp/device/ptz/stop' - return self._post(url, ctrl) + return self._post(url, ctrl) != {} #取间隔时间里的所有告警 - def get_alarminfo(self) -> list(): + def get_alarminfo(self) -> list[dict]: startime = datetime.datetime.now() - TIME_BETWEEN_UPDATES starttime_s = int(startime.timestamp() * 1000) ctrl = { From e4eb29a64a501bed59145dfface54eb8825114e1 Mon Sep 17 00:00:00 2001 From: chliny Date: Sat, 8 Jan 2022 14:02:00 +0800 Subject: [PATCH 13/14] add type hint --- ezviz/sensor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ezviz/sensor.py b/ezviz/sensor.py index a2b0763..c0d7149 100755 --- a/ezviz/sensor.py +++ b/ezviz/sensor.py @@ -291,7 +291,7 @@ def request_token(self) -> str: _LOGGER.error("Error API return, code=%s, msg=%s",response['code'],response['msg']) return access_Token - def Get_access_Token(self, isForce=False): + def Get_access_Token(self, isForce:bool=False): if not self.access_Token: entobj = self.hass.states.get(self.ENTITYID) if entobj: @@ -307,7 +307,7 @@ def Get_access_Token(self, isForce=False): _LOGGER.debug('TOKEN_SUCCESS') return - def _post(self, url, data) -> dict: + def _post(self, url:str, data:dict) -> dict: # 获取access_Token self.Get_access_Token() if not self.access_Token: @@ -381,7 +381,7 @@ def disable_defence(self, _): self.hass.states.set('sensor.ezviz_defenceStatus', '撤防') _LOGGER.info("disable defence") - def move(self, direc) -> str: + def move(self, direc:int) -> str: if not self.start(direc): _LOGGER.error("move failed") return 'FAIL' @@ -417,7 +417,7 @@ def upright(self, _): def downright(self, _): self.move(7) - def start(self, direc) -> bool: + def start(self, direc:int) -> bool: ctrl = { "channelNo": '1', "direction": direc, From ac3e4e3ad15bed82c2be9c1ff49a6e83027568d6 Mon Sep 17 00:00:00 2001 From: chliny Date: Sat, 8 Jan 2022 14:02:54 +0800 Subject: [PATCH 14/14] add miss return --- ezviz/sensor.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ezviz/sensor.py b/ezviz/sensor.py index c0d7149..01aeeee 100755 --- a/ezviz/sensor.py +++ b/ezviz/sensor.py @@ -113,6 +113,7 @@ def device_state_attributes(self): # 增加updatetime作为属性,表示获取的时间 ATTR_UPDATE_TIME: self._updatetime } + return {} def update(self): # update只是从EZVIZData中获得数据,数据由EZVIZData维护。 @@ -274,7 +275,8 @@ def get_deviceInfo(self): def request_token(self) -> str: #重新获取access_token access_Token = "" - response_async = self.session.post('https://open.ys7.com/api/lapp/token/get',data=self.apikey) + response_async = self.session.post('https://open.ys7.com/api/lapp/token/get', + data=self.apikey) try: response = response_async.result().json() except RequestException as ex: