Jump to content

Домашна автоматизация


SS7

Recommended Posts

  • Owner

Отварям темата, за не погубя идеите и написания сорс.

Всичко започна с това - http://www.olimex.co...-OLinuXino-WIFI .

Готина играчка с Android и линукс (по избор)

Дълго мислих какви термодатчици (и не само - т.е. избирах протокол по който да си говорят много неща разхвърляни по къщата) .

Спрях се на 1-wire .

http://store.comet.b...e/Product/3840/ - 1-wire usb interface

http://store.comet.b.../Product/28993/ - 1-wire датчици

http://store.comet.b...duct/9220/ - 1-wire 2xswitch

http://store.comet.b...Product/4334/ - solid state relay

http://owfs.org/ - 1-wire filesystem

След малко игра с поялника (особено с DS2413) се получи това :

post-2-0-35391300-1357060846_thumb.jpg

1- wire FS :


root@debian:~/termocon# ls /1-wire
10.45C48F020800 10.6CDE8F020800 3A.EA390D000000 alarm settings statistics system
10.66D18F020800 10.BEDA8F020800 81.C4E931000000 bus.0 simultaneous structure uncached
root@debian:~/termocon#
root@debian:~/termocon#
root@debian:~/termocon#
[/CODE] crontab :
[CODE]
*/5 * * * * /usr/lib/cgi-bin/log_temp3 > /var/www/temp.html
log_temp3 :

#!/usr/bin/perl -w
use RRDp;
$rrd= "/usr/lib/cgi-bin/digitemp.rrd";
# Diagnostic output
$koridor= &getvar("/1-wire/10.6CDE8F020800/temperature");
$bedroom= &getvar("/1-wire/10.66D18F020800/temperature");
$bedroom2= &getvar("/1-wire/10.BEDA8F020800/temperature");
$outdoor= &getvar("/1-wire/10.45C48F020800/temperature");
print "Koridor : ",$koridor,"\n";
print "Bedroom : ",$bedroom,"\n";
print "Bedroom2 : ",$bedroom2,"\n";
print "Outdoor : ", $outdoor,"\n";
#echo "Content-type: text/html"
#echo "<br><br>"
#echo '<html><body>'
#echo 'koridor : ' $koridor
#echo '<br>'
#echo 'bedroom : ' $bedroom
#echo '<br>'
#echo 'bedroom2 : ' $bedroom2
#echo '<br>'
#echo 'outdoor : ' $outdoor
#echo '</body></html>'
# Update the database
RRDp::start "/usr/bin/rrdtool";
RRDp::cmd "update $rrd N:$koridor:$bedroom:$bedroom2:$outdoor";
#$answer=RRDp::read;
RRDp::end;
# create pnp
$starttime = "-1d";
$endtime = time;
$width = "600";
$height = "200";
# $label="";
RRDp::start "/usr/bin/rrdtool";
RRDp::cmd "graphv /var/www/temp.png --imgformat PNG",
"--start '$starttime' --end '$endtime'",
"--width $width --height $height",
"DEF:kor_c=$rrd:koridor:AVERAGE",
"DEF:bed_c=$rrd:bedroom:AVERAGE",
"DEF:bed2_c=$rrd:bedroom2:AVERAGE",
"DEF:outdoor_c=$rrd:outdoor:AVERAGE",
"LINE1:kor_c#00FF00:'Koridor\\t'",
"GPRINT:kor_c:LAST:'Last %5.1lf'",
"GPRINT:kor_c:MIN:'Min %5.1lf'",
"GPRINT:kor_c:MAX:'Max %5.1lf\\n'",
"LINE1:bed_c#FF0000:'Bedroom\\t'",
"GPRINT:bed_c:LAST:'Last %5.1lf'",
"GPRINT:bed_c:MIN:'Min %5.1lf'",
"GPRINT:bed_c:MAX:'Max %5.1lf%s\\n'",
"LINE1:bed2_c#0000FF:'Bedroom2\\t'",
"GPRINT:bed2_c:LAST:'Last %5.1lf'",
"GPRINT:bed2_c:MIN:'Min %5.1lf'",
"GPRINT:bed2_c:MAX:'Max %5.1lf\\n'",
"LINE1:outdoor_c#005555:'Outdoor\\t'",
"GPRINT:outdoor_c:LAST:'Last %5.1lf'",
"GPRINT:outdoor_c:MIN:'Min %5.1lf'",
"GPRINT:outdoor_c:MAX:'Max %5.1lf\\n'" ;
$answer=RRDp::read;
print $answer;
$starttime = "-1w";
RRDp::cmd "graphv /var/www/temp_w.png --imgformat PNG",
"--start '$starttime' --end '$endtime'",
"--width $width --height $height",
"DEF:kor_c=$rrd:koridor:AVERAGE",
"DEF:attic_c=$rrd:bedroom:AVERAGE",
"DEF:desk_c=$rrd:bedroom2:AVERAGE",
"DEF:outdoor_c=$rrd:outdoor:AVERAGE",
"LINE1:kor_c#00FF00:'Koridor\\t'",
"GPRINT:kor_c:LAST:'Last %5.1lf'",
"GPRINT:kor_c:MIN:'Min %5.1lf'",
"GPRINT:kor_c:MAX:'Max %5.1lf\\n'",
"LINE1:attic_c#FF0000:'Bedroom\\t'",
"GPRINT:attic_c:LAST:'Last %5.1lf'",
"GPRINT:attic_c:MIN:'Min %5.1lf'",
"GPRINT:attic_c:MAX:'Max %5.1lf%s\\n'",
"LINE1:desk_c#0000FF:'Bedroom2\\t'",
"GPRINT:desk_c:LAST:'Last %5.1lf'",
"GPRINT:desk_c:MIN:'Min %5.1lf'",
"GPRINT:desk_c:MAX:'Max %5.1lf\\n'",
"LINE1:outdoor_c#005555:'Outdoor\\t'",
"GPRINT:outdoor_c:LAST:'Last %5.1lf'",
"GPRINT:outdoor_c:MIN:'Min %5.1lf'",
"GPRINT:outdoor_c:MAX:'Max %5.1lf\\n'" ;
$answer=RRDp::read;
print $answer;
$starttime = "-1m";
RRDp::cmd "graphv /var/www/temp_m.png --imgformat PNG",
"--start '$starttime' --end '$endtime'",
"--width $width --height $height",
"DEF:kor_c=$rrd:koridor:AVERAGE",
"DEF:attic_c=$rrd:bedroom:AVERAGE",
"DEF:desk_c=$rrd:bedroom2:AVERAGE",
"DEF:outdoor_c=$rrd:outdoor:AVERAGE",
"LINE1:kor_c#00FF00:'Koridor\\t'",
"GPRINT:kor_c:LAST:'Last %5.1lf'",
"GPRINT:kor_c:MIN:'Min %5.1lf'",
"GPRINT:kor_c:MAX:'Max %5.1lf\\n'",
"LINE1:attic_c#FF0000:'Bedroom\\t'",
"GPRINT:attic_c:LAST:'Last %5.1lf'",
"GPRINT:attic_c:MIN:'Min %5.1lf'",
"GPRINT:attic_c:MAX:'Max %5.1lf%s\\n'",
"LINE1:desk_c#0000FF:'Bedroom2\\t'",
"GPRINT:desk_c:LAST:'Last %5.1lf'",
"GPRINT:desk_c:MIN:'Min %5.1lf'",
"GPRINT:desk_c:MAX:'Max %5.1lf\\n'",
"LINE1:outdoor_c#005555:'Outdoor\\t'",
"GPRINT:outdoor_c:LAST:'Last %5.1lf'",
"GPRINT:outdoor_c:MIN:'Min %5.1lf'",
"GPRINT:outdoor_c:MAX:'Max %5.1lf\\n'" ;
RRDp::end;
#/usr/bin/rrdtool update /usr/lib/cgi-bin/digitemp.rrd N:$koridor:$bedroom:$bedroom2:$outdoor
#/usr/lib/cgi-bin/temp-all.cgi2 > /dev/null
sub getvar {
open(FILE, $_[0]);
$filevalue = <FILE>;
close(FILE);
$filevalue = $filevalue + 0;
}

