egregius.be

Urban Exploration, PHP and others…

domoticzphp450

LUA Pass2PHP v2.0 Small example and explanation

Based on the script LUA Pass2PHP v2.0 a small example:

2 pirs in this script. They have idx 123 and idx 234. In the $events array we define wich function is called when this $idx is the changed device.
Have a look at LUA Pass2PHP v2.0 for many more examples and conditional switching.

Some explanation about the code:
All data retrieved from the lua device script is decoded in to arrays:

  • $a is the status of the changed device
  • $s array of all device statusses. Ex: $s[‘pirhall’]
  • $i array of all device idxs. Ex: $i[‘hall’]
  • $t array of all last update times off devices. Ex: strtotime($t[‘hall’]) gives the unix timestamp.
#!/usr/bin/php
<?php error_reporting(E_ALL);ini_set("display_errors","on");date_default_timezone_set('Europe/Brussels');
define('api',"http://127.0.0.1:8084/");
$t=microtime(true);$micro=sprintf("%03d",($t-floor($t))*1000);define('stamp',strftime("%Y-%m-%d %H:%M:%S.", $t).$micro);
$c=json_decode(base64_decode($argv[1]),true);$s=json_decode(base64_decode($argv[2]),true);$i=json_decode(base64_decode($argv[3]),true);$t=json_decode(base64_decode($argv[4]),true);$a=$s[key($c)];$devidx=$i[key($c)];
//Create the array of events. Wich idx calls wich function?
$events=array(123=>'pirgarage',234=>'pirhall');
if(isset($events[$devidx]))call_user_func($events[$devidx]);
//Start of user functions
function pirgarage(){
	global $a,$s,$i,$t;
	if($a=="On"){
		sw($i['garage'],'On');
	}
}
function pirhall(){
	global $a,$s,$i,$t;
	if($a=="On"){
		sw($i['hall'],'On');
	}
}
//End of user functions
// ========== FUNCTIONS ==========
/* sw switches $idx on/off. If no action is provided a toggle is made. $info is optional logging */
function sw($idx,$action="",$info=""){
	$t=microtime(true);$micro=sprintf("%03d",($t-floor($t))*1000);$stamp=strftime("%Y-%m-%d %H:%M:%S.", $t).$micro;
	print $stamp."          Switch ".$idx." (".ucfirst($info).") ".strtoupper($action)."
";
	if(empty($action)) curl(api."json.htm?type=command&param=switchlight&idx=".$idx."&switchcmd=Toggle");
	else curl(api."json.htm?type=command&param=switchlight&idx=".$idx."&switchcmd=".$action);
	usleep(400000);
}
/* sl sets dimmer $idx to level $level. $info is optional logging */
function sl($idx,$level,$info=""){
	$t=microtime(true);$micro=sprintf("%03d",($t-floor($t))*1000);$stamp=strftime("%Y-%m-%d %H:%M:%S.", $t).$micro;
	print $stamp."        Set Level ".$idx." ".ucfirst($info)." ".$level."
";
	curl(api . "json.htm?type=command&param=switchlight&idx=".$idx."&switchcmd=Set%20Level&level=".$level);
	usleep(400000);
}
/* ud updates a device $idx with $nvalue and $svalue. $info is optional logging */
function ud($idx,$nvalue,$svalue,$info=""){
	$t=microtime(true);$micro=sprintf("%03d",($t-floor($t))*1000);$stamp=strftime("%Y-%m-%d %H:%M:%S.", $t).$micro;
	if(!in_array($idx, array(395,532,534))) print $stamp."  --- UPDATE ".$idx." ".$info." ".$nvalue." ".$svalue."
";
	curl(api.'json.htm?type=command&param=udevice&idx='.$idx.'&nvalue='.$nvalue.'&svalue='.$svalue);
	usleep(400000);
}
function curl($url){dl("curl.so");$headers=array('Content-Type: application/json',);$ch=curl_init();curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);curl_setopt($ch, CURLOPT_FRESH_CONNECT, TRUE);$data=curl_exec($ch);curl_close($ch);return $data;}

