Опрос
А вы где смотрите прогноз погоды?
Календарь
« Июль 2021 » Пн Вт Ср Чт Пт Сб Вс 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Запрос истории датчик в Home Assistant и построение графика
Умный дом
автор: dimon , опубликовано: 26 июля 2021
Уже год я периодически возвращаюсь к мысли слать графики из Home Assistant в Telegram..
Недавно я писал, что столкнулся со статьей описывающей как с помощью REST API вытаскивать данные из Home Assistant [
читать тут ]
В результате, почитав книгу по Python и сдув пыль с древней Sony с Ubuntu, я начал пытаться написать скрипт, который обратится к HA с помощью REST API, запросит истории датчика за указанное количество часов, построит график и сохранит его в файл картинки PNG.
В принципе скрипт получился рабочий:
'''
Обращение к НА с помощью rest api Home Assistant для запроса истории датчика
за указанное количество часов, построение графика и сохранение его в файл картинки PNG
ToDo:
1. перенести number_of_hours и entity_id в НА и передавать в виде аргументов в скрипт
2. добавить сглаживание графика?
3. разобраться почему ошибка на первом элементе
4.
'''
# подключаем библиотеки/модули
import json # Модуль JSON
from requests import get # get requesrs
from datetime import datetime, timedelta
import numpy as np # библиотека NumPy это open-source модуль для python, который предоставляет общие математические и числовые операции в виде пре-скомпилированных, быстрых функций
import matplotlib # Библиотека на языке программирования Python для визуализации данных двумерной (2D) графикой.
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker # модуль управления тиками
from matplotlib.ticker import FormatStrFormatter
from matplotlib.dates import DateFormatter
from pytz import timezone
import os
# переменные
temp = None # строка для временного хранения данных
url = None # url ссылка
filter_date_time = None # время до которого будем запрашивать данные
kol_all = 0 # количество обработанных значений
skip_flag = 0 # флаг пропуска элемента массива
number_of_hours = 24 # количество часов которые будем запрашивать
entity_id = "sensor.th2_temperature" # сенсор
# API ключ (Long-Lived Access Token) НА и адрес сервера
api_key = "ABCDEFGH"
address_hass = "192.168.0.2"
##########################################################
#print ("\nStart program\n")
# сменим рабочую папку на ту в которую нужно сохранять картинку
#path="/home/homeassistant/.homeassistant/www"
path="/home/d/py"
os.chdir(path)
# узнаем tz.
# Для этого заберем конфиг НА с помощью REST API и вычленим там time_zone
url = 'http://' + address_hass + ':8123/api/config'
headers = {
"Authorization": "Bearer " + api_key,
"content-type": "application/json",
}
response = get(url, headers=headers)
temp = response.text
readable_json = json.loads(temp)
time_zone = readable_json['time_zone']
tz = timezone(time_zone)
#print (tz)
matplotlib.rcParams['timezone'] = time_zone # чтобы в осях графика время было правильное (учет tz)
##########################################################
# ДЛЯ ТЕСТА
# читаем массив данных с НА - температура процессора
# массив заведенный ручками
#temp_data="""[[{"entity_id": "sensor.processor_temperature", "state": "46.2", "attributes": {"unit_of_measurement": "\u00b0C", "friendly_name": "Processor temperature", "device_class": "temperature"}, "last_changed": "2021-07-19T21:00:00+00:00", "last_updated": "2021-07-19T21:00:00+00:00"}, {"entity_id": "sensor.processor_temperature", "state": "47.2", "attributes": {"unit_of_measurement": "\u00b0C", "friendly_name": "Processor temperature", "device_class": "temperature"}, "last_changed": "2021-07-19T21:00:03.838474+00:00", "last_updated": "2021-07-19T21:00:03.838474+00:00"}, {"entity_id": "sensor.processor_temperature", "state": "46.2", "attributes": {"unit_of_measurement": "\u00b0C", "friendly_name": "Processor temperature", "device_class": "temperature"}, "last_changed": "2021-07-19T21:00:18.840096+00:00", "last_updated": "2021-07-19T21:00:18.840096+00:00"}, {"entity_id": "sensor.processor_temperature", "state": "47.2", "attributes": {"unit_of_measurement": "\u00b0C", "friendly_name": "Processor temperature", "device_class": "temperature"}, "last_changed": "2021-07-19T21:01:03.850947+00:00", "last_updated": "2021-07-19T21:01:03.850947+00:00"}, {"entity_id": "sensor.processor_temperature", "state": "46.2", "attributes": {"unit_of_measurement": "\u00b0C", "friendly_name": "Processor temperature", "device_class": "temperature"}, "last_changed": "2021-07-19T21:01:18.843539+00:00", "last_updated": "2021-07-19T21:01:18.843539+00:00"}, {"entity_id": "sensor.processor_temperature", "state": "46.7", "attributes": {"unit_of_measurement": "\u00b0C", "friendly_name": "Processor temperature", "device_class": "temperature"}, "last_changed": "2021-07-19T21:01:48.844643+00:00", "last_updated": "2021-07-19T21:01:48.844643+00:00"}, {"entity_id": "sensor.processor_temperature", "state": "47.2", "attributes": {"unit_of_measurement": "\u00b0C", "friendly_name": "Processor temperature", "device_class": "temperature"}, "last_changed": "2021-07-19T21:02:03.846437+00:00", "last_updated": "2021-07-19T21:02:03.846437+00:00"}, {"entity_id": "sensor.processor_temperature", "state": "46.7", "attributes": {"unit_of_measurement": "\u00b0C", "friendly_name": "Processor temperature", "device_class": "temperature"}, "last_changed": "2021-07-19T21:02:18.845491+00:00", "last_updated": "2021-07-19T21:02:18.845491+00:00"}, {"entity_id": "sensor.processor_temperature", "state": "46.2", "attributes": {"unit_of_measurement": "\u00b0C", "friendly_name": "Processor temperature", "device_class": "temperature"}, "last_changed": "2021-07-19T21:02:48.847300+00:00", "last_updated": "2021-07-19T21:02:48.847300+00:00"}, {"entity_id": "sensor.processor_temperature", "state": "46.7", "attributes": {"unit_of_measurement": "\u00b0C", "friendly_name": "Processor temperature", "device_class": "temperature"}, "last_changed": "2021-07-19T21:03:03.854238+00:00", "last_updated": "2021-07-19T21:03:03.854238+00:00"}]]"""
# прочтем массив из файла
#f = open('/home/d/py/1.txt', 'r')
#temp_data = f.read()
#f.close()
##########################################################
##########################################################
# запрашиваем данные в НА с помощью REST API
# рассчитаем время для подставновки в запрос
d = datetime.today() - timedelta(hours=number_of_hours, minutes=0)
filter_date_time = d.strftime("%Y-%m-%dT%H:%M:%S") + "+03:00"
#print (filter_date_time)
url = 'http://' + address_hass + ':8123/api/history/period/' + filter_date_time + '?filter_entity_id=' + entity_id
headers = {
"Authorization": "Bearer " + api_key,
"content-type": "application/json",
}
response = get(url, headers=headers)
#print(response.text+"\n\n")
temp_data = response.text
##########################################################
# разбираем ответ
# Уберем лишние ковычки []
temp_data = temp_data[1:len(temp_data)-1]
readable_json = json.loads(temp_data)
# пустые массивы
time_array = np.array([])
state_array = np.array([])
# Цикл обработки массива данных
for i in readable_json:
#######################
# почему-то первый элемент в ответе всегда содержит временные метки без миллисекунд
# в результате получаем ошибку. чтобы исключить эту ошибку приходится выкидывать его из обработки
if skip_flag == 0:
skip_flag = "1"
continue
#######################
try:
float(i['state']) # пробуем выполнить секцию try: до except:
# формируем массивы для построения графика
state_array = np.append(state_array, float(i['state']))
time_update = datetime.strptime(i['last_updated'], '%Y-%m-%dT%H:%M:%S.%f%z')
time_array = np.append(time_array, time_update.astimezone(tz))
kol_all += 1
except:
# ошибка
print("uknown state")
#print ("\nВсего обработанно значений = " + str(kol_all))
##########################################################
# строим график
if 1 == 0:
plt.grid()
plt.title('Temperature', fontsize=14) # заголовок графика
plt.ylabel("\u00b0C", fontsize=10) # метка Y оси
plt.xticks(fontsize=6) # шрифт X оси
plt.yticks(fontsize=10) # шрифт Y оси
plt.plot(time_array, state_array)
plt.show()
if 1 == 1:
fig = plt.figure(num=None, facecolor='w', edgecolor='k')
plt.plot(time_array, state_array)
plt.title('Temperature', fontsize=16)
plt.yticks(fontsize=10)
plt.ylabel("\u00b0C", fontsize=18, labelpad=12, rotation=0, color='steelblue')
plt.xticks(fontsize=10) # rotation = 45 - поворот Х меток на 45градусов
ax = plt.gca()
ax.yaxis.set_major_formatter(FormatStrFormatter('%.0f'))
ax.legend(['print: ' + time_array[-1].strftime('%d/%m %H:%M')])
ax.grid(which='major', color = 'gray', linestyle=':') # Добавляем линии основной сетки
ax.xaxis.set_minor_locator(ticker.MultipleLocator(1)) # Задаем шаг дополнительный делений (тиков)
ax.minorticks_on() # Включаем видимость вспомогательных делений
xformatter = DateFormatter('%H:%M')
plt.gcf().axes[0].xaxis.set_major_formatter(xformatter)
plt.show() # покажем график
fig.savefig('plot.png') # сохраним график
Код доступен на
GitHub-е Вот так график истории сенсора выглядит в Home Assistant:
А вот так график истории сенсора сохраняет скрипт в
plot.png :
Новость отредактировал dimon - 13 августа 2021
Ключевые теги: Home Assistant , HA , HomeAssistant , Python , script , скрипт , график , graph , json , request , GET , numpy , datetime , matplotlib , plt , pytz , Token , TimeZone
Голосов: 27 , рейтинг:
Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь. Чтобы Вам были доступны все функции Вам необходимо либо зарегистрироваться, либо зайти на сайт под своим именем.
Другие новости по теме:Как не нужно читать документацию по REST API Home Assistant Уведомление в Телеграм если какой-то из сенсоров Home Assistant перешел в с ... Управялем яркостью диммера Noolite из Home Assistant Сенсоры NAS NetGear ReadyNAS Pro2 в Home Assistant с помощью SNMP Автоматизация "Все ушли из дома" в Home Assistant
Просмотрено: 1157 раз
| Напечатать | Комментарии (0)
Мы будем благодарны если Вы поделитесь ссылкой на эту новость со своими друзьями.
BB-код (для вставки на форумы):
HTML-код (для вставки в ЖЖ и сайты):
Для отправки по почте:
Информация
Посетители, находящиеся в группе Гости , не могут оставлять комментарии к данной публикации.
Облако тегов
Arduino , backup , CentOS , cmd , css , div , DLE , DLE хаки , domoticz , dzvents , event , Home Assistant , HomeAssistant , Linux , log , Monster , mqtt , ogf3 , Template , VBS , windows , WSH , бумага , бумажный самолетик , верстка , иструкция , Карты , кино , Навигация , оригами , программа , рецензия , рецепт , скрипт , уведомления , фигуры , шаблон , Яндекс , яндекс-карты Показать все теги