IQhome


Get the Flash Player to see this player.

time2online Joomla Extensions: Simple Video Flash Player Module
IQhome

Nasz inteligentny dom, to projekt w którym wykorzystuje sporo informacji o stronach internetowych, przekazywaniu danych i programowaniu. Dlatego postanowiłem opisać najważniejsze elementy tego domu.

Projekt zaczynamy od instalacji systemu operacyjnego i instalacji serwera www. Ja wykorzystałem tu Apacha2 + php5 + mod_cgi. Do tego zainstalowałem Joomle 3.3, żeby się nie męczyć z ładnym wyglądem strony. Nie będę się dużo rozpisywał na ten temat, bo w necie macie mnóstwo poradników jak to zainstalować. Polecam strony:

http://rembiejewski.pl/blog/raspberry-pi-serwer-www-apache-php-mysql/

http://httpd.apache.org/docs/current/howto/cgi.html

https://www.digitalocean.com/community/tutorials/how-to-use-suexec-in-apache-to-run-cgi-scripts-on-an-ubuntu-vps

W dalszej części będę pokazywał najważniejsze elementy projektu. Tak jak to pokazałem na filmie.

1) Zacznijmy od strony HTML i PHP (kamery).

Aby uruchomić ten moduł wystarczy zainstalować mjpg_streamer. To jak to zrobić opisałem tu:

http://avrkwiat.nstrefa.pl/omnie/index.php?option=com_content&view=article&id=165&Itemid=189

Najważniejszym elementem jest użycie na naszej stronie znacznika HTML, który to będzie pobierał naszego streama w formie obrazku. Aby tego dokonać wystarczy wpisać znacznik img, gdzie 192.168.1.101 to adres naszego Raspberry Pi:

<img src=”http://192.168.1.101:8083/?action=stream” width=”640″ height=”480″/>

Oczywiście takie rozwiązanie jest mało eleganckie, ponieważ jak zmieni się adres naszego Raspberry, to stream przestanie działać. Dlatego wygodnie jest użyć języka PHP, do przechwycenia IP serwera i wstawienie tego IP w znacznik IMG. Całość będzie wyglądała tak:

<img src=”http://<?php echo $_SERVER['HTTP_HOST'];?>:8083/?action=stream” width=”640″ height=”480″/>

2) Strona Termometr.php

Pobieranie z czujnika DS18B20 ogranicza się do uruchomienia na stałe czujnika i magistrali 1-wire, odnalezienie adresu termometru, wysłanie danych do przeglądarki, obrobienie ich i odświeżanie co jakiś czas. Ja jeszcze dodałem zapisywanie tych danych w pliku dane.txt w pamięci ram, która jest zamontowana w katalogu ramdisk. To jak zamontować 1-wire i ramdisk macie w artykułach:

http://avrkwiat.nstrefa.pl/omnie/index.php?option=com_content&view=article&id=170&Itemid=194

http://avrkwiat.nstrefa.pl/omnie/index.php?option=com_content&view=article&id=214&Itemid=242

Cały program to mieszanka php, JS i HTML. Najważniejszym elementem kodu jest pobieranie danych z czujnika za pomocą php:

 
 <?php
 //odczytanie danych z magistrali w celu wyszukaniu pierwszego czujnika
 
 $sciezkaadres = '/sys/bus/w1/devices/w1_bus_master1/w1_master_slaves';
 $adres = implode(file($sciezkaadres));
 //bierze pierwszy adres i ucina wszystko po 15 linii
 $adres = substr($adres,0,15);
 
 echo "Adres twojego urządzenia to:".$adres."";
//czytanie danych z konkretnego czujnika
 $file = "/sys/bus/w1/devices/".$adres."/w1_slave";
 
 //czytanie linia po linii z konkretnego czujnika
 $lines = file($file);
 
 //wez z drugiej linii temperature
 $temp = explode('=',$lines[1]);
 
 //robienie ladnego formatu do odczytu
 $temp=number_format($temp[1]/1000,1,'.','');
 echo $temp;
//pobranie dany, aby zapisać dane do pliku
 $date = date(i);
 $fp = fopen("./ramdisk/data.txt","r");
 $staredane = fread($fp,filesize("./ramdisk/data.txt"));
 fclose($fp);
 
 //$nowedane= date('Y-m-j').",".$temp."\n";//dane w ciagu dni
 $nowedane= date('Y-m-j G:i:s').",".$temp."\n";
 $nowedane .=$staredane;
 $fp = fopen("./ramdisk/data.txt","w");
 fputs($fp,$nowedane);
 fclose($fp);
  ?>

Następnie w JS trzeba wywoływać stronę co sekundę (lub odświeżyć jakiś element na stronie), aby aktualizowany był zegar, a przy okazji zapisywane dane. Opisane tego można znaleźć na blogu:

