Присоединяйтесь!
Авторизация

Дача, USB-модемы, две малины, или сказ о том, как я температуру в доме проверял.

27 April 2016 - Автор Rampage4

Добрый день! Хочу рассказать вам про свои приключения и поиски надежного решения для удаленного мониторинга температуры помещения, наблюдения за окружающим миром и включения/выключения устройств.

Надо сказать, что устройства получились на удивление надежными и на данный момент отработали по пол года, без единого разрыва сбоя.

Дано: 2 дачи.

Первая - с газовым отоплением, и основная задача - поймать момент снижения температуры (ака потухший фитиль), чтобы осталось время приехать и зажечь его, не дать трубам разорваться от замерзшей в них воды. Интернет - gprs, качество приема - устойчивое.

Вторая - без отопления, только электрические тены. Тут необходимо удаленное включение устройств(тенов), поддержание комфортной температуры для сна. Интернет - отсутствует, gsm сигнал есть, однако работает скверно.

Так получилось, что у меня дома завалялась малинка и usb gprs свисток. Решил начать со второй дачи, дабы интеграцию с web сервисами оставить на потом.

Общение с внешним миром из-за отсутствия Интернет - только по смс.

Основная последовательность действий:

1) установка debian os

2) изменение modeswitch usb свистка, на режим модема

3) написание программы для работы с приемом, парсингом и отправкой сообщений.

Язык 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 скритпа:

1) делаем фото окружающей природы с камеры подключенной по usb к малине и отправляем на список почтовых адресов.

2) вызываем бесплатный интернет-сервис по отправке смс сообщений.

+ Запускается 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)

Вскоре обнаружились сбои, связанные с зависанием малины после нескольких дней работы, несмотря на работу вотчдогов. Победил это просто, ежедневным ребутом. И, как я писал выше, с тех пор обе системы работают без нареканий. За прошедшую зиму благодаря системе удалось дважды спасти отопление дачи, вовремя получив заветную смс.

Спасибо за прочтение статьи! Некоторые детали я пропустил в своем повествовании, но готов ответить на любые возникшие вопросы :)

27 April 2016
Rampage4
автор статьи

Комментариев: 3

  1. alfacom

    28 April 2016 - Ответить

    У меня небольшая куча вопросов. Фото природы — просто природа на даче красивая?) Код Питоновский? Многие популярные LCD-дисплеи поддерживают кириллические символы. Ваш не поддерживал, или лень возиться было? сбои связанные с зависанием малины Очень интересно. Какую малинку(и) использовали? Зависания были на обоих малинках? код отправки СМС используя бесплатный веб сервис Сразу подумал о sms.ru. Прочел код и убедился в своем предположении)

    • Rampage4

      28 April 2016 - ответить

      Фото, да насамом деле просто мониторить, что стекла в доме не разбили, соседи приехали/уехали :) Код да, все на питоне. Очень простой и понятный для понимания язык. После увлечения малинкой, начал даже на работе его продвигать. Про Lcd — да, просто не хотелось убивать времени больше, чем было необходимо для конкретных задач. Очень интересно. Какую малинку(и) использовали? Зависания были на обоих малинках? Raspberry PI Model B. Да висли обе, причем с некоторой зависмостью от зоны приема gsm. Запускаю для теста дома (москва) — неделю работает без проблем. На даче — через три дня уходит «в себя». Сразу подумал о sms.ru. Прочел код и убедился в своем предположении) Реально, очень крутой сервис, учитывая бесплатность для разработчиков. Работает без сбоев пол года.

  2. amf

    19 May 2016 - Ответить

    Очень интересно почитать. спасибо! Подскажите, почему было решено делать на Raspberry? Первый проект (да и второй тоже) точно бюджетнее было сделать на Arduino.

    • Rampage4

      19 May 2016 - ответить

      Бюджетнее ли при наличии usb модемов? :-) При оценке вариантов, конечно смотрел на трудоемкость и стоимость. Трудоемкость для меня победила малина: возможность использования Python, и наличия полноценной OS. Стоимость: смотрел на стоимость GSM шилдов в поднебесной… и видел ценники за 600+ рублей. Малину(вторую) взял за 1к рублей «с рук». Потому получилось по вполне адекватной цене, и дешевле gsm розеток :-)

      • amf

        19 May 2016 - ответить

        Спасибо за ответ. да, видимо, возможность использования usb модемов — это серьезный плюс в копилку малины. Прямо да, реально. Да еще и вторая малина за дешево )) тоже хочу что-то подобное сделать, смотрел в сторону Arduino + какой-нить GSM-модуль типа m590e. из китая, естественно. И там пока бюджет всего в 1к. ))

        • Rampage4

          19 May 2016 - ответить

          Ну, вместо малины оранж пи ван можно взять. Одноплатник за 9.99 usd. Я вот в конкурсе третью не выиграл… пришлось оранж взять :))) уже доставили… начинаю теперь новые экспиременты на нем. Ардуину, кстати про мини можешь взять. 1.45usd стоит в забугорье. Только ножки припаять надо будет и усб уарт переходник для записи скетчей.

          • amf

            20 May 2016 - ответить

            orange pi — интересная штука. ) надо будет попробовать. сначала я тоже на про мини смотрел, но потом «открыл» nano. цена чуть больше, но и паять не надо, и программировать проще. и разъем знакомый.

  3. vdk10

    22 November 2017 - Ответить

    Замечательно!Есть несколько вопросов:1)  Какие настройки у модемов для работы через gammu? Т.е. покажите настройки/конфиг файл gammu для первой дачи.Пакет gammu был предварительно установлен?2) Можно подробнее что делалось с помощью modeswitch?

