我们将任何(几乎)GPS追踪器(以Sinotrack ST-901为例)连接到HomeAssistant智能家居

引言


中国GPS追踪器ST-901不知何故落入我的手中。 该设备主要设计用于汽车和摩托车技术,具有用于与外界通信的gsm 2G模块,密封的防水盒,小的内置电池,使您每3分钟发送一次信号即可工作2-3天,而无需外部电源,以及信号点火线,可让您警告发动机的启动。 您可以通过SMS命令对跟踪器编号进行管理,并通过SMS以及通过GPRS将其连接到云来传达和接收通知。 与他玩了一段时间之后,我把他扔在抽屉里,直到HomeAssistant出现在家里​​。 有一种将其连接到智能家居的想法。

任务


要将跟踪器连接到HomeAssistant,您需要解决两个问题:从跟踪器获取坐标并将其写入HomeAssistant。 如果对于第二个任务一次有几种可能的解决方案(例如gpsloggerowntracks_http ),那么我的情况下第一个任务的解决方案就变得很复杂,因为在用于传输坐标的跟踪器设置中您只能指定IP地址,而不能指定域名。 由于我在家中没有静态地址,因此产生了使用中介的想法。 我注意到,通过这种方式,您可以连接几乎任何与中介资源兼容的GPS跟踪器(而不仅仅是在我的文章中介绍) 。 每个对此有兴趣的人都欢迎加入。


主意


就像我在上面说的,此跟踪器可以连接到许多云服务。 其中有些具有某些限制,您可以免费使用这些服务。 某些服务具有用于与它们交互的功能完善的API,但我在免费服务中找不到这样的服务。 但是几乎所有服务都通过永久链接提供“共享”跟踪器位置的服务。 在浏览了其中一些服务并在共享页面的源代码中翻阅后 ,我在livegpstracks服务中找到了搜索:一个坐标请求。 因此,一般的工作方案如下:跟踪器连接到livegpstracks服务并发送其坐标,HomeAssistant定期向该服务发出http请求,并接收最后记录的坐标,这些坐标由另一个http请求写入到HomeAssistant。 这是指向与该服务兼容的所有跟踪器的列表的链接

实作


1.根据要求获取坐标

我们在livegpstracks服务中注册并连接我们的跟踪器(该站点提供了有关各种型号的详细说明)。 之后,通过站点上的工具栏,创建用于跟踪的专用链接。 链接的格式为:

https://livegpstracks.com/dv_USERID.html 

USERID是您的球的数字ID。

仅此而已。 您可以通过请求访问服务。 为了避免长时间折磨您,我只提供请求格式:

 https://livegpstracks.com/viewer_coos_s.php?username=USER&ctp=one&code=USERID&tgst=site&tgsv=12&tkv11=TIMENOWMS 

此处USER是您在livegpstracks服务中注册的用户,USERID是分配给共享链接的数字ID,TIMENOWMS是当前时间(以毫秒为单位)(unix时间)。

一个典型的答案是:

 [{"code":"xxx","id":"xxx","lat":"44","lng":"48","speed":"0","azimuth":"0","d":"2018-06-19","t":"09:35:17","altitude":"0","battery":"0","gpsaccuracy":""}] 

注意:我大大减少了输出,还更改了参数代码id,lat,lng。

在python中获取坐标的方法如下所示:

 def getInfoFrom(self): timenow = int(datetime.now().strftime("%s")) * 1000 response = requests.get('https://livegpstracks.com/viewer_coos_s.php', params={'username': self._user, 'ctp': 'one', 'code': self._myid, 'tgst': 'site', 'tgsv': 12, 'tkv11': timenow}) data = response.json() self._lat = data[0]["lat"] self._lon = data[0]["lng"] self._speed = data[0]["speed"] self._direction = data[0]["azimuth"] self._last_time_rcv = data[0]["d"] + ' ' + data[0]["t"] 

我认为您无需在这段代码中解释任何内容:我们获取当前时间,发出get请求,获取json作为响应,进行解析并获取纬度,经度,速度,运动方向以及服务器上次收到坐标的时间。

2.坐标记录

