Введение
Как то ко мне в руки попал китайский GPS трекер ST-901. Устройство рассчитано в основном для использования в авто- и мото-технике, обладает gsm 2G модулем для связи с внешним миром, герметичным водонепроницаемым корпусом, небольшим встроенным аккумулятором, позволяющем работать без внешнего питания порядка 2-3 суток при передаче сигнала раз в 3 минуты, а также сигнальным проводом зажигания, позволяющем предупреждать о старте двигателя. Управлять данным трекером можно посредством SMS-команд на номер трекера, а общаться и получать уведомления как по SMS, так и подключив его к облаку через GPRS. Побаловавшись с ним некоторое время, я забросил его в ящик, пока дома не появился HomeAssistant. Возникла идея подключить его к умному дому для слежения в реальном времени, а также автоматизации при попадании автомобиля в определенную зону (терминология HomeAssistant) на карте.
Задачи
Для подключения трекера к HomeAssistant необходимо решить две задачи: получить координаты с трекера и записать их в HomeAssistant. Если для второй задачи есть сразу несколько возможных решений (например, gpslogger или owntracks_http), то решение первой задачи в моем случае усложнялось тем фактом, что в настройках трекера для передачи координат можно указать только IP адрес, а не доменное имя. Так как у меня дома нет статического адреса, то возникла идея использовать посредника. Всем, кому интересно, что из этого вышло, добро пожаловать под кат.
Идея
Как я уже говорил выше, данный трекер можно подключать ко многим облачным сервисам. Некоторые из них с определенными ограничениями позволяют пользоваться услугами бесплатно. Некоторые сервисы имеют полноценные 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 time).
Типичный ответ имеет вид:
[{"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":""}]
Примечание: я существенно сократил вывод, а также изменил параметры code, 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 – ip адрес или имя сервера с HA, 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 уже не один месяц безо всяких сбоев и иных проблем.
На этом все, спасибо за внимание.