loglevel) { case 'debug': $loglevel = 4; break; case 'info': $loglevel = 3; break; case 'warn': $loglevel = 2; break; case 'error': $loglevel = 1; break; } if ($loglevel > 0) { $logfile = (!str_starts_with($config->logfile, '/')) ? fopen($scriptPath . '/' . $config->logfile, 'a') : fopen($config->logfile, 'a'); writeLog("===================================================\r\n", 1); writeLog("worker startet at $startAt\r\n", 1); writeLog("loglevel: $loglevel (" . $config->loglevel . ")\r\n\r\n", 1); } //create database if it does not exist yet if(!is_file((!str_starts_with($config->database, '/')) ? $scriptPath. '/' . $config->database : $config->database)) { writeLog('Database not found! I will create it! ', 3); if( !initializeDB() ) { writeLog("failed! Exit!\r\n\r\n"); cleanUp('with errors '); } else writeLog("succeess!\r\n\r\n", 3); } $data = readData(); if( !$data ) cleanUp('with errors '); if( !processData($data, $startAt) ) cleanUp('with errors '); cleanUp('successfully '); /* * cleanup */ function cleanUp($status) { global $loglevel; if( $loglevel > 0) { global $logfile; writeLog('worker finished ' . $status . 'at ' . date('Y-m-d H:i:s') . "\r\n", 1); writeLog("===================================================\r\n\r\n", 1); fclose($logfile); } exit(); } /* * global function to write new data to logifle */ function writeLog($strData, $minLogLevel) { global $config, $logfile, $loglevel; if($loglevel >= $minLogLevel) fwrite($logfile, $strData); } /* * read data stream from VE Direct USB serial interface */ function readData() { global $config; writeLog("Open VE Direct interface:\r\n" . $config->device . "\r\n", 3); $VEinterface = dio_open($config->device, O_RDONLY | O_NONBLOCK); if($VEinterface === false) { writeLog("unable to open VE Direct interface!\r\n", 1); return false; } writeLog("success!\r\n\r\n", 3); //set up the interface to properly communicate with the interface dio_tcsetattr( $VEinterface, array( 'baud' => 19200, 'bits' => 8, 'stop' => 1, 'parity' => 0, 'flow_control' => 0, 'is_canonical' => 0) ); $bytesToRead = 1024; // read 1KB by default if(isset($config->bytesToRead)) $bytesToRead = $config->bytesToRead; writeLog("Reading $bytesToRead Byte from VE.Direct interface\r\n", 3); $dataStream = ""; $startTime = time(); while(strlen($dataStream) < $bytesToRead && time() < $startTime + $config->timeout) $dataStream .= dio_read($VEinterface, $bytesToRead); dio_close($VEinterface); writeLog($dataStream . "\r\n\r\n", 4); //split data stream into array and remove checksums $dataArray = explode("\n", $dataStream); $collect = false; $returnData = array(); for($i=0; $i < count($dataArray); $i++) { if(!$collect && str_starts_with($dataArray[$i], 'PID')) $collect = true; else if($collect && str_starts_with($dataArray[$i], 'PID')) break; if($collect) { $dataLine = trim($dataArray[$i]); if( strlen($dataLine) == 0 || str_starts_with($dataLine, 'Checksum') || str_starts_with($dataLine, ':') ) //skip empty lines and checksums continue; $dataFields = explode("\t", $dataLine); $returnData[$dataFields[0]] = $dataFields[1]; } } ksort($returnData); writeLog("Collected data:\r\n" . print_r($returnData, true) . "\r\n", 3); return $returnData; } function processData($data, $collectionDateTime) { global $config, $scriptPath; $db = (!str_starts_with($config->database, '/')) ? new SQLITE3($scriptPath . '/' . $config->database) : new SQLITE3($config->database); $dbTableName = $data['PID'] . '-' . $data['SER#']; $sql = "SELECT name FROM sqlite_schema WHERE type='table' AND name='$dbTableName';"; $tableNames = $db->query($sql); if( !$tableNames->fetchArray(SQLITE3_NUM) ) { writeLog('New Victron Energy Device found. Crating a new database table... ', 3); if( $db->exec("CREATE TABLE '$dbTableName' (date TEXT, time TEXT, data TEXT);") ) writeLog("success!\r\n", 3); else { writeLog("failed! Cancel!\r\n", 3); return false; } } $dateTime = explode(" ", $collectionDateTime); unset($data['PID']); unset($data['SER#']); $dataJson = json_encode($data); writeLog('Add dataset to database... ', 3); $sql = "INSERT INTO '$dbTableName' (date, time, data) VALUES('$dateTime[0]', '$dateTime[1]', '$dataJson')"; if( !$db->exec($sql) ) { writeLog("failed!\r\n\r\n", 3); return false; } writeLog("success!\r\n\r\n", 3); return true; } function initializeDB() { global $config, $scriptPath; $dateTime = date('Y-m-d H:m:s'); $db = (!str_starts_with($config->database, '/')) ? new SQLITE3($scriptPath . '/' . $config->database) : new SQLITE3($config->database); if( !$db->exec('CREATE TABLE meta (data TEXT);') ) return false; if( !$db->exec("INSERT INTO meta (data) VALUES ('{\"creation\": \"$dateTime\"');") ) return false; return true; } ?>