为了进行记录,我将GPSLogger模块用于HomeAssistant,因为它通过http请求工作,并允许您使用单独的密码,该密码不同于整个HA的密码。 文档( gpslogger )显示请求具有以下格式:

 https://HAADRESS:HAPORT/api/gpslogger?latitude=LAT&longitude=LON&device=DEV&accuracy=ACC&speed=SPD&direction=DIR&api_password=PASS 

这里HAADRESS是带有HA的IP地址或服务器名称,HAPORT是服务器端口,LAT是纬度,LON是经度,DEV是要在HA中显示的设备的名称,ACC是确定坐标的准确性(由于某些原因,它在HA中不起作用,给出了错误,我未使用),SPD-速度,DIR-运动方向,PASS-传输坐标的密码

用python编写坐标的方法如下所示:

 def putInfoTo(self): if self._lat != '' and self._lon != '': req_str = self._haddr+'/api/gpslogger' response = requests.get(req_str, params={'latitude': self._lat, 'longitude': self._lon, 'accuracy': 30, 'speed': self._speed, 'direction': self._direction, 'device': self._name, ' api_password': self._pwd}) self._last_time_upd = time.strftime("%Y.%m.%d %H:%M") 

我认为这里的评论也是多余的。

3.模组

下面给出了用于接收和记录坐标的模块的完整代码。

模块代码
 #!/usr/local/bin/python3 # coding: utf-8 import time import requests import json import logging from datetime import datetime from datetime import timedelta import voluptuous as vol import homeassistant.helpers.config_validation as cv from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import (CONF_NAME) from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) CONF_USER = 'user' CONF_ID = 'myid' CONF_PWD = 'pwd' CONF_SITE = 'haddr' ATTR_LAT = '' ATTR_LON = '' ATTR_SPEED = '' DEFAULT_NAME = 'GPS_Sensor' SCAN_INTERVAL = timedelta(seconds=120) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_USER): cv.string, vol.Required(CONF_ID): cv.string, vol.Required(CONF_PWD): cv.string, vol.Required(CONF_SITE): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, }) def setup_platform(hass, config, add_devices, discovery_info=None): user = config.get(CONF_USER) name = config.get(CONF_NAME) pwd = config.get(CONF_PWD) myid = config.get(CONF_ID) haddr = config.get(CONF_SITE) add_devices([CarGPS(name, user, myid, haddr, pwd)]) class CarGPS(Entity): def __init__(self, name, user, myid, haddr, pwd): self._name = name self._user = user self._myid = myid self._haddr = haddr self._pwd = pwd self._lat = '' self._lon = '' self._speed = '0' self._direction = '0' self._last_time_rcv = '' self._last_time_upd = '' def getInfoFrom(self): try: today = int(datetime.now().strftime("%s")) * 1000 response = requests.get('https://livegpstracks.com/viewer_coos_s.php', params={'username': self._user, 'ctp': 'one', 'code': self._myid, 'tgst': 'site', 'tgsv': 12, 'tkv11': today}) data = response.json() self._lat = data[0]["lat"] self._lon = data[0]["lng"] self._speed = data[0]["speed"] self._direction = data[0]["azimuth"] self._last_time_rcv = data[0]["d"] + ' ' + data[0]["t"] except: _LOGGER.error('coudnt get parameters') def putInfoTo(self): if self._lat != '' and self._lon != '': try: req_str = self._haddr+'/api/gpslogger' response = requests.get(req_str, params={'latitude': self._lat, 'longitude': self._lon, 'accuracy': 30, 'speed': self._speed, 'direction': self._direction, 'device': self._name, ' api_password': self._pwd}) _LOGGER.info(response) self._last_time_upd = time.strftime("%Y.%m.%d %H:%M") except: _LOGGER.error('coudnt put parameters') #for HASS @property def name(self): return self._name @property def state(self): return self._last_time_upd def update(self): self.getInfoFrom() self.putInfoTo() @property def device_state_attributes(self): attr = {} attr[ATTR_LAT] = self._lat attr[ATTR_LON] = self._lon attr[ATTR_SPEED] = self._speed return attr 


