Page 1 of 1

Virtual Thermostat

Posted: Thursday 25 August 2016 18:51
by peter8wun
I was wondering if it would be doable to build a virtual thermostat in domoticz?

So: have a “device” on the dashboard (one per room) Where you can set the set point temperature, configure a temperature sensor for it to get the actual temperature of the room, and have that thermostat control a switch device that will control the heating or cooling equipment; for instance a solenoid that will open the radiator valve for just that room.
Thus not using a hardware thermostat that is mounted on the wall of the room, but the logic within Domoticz

I would really like that.

Re: Virtual Thermostat

Posted: Thursday 25 August 2016 21:07
by Egregius
Ofcourse, I'm using that for almost a year now. Very happy with it.

Re: Virtual Thermostat

Posted: Friday 02 September 2016 19:05
by anasazi
Egregius wrote:Ofcourse, I'm using that for almost a year now. Very happy with it.
HI,

Would like to explain how you have done this.
I would also like my thermostats to show the actual temperature.
Not the setpoint and actual temperature is the same...

Re: Virtual Thermostat

Posted: Saturday 03 September 2016 0:33
by Egregius
Well, I'll try...

For each room I have 3 devices.
1) a dummy setpoint: desired temperature (name=room_set)
2) a Danfoss LC-13 Setpoint: setting of the valve (name=roomZ)
3) a thermometer (name=room)

Then, in my pass2php script there are several parts of code. The heating part of the whole script is the most complicated and most difficult.

First parts takes care of the scheduling.
The "cget('setpointtobi')" grabs a memcached variable to see if the setpoint is on auto mode, or we did a manual override on my floorplan. The manual override is automatically resetted after one hour, or even instantly if we leave the house.

As example my sons room, the most advanced schedule I use:

Code: Select all

$Settobi=8;$setpointtobi=cget('setpointtobi');
if($setpointtobi!=0&&strtotime($t['tobi_set'])<eenuur){cset('setpointtobi',0);$setpointtobi=0;}
if($setpointtobi!=2){
    if($buiten_temp<15&&$s['raamtobi']=='Closed'&&$s['heating']=='On'&&(strtotime($t['raamtobi'])<tweeuur)){
        $Settobi=12.0;
        if(date('W')%2==1){
                 if(date('N')==3)if(time>achtavond)$Settobi=16;
            elseif(date('N')==4)if(time<zevenochtend||time>achtavond)$Settobi=16;
            elseif(date('N')==5)if(time<zevenochtend)$Settobi=16;
        }else{
                 if(date('N')==3)if(time>achtavond)$Settobi=16;
            elseif(in_array(date('N'),array(4,5,6)))if(time<zevenochtend||time>achtavond)$Settobi=16;
            elseif(date('N')==7)if(time<zevenochtend)$Settobi=16;
        }
    }
    if(isset($s['tobi_set'])&&$s['tobi_set']!=$Settobi){ud($i['tobi_set'],0,$Settobi,'Rtobi_set');$s['tobi_set']=$Settobi;}
}
So, default setpoint is 8°. Except when the outside temperature is lower than 15° and his window is closed for more than 2 hours, then the setpoint is 12°.
Then, when the weeknumber is odd there's a schedule for Wednesday, Thursday and Friday night. When the weeknumber is even there's a schedule for Wednesday till Sunday night.

Further in the script I loop thru all the rooms to do some calculations:

Code: Select all

$kamers=array('living','badkamer','tobi','alex','kamer');$kamersgas=array('living','tobi','alex','kamer');
$bigdif=100;$brander=$s['brander'];$Tbrander=strtotime($t['brander']);$Ibrander=$i['brander'];
foreach($kamers as $kamer){
    ${'dif'.$kamer}=number_format($s[$kamer.'_temp']-$s[$kamer.'_set'],1);
    if(in_array($kamer,$kamersgas))
        if(${'dif'.$kamer}<$bigdif)$bigdif=${'dif'.$kamer};
        ${'Set'.$kamer}=$s[$kamer.'_set'];
    }
This calculates the biggest difference in room temperature and setpoint.

Then I do some more magic with those numbers:

Code: Select all

foreach($kamers as $kamer){
    if(${'dif'.$kamer}<=number_format(($bigdif+ 0.2),1)&&${'dif'.$kamer}<1)${'RSet'.$kamer}=setradiator($kamer,${'dif'.$kamer},true,$s[$kamer.'_set']);
    else ${'RSet'.$kamer}=setradiator($kamer,${'dif'.$kamer},false,$s[$kamer.'_set']);
}
This calculates a lower/higher temperature setting for the valve. The 'coldest' room automatically gets a higher valve setting so the valve is already open when the heater starts, otherwise there could be a 5 minute delay (depending of the wake-up time of the Danfoss).

Then, all variables are calculated and set, so I update the valves if needed:

Code: Select all

if($s['kamerZ']!=$RSetkamer)ud($i['kamerZ'],0,$RSetkamer,'RkamerZ');
if($s['tobiZ']!=$RSettobi)ud($i['tobiZ'],0,$RSettobi,'RtobiZ');
if($s['alexZ']!=$RSetalex)ud($i['alexZ'],0,$RSetalex,'RalexZ');
if($s['livingZ']!=$RSetliving)ud($i['livingZ'],0,$RSetliving,'RlivingZ');
if($s['livingZZ']!=$RSetliving)ud($i['livingZZ'],0,$RSetliving,'RlivingZZ');
if($s['livingZE']!=$RSetliving)ud($i['livingZE'],0,$RSetliving,'RlivingZE');
And finally, depending on all above I put on the heater, or switch it already of when temperature is almost met, that way I avoid overheating.

Code: Select all

if($bigdif<=-0.3&&$brander=="Off"&& $Tbrander<time-60)sw($Ibrander,'On','brander dif = '.$bigdif);
elseif($bigdif<=-0.2&&$brander=="Off"&& $Tbrander<time-120)sw($Ibrander,'On','brander dif = '.$bigdif);
elseif($bigdif<=-0.1&&$brander=="Off"&& $Tbrander<time-180)sw($Ibrander,'On','brander dif = '.$bigdif);
elseif($bigdif<=0&&$brander=="Off"&& $Tbrander<time-240)sw($Ibrander,'On','brander dif = '.$bigdif);
elseif($bigdif>=0.1&&$brander=="On"&& $Tbrander<time)sw($Ibrander,'Off','brander dif = '.$bigdif);
elseif($bigdif>=0&&$brander=="On"&& $Tbrander<time-60)sw($Ibrander,'Off','brander dif = '.$bigdif);
elseif($bigdif>=-0.1&&$brander=="On"&& $Tbrander<time-120)sw($Ibrander,'Off','brander dif = '.$bigdif);
elseif($bigdif>=-0.2&&$brander=="On"&& $Tbrander<time-180)sw($Ibrander,'Off','brander dif = '.$bigdif);
elseif($bigdif>=-0.3&&$brander=="On"&& $Tbrander<time-240)sw($Ibrander,'Off','brander dif = '.$bigdif);
All of the above is evaluated on every temperature update that comes from Fibaro smoke detectors and also every minute. My heating is perfectly controlled, exactly the way I want.

So again, to all the lua lovers (and php haters) overhere, try this in lua...
In PHP only your imagination is the limit, not your skills because Google knows everything about PHP.

The complete code can be found at http://egregius.be/tag/domoticz/
Discussions about pass2php in this topic: http://www.domoticz.com/forum/viewtopic ... 23&t=12343