[/code] резултат : post-2-0-38699300-1357061377_thumb.jpg Тъй като ще управлявам електрически и водни подови отопления (които са безумно интертни) , единствения разумен начин е с PID контолер. Днес драснах набързо PWM регулаторите :
[CODE]
#include <stdio.h>
void pwm (int,int,int,int );
main ()
{
while (1)
{
pwm (50, 80, 20, 0);
}
}
void pwm (int pw1, int pw2,int pw3,int pw4)
{
int out1=0;
int out2=0;
int out3=0;
int out4=0;
int i = 100 ;
FILE *fp;
// set all outputs to 0;
fp=fopen("/1-wire/3A.EA390D000000/PIO.ALL", "w");
fprintf (fp,"%i,%i",out1,out2);
fclose(fp);

while (i)
{
if ( i == pw1)
{
// set output_1 to 1
out1 =1;
fp=fopen("/1-wire/3A.EA390D000000/PIO.A", "w");
fprintf (fp,"%i",out1);
fclose(fp);
}
if ( i == pw2)
{
out2 =1;
fp=fopen("/1-wire/3A.EA390D000000/PIO.B", "w");
fprintf (fp,"%i",out2);
fclose(fp);
}
if ( i == pw3)
{
out3 =1;
}
if ( i == pw4)
{
out4 =1;
}
printf ("cycle: %i out1: %i out2: %i out3: %i out4: %i\n", i,out1 , out2, out3, out4 );
i--;
//wait time
sleep (1);
}
}

Link to comment
Share on other sites

Браво, идеална играчка и аз си мисля за същото ще може ли да пуснеш повече ИНФО или, директно да го направиш за пари???

Link to comment
Share on other sites

  • Owner

Ще пиша тук , едва в началото съм. Следва кода на PID контролера (най-елементарния за начало)

