Интернет термометр или телеметрия загородного дома

    Построил я «загородный» домик, поскольку в нем не живу, столкнулся с проблемой определения температуры. На стройке живет теща. Вода в систему отопления набрана. Опытным путем определено, что при +8 в доме, трубы на стенах за гипсокартоном начинают промерзать, а при +18 теща болеть. Вот и возникла идея мониторить температуру удаленно.

    После поисков в интернетах, было закуплено 2 девайса: отечественного производства ВМ1707 и китайский termoHID. Софт к обоим прилагался. Китайское творчество было наляписто, но по функцианалу немного превосходило наше, но к нашему девайсу можна подключать до 10 датчиков DS18B20. Этот аргумент был решающим.

    Сейчас в системе 4 датчика, улица, 1-й этаж, 2-й этаж и чердак. Накоплено год статистики. Фронт выглядит вот так:


    Спс Dennsy термометр в проекте openweathermap.org, станция тут.
    Спс SSar термометр в проекте narodmon.ru, станция тут.
    Родной сайт tarasii.dyndns.org в силу ограничений windows xp ложится при 10 подключениях.

    ПО BM1707 умеет записывать результаты измерений в текстовые файлы. Так что долго не думая на ASP был набросан преобразователь файлов в таблицы. Читать такие таблицы оказалось нелегко, а главное трудно заметить момент когда же все таки температура не в норме. Вот тут то пришли на помощь коллеги (спс KOJISI), и подтолкнули на правильную дорогу. В поле зрения попал javascript Highstock. Как им пользоватся расписано в статьх Highstock: мониторим Премию Рунета и Динамические графики на основе highstock.

    После некоторого бдения таблицы на ASP были совмещены с JS. По сути графики получились такие же как и сейчас, но строились по файлам. Через два месяца работы от файлов пришлось отказаться. Обработка файлов длилась невероятно долго. Решение было принято молниеносно — читаем графики из MySQL. ПО BM1707 позволяет периодично опрашивать датчики и после выполнять bat файлы. Был написан VBScript которй складирует результаты измерений в MySQL. В скрипте есть преобразование текстовой даты в дату в секундах с 1970, а также проверка на существование записи с таким временем.
    Const ForReading = 1
    Const TristateUseDefault = -2
    
    Dim FSO
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Dim FilePath
    FilePath = "C:\BM1707\bm1707.temp" 
    
    set cn = CreateObject("ADODB.Connection")
    cn.connectionstring = "Driver={MySQL ODBC 5.1 Driver};Server=localhost;DataBase=test; " &_
    "USER=usr;PASSWORD=psw;"
    
    cn.open
    If FSO.FileExists(FilePath) Then
    	Dim file
    	Set file = FSO.GetFile(FilePath)
    
    	Dim TextFileStream
    	Set TextFileStream = file.OpenAsTextStream(ForReading,TristateUseDefault)
    
    	Do While Not TextFileStream.AtEndOfStream
    		Dim line
    		line = TextFileStream.ReadLine
    
    		curday = Mid(Line,2,2)
                    curmnth = Mid(Line,5,2)
                    curyear = Mid(Line,8,4)
    		curData = Mid(Line,2,10)  
    		curhour = Mid(Line,13,2)  
    		curmin = Mid(Line,16,2)  
    		cursec = Mid(Line,19,2)  
    		curdt = curyear & curmnth & curday & curhour & curmin & cursec
    		curhour = Cint(curhour)  
    		curmin = Cint(curmin)  
    		cursec = Cint(cursec)  
    		aspdate = CDate(curData)
    		javadt = ((((aspdate - 25569) * 24 + curhour) * 60 + curmin) * 60 + cursec) * 1000    
     
    		sqlStr = "SELECT Count( * ) FROM temperatures WHERE javadatetime = " & javadt
    		res = cn.execute(sqlStr)
    
    		if res(0)="0" then
    
    		line = trim(Mid(Line,24))
    
    		cnt = 1
    		lst = Split(line)
    		for each str in lst
    			nm = ""
    			val = ""
    			vals = Split(str,"=")
    			for each z in vals
    				if nm = "" then
    					nm = z
    				else
    					val = Replace(z,",",".")
    				end if
    			next			
    			if (nm <> "") and (val <> "") then
    				cmdStr = "INSERT INTO temperatures" &_ 
    					"(measurementdatetime, thermometerid, value, javadatetime, thermometername)" &_ 
    					"VALUES ('" & curdt & "','" & cnt & "','" & val & "','" & javadt & "','" & nm & "')"				
    				cn.execute cmdStr 
    			End If
    			cnt = cnt + 1
    		next
    		End if
    	Loop
    	TextFileStream.Close
    	Set TextFileStream = Nothing
    End If
    
    cn.close
    

    Дальше адаптер на PHP который формирует JSON для Highstock.
    $rcn = mysql_connect("localhost","usr","psw"); 
    mysql_select_db("test"); 
    $termid = " and `thermometerid` = 2";
    $last = "order by `measurementdatetime`";
    $from = "";
    $to = "";
    $funk = "MIN";
    if (isset($_GET['termid'])) $termid=" and `thermometerid` = ".$_GET['termid'];
    if (isset($_GET['last'])) $last="order by `measurementdatetime` desc, 'termid' 
    limit ".$_GET['last'];
    if (isset($_GET['from'])) $from=" and `measurementdatetime` >= ".$_GET['from'];
    if (isset($_GET['to'])) $to=" and `measurementdatetime` <= ".$_GET['to'];
    if (isset($_GET['funk'])) $funk="".$_GET['funk'];
    
    $sqlstr = "SELECT MIN(`javadatetime`) as javadatetime, ROUND(".$funk."(`value`),1) as value 
    FROM `temperatures` 
    WHERE 1 ".$termid." ".$from." ".$to."
    group by TO_DAYS(`measurementdatetime`)  
    ".$last;
    
    $res = mysql_query($sqlstr); 
    
    $number = mysql_num_rows($res);
    printf("[");
    
    $first = false;
    
    if ($number > 0) 
    {
      while ($row=mysql_fetch_array($res)) {
        if ($first) printf(",");
        printf("[");
        printf($row['javadatetime']);
        printf(", ");
        printf($row['value']);
        printf("]");
        $first = true;
      }
    } 
    printf("]");
    
    mysql_close();
    

    Пример вывода графика:
    	var cnt = 0, seriesOptions = [],  names = ['MAX','AVG', 'MIN'];
    
    	createAll();
    
    	function createAll() {
    		cnt = 0;
    		$.each(names, function(i, name) {
    			$.getJSON('http://tarasii.dyndns.org/minmax.php?termid=2&funk='+name, function(data) {
    				seriesOptions[i] = {name: name, data: data, tooltip: { yDecimals: 1}};
    				cnt++;
    				if (cnt == names.length) {
    					createChart();
    				}
    			});
    		});
    	}
    
    	function createChart() {
    		window.chart = new Highcharts.StockChart({
    			chart : { renderTo : 'container'}, title : { text : 'Day Temperature Statistics'},
    			xAxis : { maxZoom : 1 * 24 * 3600000 // fourteen days},
    			series : seriesOptions
    		});
    	}
    

    Недавно опять же колеги натолкнули меня на jQuery gauge widget (спс ASM). Получились аналоговые термометры и часы
    	function createGauge(inGauge) {
        		inGauge.jqxLinearGauge({
                    	orientation: 'vertical', width: 80, height: 150,
                   		ticksMajor: { size: '10%', interval: 10 },
                    	ticksMinor: { size: '5%', interval: 2.5, style: { 'stroke-width': 1, stroke: '#aaaaaa'} },
                    	max: 40, min: -40,
                    	pointer: { size: '5%' }, colorScheme: 'scheme05',
                    	labels: {position: 'far', interval: 20, formatValue: function (value, position) {
                    		if (value === -40) {
                            		return '°C';
                        		}
                        		return value + '°';
                    		}
                    	},
                    	animationDuration: 100
            	});
    	};
    

    Скрипт который отправляет результаты на openweathermap
    On Error Resume Next
    set cn = CreateObject("ADODB.Connection")
    cn.connectionstring = "Driver={MySQL ODBC 5.1 Driver};Server=localhost;DataBase=test; " &_
    "USER=usr;PASSWORD=pwd;"
    cn.open
    sqlStr = "SELECT t.value as vl, transactiondatetime,thermometername FROM temperatures t where thermometername='Outdor' order by transactiondatetime desc limit 1; "
    res = cn.execute(sqlStr)
    str = FormatNumber(res(0),1,-1,0,0)
    str = Replace(Str,",",".") 
    cn.close
    Set cn = Nothing
    strURL = "http://openweathermap.org/data/post"
    strDatatoSend ="user=usr&password=pwd&temp="&str&"&lat=50.5193&long=30.5915&alt=100"
    Dim objHTTP
    Set objHTTP = CreateObject("Microsoft.XMLHTTP")    'Create XML HTTP object for the Post method
    objHTTP.open "POST", strURL, False, "usr", "pwd"    'Opening the HTTP post method
    objHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    objHTTP.send strDatatoSend    'Sending the request
    Set objHTTP = Nothing
    

    Пример гаджета для windows7 который показывает температуру со станции openweathermap
    Чтение данных происходит скриптом jquery
    function updateList() {  
    $.getJSON('http://openweathermap.org/data/2.1/weather/station/46933?type=json&callback=?', function(json) {
        $.each(json, function(i, head) {
        	if(i=="main"){
        		curTmp = Math.round((head.temp-273)*10)/10;
        		if (curTmp>0){
        			$('#main').html('<p>+'+curTmp+'°C</p>');
        		}else{
        			$('#main').html('<p>-'+curTmp+'°C</p>');  			
        		}
        	}
        });
    }); 
    }
    


    Немного об оборудовании.

    Контроллер BM1707 соединен с датчиками DS18B20 витой парой, датчики подключены параллельно. Длина шины около 10 метров.

    По началу сервером был нетбук EeePC900H под управлением WIN XP. Спустя некоторое время сервер переехал на miniITX VIA C7-D 1800MHz в старом AT корпусе.


    По стоимости компонентов включая «сервер» можно уложится в 100$

    Надеюсь статья дополнит Электронный термометр с web-интерфейсом на основе UniPing RS-485
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 41

      +1
      В принцепе неплохо, а как насчет использования не Win, а Linux/Unix или прикручивание к маршрутизатору типа ASUS WL500?
        0
        руки никак не дойдут, переезд обязательно будет, идеологически все готово
          +2
          flyrouter.net этим занимаются, адаптацией функции сбора показаний к модифицированным роутерам.
          PS промахнулся с вложением, это ответ на реплику SysCat.
          +1
          Проблем минимум — на любом современном линуксе заводится с полпинка любительский софт распространяется в откомпилированном виде, для запуска требуется только libusb.
          На WL500 завестись должно, но не на всех прошивках, нужно иметь совместимую версию libusb.

          Сам сейчас собрал на таком термометре простенький мониторинг температуры на даче. Пришлось переходить с фряхи на линукс, сугубо из-за прекомпилированности софта. Завестись завелся — но датчик не увидел. Немного не успел закончить и черкануть заметку.
          +3
          Автор не ищет легких путей, на вскидку могу предположить что с ВМ1707 можно снимать показания напрямую с помошью пакета owfs примерно так: cat /mnt/1wire/идентификатор_датчика/temperature. Если бы протестировали было бы замечательно!
            +1
            Под линуха для MP707 (BM1707 старое название) есть консольная тулза bmcontrol.
            Жаль проект перестал развиваться и пришлось обвязку для передачи данных на сокетах php в cron повесить.
            Если кому надо — поделюсь наработками. Мне такой вариант уже не актуален из-за отказа от USB версии.
              0
              Смогу попробовать в выходные, но скорее всего нет.
              Наши Левши запилили ВМ1707 в качестве USB-HID устройства с «уникальным» протоколом. Спецификаций нет, есть только примеры кода. Именно по ним и были сделаны bmcontrol и dll-ка для включения в собственные проекты.
              +1
              Хочется верить, что когда-нибудь авторы начнут тестировать свои сайты на нагрузку прежде, чем выкладывать ссылку на хабр
                +1
                У него наверное просто замерз интернет. :)
                  0
                  да этож dyndns, 99% то что его сервар, это обычный домашний комп с мегабитным интернетом :)
                  0
                  Я проблему измерения и передачи данных решил с помощью arduino и arduino ethernet shield. И просто и компактно.
                    0
                    Думаю скоро перееду на свою метеостанцию на STM32, осваиваю USB интерфейс, будут датчики температуры + давление и влажность. ВМ1707 дал возможность не заморачиватся на девайс, а получить результат.
                      0
                      Компактно, но вот стоимость решения… явно больше 20$ даже если шилды в Китае найти.
                      Хотя видел реализацию сбора и передачи показаний на клоне ардуино+GPRS — прикольно вышло и автономно.
                      +2
                      «На стройке живет теща» — пять баллов! :-D
                      • UFO just landed and posted this here
                          0
                          А мне понравилась SMS-розетка от мегафона. Правда там статистику не поведешь, зато розетка сама присылает SMS, если температура изменилась выше/ниже плановой.
                            +1
                            Популярное применение но увы морально устаревшему USB термометру MP707, года 3 назад тоже купил себе такой поиграться, прельстила возможность пасти температуру за окном и в помещении не вставая от компа, но со временем както дорос до автономной LAN-версии ибо комп шумел ночами да и тарифы на электричество выросли значительно за эти годы.

                            Буквально только сегодня как раз для похожих нужд заявил о необходимости утилиты для наглядного мониторинга для автономных и LAN датчиков дабы разделить постоянный сбор данных и возможность контроля, которая должна быть не только на домашнем компе с локально подключенным датчиком но и с работы например или от гостей и т.п. К тому же домашний комп не столь надежен в плане сбора и передачи показаний из-за рисков отключения света, интернета за неуплату вовремя после праздников или банально установленного кривого софта.

                            PS Увидев название статьи сработало дежавю, у себя на проекте видел датчик на карте с аналогичным названием, но он правда с Cosm.com по HTTP POST данные транслировал. Автору статьи быть может будет интересен список «Устройств» для сбора и передачи информации о показателях среды на сайте проекта, что я смог насобирать на просторах РФ и СНГ за пару лет изучения данной темы.

                            PPS SMS уведомления тоже любопытная штука, но увы не бесплатная, продвигаемся в эту сторону тоже.
                              +1
                              А адскую жару теще удаленно можно устроить?
                                +1
                                График Ваш нравится и изображение термометров.
                                Сам недавно раскидал несколько датчиков DS18S20 с мониторингом через cacti.
                                Думаю, в будущем мне может пригодиться такой опыт для умного дома.

                                image
                                  +1
                                  А Вы через какой девайс датчики 1-wire завели на «кактус»? Сами что-то разработали?
                                    +2
                                    Схема примерно как в этой статье. Тоже через COM-порт втыкается в сервер и мониторится через digitemp на FreeBSD.
                                      +1
                                      И стабильно работает при подключении десятка датчиков? не «проседает»?
                                        +1
                                        Относительно стабильно. Пока наблюдаю. Я в конфиг прописал все идентификаторы датчиков — так их опрос корректнее происходит. В автоматическом режиме с ключом -i иногда некоторые датчики не находились.
                                          +1
                                          Попробуйте DS18B20 там класс точности получше, разброс меньше будет и меньше риска спутать с глюком линии.
                                          У меня 3 датчика на обычном 4х жильном телеф кабеле так подключены, один из них причем на 25м удален и провод явно хуже чем витая пара, зато более эстетично. Если датчики не находятся значит и у Вас сопротивление провода многовато.
                                            +1
                                            Опечатался, у меня DS18B20 конечно же.
                                          +1
                                          Проверял на такой схеме 15 датчиков — работает.
                                          Только с прописанными идентификаторами быстрее.
                                          Еще иногда надо в digitemp поправить задержку.
                                          У меня уже где-то два года статистики.
                                          Но все еще хочу перенести датчики на отдельное устройство, а не использовать COM в старом компе (шумит гад сильно).
                                      +3
                                      Черт, как же у вас холодно в туалете!
                                        +2
                                        Там по нулям, так как датчики еще не дотянул, и чтобы не убивать данные по графику после добавления новых термометров, сделал «echo 0.0».
                                        А не потому, что туалет вынесен на улицу :)
                                      0
                                      А я вот это использовал: npp-alion.ru/products/mbk/
                                      Не нужен компьютер: все передается по воздуху. Фирма хоть и «совковая», но если копнуть, то окажется, что есть облачный сервис по мониторингу параметров приходящих с датчиков: с соответствующей настройкой реагирования и т.п.
                                        0
                                        из беспроводных несовковых альтернатив:
                                        GPRS+ардуино Cosmo GSM Connect
                                        WiFi+роутер FlyRouter (WiFi-роутер)
                                          0
                                          Посмотрел… Спасибо. Но у нас кейс был значительно шире, а именно надо было помимо собственных данных о температуре и давлении передавать так же и информацию с тепловычислителя + к этому управлять питанием 220. На первый взгляд, научить подобному последние девайсы проблематично. Да и количество входов-выходов для нашего случая оставляет желать лучшего… Даже если наворотить сверху что-то свое, то врядли будет дешевле 7000…
                                            0
                                            оба предложенных варианта программируются, както сильно переоценили исполнительное реле, посмотрите на томже ebay электронные компоненты для умных домов почем стоят, особенно еси сборка гонконга к примеру. управляемые релюшки врядли так дорого встанут. в общем дело вкуса.
                                        0
                                        только сегодня мне пришел десяток 2 и 3 ревизии…
                                          0
                                          прикручено все к Netxms
                                          Прикручено к netxms
                                          0
                                          Может есть у кого нибудь опыт использования беспроводных датчиков измерения температуры, влажности и т.п.?
                                          Интересно узнать, что можно использовать для этих целей
                                            0
                                            чуть выше в комментах уже было
                                              0
                                              Не сосем то. Есть желание подключить датчик(ки) к уже имеющемуся маршрутизатору. В идеале конечно.
                                                0
                                                маршрутизатору какому? eth / wifi или еще какой? 1-wire датчики без обвязки к типовым маршрутизаторам не подключить…
                                              0
                                              Есть какие-нибудь компактные беспроводные решения на Z-Wave технологии по передачи температуры/влажности? Подскажите плиз.
                                                0
                                                Вариант 1 Модуль Sigma Designs ZM3102 и залить в него протокол работы с 18B20, у него есть ком порт — значит на нем можно попробовать 1-wire. Z-Wave to 1-wire. Вариант 2 собственно готовый вариант 1 Универсальный бинарный датчик FGBS-001
                                              0
                                              А мы в своё время сделали проще. Система просто рассказывает всё голосом по мобильному телефону.

                                              Only users with full accounts can post comments. Log in, please.