Question

I'm looking for a php example / extension to be able to launch the execution of different PHP subroutines at regular period (specific for each routing)

For my smarthome automation, I've a list of sensors defined in a mysql table:

id tinyint(4) Auto increment
nom char(50) NULL
zone_id tinyint(4) NULL
grandeur_id tinyint(4) NULL
adresse_source varchar(255) NULL
polling_time smallint(6) NULL [5]
label_unite varchar(15) NULL
description varchar(255) NULL

Each sensor (url given in field adresse_source) should be read every from 1min to 1day interval and recorder in a data table. We can have sensor A to be read every minute, sensor B every 5 min etc...

Sensor read procedure is the same for all sensors.

I was planning to create different version of this PHP script for different time period and multiple cron entry, but this is not convenient and heavy to manage

Is there a PHP feature for interrupt management, where in an infinite loop there will be event time trigger launching the read & write of the sensor depending on its polling_time?

Was it helpful?

Solution

For a crude solution, given the timings range (1 minute to 1 day), you could get away with a simple loop.

If your loop runs reliably within a few seconds, you can check the php time (now()) (rounded to the nearest minute - by diving by 60)) (php time is given in seconds as an integer). You can then test the mod() of this value dividing by the relevant interval represented as minutes.

If the result is 0, that event can be triggered.

If the number of sensors isn't to large, it might help to read them in once (before your loop) and stored them in an associative array keyed on the interval.

$sensors=array();

... while(fetch_row ..){ 
$interval=$row['polling_time'];
$sensors["$interval"][]=$row;
}
...
$prevtime=intval(round(floatval(now()/60),0);
while (true)
{
  $thistime=intval(round(floatval(now()/60),0);
  if ($thistime == $prevtime)
  {
    sleep(1);
    continue;
  }
  $prevtime=$thistime;
  foreach ($sensors as $interval=>$intsensors)
  {
    if (($thistime%intval($interval)) == 0)
    { // this interval has been matched to the current time - so get the sensors
      foreach ($intsensors as $this_sensor)
      {
        extract($this_sensor);
        // do what you like with this sensor's details.
      }
    }
  }
  sleep(10) // or however many seconds you need to make your loop work smoothly
}
... etc

Like I said - crude but may work OK - given your (in computing terms) reasonably large timescales. Cheers

OTHER TIPS

Interrupt management? This is low level stuff and you don't even say what OS it's running on. Interrupts must be handled by the kernel - which can in theory invoke userspace programs - but it's a very roundabout way of doing things in any language. Your mention of cron makes me believe that you don't really mean interrupts at all.

On a POSIX system you could use the pcntl_signal(), [u]sleep() and pcntl_alarm() to schedule running of code, Actually it's possible to do it just with usleep() and an event queue.

If it were me, I'd use a scheduling engine like Nagios (there are complications with high frequency cron jobs) to invoke the PHP scripts rather than letting PHP act as the controller.

I tried with event php extension, but it execute only once each event and then nothing else.

may be an idea ?

    $base = new EventBase();
    $delay1 = 2;
    $delay2 = 10;

    $event1 = Event::timer($base, function($delay1) use (&$event1) {
        // subroutine event1
        echo "$delay1 seconds elapsed event 1\n";
        $event1->delTimer();
        }, $delay1);
    $event1->addTimer($delay1);

    $event2 = Event::timer($base, function($delay2) use (&$event2) {
        // subroutine event1
        echo "$delay2 seconds elapsed event 2\n";
        $event2->delTimer();
        }, $delay2);
    $event2->addTimer($delay2);
    $base->loop();
    while (1);

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top