10 COMMENTS

  1. Moh, zo vreemd. Nu ja, ik gebruik wel liever 127.0.0.1 dan localhost.
    Kijk maar even bij de functienamen die starten met PIR, zit redelijk wat in. Voor mij ‘zon’ = vermogen zonnepanelen, gelijkaardig als een luxmeter dus.
    Zeker tijdens het inrichten voldoende prints toevoegen, eens een functie dan perfect werkt kan je die steeds verminderen.

  2. Hallo Guy,

    Bedankt voor je ondersteuning. Het hele script werkte naar behoren, echter snapte de Synology het localhost adres niet. Na het aanpassen van het IP adres naar het juiste adres werkt het prima ;-)

    Nu verder doorspitten in het ‘echte’ script om te kijken of er iets in staat over een tijdsbeperking, zodat de PIR enkel schakelt binnen een bepaalde periode en bij een bepaalde lux waarde.

  3. Heb je error_reporting(E_ALL);ini_set(“display_errors”,”on”); bovenaan staan om foutmeldingen te loggen?
    Alle output dat het script geeft komt in de domoticz log terecht.
    De lampen hoeven normaal niet in de events array te staan. Enkel de IDX’en die acties triggeren.
    Denk dat je stap voor stap print lijnen moet toevoegen om te zien wat wel en wat niet uitgevoerd wordt.
    Bv meteen na de events array:
    print stamp.’pass2php started’;
    1ste lijn van de function:
    print stamp.’ PIR_hal_beneden starten.
    enz.

  4. Ik heb de print array uitgevoerd en zie daar alle devices in staan. Vervolgens heb ik mijn lampen die ik probeer te schakelen via het script ook opgenomen in de array, maar dit maakt geen verschil.

    Het enige wat ik momenteel aan het script is aangepast staat hieronder.

    $events=array(141=>’PIR_hal_beneden’,148=>’PIR_hal_zolder’,126=>’Hal_beneden_lamp’,151=>’Hal_zolder_lamp’);
    if(isset($events[$devidx]))call_user_func($events[$devidx]);
    //Start of user functions
    function PIR_hal_beneden(){
    global $a,$s,$i,$t;
    if($a==”On”){
    sw($i[‘Hal_beneden_lamp’],’On’);
    }
    }
    function PIR_hal_zolder(){
    global $a,$s,$i,$t;
    if($a==”On”){
    sw($i[‘Hal_zolder_lamp’],’On’);
    }
    }

  5. Hmmm, dan heb ik nog wat werk te verzetten om alle namen aan te passen ;-)

    Ik heb het script nu zonder foutmeldingen (nadat ik dl heb ingeschakeld) en zie dat de lamp op IDX wordt ingeschakeld… hij gaat echter niet aan. Ik ontvang daarentegen geen foutmelding.

    2016-11-18 23:33:23.394 (Aeotec Gen5 Z-Wave USB) Light/Switch (PIR_hal_beneden)
    2016-11-18 23:33:23.900 Switch 60 () ON

    Het nummer 60 komt overeen met de lamp onder Devices

    • Lamp op IDX? Nee, op naam toch?
      Misschien geen slecht idee om eens dit net onder de event_array te zetten:
      print_r($a);
      print_r($s);
      print_r($i);
      Dan zal je zien wat er in de array’s zit.
      Lamp wordt op naam ingevoerd, het schakelen naar Domoticz gaat dan wel via IDX omdat die in de $i array zit. Dus sw($i[‘licht_beneden’],’On’); zou het moeten doen. Anders misschien even jouw functie copy/pasten?

  6. Ik heb speciaal geen enkele spatie in mijn device namen, net omdat dat in veel systemen voor rariteiten kan zorgen.

    Inderdaad.
    Toch nog even voor de duidelijkheid:
    In de events array zet je de IDX van de PIR bv 123=>’PIRkeuken’

    dan maak je een function met exact dezelfde naam:
    function PIRkeuken(){
    global $a,$s,$i;
    if($a==’On’)sw($i[‘lichtkeuken’],’On’);
    }

    Let daarbij wel op dat alles hoofdlettergevoelig is en dus EXACT moet overeenkomen met de benamingen in domoticz. Ook de functienaam moet exact zijn als de naam in de array.
    De global lijn is om de arrays beschikbaar te hebben in de functie. $a = status van het device die triggerde, $s alle devices en $i alle IDX’en.

    Wat in het begin ook altijd handig is is om een print toe te voegen. bv:
    print stamp.’ Deze functie wordt nu gestart’;
    het sw commando zal automatisch een lijn in de domoticz logfile printen, bv:
    2016-11-18 23:13:00.763 — SWITCH Off licht garage

  7. Kleine correctie op mijn eerdere reactie. Ik heb spaties in mijn apparaat namen en heb dit geprobeerd te omzeilen met een “‘”. Aangezien dit niet werkte, heb ik mijn apparaten even hernoemd.

    Wanneer de PIR nu een detectie detecteert schakelt echter de lamp niet in. In het stukje sw($i[‘xxx’],’On’); dient toch de xxx te worden vervangen door de lamp naam ?

  8. Ik krijg onderstaande fout (vanaf mijn Synology). Enig idee ?

    Parse error: syntax error, unexpected ”pir_hal_beneden” (T_CONSTANT_ENCAPSED_STRING), expecting ‘(‘ in /volu…

    Het is een kopie van het script boven. Omgezet in Notepad++ in UNIX formaat en enkel de benamingen zijn aangepast.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.