http://blog.codebusters.pl/pl/odswiez-zawartosc-strony-automatycznie-co-okreslony-czas-jquery

Oczywiście jest to metoda czołgowa i przy skomplikowanych projektach będziecie mieli dużo problemów, dlatego lepiej wykorzystać technologie AJAX i asynchronicznie pobierać coś z servera. Super opis tego jak to zrobić macie na stronie:

http://software.dictum.com.pl/blog/php/ajax-czasowe-odswiezanie-elementu-na-stronie/

W tym projekcie jest to zrobione metodą czołgową, ale uczniom pokazuje AJAX'a.

3) Strona z PiFace oswietlenie.html

Ta strona jest skryptem JS, który wybiera odpowiednie elementy za pomocą checkbox i w zależności od tego co było ustawione wysyła do programu napisanego w C. Ten program odbiera te dane i przykazuje dalej na diody itp.

Wszystkie strony można pobrać tu:

4) Tera czas na Kody w C.

Programy w C podzielone są na 2 typy, odbiorczy (pobiera dane z formularz jako skrypt CGI ) i wykonywalny (odpalony z uprawnieniami administratora, który ma dostęp do wszystkiego i jest gdzieś na komputerze z dala od katalogu cgi-bin).

a) Pierwszy to program który wywoływany jest bezpośrednio przez stronę www jako skrypt CGI. Ten program możecie pobrać tu

Jest to program, który przechwytuje formularz z HTML i zapisuje go do pamięci ram urządzenia w postaci pliku TXT. Oczywiście można pobawić się strumieniami danych i przekazywać te dane strumieniami, ale jest to projekt dla uczniów w technikum, więc obsługa plików jest wystarczająca i pasująca do Linuxa, gdzie wszystko jest plikiem.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
int main (void)
{
char *data;
FILE *fp;
printf("Content-Type: text/plain;charset=us-ascii\n\n");
 
fp=fopen("../../IQhome/strona/ramdisk/test.txt","w");
if (!fp){
printf("nie mozna otworzyc pliku");
return -1;
}
 data = getenv("QUERY_STRING");
 printf("Pobrales stronga: %s\n",data); 
 if(!data){
  printf("Nie przekazano parametrów");
 }else {
  fprintf(fp,"%s",data);
  fclose(fp); 
 }
return 0 ;
}

b) Drugi program odpalony jest z uprawnieniami administratora i może wszystko. Ten program pobiera dane z pliku TXT, uruchamia magistrale SPI i wysyła dane na poszczególne diody i przekaźniki. W ten sposób mamy rozdzielność skryptów CGI i programów wykonywalnych.

Program który pobiera dane z pliku txt i zapala diody wygląda następująco:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include "pifacedigital.h"
#include "mcp23s17.h"
 
int main( int argc, char *argv[] )
{
uint8_t i = 0;     /**< Loop iterator */
uint8_t inputs;    /**< Input bits (pins 0-7) */
int hw_addr = 0;   /**< PiFaceDigital hardware address  */
char path [50]="";
strcat (path,"/var/www/IQhome/strona/ramdisk/test.txt");
FILE *fd;
int spr=0;
 
for(;;){
//jest on wykonywany w kolko wiec warto uspic go na kilka sekund
sleep(3);
char bufor [15]="";
char tempX[2]="";
int x=0;
fd = fopen(path,"r");
 
if(!fd){
printf("blad przy otwieraniu");
return -1;
}else {
  if(!fgets(bufor,14,fd)){
  }else{
printf("bufor to %s\n",bufor);
 for(i=0;i<14;i++){
  if(bufor[i]=='='){
    tempX[0]=bufor[i+1];
  tempX[1]=bufor[i+2];
  tempX[2]=bufor[i+3];
  }
 }
  x=atoi(tempX);
  } 
 }
if (argc > 1) {
hw_addr = atoi(argv[1]);
}
// printf("Otwieramy polaczenie piface digital w lokacji %d\n", hw_addr);
pifacedigital_open(hw_addr);
 if(spr!=x){
spr = x;
printf("Ustawiamy outputs %d\n",x);
pifacedigital_write_reg(x, OUTPUT, hw_addr);
} 
pifacedigital_close(hw_addr);
fclose(fd);
}
}

Jak widać w programie jest pętla nieskończona, która w kółko pobiera dane z pliku. Jest to mało eleganckie, ale na poziomie technikum wystarczające. Dodanie zdarzeń strasznie zaciemniłoby kod.

Program jest modyfikacją programu na PiFace Digital ze strony:

http://avrkwiat.nstrefa.pl/omnie/index.php?option=com_content&view=article&id=235&Itemid=263

Całość można pobrać tu:

Są to najważniejsze elementy tego domu. Aby to wszystko było w pełni zautomatyzowane, należałoby uruchomić to wszystko przy starcie systemu. Czyli wystarczy dodać odpowiednie komendy w pliku /etc/rc.local