Отправить комментарий

Авторизуйтесь для отправки комментария

Присоединяйтесь
Новые сообщения
  • Проект по удаленному доступу
    09 July, 2020
    Ищу помощника на проект по созданию проекта на базе RPi. Базово - настройка вебкамеры+модема. Далее, возможно будут...…
  • Raspberry pi 4 не включается
    27 June, 2020
    @antonabsatarov#6188 что ты имеешь введу под "правильным" форматированием флешки? Все же исправно работало, а в один момент...…
  • Raspberry pi 4 не включается
    27 June, 2020
    @x6vital#6185 я сам столкнулся со схожей проблемой. Решил правильным форматированием флэшки (криво устанавливалась ОС), а...…
  • Как запустить X без монитора?
    22 June, 2020
    Как вы поняли, что они не запускаются? …
  • Как запустить X без монитора?
    22 June, 2020
    Добрый день, поставил на малину расбери ос с рабочим столом, если она загружается без монитора то не стартуют приложения...…
  • Raspberry pi 4 не включается
    19 June, 2020
    @mojo#6171 дело в том что она вообще неадекватно себя как то ведёт. Просто в один момент перестала включаться. Пробую...…
  • Troyka Cap
    19 June, 2020
    Всем спасибо вопрос больше не актуален …
  • Troyka Cap
    19 June, 2020
    @mojo#6178 спасибо скорее всего я уже нашёл ответ: Подключение Платформа устанавливается сверху на одноплатник Raspberry...…
  • rap os без Х + twinkle + service чо происходит
    18 June, 2020
    Добрый день, подскажите пожалуйста, установил настроил twinkle на малину(rasp os linux 10), запускаю через терминал twinkle...…
  • Troyka Cap
    18 June, 2020
    @mojo#6178 держу в курсе) я гулять пошёл и по этому от меня связи не будет до след дня надеюсь что Вы сможете помочь …
  • Troyka Cap
    18 June, 2020
    @mojo#6178 да и как могут быть проблемы с пинами Pi если вентелятор работает от тройка кэп просто от других пинов вопрос...…
  • Troyka Cap
    18 June, 2020
    @mojo#6175 дело не в разбери пинах так как я пробовал ставить вентилятор на саму разбери и он работал и на тройке он...…
  • Troyka Cap
    18 June, 2020
    нет. проблема врядли в токе. Там 1 светодиод, ему вполне хватит питания от RasPi …
  • Troyka Cap
    18 June, 2020
    @mojo#6176 просто в видео у амперки где обзор на тройку обзор там доп блок питания может просто не хватает тока? …
  • Troyka Cap
    18 June, 2020
    В самом Cap'е врядли могут быть проблемы. Там почти нет ничего такого, что может не работать. …
  • Troyka Cap
    18 June, 2020
    На схеме есть соответствие пинам Cap'а пинам на Raspberry Pi Попробуй модуль со светодиодом подключить напрямую к RasPi...…
  • Troyka Cap
    18 June, 2020
    > @Artem90056#6167 какие подробности я не сказал? Никаких. Я в принципе не понимаю, как ПИН может не работать....…
  • Troyka Cap
    18 June, 2020
    @mojo#6170 возможно что я не втыкаю в тройку кэп доп зарядник и мне не хватает мощности? …
  • Troyka Cap
    18 June, 2020
    @mojo#6170 http://wiki.amperka.ru/продукты:raspberry-troyka-cap пролистни чуть ниже проект маячок дана схема и код …
  • Raspberry pi 4 не включается
    18 June, 2020
    так и должно быть. Без SD карты горят все светодиоды Скорее всего не тот образ записал на карту …
  • Troyka Cap
    18 June, 2020
    Скидывай код и схему к какому пину Troyka Cap и что ты подключаешь …
  • Troyka Cap
    18 June, 2020
    @sv-lary#6166 не работают пины на troyka cap беру пример кода с амперки делаю всё по схеме но результата нет …
  • Troyka Cap
    18 June, 2020
    @sv-lary#6166 скажи что тебе ещё сказать? …
  • Troyka Cap
    18 June, 2020
    @sv-lary#6166 какие подробности я не сказал? я то знаю почему пины не работают да? …
  • Troyka Cap
    18 June, 2020
    > @Artem90056#6165 Troyka Cap не хочет работать И? А можно - хоть какие-то подробности? Или Вы предполагаете, что...…