function io_check_hardware($in1, $in2, $in3, $in4, $out1, $out2) { # set all pins as inputs on the input boards $error = 0; if ($i1 = I2C_Write($in1, 255) < 0) { $error++; } //chip is bidirectional, set outputs to 1 to read as input if ($i2 = I2C_Write($in2, 255) < 0) { $error++; } //chip is bidirectional, set outputs to 1 to read as input if ($i3 = I2C_Write($in3, 255) < 0) { $error++; } //chip is bidirectional, set outputs to 1 to read as input if ($i4 = I2C_Write($in4, 255) < 0) { $error++; } //chip is bidirectional, set outputs to 1 to read as input if ($i1) { logformat(sprintf("Opto input board 1 with address: 0x%X is missing or not functioning!\n", PCF8574_ADDR1), 1); } if ($i2) { logformat(sprintf("Opto input board 2 with address: 0x%X is missing or not functioning!\n", PCF8574_ADDR2), 1); } if ($i3) { logformat(sprintf("Opto input board 3 with address: 0x%X is missing or not functioning!\n", PCF8574_ADDR3), 1); } if ($i4) { logformat(sprintf("Opto input board 4 with address: 0x%X is missing or not functioning!\n", PCF8574_ADDR4), 1); } if ($error) { return $error; } #set all pins as outputs on the output boards and set all outputs high if ($o1 = I2C_WriteReg16($out1, PCA9555_CONFPORT0, 0) < 0) { $error++; } //sends to CONFPORT0 and 1 if ($o2 = I2C_WriteReg16($out2, PCA9555_CONFPORT0, 0) < 0) { $error++; } //sends to CONFPORT0 and 1 if ($o1) { logformat(sprintf("PCA9555 based output board 1 with address: 0x%X is missing or not functioning!\n", PCA9555_ADDR1), 1); } if ($o2) { logformat(sprintf("PCA9555 based output board 2 with address: 0x%X is missing or not functioning!\n", PCA9555_ADDR2), 1); } if ($error) { return $error; } return 0; }
function signal_handler($signo) { global $must_exit; switch ($signo) { case SIGTERM: $must_exit = 'SIGTERM'; break; case SIGINT: $must_exit = 'SIGINT'; break; default: $must_exit = $signo; break; } logformat(sprintf("Received signal: %s\n", $must_exit)); }
function shmop_write_with_lock($shm_id, $sem_id, $s, $offset = 0) { //Acquire the semaphore if (!sem_acquire($sem_id)) { //If not available this will stall until the semaphore is released by the other process logformat("Failed to acquire shared memory semaphore!\n"); sem_remove($sem_id); //Use even if we didn't create the semaphore as something has gone wrong and its usually debugging so lets no lock up this semaphore key exit(1); } shmop_write($shm_id, $s, $offset); //Release the semaphore if (!sem_release($sem_id)) { //Must be called after sem_acquire() so that another process can acquire the semaphore logformat("Failed to release shared memory semaphore!\n"); } }
function xap_check_address_match($source, $target) { global $debug; if ($debug & ADDR_DEBUG_ID) { logformat(sprintf("Checking %s against %s : ", $source, $target)); } if ($target == '' or $source == '') { return 0; } //can't match empty source or target $s = explode(":", $source); //split up address and subaddress parts $s1 = explode(".", $s[0]); if (isset($s[1])) { $s2 = explode(".", $s[1]); } else { $s2 = array(); } $cs1 = count($s1); $cs2 = count($s2); $t = explode(":", $target); $t1 = explode(".", $t[0]); if (isset($t[1])) { $t2 = explode(".", $t[1]); } else { $t2 = array(); } $s1matches = 0; $s2matches = 0; for ($i = 0; $i < $cs1; $i++) { if (isset($t1[$i])) { if ($t1[$i] == '>') { $s1matches = $cs1; $s2matches = $cs2; break; } if (strcasecmp($s1[$i], $t1[$i]) == 0 or $t1[$i] == '*') { $s1matches++; } } } if ($s1matches == $cs1 and $s2matches == $cs2) { if ($debug & ADDR_DEBUG_ID) { logformat("True\n"); } return 1; } for ($i = 0; $i < $cs2; $i++) { if (isset($t2[$i])) { if ($t2[$i] == '>') { $s2matches = $cs2; break; } if (strcasecmp($s2[$i], $t2[$i]) == 0 or $t2[$i] == '*') { $s2matches++; } } } if ($s1matches == $cs1 and $s2matches == $cs2) { if ($debug & ADDR_DEBUG_ID) { logformat("True\n"); } return 1; } if ($debug & ADDR_DEBUG_ID) { logformat("False\n"); } return 0; }
function dmx_write($cmd, $s, &$data) { global $debug, $dmx; $sLSB = $s % 256; $sMSB = floor($s / 256); $packet = chr(DMX_START_BYTE) . chr($cmd) . chr($sLSB) . chr($sMSB) . $data . chr(DMX_END_BYTE); if ($debug & DMX_DEBUG_ID) { logformat(sprintf("Sent: %s\n", hex_display($packet))); } $w = fwrite($dmx, $packet); fflush($dmx); return $w; }
for ($i = 0; $i < 128; $i++) { if (substr($do1, $i * 2, 2) != substr($dmx_outputs1, $i * 2, 2)) { //send xap dmx level change message for universe 1 send_dmx_output_level_event_message($i, XAPSRC_DMX_OUT1, XAPUID_DMX_OUT1, $do1, $donames1); $outs1_changed = 1; } if (substr($do2, $i * 2, 2) != substr($dmx_outputs2, $i * 2, 2)) { //send xap dmx level change message for universe 2 send_dmx_output_level_event_message($i, XAPSRC_DMX_OUT2, XAPUID_DMX_OUT2, $do2, $donames2); $outs2_changed = 1; } } } if ($outs1_changed) { $dmx_outputs1 = $do1; dmx_set_levels_U1(bcd_to_chr($dmx_outputs1)); } if ($outs2_changed) { $dmx_outputs2 = $do2; dmx_set_levels_U2(bcd_to_chr($dmx_outputs2)); } usleep(5000); } } dmx_set_dmx_receive_mode(SEND_ON_CHANGE_ONLY); dmx_close(); dmx_write_state_file($dstate_file, $dmx_inputs, $dmx_outputs1, $dmx_outputs2); socket_close($xap_sock_in); shmop_close($shm_id); logformat("hac_dmx exiting cleanly.\n");
function enumerate_w1_sensors($keep_existing = 1, $keep_names = 1) { global $debug; if (!file_exists(SENSORMAPFILE)) { file_put_contents(SENSORMAPFILE, ''); } //create file if not exists $map = @file(SENSORMAPFILE, FILE_IGNORE_NEW_LINES); //build a sensor list from the history file $sensors = array(); if ($keep_existing) { //keep the mappings and names already in the list or start again? foreach ($map as $l) { if (preg_match_all("/^([0-9]+)[\t]+([0-9]{2})[\t]+([0-9a-f]{12})[\t]+(YES|NO)[\t]+([a-z0-9\\ \\_\\-\\.]+)\$/i", $l, $m)) { $sensors[$m[1][0]] = array('ID' => $m[1][0], 'TYPE' => $m[2][0], 'SENSOR_ID' => $m[3][0], 'AVAILABLE' => 'NO', 'NAME' => $m[5][0]); } } } else { //start again if ($keep_names) { //but keep names foreach ($map as $l) { if (preg_match_all("/^([0-9]+)[\t]+([0-9]{2})[\t]+([0-9a-f]{12})[\t]+(YES|NO)[\t]+([a-z0-9\\ \\_\\-\\.]+)\$/i", $l, $m)) { $names[$m[2][0] . '-' . $m[3][0]] = $m[5][0]; } } } } $sensor_count = count($sensors); //now check whats is actually present and update the file if necessary $sl = @file(SENSORLIST, FILE_IGNORE_NEW_LINES); if (is_array($sl)) { foreach ($sl as $f) { if (preg_match_all("/^([0-9]{2})\\-([0-9a-f]{12})\$/i", $f, $m)) { $type = $m[1][0]; $sensor_id = $m[2][0]; $cid = $type . '-' . $sensor_id; $not_found = 1; if ($sensor_count) { for ($i = 0; $i < $sensor_count; $i++) { if ($sensors[$i]['TYPE'] == $type and $sensors[$i]['SENSOR_ID'] == $sensor_id) { $id = $sensors[$i]['TYPE'] . '-' . $sensors[$i]['SENSOR_ID']; if (file_exists(SENSORPATH . '/' . $id . '/w1_slave')) { $sensors[$i]['AVAILABLE'] = 'YES'; } else { $sensors[$i]['AVAILABLE'] = 'NO'; } $not_found = 0; } } } if ($not_found) { $sensor_name = 'NewSensor' . $cid; if ($keep_existing === 0 and $keep_names and isset($names[$cid])) { $sensor_name = $names[$cid]; } $sensors[$sensor_count] = array('ID' => $sensor_count, 'TYPE' => $type, 'SENSOR_ID' => $sensor_id, 'NAME' => $sensor_name, 'AVAILABLE' => 'YES'); $sensor_count++; logformat(sprintf("Found new sensor Type: %s, ID: %s, Name: '%s'\n", $type, $sensor_id, $sensor_name)); } } } } else { logformat("No Sensors Found!\n"); } if ($fp = @fopen(SENSORMAPFILE, 'wb')) { fwrite($fp, "ID\tTYPE\tSENSOR_ID\tAVAILABLE\tNAME\n"); for ($i = 0; $i < $sensor_count; $i++) { fwrite($fp, sprintf("%s\t%s\t%s\t%s\t\t%s\n", $sensors[$i]['ID'], $sensors[$i]['TYPE'], $sensors[$i]['SENSOR_ID'], $sensors[$i]['AVAILABLE'] ? 'YES' : 'NO', $sensors[$i]['NAME'])); } fclose($fp); } return $sensors; }
//startup processes: while ($must_exit === 0) { foreach ($processes as $pn => $pe) { $descriptorspec = array(0 => array("pipe", "r"), 1 => array("file", $startup_dir . '/log/' . $pn . '.out.log', "a"), 2 => array("file", $startup_dir . '/log/' . $pn . '.err.log', "a")); if ($processes[$pn]['start'] === 1) { if ($processes[$pn]['resource_id'] === 0) { $exe = sprintf("%s/%s %s", $startup_dir, $processes[$pn]['cmd'], $processes[$pn]['args']); logformat("Starting process '{$exe}'\n"); $rp = proc_open($exe, $descriptorspec, $processes[$pn]['pipes'], $startup_dir); if (is_resource($rp)) { stream_set_blocking($processes[$pn]['pipes'][0], 0); $processes[$pn]['resource_id'] = $rp; $processes[$pn]['status'] = proc_get_status($rp); print_r($processes[$pn]); } else { logformat("Error Starting process '{$exe}'\n"); } } else { //check if process still running $processes[$pn]['status'] = proc_get_status($processes[$pn]['resource_id']); print_r($processes[$pn]); } } if ($must_exit) { break; } sleep(1); } if ($must_exit) { break; }
set_output_state($outputs, $i, substr($os, $i * 2, 2)); //toggle the real output $otimes[$i + 1] = sprintf("%d,%.02f", 1 - $tstate[0], $t); //remember time of the state change $houtputs_changed++; } } } if ($houtputs_changed) { set_outputs($outputs); //set the hardware outputs if ($debug & IO_DEBUG_ID) { logformat("Current Hardware State:\n"); logformat(sprintf("Out States :%s\n", $outputs)); } } } if ($must_exit) { break; } //now sleep until our next POLL period starts while ((microtime(true) - $t) * 1000 < POLLINTERVAL) { usleep(10000); } //10ms sleep } io_write_state_file($state_file, $out_states, $in_states, $in_programs, $in_levels); socket_close($xap_sock_in); shmop_close($shm_id); logformat("hac_io exiting cleanly.\n");
} else { $io_counter++; } } //send info messages for dmx inputs and outputs if ($t - $dmx_last_info > DMXINFOSENDTIME) { if ($dmx_counter < DMX_CH_IN) { send_dmx_input_level_info_message($dmx_counter, $dmx_inputs); } if ($dmx_counter < DMX_CH_OUT1) { send_dmx_output_level_info_message($dmx_counter, XAPSRC_DMX_OUT1, XAPUID_DMX_OUT1, $dmx_outputs1, $donames1); } if ($dmx_counter < DMX_CH_OUT2) { send_dmx_output_level_info_message($dmx_counter, XAPSRC_DMX_OUT2, XAPUID_DMX_OUT2, $dmx_outputs2, $donames2); } if ($dmx_counter >= DMX_CH_IN and $dmx_counter >= DMX_CH_OUT1 and $dmx_counter >= DMX_CH_OUT2) { $dmx_counter = 0; $dmx_last_info = $t; } else { $dmx_counter++; } } $last_tick_time = $t; } } $t = xap_send_heartbeat_stop(array(XAPUID_IO_IN, XAPUID_IO_OUT, XAPUID_DMX_IN1, XAPUID_DMX_OUT1, XAPUID_DMX_OUT2), array(XAPSRC_IO_IN, XAPSRC_IO_OUT, XAPSRC_DMX_IN1, XAPSRC_DMX_OUT1, XAPSRC_DMX_OUT2)); socket_close($xap_sock_in); shmop_close($io_shm_id); shmop_close($dmx_shm_id); logformat("hac_cmd exiting cleanly.\n");