За долго до начала использования Majordomo и всяких Ардуин покупал и ставил себе разные погодные станции и другие приспособления, чтобы хоть как-то автоматизировать и сделать умным дом. В итоге купил погодную станцию Netatmo. Потом докупил к ней еще один внутренний модуль для второй комнаты. но с началом изучения majordomo встал вопрос - как бы сделать так, чтобы подвязать все существующие железки в систему много дома. Перерыл форум, но подключения netatmo к мажордоме там и не нашел. Перерыл кучу сайтов, нашел библиотеки на
Смотри ниже модификацию скрипта и описание без использования MQTT. Update от 12.05.2020
Python и решил скрестить это все через протокол MQTT.
Имеем:
Raspberry PI 3 (в данном случае все равно какая версия). Т.к. именно на этом решении проще и удобней было сделать сервер умного дома.
Netatmo: погодная станция с несколькими модулями - спальня, детская, улица.
Решение:
Raspberry, Netatmo - понятное дело, что оба в общей домашней сети (один через ethernet, второй через wifi - в данном случае не важно, что куда воткнуто).
Для подключения нужен сам MQTT брокер. У меня стоит mosquitto, но не важно какой, может быть и другим. Python. Библиотеки для Python нужны от MQTT брокера и для Netatmo (https://github.com/philippelt/netatmo-api-python).
Саму питоновскую библиотеку лучше поставить в систему (в директории с библиотекой указанной выше сделать: pip install lnetatmo)
Вот скрипт для получения данных со станции и публикация их через MQTT. Все достаточно просто и комментариями расписал все стадии:
Код: Выделить всё
#!/usr/bin/python
# coding=utf-8
import sys
import paho.mqtt.client as mosquitto
import time
# https://github.com/philippelt/netatmo-api-python
import lnetatmo
# IP/localhost сервера MQTT брокера (если он установлено локально, то оставить localhost)
broker = "localhost"
# Произвольное ммя клиента, которым конектимся к брокеру MQTT
client_name = "NetatmoOverPythonOnRaspPi"
# Начало имени топика для данных с модулей Netatmo
topic_Start = "/fromRaspNetatmo"
# Подключаемся к mosquitto
client = mosquitto.Mosquitto(client_name)
# userdata заполняется если нужна авторизация на MQTT брокере, в противном случае -> коментарим строчку ниже
userdata = client.username_pw_set(username="имя пользователя на mqtt брокере",password="пароль на mqtt брокере")
# Подключаемся к Netatmo
authorization = lnetatmo.ClientAuth(clientId="вставить client id",
clientSecret="вставить client secret", username="имя пользователя", password="пароль")
# For each available module in the returned data that should not be older than one hour (3600 s) from now
devList = lnetatmo.WeatherStationData(authorization)
client.connect(broker)
for module, moduleData in devList.lastData(exclude=3600).items() :
# Топик в MQTT будет для каждого модуля свой
topic_Middile = topic_Start + "/" + module
# начитываем данные из Netatmo
for sensor, value in moduleData.items() :
# Для понимания дат и вреемни превращаем их в читабельный вид (hh:mm:ss)
if sensor == "When" : value = time.strftime("%H:%M:%S",time.localtime(value))
if sensor == "date_max_temp" : value = time.strftime("%H:%M:%S",time.localtime(value))
if sensor == "date_min_temp" : value = time.strftime("%H:%M:%S",time.localtime(value))
#print("%30s : %s" % (sensor, value))
# Собираем топик с сенсором в одно целое для публикации
topicFull = topic_Middile + "/" + sensor
valueFull = str(value)
# Публикуем в MQTT данные сенсора из цикла
client.publish(topicFull, valueFull ,0)
#print topicFull + ": " + valueFull
time.sleep(5)
client.disconnect()
Код: Выделить всё
*/5 * * * * /root/bin/Netatmo_on_Rasp2MQTT.py > /dev/null 2>&1
В случае если в данных majordomo в устройстве MQTT ничего не появляется, то откоментаривайте print'ы и запускайте скрипт вручную, чтобы понять, какие данные он получает от станции и получает ли их вообще.
Сделал НЕ через цикл в самом скрипте, т.к. лень было отлавливать почему иногда скрипт вылетает с ошибкой, т.к. брокер сам закрывает соединение. В данном случае, запуск через крон даже лучше в каком-то смысле, т.к. если скрипт по каким-то причинам "вылетит", то запускать его будет уже не кому и надо обрабатывать как-то этот момент.
Я не описываю тут как именно подключить и установить MQTT брокер к Majordomo - на сайте есть описания этого процесса.
UPD (12.05.2020)
В общем, идеология в корне изменилась. Переписал код так, чтобы он работал внутри Majordomo и не затрагивал вообще MQTT.
Данные разбрасываются по свойствам объектов.
Забыл вверху добавить, что для clientID, clientSecret нужно сперва создать App по адресу https://dev.netatmo.com/
Вот код:
Код: Выделить всё
import sys
import time
# https://github.com/philippelt/netatmo-api-python
import lnetatmo
# Подключаемся к Netatmo
authorization = lnetatmo.ClientAuth(clientId="подставить свой clientID",
clientSecret="подставить свой clientSecret", username="свое имя пользователя к станции", password="пароль пользователя к станции")
# For each available module in the returned data that should not be older than one hour (3600 s) from now
devList = lnetatmo.WeatherStationData(authorization)
for module, moduleData in devList.lastData(exclude=3600).items() :
# Если нужно, то преобразовываем названия комнат, что задали в приложении (при настройке станции), в имена тех объектов, что задали в названии объектов класса
if module == "Egor" : sg_str = "Kinder_room"
if module == "Street" : sg_str = "Street_out"
if module == "Bedroom" : sg_str = "Bed_room"
# начитываем данные из Netatmo и преобразовываем в названия свойств, что задали.
# преобразование можно убрать
for sensor, value in moduleData.items() :
# Для понимания дат и вреемни превращаем их в читабельный вид (hh:mm:ss)
if sensor == "When" :
value = time.strftime("%H:%M:%S",time.localtime(value))
sensor = "timeOfChange"
if sensor == "battery_vp" : sensor = "voltage"
if sensor == "Temperature" : sensor = "temperature"
if sensor == "Humidity" : sensor = "humidity"
if sensor == "Pressure" : sensor = "pressure"
if sensor == "Noise" : sensor = "noise"
# отбрасываем те свойства, коотрые нам не нужны в Majordomo
if sensor == "min_temp" : continue
if sensor == "max_temp" : continue
if sensor == "temp_trend" : continue
if sensor == "rf_status" : continue
if sensor == "date_min_temp" : continue
if sensor == "date_max_temp" : continue
if sensor == "wifi_status" : continue
if sensor == "AbsolutePressure" : continue
if sensor == "pressure_trend" : continue
# Собираем топик с сенсором в одно целое для публикации
topicFull = sg_str + "." + sensor
valueFull = str(value)
# для отладки
# print "mjdm.setGlobal(" + topicFull + "," + valueFull +")"
mjdm.setGlobal(topicFull,valueFull)
Расписываю подробно:
- Нужно доставить библиотеки на систему. Библиотека python-mysqldb для raspbian/debian. В других OS может отличаться. Называется библиотека "Python interface to MySQL". Сергей ее, видимо, забыл описать в топике по скриптам Питона. Без нее ничего не работает.
- Библиотеку, которая описана в скрипте "netatmo-api-python" тоже надо поставить - скачать с гитхаба и поставить, как там написано.
- Создать класс, например с именем Netatmo в нем создать объекты с теми именами, что дали комнатам при настройке станции на сайте/приложении для смартфона. Если даете другие имена объектам, то тогда нужно делать преобразование имен, которое описано в скрипте выше. В моем варианте, объекты с именами Bed_room, Kinder_room, Street_out, но при этом названия комнтам чуть другие (см. выше в сам скрипт). Если это не нужно, то закоментарьте в скрипте это действие.СпойлерПоказать
- Свойства хотите создавайте, хотите нет - они сами создадуться. Но с учетом тех преобразований, что записаны в скрипте. Не хотите такие названия - коментарим и смотрим, что создасться на автомате.
- В классе, которые создали (Netatmo например) создаем метод. У меня имя метода "netatmoGetData": СпойлерПоказать
- И последнее, в объекте onNewMinute сласса Time нужно вызывать метод для того, чтобы он забирал данные со станции.
Обращаю внимание, что скрипт создан так, чтобы вызываться из одного объекта, а не по очередности из всех. Т.е. запись в onNewMinute должна быть одна. Вызываемый там метод может быть из любого из созданных в классе объектов. См. скриншот для примера.СпойлерПоказать