Дача, USB-модемы, две малины, или сказ о том, как я температуру в доме проверял.
-
Добрый день! Хочу рассказать вам про свои приключения и поиски надежного решения для удаленного мониторинга температуры помещения, наблюдения за окружающим миром и включения/выключения устройств.
Надо сказать, что устройства получились на удивление надежными и на данный момент отработали по пол года, без единого разрыва сбоя.
Дано: 2 дачи.
Первая - с газовым отоплением, и основная задача - поймать момент снижения температуры (ака потухший фитиль), чтобы осталось время приехать и зажечь его, не дать трубам разорваться от замерзшей в них воды. Интернет - gprs, качество приема - устойчивое.
Вторая - без отопления, только электрические тены. Тут необходимо удаленное включение устройств(тенов), поддержание комфортной температуры для сна. Интернет - отсутствует, gsm сигнал есть, однако работает скверно.
Так получилось, что у меня дома завалялась малинка и usb gprs свисток. Решил начать со второй дачи, дабы интеграцию с web сервисами оставить на потом.
Общение с внешним миром из-за отсутствия Интернет - только по смс.
Основная последовательность действий:
-
установка debian os
-
изменение modeswitch usb свистка, на режим модема
-
написание программы для работы с приемом, парсингом и отправкой сообщений.
Язык python, библиотека для общения с модемом - gammu, датчик температуры bmp085, LCD дисплей, и два простых реле.
Основные функции: Включение питания (пин 4), Включение второго устройства (пин 17), получение сведений о температуре и их отправка, переход в режим поддержания температуры в определенном интервале.
Самое интересное, код:
# -*- coding: utf-8 -*- import gammu import time import RPi.GPIO as GPIO import Adafruit_BMP.BMP085 as BMP085 import lcddriver import os from datetime import datetime from subprocess import call f = open('/var/log/sms','a') f.write(str(datetime.now()) + ' System started\n') f.close() GPIO.setmode(GPIO.BCM) pinList = [4, 17] sensor = BMP085.BMP085() lcd = lcddriver.lcd() #Обьявляем телефоны, с которых мы будем обрабатывать смски cellphones = ['+7926XXXXX','+7926XXXXXX'] currcommand = '' for i in pinList: GPIO.setup(i, GPIO.OUT) GPIO.output(i, GPIO.HIGH) sm = gammu.StateMachine() sm.ReadConfig() sm.Init() sm.GetSMSStatus() #Создаем функцую для удаления всех смс, на случай, если аппарат был выключен и накопилась очередь сообщений. def delete_all_sms(): status = sm.GetSMSStatus() remain = status['SIMUsed'] + status['PhoneUsed'] + status['TemplatesUsed'] start = True while remain > 0: sms = sm.GetNextSMS(Start = True, Folder = 0) remain = remain - len(sms) for m in sms: sm.DeleteSMS(Location = m['Location'], Folder = 0) #функция чтения смс, с удалением после прочтения. def retSMS(): start = True sms=[{'Number':0,'Text':2},{'Number':0,'Text':2}] while 1: try : if start: sms = sm.GetNextSMS(Start = True, Folder=0) start = False else: sms = sm.GetNextSMS(Location = sms[0]['Location'], Folder=0) except gammu.ERR_EMPTY: break try: delete_all_sms() except gammu.ERR_EMPTY: a=1 return(sms[0]['Number'],sms[0]['Text']) #Объявляем функцию отправки сообщений, с перезагрузкой, в случае сбоя. Такое случается крайне редко # Однако, т.к. система находится далеко, необходимо, чтобы в случае падений, перезапускалось само. def sndSMS(number,smstext): message = { 'Text': smstext, 'SMSC': {'Location': 1}, 'Number': number, } try: sm.SendSMS(message) except gammu.ERR_UNKNOWN: f = open('/var/log/sms','a') f.write(str(datetime.now()) + ' Failed to send sms\n') f.write(str(datetime.now()) + ' Rebooting in 3.5 minutes...\n') print ("failed to send") time.sleep(200) f.write(str(datetime.now()) + ' Rebooting...\n') f.close() os.system("sudo shutdown -r now") #read temperature def readtemp(): curtemp=sensor.read_temperature() return curtemp #Основная функция расшифровки сообщений, обработки заданий. def parscom(detSms): currcommand='' if detSms[0] in cellphones: if detSms[1]=='On': GPIO.output(4, GPIO.LOW) sndSMS(detSms[0], 'Otoplenie on') currcommand='On' if detSms[1]=='Poliv': GPIO.output(17, GPIO.LOW) sndSMS(detSms[0], 'Poliv ON') currcommand='PolivOn' if detSms[1]=='PolivOff': GPIO.output(17, GPIO.HIGH) sndSMS(detSms[0], 'Poliv Otkluchen') currcommand='PolivOff' if detSms[1]=='Off': GPIO.output(4, GPIO.HIGH) sndSMS(detSms[0], 'Otoplenie Off') currcommand='Off' if detSms[1]=='Temp': print readtemp() sndSMS(detSms[0], 'Temp: ' + str(readtemp())) if detSms[1].split()[0]=='Set': temp=detSms[1].split()[1] GPIO.output(4, GPIO.LOW) currcommand='Set ' + temp sndSMS(detSms[0], 'Night mode On. Temperature set: ' + str(temp)) return currcommand #Реализация функции поддержания температуры. def otoplenie_night(settemp): curtemp=readtemp() try: if curtemp>int(settemp)+0.5: GPIO.output(4, GPIO.HIGH) if curtemp GPIO.output(4, GPIO.LOW) except: GPIO.output(4, GPIO.HIGH) #Основной цикл - отправка смс при включении, вызов функций чтения смс, парсинга, и вывода на lcd дисплей. sndSMS('+7926XXXXXX', 'Cucmema Pa6omaem') while 1: detSms=retSMS() newcommand = parscom(detSms) lcd.lcd_display_string("TEMnEPATYPA: " + str(readtemp()) + " C" , 1) if currcommand != newcommand and newcommand != '': currcommand=newcommand lcd.lcd_display_string("KOMAHDA: " , 2) lcd.lcd_display_string("KOMAHDA: " + currcommand , 2) try: if currcommand.split()[0]=='Set': otoplenie_night(currcommand.split()[1]) except IndexError: a=0 time.sleep(5)
После окончания работы над первым устройством экстренно закупил вторую малину, нашел второй свисток и начал ваять устройство для первой дачи. Благодаря наличию хорошего интернета, отсутсвия необходимости включать реле концепция немного изменилась, но работает так же надежно.
Работает по крону 2 скритпа:
-
делаем фото окружающей природы с камеры подключенной по usb к малине и отправляем на список почтовых адресов.
-
вызываем бесплатный интернет-сервис по отправке смс сообщений.
- Запускается gammu демон, который автоматически подключается к интернету при загрузке малины.
Код получения картинки и отправки по почте:
from smtplib import SMTP_SSL from email.MIMEMultipart import MIMEMultipart from email.MIMEBase import MIMEBase from email import Encoders import os #Меряем температуру (Датчик DS18B20) def readtemp(): tfile=open("/sys/bus/w1/devices/28-00000633a133/w1_slave") ttext=tfile.read() tfile.close() temp=ttext.split("\n")[1].split(" ")[9] temperature=float(temp[2:])/1000 return temperature temperatur=str(readtemp()) #Делаем фото os.system ("fswebcam -r 1024x768 -S 15 /home/pi/pics/static/temp.jpg") #Путь для аттача filepath = "/home/pi/pics/static/temp.jpg" basename = os.path.basename(filepath) #куда отправлять письма: address = ['XXX@gmail.com','XXXX@list.ru','XXX@mail.ru'] Наш аккаунт, откуда отправляем adressfrom='XXX@yandex.ru' # Compose attachment part = MIMEBase('application', "octet-stream") part.set_payload(open(filepath,"rb").read() ) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % basename) # Compose message msg = MIMEMultipart() msg['From'] = adressfrom msg['To'] = ", ".join(address) msg['Subject'] = 'A vot i temperatura ' + temperatur msg['Body']='Temperatura' msg.attach(part) # Send mail smtp = SMTP_SSL() smtp.connect('smtp.yandex.ru') smtp.login(adressfrom, 'PASSWORD') smtp.sendmail(adressfrom, address, msg.as_string()) smtp.quit()
В результате получаем на почту такую красивую картинку, и на душе как-то становится теплее.
А это код отправки СМС с использованием бесплатного веб-сервиса:
import requests import os #Читаем температуру def readtemp(): tfile=open("/sys/bus/w1/devices/28-00000633a133/w1_slave") ttext=tfile.read() tfile.close() temp=ttext.split("\n")[1].split(" ")[9] temperature=float(temp[2:])/1000 return temperature temperatur=str(readtemp()) #вызываем веб сервис, для формирования смс. r = requests.get('http://sms.ru/sms/send?api_id=ID_API&to=7926NUMBER4&text=Temperatura+'+ temperatur) q = requests.get('http://sms.ru/sms/send?api_id=ID_API&to=7910NUMBER&text=Temperatura+'+ temperatur)
Вскоре обнаружились сбои, связанные с зависанием малины после нескольких дней работы, несмотря на работу вотчдогов. Победил это просто, ежедневным ребутом. И, как я писал выше, с тех пор обе системы работают без нареканий. За прошедшую зиму благодаря системе удалось дважды спасти отопление дачи, вовремя получив заветную смс.
Спасибо за прочтение статьи! Некоторые детали я пропустил в своем повествовании, но готов ответить на любые возникшие вопросы
-
-
У меня небольшая куча вопросов.
Фото природы — просто природа на даче красивая?)
Код Питоновский?
Многие популярные LCD-дисплеи поддерживают кириллические символы. Ваш не поддерживал, или лень возиться было?
сбои связанные с зависанием малины
Очень интересно. Какую малинку(и) использовали? Зависания были на обоих малинках?код отправки СМС используя бесплатный веб сервис
Сразу подумал о sms.ru. Прочел код и убедился в своем предположении) -
Фото, да насамом деле просто мониторить, что стекла в доме не разбили, соседи приехали/уехали
Код да, все на питоне. Очень простой и понятный для понимания язык. После увлечения малинкой, начал даже на работе его продвигать.
Про Lcd — да, просто не хотелось убивать времени больше, чем было необходимо для конкретных задач.Очень интересно. Какую малинку(и) использовали? Зависания были на обоих малинках?Raspberry PI Model B. Да висли обе, причем с некоторой зависмостью от зоны приема gsm. Запускаю для теста дома (москва) — неделю работает без проблем. На даче — через три дня уходит «в себя».
Сразу подумал о sms.ru. Прочел код и убедился в своем предположении) Реально, очень крутой сервис, учитывая бесплатность для разработчиков. Работает без сбоев пол года.
-
Очень интересно почитать. спасибо!
Подскажите, почему было решено делать на Raspberry?
Первый проект (да и второй тоже) точно бюджетнее было сделать на Arduino. -
Бюджетнее ли при наличии usb модемов?
При оценке вариантов, конечно смотрел на трудоемкость и стоимость.
Трудоемкость для меня победила малина: возможность использования Python, и наличия полноценной OS.
Стоимость: смотрел на стоимость GSM шилдов в поднебесной… и видел ценники за 600+ рублей. Малину(вторую) взял за 1к рублей «с рук». Потому получилось по вполне адекватной цене, и дешевле gsm розеток -
Спасибо за ответ.
да, видимо, возможность использования usb модемов — это серьезный плюс в копилку малины. Прямо да, реально. Да еще и вторая малина за дешево ))
тоже хочу что-то подобное сделать, смотрел в сторону Arduino + какой-нить GSM-модуль типа m590e. из китая, естественно. И там пока бюджет всего в 1к. ))
-
Ну, вместо малины оранж пи ван можно взять. Одноплатник за 9.99 usd.
Я вот в конкурсе третью не выиграл… пришлось оранж взять :))) уже доставили… начинаю теперь новые экспиременты на нем.Ардуину, кстати про мини можешь взять. 1.45usd стоит в забугорье. Только ножки припаять надо будет и усб уарт переходник для записи скетчей.
-
orange pi — интересная штука. )
надо будет попробовать.сначала я тоже на про мини смотрел, но потом «открыл» nano. цена чуть больше, но и паять не надо, и программировать проще. и разъем знакомый.
-
Замечательно!Есть несколько вопросов:
1) Какие настройки у модемов для работы через gammu? Т.е. покажите настройки/конфиг файл gammu для первой дачи.Пакет gammu был предварительно установлен?
2) Можно подробнее что делалось с помощью modeswitch?