Навремето работех във фирма, която искаше да се занимава с подобни работи , ама тя фалира поради липса на достатъчно пазар. Удоволствието е скъпичко за съжаление , па ако се сметнат и разходите за висококвалициран труд - става безумно скъпо.

Link to comment
Share on other sites

Ще пиша тук , едва в началото съм. Следва кода на PID контролера (най-елементарния за начало)

Навремето работех във фирма, която искаше да се занимава с подобни работи , ама тя фалира поради липса на достатъчно пазар. Удоволствието е скъпичко за съжаление , па ако се сметнат и разходите за висококвалициран труд - става безумно скъпо.

Аз ще си го напиша, и отново браво за темата

Link to comment
Share on other sites

  • Owner

Набързо парче код за четене на температурите :


struct _pid {
float pv; /* process value*/
float sp; /*set point*/
float integral;
float pgain;
float igain;
float dgain;
int deadband;
int last_error;
int output;
};
void read_temps( _pid,_pid,_pid,_pid );
void read_temps( struct _pid *a,struct _pid *b,struct _pid *c,struct _pid *d )
{
FILE *fp ;
int err;
fp=fopen("/1-wire/10.66D18F020800/temperature", "r"); ///et2. big one
err=fscanf(fp,"%f", &(a->pv) );
//printf ("error: %i , temp_inside: %2.2f\n",err,a->pv);
fclose(fp);
fp=fopen("/1-wire/10.BEDA8F020800/temperature", "r"); ///et2. big one
err=fscanf(fp,"%f", &(b->pv) );
//printf ("error: %i , temp_inside: %2.2f\n",err,b->pv);
fclose(fp);
}
[/CODE] Основния цикъл ще се върти в main () :
[CODE]
main ()
{
struct _pid room1 , room2 , room3, room4;
while (1)
{
// read set points

// read temps
read_temps( &room1, &room2, &room3, &room4 );
printf("temp1: %f temp2: %f\n",room1.pv,room2.pv);
// calc PID outputs

// send to PWM
pwm (room1.output, room2.output, 20, 0);
}
}

Link to comment
Share on other sites

и аз напоследък през свободното време автоматизирам разни работи из дома но съм се спрял на ардуино с атмега 328. но и това за тези пари е с пъти повече възможности

Link to comment
Share on other sites

  • 2 months later...

Готина тема. На SS7 съм му следил блога още преди години :)

Аз също се занимавам с домашна автоматизация, засега само като хоби. Бих искал да вметна някои неща, а и да насоча интересуващите се към малко полезно инфо по въпроса. OLinuXino е много готино компютърче, но няма Ethernet, а и лично на мен ми идва малко скъпо вече, при наличието на Raspberry Pi, CubieBoard или пък този 4 ядрен змей - ODROID-U.

Освен това, има много готини опън сорс Home Automation софтуери, които абстрактват protocol-related неща от сорта на owfs за 1-wire пирмерно. Аз съм contributor в един такъв софтуер, наречен openHAB. Но има и много други - OpenRemote, Domotiga, smarthome.py, Domogik, ветерана MisterHouse и много други.

Успех с начинанието! :)

Link to comment
Share on other sites

  • 5 years later...

Здравейте,

да придвижим темата малко по напред в настоящето. :)

Предполагам вече има доста колеги, които има какво да споделят.

Търся идеи и "know-how" за датчици свързани с кабели.
Идеята за всичко по безжичен път не ми харесва, а на пазара общо взето безжичните решения доминират.

Коя платформа би била най универсална и в същото време лесна за конфигурация и работа.

Поздрави

Link to comment
Share on other sites

Цитат

Търся идеи и "know-how" за датчици свързани с кабели.
Идеята за всичко по безжичен път не ми харесва, а на пазара общо взето безжичните решения доминират.

Коя платформа би била най универсална и в същото време лесна за конфигурация и работа.

Работещо DIY решение е:

1. RPi 3 - централен хъб с Hasbian и фронтенд Home Assistant, Domoticz или подобни

2. ESP8266 или ESP32 за отдалечените датчици и управления

3. Датчици дал господ.

Ако държиш всичко да е окабелено, можеш да минеш и само с RPi. Има достатъчно входове и изходи да вържеш каквото се сетиш.

Ако пък си минималист, може да минеш и само с едно Arduino и Ethernet Shield или едно ESP8266. ESP-то има 11 използваеми пина на които може да закачиш нещо. Да не споменаваме че има и OneWire датчици в изобилие.

За визуализация и анализ може да ползваш пакети инсталирани на RPi-то ( Grafana, EmonCMS ) или външни такива ( thingspeak.com ).

Link to comment
Share on other sites

преди 32 минути, master написа:

Да, това го знам но за жалост избора е много малък да не казвам, че няма.

Погледни пак в линка. Има PRODUCT TREE. ?

Евтини са обаче основно температурните. Щото китайците масово ги произвеждат. Дори и само те да са пак е предимство на OneWire да си закачиш осем температурни сензора на един пин. В домашната автоматизация температурата е най-често следеният параметър.

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.