要连接此模块,必须将代码复制到“ config_folder_homeassistant / custom_components / sensor / car_location.py”目录中,并在配置中添加以下几行:

 device_tracker: - platform: gpslogger password: !secret gpslogger_password sensor: - platform: car_location name: car_sensor user: USER myid: USERID haddr: YOUR_HA_ADDRESS pwd: !secret gpslogger_password 

这是“按请求获取坐标”部分中的所有变量。

该模块已经在HA中运行了一个多月,没有任何故障或其他问题。

就这样,谢谢您的关注。

UPD:
HomeAssistant更新了GPSLogger组件,与此相关的新版本的mod和设置:

新设定
 device_tracker: - platform: gpslogger sensor: - platform: car_location name: car_sensor user: USER myid: USERID haddr: YOUR_HA_ADDRESS_WEBHOOK 

YOUR_HA_ADDRESS_WEBHOOK-GPSLogger的Web日志地址,您可以在“设置-集成-GPSLogger”部分中获取它。


新模块代码
 #!/usr/local/bin/python3 # coding: utf-8 import time import requests import json import logging from datetime import datetime from datetime import timedelta import voluptuous as vol import homeassistant.helpers.config_validation as cv from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import (CONF_NAME) from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) CONF_USER = 'user' CONF_ID = 'myid' CONF_SITE = 'haddr' CONF_NAME = 'name' ATTR_LAT = '' ATTR_LON = '' ATTR_SPEED = '' ATTR_DATE = '' DEFAULT_NAME = 'GPS_Sensor' SCAN_INTERVAL = timedelta(seconds=120) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_USER): cv.string, vol.Required(CONF_ID): cv.string, vol.Required(CONF_SITE): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, }) def setup_platform(hass, config, add_devices, discovery_info=None): user = config.get(CONF_USER) name = config.get(CONF_NAME) myid = config.get(CONF_ID) haddr = config.get(CONF_SITE) add_devices([CarGPS(name, user, myid, haddr)]) class CarGPS(Entity): def __init__(self, name, user, myid, haddr): self._name = name self._user = user self._myid = myid self._haddr = haddr self._lat = '' self._lon = '' self._speed = '0' self._direction = '0' self._last_time_rcv = '' self._last_time_upd = '' def getInfoFrom(self): try: today = int(datetime.now().strftime("%s")) * 1000 response = requests.get('https://livegpstracks.com/viewer_coos_s.php', params={'username': self._user, 'ctp': 'one', 'code': self._myid, 'tgst': 'site', 'tgsv': 12, 'tkv11': today}) data = response.json() self._lat = str(data[0]["lat"]) self._lon = str(data[0]["lng"]) self._speed = str(data[0]["speed"]) self._direction = str(data[0]["azimuth"]) self._last_time_rcv = data[0]["d"] + ' ' + data[0]["t"] except: _LOGGER.error('coudnt get parameters') def putInfoTo(self): if self._lat != '' and self._lon != '': try: header = {'Content-Type': 'application/x-www-form-urlencoded'} body = 'latitude=' + self._lat + '&longitude=' + self._lon + '&device=' + self._name + '&accuracy=30&battery=100&speed=' + self._speed + '&direction=' + self._direction + '&altitude=0&provider=0&activity=0' response = requests.post(self._haddr, headers=header, data=body) self._last_time_upd = time.strftime("%Y.%m.%d %H:%M") except: _LOGGER.error('coudnt put parameters') #for HASS @property def name(self): return self._name @property def state(self): return self._last_time_upd def update(self): self.getInfoFrom() self.putInfoTo() @property def device_state_attributes(self): attr = {} attr[ATTR_LAT] = self._lat attr[ATTR_LON] = self._lon attr[ATTR_SPEED] = self._speed attr[ATTR_DATE] = self._last_time_rcv return attr 



UPD2:
HomeAssistant从0.88版本更新了工作逻辑,与此相关的是新版本的mod: sensor

UPD3:
集成的新版本。 该项目移至GitHub 。 当前版本在那里。

Source: https://habr.com/ru/post/zh-CN414509/


All Articles