Home Automation

Home Automation has been a popular term over the last years, i have read a lot about this and wanted to try things out.

When I didn’t find an open and configurable system I decided to build one on my own.

The design criteria of the system was
  1. Independent of platform
  2. Support the used of a single database with no needs of synchronization between platforms
  3. Support Dallas one-wire devices
  4. Simple and fast
  5. Web enabled GUI
  6. Open and configurable

Control program was build in Perl. Database access was enabled via a HTTP interface, thus supporting both Perl application and future consumers (see PHP - DB Adapter) All variables and constants was maintained in a excel sheet and copied to the Perl program to minimize spelling errors. By using excel it is also possible to generate variables and constants to other programming langauges as e.g. Arduino (see listing in Arduino - NEXA Transm.)

The I/O for the system was built by using sensors and relays on a one-wire bus (see Linux - OWFS)

Overview of GUI Mobile version

Overview of GUI Full version



Perl Program (has been around for more than five years now…)

    1: #####################################################################################
    2: #Change log
    3: #####################################################################################
    4: #2008-06-18
    5: #Added so that temperature value is sent to temperatur.nu automatically
    6: # URL used is 'http://www.temperatur.nu/report/puttemp.php?s=ramlosa&id=<hiddenvalue>&t=<value>
    7: #2008-07-12
    8: #Changed from USB card to OW for output and input
    9: #URL changed so that is uses .../ha/... instead of .../ha_2/...
   10: #2008-09-23
   11: #Added path to real IO board, to be tested
   12: #2009-03-23
   13: #Added so that IO is reet once every hour, to prevent overheating
   14: #2009-11-14
   15: #Added so that IO reset is run every minute
   16: #2011-02-26
   17: #Added support for power meter
   18: #2013-11-11
   19: #Added support for RF (NEXA)
   20: #2013-12-01
   21: #Deleted data type from setValue method
   22: #2013-12-13
   23: #Added paratmeter for old light switch
   24: #
   25: #!usr/bin/perl
   26:
   27: #pragma
   28: use strict;
   29: #use warnings;
   30: use LWP::Simple;
   31: use OW;
   32:
   33: #####################################################################################Insert from Const from EXCEL
   34: #Declare generic constants
   35: #Declare generic constants
   36: my $ha_ow_config = '/dev/ttyS3';
   37: my $ha_url_setvalue = 'http://localhost/ha/setvalue.php?A_N=_name_&A_V=_value_';
   38: my $ha_url_getvalue = 'http://localhost/ha/getvalue.php?A_N=_name_';
   39: my $ha_url_log = 'http://localhost/ha/log.php?L_N=_name_&L_V=_value_&L_T=_type_';
   40: my $ha_ow_temp_outdoor_sensor = '10.ED3F02010800';
   41: my $ha_ow_temp_indoor_sensor = '10.BD727C010800';
   42: my $ha_ow_temp_heater_return_sensor = '10.26737C010800';
   43: my $ha_ow_energy_electrical_counter = '1D.AFBD0D000000';
   44: my $ha_ow_valve_actuator_open = '20.xxx';
   45: my $ha_ow_valve_actuator_close = '20.yyy';
   46: my $ha_ow_running = '10.xxx';
   47:
   48:
   49: #Declare generic constants
   50: my $ha_ow_temp_outdoor_c = 'HA.OW.TEMP.OUTDOOR';
   51: my $ha_ow_temp_indoor_c = 'HA.OW.TEMP.INDOOR';
   52: my $ha_ow_heater_return_c = 'HA.OW.HEATER.RETURN';
   53:
   54: my $ha_running_c = 'HA.RUNNING';
   55:
   56: my $ha_heater_return_setpoint_c = 'HA.HEATER.RETURN.SETPOINT';
   57: my $ha_heater_constant_high_k_c = 'HA.HEATER.CONSTANT.HIGH.K';
   58: my $ha_heater_constant_high_t_c = 'HA.HEATER.CONSTANT.HIGH.T';
   59: my $ha_heater_constant_low_k_c = 'HA.HEATER.CONSTANT.LOW.K';
   60: my $ha_heater_constant_low_t_c = 'HA.HEATER.CONSTANT.LOW.T';
   61:
   62: my $ha_room_setpoint_active_c = 'HA.ROOM.SETPOINT.ACTIVE';
   63: my $ha_room_setpoint_default_c = 'HA.ROOM.SETPOINT.DEFAULT';
   64: my $ha_room_setpoint_reduced_c = 'HA.ROOM.SETPOINT.REDUCED';
   65: my $ha_room_setpoint_reduced_hours_c = 'HA.ROOM.SETPOINT.REDUCED.HOURS';
   66: my $ha_room_setpoint_reduced_active_c = 'HA.ROOM.SETPOINT.REDUCED.ACTIVE';
   67: my $ha_room_setpoint_reduced_weekdays_c = 'HA.ROOM.SETPOINT.REDUCED.WEEKDAYS';
   68: my $ha_room_setpoint_reduced_forced_c = 'HA.ROOM.SETPOINT.REDUCED.FORCED';
   69:
   70: my $ha_startup_date_c = 'HA.STARTUP.DATE';
   71:
   72: #my $ha_light_status_forced_c = 'HA.LIGHT.STATUS.FORCED';
   73: #my $ha_light_forced_c = 'HA.LIGHT.FORCED';
   74: #my $ha_light_status_c = 'HA.LIGHT.STATUS';
   75: #my $ha_light_on_hours_c = 'HA.LIGHT.ON.HOURS';
   76:
   77: my $ha_ow_energy_electrical_last_hour_c = 'HA.OW.ENERGY.ELECTRICAL.LAST.HOUR';
   78: my $ha_ow_energy_electrical_last_counter_c = 'HA.OW.ENERGY.ELECTRICAL.LAST.COUNTER';
   79:
   80: my $ha_rf_switch_1_isdirty_c = 'HA.RF.SWITCH.1.ISDIRTY';
   81: my $ha_rf_switch_1_on_c = 'HA.RF.SWITCH.1.ON';
   82: my $ha_rf_switch_1_off_c = 'HA.RF.SWITCH.1.OFF';
   83: my $ha_rf_switch_1_status_c = 'HA.RF.SWITCH.1.STATUS';
   84: my $ha_rf_switch_2_isdirty_c = 'HA.RF.SWITCH.2.ISDIRTY';
   85: my $ha_rf_switch_2_off_c = 'HA.RF.SWITCH.2.OFF';
   86: my $ha_rf_switch_2_on_c = 'HA.RF.SWITCH.2.ON';
   87: my $ha_rf_switch_2_status_c = 'HA.RF.SWITCH.2.STATUS';
   88: my $ha_rf_switch_3_isdirty_c = 'HA.RF.SWITCH.3.ISDIRTY';
   89: my $ha_rf_switch_3_off_c = 'HA.RF.SWITCH.3.OFF';
   90: my $ha_rf_switch_3_on_c = 'HA.RF.SWITCH.3.ON';
   91: my $ha_rf_switch_3_status_c = 'HA.RF.SWITCH.3.STATUS';
   92: my $ha_rf_switch_4_isdirty_c = 'HA.RF.SWITCH.4.ISDIRTY';
   93: my $ha_rf_switch_4_off_c = 'HA.RF.SWITCH.4.OFF';
   94: my $ha_rf_switch_4_on_c = 'HA.RF.SWITCH.4.ON';
   95: my $ha_rf_switch_4_status_c = 'HA.RF.SWITCH.4.STATUS';
   96: my $ha_rf_switch_5_isdirty_c = 'HA.RF.SWITCH.5.ISDIRTY';
   97: my $ha_rf_switch_5_off_c = 'HA.RF.SWITCH.5.OFF';
   98: my $ha_rf_switch_5_on_c = 'HA.RF.SWITCH.5.ON';
   99: my $ha_rf_switch_5_status_c = 'HA.RF.SWITCH.5.STATUS';
  100: my $ha_rf_switch_a_isdirty_c = 'HA.RF.SWITCH.A.ISDIRTY';
  101: my $ha_rf_switch_a_id_c = 'HA.RF.SWITCH.A.ID';
  102: my $ha_rf_switch_a_off_c = 'HA.RF.SWITCH.A.OFF';
  103: my $ha_rf_switch_a_on_c = 'HA.RF.SWITCH.A.ON';
  104: my $ha_rf_switch_a_status_c = 'HA.RF.SWITCH.A.STATUS';
  105: my $ha_rf_switch_b_isdirty_c = 'HA.RF.SWITCH.B.ISDIRTY';
  106: my $ha_rf_switch_b_id_c = 'HA.RF.SWITCH.B.ID';
  107: my $ha_rf_switch_b_off_c = 'HA.RF.SWITCH.B.OFF';
  108: my $ha_rf_switch_b_on_c = 'HA.RF.SWITCH.B.ON';
  109: my $ha_rf_switch_b_status_c = 'HA.RF.SWITCH.B.STATUS';
  110: #####################################################################################End Const EXCEL
  111:
  112: #####################################################################################Insert Vars from EXCEL
  113: my $ha_ow_temp_outdoor = 0;
  114: my $ha_ow_temp_indoor = 0;
  115: my $ha_ow_heater_return = 0;
  116:
  117: my $ha_running = 0;
  118:
  119: my $ha_heater_return_setpoint = 0;
  120: my $ha_heater_constant_high_k = 0;
  121: my $ha_heater_constant_high_t = 0;
  122: my $ha_heater_constant_low_k = 0;
  123: my $ha_heater_constant_low_t = 0;
  124:
  125: my $ha_room_setpoint_active = 20;
  126: my $ha_room_setpoint_default = 20;
  127: my $ha_room_setpoint_reduced = 20;
  128: my $ha_room_setpoint_reduced_hours = 0;
  129: my $ha_room_setpoint_reduced_active = 0;
  130: my $ha_room_setpoint_reduced_weekdays = 0;
  131: my $ha_room_setpoint_reduced_forced = 0;
  132:
  133: my $ha_startup_date = localtime;
  134:
  135: #my $ha_light_status_forced = 0;
  136: #my $ha_light_forced = 0;
  137: #my $ha_light_status = 0;
  138: #my $ha_light_on_hours = 0;
  139:
  140: my $ha_ow_energy_electrical_last_hour = 0;
  141: my $ha_ow_energy_electrical_last_counter = 0;
  142:
  143: my $ha_rf_switch_1_on = 0;
  144: my $ha_rf_switch_1_off = 0;
  145: my $ha_rf_switch_1_status = 0;
  146: my $ha_rf_switch_2_off = 0;
  147: my $ha_rf_switch_2_on = 0;
  148: my $ha_rf_switch_2_status = 0;
  149: my $ha_rf_switch_3_off = 0;
  150: my $ha_rf_switch_3_on = 0;
  151: my $ha_rf_switch_3_status = 0;
  152: my $ha_rf_switch_4_off = 0;
  153: my $ha_rf_switch_4_on = 0;
  154: my $ha_rf_switch_4_status = 0;
  155: my $ha_rf_switch_5_off = 0;
  156: my $ha_rf_switch_5_on = 0;
  157: my $ha_rf_switch_5_status = 0;
  158: my $ha_rf_switch_a_isdirty = 0;
  159: my $ha_rf_switch_a_id = 0;
  160: my $ha_rf_switch_a_off = 0;
  161: my $ha_rf_switch_a_on = 0;
  162: my $ha_rf_switch_a_status = 0;
  163: my $ha_rf_switch_b_isdirty = 0;
  164: my $ha_rf_switch_b_id = 0;
  165: my $ha_rf_switch_b_off = 0;
  166: my $ha_rf_switch_b_on = 0;
  167: my $ha_rf_switch_b_status = 0;
  168: #####################################################################################End Vars EXCEL
  169:
  170: #Declare program specific variables
  171: my @now = -1;
  172: my $counterheating = 0;
  173: my $lastsec = -1;
  174: my $lastmin = -1;
  175: my $lasthour = -1;
  176: my $minute;
  177: my $hour;
  178: my $currtime;
  179:
  180: #Init OWFS
  181: OW::init("4304");
  182:
  183: #Init variables
  184: &db_read;
  185:
  186: #Store startup time stamp
  187: &setvalue($ha_startup_date_c, localtime);
  188:
  189: while () {
  190:         #Allow other processes to execute
  191:         sleep(2);
  192:         @now = localtime;
  193:
  194:         #Second task
  195:         if ($now[0] != $lastsec) {
  196:                 $lastsec = $now[0];
  197:         }
  198:
  199:         #Minute task
  200:         if ($now[1] != $lastmin) {
  201:                 &do_light;
  202:
  203:                 $lastmin = $now[1];
  204:                 $counterheating--;
  205:
  206:                 if ($counterheating <= 0) {
  207:                         &ow_read;
  208:                         &do_heating;
  209:                         &db_write;
  210:             &resetio;
  211:                 }
  212:
  213:                 #Check if even five minutes
  214:                 if ((sprintf ("%02d",$now[1]) eq "00") ||
  215:                         (sprintf ("%02d",$now[1]) eq "05") ||
  216:                         (sprintf ("%02d",$now[1]) eq "10") ||
  217:                         (sprintf ("%02d",$now[1]) eq "15") ||
  218:                         (sprintf ("%02d",$now[1]) eq "20") ||
  219:                         (sprintf ("%02d",$now[1]) eq "25") ||
  220:                         (sprintf ("%02d",$now[1]) eq "30") ||
  221:                         (sprintf ("%02d",$now[1]) eq "35") ||
  222:                         (sprintf ("%02d",$now[1]) eq "40") ||
  223:                         (sprintf ("%02d",$now[1]) eq "45") ||
  224:                         (sprintf ("%02d",$now[1]) eq "50") ||
  225:                         (sprintf ("%02d",$now[1]) eq "55")) {
  226:
  227:                         #Store current timestamp
  228:                         $currtime = sprintf ("%02d",$now[2]) . ":" . sprintf ("%02d",$now[1]);
  229:                
  230:                         #Determine status for RF switch 1
  231:                         if ($ha_rf_switch_1_on eq $currtime){
  232:                                 #Set switch On
  233:                                 &setvalue($ha_rf_switch_1_status_c, "1");
  234:                                 &setvalue($ha_rf_switch_1_isdirty_c, "1");
  235:                                 &writelog($ha_rf_switch_1_status_c, "double", "1");
  236:                         }
  237:                         if ($ha_rf_switch_1_off eq $currtime){
  238:                                 #Set switch Off
  239:                                 &setvalue($ha_rf_switch_1_status_c, "0");
  240:                                 &setvalue($ha_rf_switch_1_isdirty_c, "1");
  241:                                 &writelog($ha_rf_switch_1_status_c, "double", "0");
  242:                         }
  243:                
  244:                         #Determine status for RF switch 2
  245:                         if ($ha_rf_switch_2_on eq $currtime){
  246:                                 #Set switch On
  247:                                 &setvalue($ha_rf_switch_2_status_c, "1");
  248:                                 &setvalue($ha_rf_switch_2_isdirty_c, "1");
  249:                                 &writelog($ha_rf_switch_2_status_c, "double", "1");
  250:                         }
  251:                         if ($ha_rf_switch_2_off eq $currtime){
  252:                                 #Set switch Off
  253:                                 &setvalue($ha_rf_switch_2_status_c, "0");
  254:                                 &setvalue($ha_rf_switch_2_isdirty_c, "1");
  255:                                 &writelog($ha_rf_switch_2_status_c, "double", "0");
  256:                         }
  257:                
  258:                         #Determine status for RF switch 3
  259:                         if ($ha_rf_switch_3_on eq $currtime){
  260:                                 #Set switch On
  261:                                 &setvalue($ha_rf_switch_3_status_c, "1");
  262:                                 &setvalue($ha_rf_switch_3_isdirty_c, "1");
  263:                                 &writelog($ha_rf_switch_3_status_c, "double", "1");
  264:                         }
  265:                         if ($ha_rf_switch_3_off eq $currtime){
  266:                                 #Set switch Off
  267:                                 &setvalue($ha_rf_switch_3_status_c, "0");
  268:                                 &setvalue($ha_rf_switch_3_isdirty_c, "1");
  269:                                 &writelog($ha_rf_switch_3_status_c, "double", "0");
  270:                         }
  271:                
  272:                         #Determine status for RF switch 4
  273:                         if ($ha_rf_switch_4_on eq $currtime){
  274:                                 #Set switch On
  275:                                 &setvalue($ha_rf_switch_4_status_c, "1");
  276:                                 &setvalue($ha_rf_switch_4_isdirty_c, "1");
  277:                                 &writelog($ha_rf_switch_4_status_c, "double", "1");
  278:                         }
  279:                         if ($ha_rf_switch_4_off eq $currtime){
  280:                                 #Set switch Off
  281:                                 &setvalue($ha_rf_switch_4_status_c, "0");
  282:                                 &setvalue($ha_rf_switch_4_isdirty_c, "1");
  283:                                 &writelog($ha_rf_switch_4_status_c, "double", "0");
  284:                         }
  285:                
  286:                         #Determine status for RF switch 5
  287:                         if ($ha_rf_switch_5_on eq $currtime){
  288:                                 #Set switch On
  289:                                 &setvalue($ha_rf_switch_5_status_c, "1");
  290:                                 &setvalue($ha_rf_switch_5_isdirty_c, "1");
  291:                                 &writelog($ha_rf_switch_5_status_c, "double", "1");
  292:                         }
  293:                         if ($ha_rf_switch_5_off eq $currtime){
  294:                                 #Set switch Off
  295:                                 &setvalue($ha_rf_switch_5_status_c, "0");
  296:                                 &setvalue($ha_rf_switch_5_isdirty_c, "1");
  297:                                 &writelog($ha_rf_switch_5_status_c, "double", "0");
  298:                         }
  299:
  300:                         #Determine status for switch A
  301:                         if ($ha_rf_switch_a_on eq $currtime){
  302:                                 #Set switch On
  303:                                 &setvalue($ha_rf_switch_a_status_c, "1");
  304:                                 &setvalue($ha_rf_switch_a_isdirty_c, "1");
  305:                                 &writelog($ha_rf_switch_a_status_c, "double", "1");
  306:                         }
  307:                         if ($ha_rf_switch_a_off eq $currtime){
  308:                                 #Set switch Off
  309:                                 &setvalue($ha_rf_switch_a_status_c, "0");
  310:                                 &setvalue($ha_rf_switch_a_isdirty_c, "1");
  311:                                 &writelog($ha_rf_switch_a_status_c, "double", "0");
  312:                         }
  313:                         #Determine status for switch B
  314:                         if ($ha_rf_switch_b_on eq $currtime){
  315:                                 #Set switch On
  316:                                 &setvalue($ha_rf_switch_b_status_c, "1");
  317:                                 &setvalue($ha_rf_switch_b_isdirty_c, "1");
  318:                                 &writelog($ha_rf_switch_b_status_c, "double", "1");
  319:                         }
  320:                         if ($ha_rf_switch_b_off eq $currtime){
  321:                                 #Set switch Off
  322:                                 &setvalue($ha_rf_switch_b_status_c, "0");
  323:                                 &setvalue($ha_rf_switch_b_isdirty_c, "1");
  324:                                 &writelog($ha_rf_switch_b_status_c, "double", "0");
  325:                         }
  326:                 }
  327:         }
  328:        
  329:         #Hour task
  330:         if ($now[2] != $lasthour) {
  331:                 $lasthour = $now[2];
  332:                 &calcenergy;
  333:                 &db_read;
  334:                 &db_writelog;
  335:                 &do_running;
  336:         }
  337:        
  338: #       exit 0;
  339: }
  340:
  341: sub do_running
  342: {
  343:         #Toggle running var in DB
  344:         if ($ha_running == 1) {
  345:                 $ha_running = 0;
  346:         }
  347:         else {
  348:                 $ha_running = 1;
  349:         }
  350:         &setvalue($ha_running_c, $ha_running);
  351:
  352: }
  353:
  354: ################################################################################################
  355: # Update and calc power consumption
  356: ################################################################################################
  357: sub calcenergy
  358: {
  359:         my $valuelast;
  360:         my $valuecurrent;
  361:         my $consumption;
  362:        
  363:         $valuecurrent = OW::get("/1D.AFBD0D000000/counters.A");
  364:         $valuecurrent =~ s/^\s+//;
  365:         $valuelast = &getvalue($ha_ow_energy_electrical_last_counter_c);
  366:         $consumption = ($valuecurrent - $valuelast) / 1000;
  367:        
  368:         &writelog($ha_ow_energy_electrical_last_hour_c, "double", $consumption);
  369:         &writelog($ha_ow_energy_electrical_last_counter_c, "double", $valuecurrent);
  370:         &setvalue($ha_ow_energy_electrical_last_hour_c, $consumption);
  371:         &setvalue($ha_ow_energy_electrical_last_counter_c, $valuecurrent);
  372: }
  373:
  374: ################################################################################################
  375: #Reset IO to avoid misstakes in regulation
  376: ################################################################################################
  377: sub resetio
  378: {
  379:         #Heating
  380:         OW::put("/uncached/05.5F7033000000/PIO", "0"); #Increase
  381:         OW::put("/uncached/05.617A33000000/PIO", "0"); #Decrease        
  382:         #Light switch
  383:         OW::put("/uncached/05.878033000000/PIO", "0"); #On
  384:         OW::put("/uncached/05.558833000000/PIO", "0"); #Off
  385: }
  386:
  387: ################################################################################################
  388: #Ligthing related subs
  389: ################################################################################################
  390: sub do_light
  391: {
  392:         #Check if to light up or shut down
  393:         if (&getvalue($ha_rf_switch_a_isdirty_c) eq "1"){
  394:                 if (&getvalue($ha_rf_switch_a_status_c) eq "1"){
  395:                         &lighton;
  396:                 } else {
  397:                         &lightoff;
  398:                 }
  399:                 &setvalue($ha_rf_switch_a_isdirty_c, "0");
  400:         }
  401:        
  402:         if (&getvalue($ha_rf_switch_b_isdirty_c) eq "1"){
  403:                 if (&getvalue($ha_rf_switch_b_status_c) eq "1"){
  404:                         &lighton;
  405:                 } else {
  406:                         &lightoff;
  407:                 }
  408:                 &setvalue($ha_rf_switch_b_isdirty_c, "0");
  409:         }
  410:        
  411:        
  412: #       #Get current data from DB
  413: #       $ha_light_status_forced = &getvalue($ha_light_status_forced_c);
  414: #       $ha_light_forced = &getvalue($ha_light_forced_c);
  415: #       $ha_light_status = &getvalue($ha_light_status_c);
  416: #       $ha_light_on_hours = &getvalue($ha_light_on_hours_c);
  417: #      
  418: #       #Check if current hour in var 'my $ha_light_on_hours;' in that case light up if not done
  419: #       if ($ha_light_forced eq "0") {
  420: #               if (index($ha_light_on_hours, ','.$now[2].',') > -1){
  421: #                       if ($ha_light_status eq "0"){
  422: #                               &lighton;
  423: #                       }
  424: #               }
  425: #      
  426: #               if (index($ha_light_on_hours, ','.$now[2].',') < 0){
  427: #                       if ($ha_light_status eq "1"){
  428: #                               &lightoff;
  429: #                       }
  430: #               }
  431: #       }
  432: #      
  433: #       if ($ha_light_forced eq "1") {
  434: #               if ($ha_light_status_forced eq "0"){
  435: #                       if ($ha_light_status eq "1"){
  436: #                               &lightoff;
  437: #                       }
  438: #               }
  439: #               if ($ha_light_status_forced eq "1"){
  440: #                       if ($ha_light_status eq "0"){
  441: #                               &lighton;
  442: #                       }
  443: #               }
  444: #              
  445: #       }
  446: }
  447:
  448: sub lighton
  449: {
  450: #       $ha_light_status = 1;
  451:         OW::put("/uncached/05.878033000000/PIO", "1");
  452:         sleep(2);
  453:         OW::put("/uncached/05.878033000000/PIO", "0");
  454:         sleep(2);
  455:         OW::put("/uncached/05.878033000000/PIO", "1");
  456:         sleep(2);
  457:         OW::put("/uncached/05.878033000000/PIO", "0");
  458:        
  459: #       &setvalue($ha_light_status_c, $ha_light_status);
  460: }
  461:
  462: sub lightoff
  463: {
  464: #       $ha_light_status = 0;
  465:         OW::put("/uncached/05.558833000000/PIO", "1");
  466:         sleep(2);
  467:         OW::put("/uncached/05.558833000000/PIO", "0");
  468:         sleep(2);
  469:         OW::put("/uncached/05.558833000000/PIO", "1");
  470:         sleep(2);
  471:         OW::put("/uncached/05.558833000000/PIO", "0");
  472:        
  473: #       &setvalue($ha_light_status_c, $ha_light_status);
  474: }
  475:
  476: ################################################################################################
  477: #Heating related subs
  478: ################################################################################################
  479: sub do_heating
  480: {
  481:         #Do all activities for heating ($temp = (-0,6 * $ha_ow_temp_outdoor) + $t)
  482:         #$k = -0.6; #Base -0.6, if temp to low when outdoor below -5 => increase and vice versa
  483:         #$t = 34;   #Base 34, if temp to low when outdoor over +5 => increase and vice versa
  484:
  485:         #Calc forward temp based on outdoor temp
  486:         if ($ha_ow_temp_outdoor > 0){
  487:                 $ha_heater_return_setpoint = ($ha_heater_constant_high_k * $ha_ow_temp_outdoor) + $ha_heater_constant_high_t;
  488:         }
  489:         if ($ha_ow_temp_outdoor <= 0){
  490:                 $ha_heater_return_setpoint = ($ha_heater_constant_low_k * $ha_ow_temp_outdoor) + $ha_heater_constant_low_t;
  491:         }
  492:
  493:         #Calc new setpoint temp
  494:         $ha_room_setpoint_active = $ha_room_setpoint_default;
  495:         if (($ha_room_setpoint_reduced_active eq "1") || ($ha_room_setpoint_reduced_forced eq "1")){
  496:                 if (((index($ha_room_setpoint_reduced_weekdays, ','.$now[6].',') > -1) && (index($ha_room_setpoint_reduced_hours, ','.$now[2].',') > -1)) || ($ha_room_setpoint_reduced_forced == '1')){
  497:                         $ha_room_setpoint_active = $ha_room_setpoint_default + $ha_room_setpoint_reduced;
  498:                         $ha_heater_return_setpoint = $ha_heater_return_setpoint + $ha_room_setpoint_reduced;
  499:                 }
  500:         }
  501:
  502:
  503:         #Determine action based
  504:         if(($ha_ow_heater_return > $ha_heater_return_setpoint) || ($ha_ow_temp_indoor > $ha_room_setpoint_active)){
  505:                 #Lower temp
  506:                 $counterheating = 10;
  507:                 &decreasetemp;
  508:         }
  509:         if(($ha_ow_heater_return < $ha_heater_return_setpoint) && ($ha_ow_temp_indoor < $ha_room_setpoint_active)){
  510:                 #Increase temp
  511:                 $counterheating = 10;
  512:                 &increasetemp;
  513:                 if(($ha_ow_heater_return + 3) < $ha_heater_return_setpoint){
  514:                         $counterheating = 5;
  515:                 }
  516:         }
  517: }
  518:
  519: sub increasetemp
  520: {
  521:         OW::put("/uncached/05.5F7033000000/PIO", "1");
  522:         sleep(1);
  523:         OW::put("/uncached/05.5F7033000000/PIO", "0");
  524: }
  525:
  526: sub decreasetemp
  527: {
  528:         OW::put("/uncached/05.617A33000000/PIO", "1");
  529:         sleep(1);
  530:         OW::put("/uncached/05.617A33000000/PIO", "0");
  531: }
  532:
  533:
  534: ################################################################################################
  535: # OW Related
  536: ################################################################################################
  537: sub ow_read
  538: {
  539:         $ha_ow_heater_return = OW::get("/10.26737C010800/temperature");
  540:         $ha_ow_heater_return =~ s/^\s+//;
  541:         $ha_ow_temp_outdoor = OW::get("/10.ED3F02010800/temperature");
  542:         $ha_ow_temp_outdoor =~ s/^\s+//;
  543:         $ha_ow_temp_indoor = OW::get("/10.BD727C010800/temperature");
  544:         $ha_ow_temp_indoor =~ s/^\s+//;
  545: }
  546:
  547:
  548: ################################################################################################
  549: # Read/Write and Logging
  550: ################################################################################################
  551:
  552: sub db_write
  553: {
  554:         #Write data from variables to db
  555:         &setvalue($ha_ow_temp_outdoor_c, $ha_ow_temp_outdoor);
  556:         &setvalue($ha_ow_temp_indoor_c, $ha_ow_temp_indoor);    
  557:         &setvalue($ha_ow_heater_return_c, $ha_ow_heater_return);
  558:         &setvalue($ha_heater_return_setpoint_c, $ha_heater_return_setpoint);
  559:         &setvalue($ha_room_setpoint_active_c, $ha_room_setpoint_active);
  560:        
  561:         #Write to temperatur.nu
  562:         get 'http://www.temperatur.nu/report/puttemp.php?s=ramlosa&id=928347987&t='.$ha_ow_temp_outdoor;
  563: }
  564:
  565: sub db_read
  566: {
  567:         #Read data from db to variables
  568:         $ha_heater_constant_high_k = &getvalue($ha_heater_constant_high_k_c);
  569:         $ha_heater_constant_high_t = &getvalue($ha_heater_constant_high_t_c);
  570:         $ha_heater_constant_low_k = &getvalue($ha_heater_constant_low_k_c);
  571:         $ha_heater_constant_low_t = &getvalue($ha_heater_constant_low_t_c);
  572:
  573:         $ha_room_setpoint_default = &getvalue($ha_room_setpoint_default_c);
  574:         $ha_room_setpoint_reduced = &getvalue($ha_room_setpoint_reduced_c);
  575:         $ha_room_setpoint_reduced_hours = &getvalue($ha_room_setpoint_reduced_hours_c);
  576:         $ha_room_setpoint_reduced_active = &getvalue($ha_room_setpoint_reduced_active_c);
  577:         $ha_room_setpoint_reduced_weekdays = &getvalue($ha_room_setpoint_reduced_weekdays_c);
  578:         $ha_room_setpoint_reduced_forced = &getvalue($ha_room_setpoint_reduced_forced_c);
  579:        
  580:         $ha_rf_switch_1_status = &getvalue($ha_rf_switch_1_status_c);  
  581:         $ha_rf_switch_1_on = &getvalue($ha_rf_switch_1_on_c);
  582:         $ha_rf_switch_1_off = &getvalue($ha_rf_switch_1_off_c);
  583:         $ha_rf_switch_2_status = &getvalue($ha_rf_switch_2_status_c);  
  584:         $ha_rf_switch_2_on = &getvalue($ha_rf_switch_2_on_c);
  585:         $ha_rf_switch_2_off = &getvalue($ha_rf_switch_2_off_c);
  586:         $ha_rf_switch_3_status = &getvalue($ha_rf_switch_1_status_c);  
  587:         $ha_rf_switch_3_on = &getvalue($ha_rf_switch_3_on_c);
  588:         $ha_rf_switch_3_off = &getvalue($ha_rf_switch_3_off_c);
  589:         $ha_rf_switch_4_status = &getvalue($ha_rf_switch_4_status_c);  
  590:         $ha_rf_switch_4_on = &getvalue($ha_rf_switch_4_on_c);
  591:         $ha_rf_switch_4_off = &getvalue($ha_rf_switch_4_off_c);
  592:         $ha_rf_switch_5_status = &getvalue($ha_rf_switch_5_status_c);  
  593:         $ha_rf_switch_5_on = &getvalue($ha_rf_switch_5_on_c);
  594:         $ha_rf_switch_5_off = &getvalue($ha_rf_switch_5_off_c);
  595:
  596:         $ha_rf_switch_a_status = &getvalue($ha_rf_switch_a_status_c);  
  597:         $ha_rf_switch_a_on = &getvalue($ha_rf_switch_a_on_c);
  598:         $ha_rf_switch_a_off = &getvalue($ha_rf_switch_a_off_c);
  599:         $ha_rf_switch_b_status = &getvalue($ha_rf_switch_b_status_c);  
  600:         $ha_rf_switch_b_on = &getvalue($ha_rf_switch_b_on_c);
  601:         $ha_rf_switch_b_off = &getvalue($ha_rf_switch_b_off_c);
  602: }
  603:
  604: sub db_writelog
  605: {
  606:         &writelog($ha_ow_heater_return_c, "double", $ha_ow_heater_return);
  607:         &writelog($ha_ow_temp_outdoor_c, "double",$ha_ow_temp_outdoor);
  608:         &writelog($ha_ow_temp_indoor_c, "double", $ha_ow_temp_indoor);
  609:         &writelog($ha_heater_return_setpoint_c, "double", $ha_heater_return_setpoint);
  610:         &writelog($ha_room_setpoint_active_c, "double", $ha_room_setpoint_active);
  611: #       &writelog($ha_light_status_c, "boolean", $ha_light_status);
  612: }
  613:
  614: ################################################################################################
  615: # Data storage and retrieval
  616: ################################################################################################
  617: sub writelog
  618: {
  619:         # Get input parameters and parse URL and retrieve
  620:         # Param 1 - Log Name
  621:         # Param 2 - Log Type
  622:         # Param 3 - Log Value
  623:
  624:         my $url;
  625:         $url =  $ha_url_log;
  626:         $url =~ s/_name_/$_[0]/;
  627:         $url =~ s/_type_/$_[1]/;
  628:                 ##      #If double replace . with ,
  629:                 ##      if ($_[1] eq "double"){
  630:                 ##              $_[2] =~ tr/./,/;
  631:                 ##      }
  632:         $url =~ s/_value_/$_[2]/;
  633:         get $url;
  634: }
  635:
  636: sub setvalue
  637: {
  638:         # Get input parameters and parse URL and retrieve
  639:         # Param 1 - Attribute Name
  640:         # Param 2 - Attributy Value
  641:
  642:         my $url;
  643:         $url =  $ha_url_setvalue;
  644:         $url =~ s/_name_/$_[0]/;
  645:         $url =~ s/_value_/$_[1]/;
  646:         get $url;
  647: }
  648:
  649: sub getvalue
  650: {
  651:         # Get input parameters and parse URL and retrieve and return value
  652:         # Param 1 - Attribute Name
  653:         # Return - Attribute Value
  654:
  655:         my $url;
  656:         my $content;
  657:         my $value;
  658:         my $start;
  659:         my $length;
  660:
  661:         $url =  $ha_url_getvalue;
  662:         $url =~ s/_name_/$_[0]/;
  663:         $content = get $url;
  664:         $start = index($content, '<A_V>') + 5;
  665:         $length = index($content, '</A_V>') - $start;
  666:         $value = substr($content, $start, $length);
  667:         $value;
  668: }