Nous connectons tout (presque) tracker GPS (en utilisant le Sinotrack ST-901 comme exemple) à la maison intelligente HomeAssistant

Présentation


D'une manière ou d'une autre, le tracker GPS chinois ST-901 est tombé entre mes mains. L'appareil est principalement conçu pour une utilisation dans la technologie automobile et moto, possède un module gsm 2G pour la communication avec le monde extérieur, un boîtier étanche étanche, une petite batterie intégrée qui vous permet de travailler environ 2-3 jours sans alimentation externe lors de la transmission d'un signal toutes les 3 minutes, ainsi qu'un fil d'allumage de signal, qui vous permet d'avertir du démarrage du moteur. Vous pouvez gérer ce tracker via des commandes SMS vers le numéro du tracker, et communiquer et recevoir des notifications à la fois par SMS et en le connectant au cloud via GPRS. Après avoir joué avec lui pendant un certain temps, je l'ai jeté dans un tiroir jusqu'à ce que HomeAssistant apparaisse à la maison. Il y avait une idée pour le connecter à une maison intelligente.

Les tâches


Pour connecter le tracker à HomeAssistant, vous devez résoudre deux problèmes: obtenir les coordonnées du tracker et les écrire dans HomeAssistant. Si pour la deuxième tâche, il existe plusieurs solutions possibles à la fois (par exemple, gpslogger ou owntracks_http ), la solution à la première tâche dans mon cas a été compliquée par le fait que dans les paramètres du tracker pour le transfert des coordonnées, vous ne pouvez spécifier qu'une adresse IP, pas un nom de domaine. Comme je n'ai pas d'adresse statique à la maison, l'idée est venue d'utiliser un intermédiaire. Je note que de cette façon, vous pouvez connecter presque n'importe quel tracker GPS (et pas seulement considéré dans mon article), compatible avec les ressources d'un intermédiaire . Tous ceux qui sont intéressés par ce qui en est arrivé, bienvenue au chat.


Idée


Comme je l'ai dit ci-dessus, ce tracker peut être connecté à de nombreux services cloud. Certains d'entre eux avec certaines restrictions vous permettent d'utiliser gratuitement les services. Certains services ont des API à part entière pour interagir avec eux, mais je n'en ai pas trouvé parmi les gratuits. Mais presque tous les services fournissent le service de «partage» de l'emplacement du tracker via un lien permanent. Après avoir parcouru plusieurs de ces services et fouillé dans le code source des pages partagées, j'ai trouvé la recherche des coordonnées recherchées dans le service livegpstracks : Ainsi, le schéma général de travail est le suivant: le tracker se connecte au service livegpstracks et transmet ses coordonnées, HomeAssistant fait périodiquement une requête http au service et reçoit les dernières coordonnées enregistrées, qui sont écrites au HomeAssistant par une autre requête http. Voici un lien vers une liste de tous les trackers compatibles avec le service.

Implémentation


1. Obtention de coordonnées sur demande

Nous nous inscrivons au service livegpstracks et connectons notre tracker (le site contient des instructions détaillées pour différents modèles). Après cela, via la barre d'outils du site, créez un lien privé pour le suivi. Le lien a la forme:

https://livegpstracks.com/dv_USERID.html 

où USERID est l'ID numérique de vos balles.

C’est tout. Vous pouvez accéder au service via des demandes. Afin de ne pas vous tourmenter pendant longtemps, je vais simplement donner le format de demande:

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

Ici, USER est l'utilisateur sous lequel vous vous êtes inscrit au service livegpstracks, USERID est l'ID numérique affecté au lien partagé, TIMENOWMS est l'heure actuelle en millisecondes (heure unix).

Une réponse typique est:

 [{"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":""}] 

Remarque: j'ai considérablement réduit la sortie et également modifié le code des paramètres, id, lat, lng.

La méthode pour obtenir des coordonnées en python ressemble à ceci:

 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"] 

Je pense que vous n'avez pas besoin d'expliquer quoi que ce soit dans ce code: nous obtenons l'heure actuelle, faisons une demande get, obtenons json en réponse, analysons-le et obtenons la latitude, la longitude, la vitesse, la direction du mouvement et l'heure à laquelle le serveur a reçu les coordonnées en dernier.

2. Enregistrement des coordonnées

Pour l'enregistrement, j'ai utilisé le module GPSLogger pour HomeAssistant, car il fonctionne via une requête http et vous permet d'utiliser un mot de passe distinct, différent du mot de passe pour l'ensemble du HA. La documentation ( gpslogger ) montre que la demande a le format suivant:

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

Ici HAADRESS est l'adresse IP ou le nom du serveur avec HA, HAPORT est le port du serveur, LAT est la latitude, LON est la longitude, DEV est le nom de l'appareil à afficher en HA, ACC est la précision de la détermination des coordonnées (pour une raison quelconque, cela ne fonctionne pas en HA, cela donne une erreur, je ne l'utilisait pas), SPD - vitesse, DIR - sens de déplacement, PASS - mot de passe pour le transfert

La méthode pour écrire des coordonnées en python ressemble à ceci:

 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") 

Je pense qu'ici aussi les commentaires sont superflus.

3. Module

Le code complet du module de réception et d'enregistrement des coordonnées est donné ci-dessous.

Code du module
 #!/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 


Pour connecter ce module, le code doit être copié dans le répertoire "config_folder_homeassistant / custom_components / sensor / car_location.py" et ajouter également les lignes suivantes à la configuration:

 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 

Voici toutes les variables de la section "Obtention de coordonnées sur demande".

Ce module fonctionne en HA depuis plus d'un mois sans échecs ni autres problèmes.

C'est tout, merci de votre attention.

UPD:
HomeAssistant a mis à jour le composant GPSLogger, à propos duquel une nouvelle version du mod et des paramètres:

nouveaux paramètres
 device_tracker: - platform: gpslogger sensor: - platform: car_location name: car_sensor user: USER myid: USERID haddr: YOUR_HA_ADDRESS_WEBHOOK 

YOUR_HA_ADDRESS_WEBHOOK - l'adresse du blog de GPSLogger, vous pouvez l'obtenir dans la section Paramètres - Intégrations - GPSLogger.


nouveau code de module
 #!/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 a mis à jour la logique de travail à partir de la version 0.88, à propos de laquelle la nouvelle version du mod: sensor

UPD3:
Nouvelle version d'intégration. Le projet a été déplacé vers GitHub . La version actuelle est là.

Source: https://habr.com/ru/post/fr414509/


All Articles