modified functions and dependencies.
This commit is contained in:
@@ -13,6 +13,16 @@ $aRRDCreate = array(
|
|||||||
DS:PAC:GAUGE:120:0:U
|
DS:PAC:GAUGE:120:0:U
|
||||||
DS:ETOTAL:GAUGE:120:0:U
|
DS:ETOTAL:GAUGE:120:0:U
|
||||||
DS:ETODAY:GAUGE:120:0:U
|
DS:ETODAY:GAUGE:120:0:U
|
||||||
|
RRA:MIN:0.5:1:720
|
||||||
|
RRA:MIN:0.5:17:1017
|
||||||
|
RRA:MIN:0.5:120:1008
|
||||||
|
RRA:MIN:0.5:535:1002
|
||||||
|
RRA:MIN:0.5:6324:1001
|
||||||
|
RRA:MAX:0.5:1:720
|
||||||
|
RRA:MAX:0.5:17:1017
|
||||||
|
RRA:MAX:0.5:120:1008
|
||||||
|
RRA:MAX:0.5:535:1002
|
||||||
|
RRA:MAX:0.5:6324:1001
|
||||||
RRA:AVERAGE:0.5:1:720
|
RRA:AVERAGE:0.5:1:720
|
||||||
RRA:AVERAGE:0.5:17:1017
|
RRA:AVERAGE:0.5:17:1017
|
||||||
RRA:AVERAGE:0.5:120:1008
|
RRA:AVERAGE:0.5:120:1008
|
||||||
@@ -54,7 +64,7 @@ foreach (glob($sDataDirectory . '/*.csv') as $sFile) {
|
|||||||
if ($bFirst) {
|
if ($bFirst) {
|
||||||
foreach ($aRRDCreate as $sRRDFile => $sRRDCreate) {
|
foreach ($aRRDCreate as $sRRDFile => $sRRDCreate) {
|
||||||
/* Create RRD database */
|
/* Create RRD database */
|
||||||
echo $sCommand = str_replace("\n", ' ', sprintf($sRRDCreate, $sRRDFile, $aValues[0] - 1)) . "\n";
|
$sCommand = str_replace("\n", ' ', sprintf($sRRDCreate, $sRRDFile, $aValues[0] - 1)) . "\n";
|
||||||
fwrite($rHandle, $sCommand);
|
fwrite($rHandle, $sCommand);
|
||||||
}
|
}
|
||||||
$bFirst = false;
|
$bFirst = false;
|
||||||
@@ -64,7 +74,7 @@ foreach (glob($sDataDirectory . '/*.csv') as $sFile) {
|
|||||||
/* Update relevant fields in RRD database */
|
/* Update relevant fields in RRD database */
|
||||||
$aRRDValues = array_intersect_key($aValues, $aRRDKeys[$sRRDFile]);
|
$aRRDValues = array_intersect_key($aValues, $aRRDKeys[$sRRDFile]);
|
||||||
$sCommand = sprintf("update %s %d:%s\n", $sRRDFile, $aValues[0], implode(':', $aRRDValues));
|
$sCommand = sprintf("update %s %d:%s\n", $sRRDFile, $aValues[0], implode(':', $aRRDValues));
|
||||||
printf('[%d] %s', $i, $sCommand);
|
//printf('[%d] %s', $i, $sCommand);
|
||||||
fwrite($rHandle, $sCommand);
|
fwrite($rHandle, $sCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
<?php
|
<?php
|
||||||
|
require_once 'wunderground.php';
|
||||||
|
|
||||||
|
define('DEFAULT_WAKE', '7:00');
|
||||||
|
define('DEFAULT_SLEEP', '19:00');
|
||||||
|
|
||||||
define('TWILIGHT_FILE', 'data/twilight_%d.csv');
|
define('TWILIGHT_FILE', 'data/twilight_%d.csv');
|
||||||
|
define('STATION', 'INOORDHO4');
|
||||||
|
|
||||||
function getHour($sTime = null) {
|
function getHour($sTime = null) {
|
||||||
$iTime = $sTime === null ? time() : strtotime($sTime);
|
if (!is_numeric($sTime)) {
|
||||||
|
$iTime = !isset($sTime) ? time() : strtotime($sTime);
|
||||||
|
} else {
|
||||||
|
$iTime = $sTime;
|
||||||
|
}
|
||||||
return date('H', $iTime) + date('i', $iTime) / 60;
|
return date('H', $iTime) + date('i', $iTime) / 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,6 +30,25 @@ function getTwilight($iYear, $iDay) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getWake(&$aTwilight = null) {
|
||||||
|
if (!isset($aTwilight)) {
|
||||||
|
$aTwilight = getTwilight(date('Y'), date('z'));
|
||||||
|
}
|
||||||
|
return strtotime($sWake = isset($aTwilight) ? $aTwilight[1] : DEFAULT_WAKE);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSleep(&$aTwilight = null) {
|
||||||
|
if (!isset($aTwilight)) {
|
||||||
|
$aTwilight = getTwilight(date('Y'), date('z'));
|
||||||
|
}
|
||||||
|
return strtotime($sWake = isset($aTwilight) ? $aTwilight[3] : DEFAULT_WAKE);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTemperature($sStation = STATION) {
|
||||||
|
$aData = wunderground('conditions', sprintf('pws:%s', STATION));
|
||||||
|
return isset($aData['current_observation']['temp_c']) ? $aData['current_observation']['temp_c'] : null;
|
||||||
|
}
|
||||||
|
|
||||||
function command($sCommand) {
|
function command($sCommand) {
|
||||||
ob_start();
|
ob_start();
|
||||||
system($sCommand);
|
system($sCommand);
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ require_once 'daemon.php';
|
|||||||
define('NAME', 'inverter');
|
define('NAME', 'inverter');
|
||||||
define('TASK', '/opt/inverter/inverter.pl > /dev/null');
|
define('TASK', '/opt/inverter/inverter.pl > /dev/null');
|
||||||
define('CWD', '/opt/inverter/');
|
define('CWD', '/opt/inverter/');
|
||||||
define('DEFAULT_WAKE', '7:00');
|
|
||||||
define('DEFAULT_SLEEP', '19:00');
|
|
||||||
|
|
||||||
/* Initialize */
|
/* Initialize */
|
||||||
chdir(CWD);
|
chdir(CWD);
|
||||||
@@ -24,9 +22,10 @@ foreach (explode("\n", trim(command('atq 2> /dev/null'))) as $sJob) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Wake at sunrise, sleep at sunset */
|
/* Wake at sunrise, sleep at sunset */
|
||||||
$aTwilight = getTwilight(date('Y'), date('z'));
|
$fWake = getHour(getWake($aTwilight));
|
||||||
$fWake = getHour($sWake = isset($aTwilight) ? $aTwilight[1] : DEFAULT_WAKE);
|
$fSleep = getHour($sSleep = getSleep($aTwilight));
|
||||||
$fSleep = getHour($sSleep = isset($aTwilight) ? $aTwilight[3] : DEFAULT_SLEEP);
|
$sWake = $aTwilight[1];
|
||||||
|
$sSleep = $aTwilight[3];
|
||||||
System_Daemon::info(sprintf('Be awake between %s and %s', $sWake, $sSleep));
|
System_Daemon::info(sprintf('Be awake between %s and %s', $sWake, $sSleep));
|
||||||
|
|
||||||
/* Check appropriate state */
|
/* Check appropriate state */
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
#!/usr/bin/php
|
#!/usr/bin/php
|
||||||
<?php
|
<?php
|
||||||
require_once 'functions.php';
|
require_once 'functions.php';
|
||||||
require_once 'wunderground.php';
|
|
||||||
|
|
||||||
define('STATION', 'INOORDHO4');
|
|
||||||
define('RRD_FILE', 'data/inverter_%s_today.rrd');
|
define('RRD_FILE', 'data/inverter_%s_today.rrd');
|
||||||
define('RRD_FETCH', 'rrdtool fetch %s AVERAGE -r %d -s %d -e %d');
|
define('RRD_FETCH', 'rrdtool fetch %s AVERAGE -r %d -s %d -e %d');
|
||||||
define('PVOUTPUT_URL', 'http://pvoutput.org/service/r1/addstatus.jsp');
|
define('PVOUTPUT_URL', 'http://pvoutput.org/service/r1/addstatus.jsp');
|
||||||
define('TODAY_FILE', 'data/today_%s.csv');
|
define('TODAY_FILE', 'data/today_%s.csv');
|
||||||
define('FIELD', 'PAC');
|
define('FIELD', 'PAC');
|
||||||
define('RESOLUTION', 5);
|
define('RESOLUTION', 5);
|
||||||
|
define('TRESHOLD_CORRECT', 1);
|
||||||
define('MARGIN_ENERGY', 0.5);
|
define('MARGIN_ENERGY', 0.5);
|
||||||
define('MARGIN_TEMPERATURE', 0.4);
|
define('MARGIN_TEMPERATURE', 0.4);
|
||||||
|
|
||||||
$aSystems = array(
|
$aSystems = array(
|
||||||
'1206DS0163' => array('16e7a916d69656e354d00461a4da1d2e40cfa4f1', '12419')
|
'1206DS0163' => array('16e7a916d69656e354d00461a4da1d2e40cfa4f1', '12419')
|
||||||
);
|
);
|
||||||
@@ -28,8 +28,7 @@ $fVoltage = floatval($argv[3]); // V
|
|||||||
$sSerial = $argv[4];
|
$sSerial = $argv[4];
|
||||||
|
|
||||||
/* Fetch temperature */
|
/* Fetch temperature */
|
||||||
$aData = wunderground('conditions', sprintf('pws:%s', STATION));
|
$fTemperature = getTemperature();
|
||||||
$fTemperature = isset($aData['current_observation']['temp_c']) ? $aData['current_observation']['temp_c'] : null;
|
|
||||||
|
|
||||||
/* Fetch twilight data */
|
/* Fetch twilight data */
|
||||||
$iDay = date('z');
|
$iDay = date('z');
|
||||||
@@ -79,7 +78,10 @@ $aToday[3] = $fTemperature;
|
|||||||
file_put_contents($sTodayFile, implode(',', $aToday));
|
file_put_contents($sTodayFile, implode(',', $aToday));
|
||||||
|
|
||||||
/* Correct today data */
|
/* Correct today data */
|
||||||
$fToday = abs($aToday[1] - $fToday) > (MARGIN_ENERGY * $aToday[1]) ? $aToday[1] : $fToday;
|
$iWake = getWake($aTwilight);
|
||||||
|
if (($iTime - $iWake) / 3600 < TRESHOLD_CORRECT && abs($aToday[1] - $fToday) > (MARGIN_ENERGY * $aToday[1])) {
|
||||||
|
$fToday = $aToday[1];
|
||||||
|
}
|
||||||
|
|
||||||
/* Construct PVOutput data */
|
/* Construct PVOutput data */
|
||||||
$aData = array(
|
$aData = array(
|
||||||
@@ -95,6 +97,7 @@ if (isset($fTemperature)) {
|
|||||||
$fTemperature = abs($aToday[3] - $fTemperature) > (MARGIN_TEMPERATURE * $aToday[3]) ? $aToday[3] : $fTemperature;
|
$fTemperature = abs($aToday[3] - $fTemperature) > (MARGIN_TEMPERATURE * $aToday[3]) ? $aToday[3] : $fTemperature;
|
||||||
}
|
}
|
||||||
$aData['v5'] = $fTemperature; // ignore potential flaws in first temperature of the day
|
$aData['v5'] = $fTemperature; // ignore potential flaws in first temperature of the day
|
||||||
|
file_put_contents('temp.csv', sprintf("%d,%f\n", $iTime,$fTemperature), FILE_APPEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store debug data */
|
/* Store debug data */
|
||||||
|
|||||||
66
opt/inverter/rrd.php
Normal file
66
opt/inverter/rrd.php
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
class RRD {
|
||||||
|
const CREATE = 'create %s --step %d --start %d %s';
|
||||||
|
const UPDATE = 'update %s %d:%s';
|
||||||
|
const FETCH = 'fetch %s %s -r %d -s %d -e %d';
|
||||||
|
|
||||||
|
protected static $oInstance;
|
||||||
|
protected static $rProcess;
|
||||||
|
protected static $aPipes = array();
|
||||||
|
|
||||||
|
protected function __construct() {
|
||||||
|
self::$rProcess= proc_open('rrdtool -', array(
|
||||||
|
0 => array('pipe', 'r'),
|
||||||
|
1 => array('pipe', 'w')), self::$aPipes);
|
||||||
|
stream_set_blocking(self::$aPipes[1], false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function command($sCommand) {
|
||||||
|
if (!isset(self::$rProcess)) {
|
||||||
|
self::$oInstance = new self();
|
||||||
|
}
|
||||||
|
var_dump($sCommand);
|
||||||
|
fwrite(self::$aPipes[0], $sCommand . PHP_EOL);
|
||||||
|
$nNull = null;
|
||||||
|
$aRead = array(self::$aPipes[1]);
|
||||||
|
stream_select($aRead, $nNull, $nNull, 10);
|
||||||
|
return trim(stream_get_contents(self::$aPipes[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static function create($sFile, $iStep, $iStart, $sContents) {
|
||||||
|
$sCommand = sprintf(self::CREATE, $sFile, $iStep, $iStart, str_replace("\n", ' ', trim($sContents)));
|
||||||
|
return RRD::command($sCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function update($sFile, $iTime, $aValues) {
|
||||||
|
$sCommand = sprintf(self::UPDATE, $sFile, $iTime, implode(':', $aValues));
|
||||||
|
return RRD::command($sCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function fetch($sFile, $iResolution, $iStart, $iEnd, $sType = 'AVERAGE') {
|
||||||
|
$sCommand = sprintf(self::FETCH, $sFile, $sType, $iResolution, $iStart, $iEnd);
|
||||||
|
$sData = RRD::command($sCommand);
|
||||||
|
$aData = explode("\n", trim($sData));
|
||||||
|
$aFields = preg_split("~[\s]+~", array_shift($aData));
|
||||||
|
$aFields = array_flip($aFields);
|
||||||
|
array_shift($aData);
|
||||||
|
array_pop($aData);
|
||||||
|
foreach ($aData as $iKey => $sRow) {
|
||||||
|
$aRow = explode(':', $sRow);
|
||||||
|
$iTime = current($aRow);
|
||||||
|
$mValue = trim(next($aRow));
|
||||||
|
if ($mValue != '-nan') {
|
||||||
|
$aValues[$iTime] = floatval($mValue);
|
||||||
|
}
|
||||||
|
//$aValues[$iTime] = $fValue == 0 ? null : $fValue;
|
||||||
|
}
|
||||||
|
return array($aFields, $aValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
function __destruct() {
|
||||||
|
fwrite(self::$aPipes[0], "quit\n");
|
||||||
|
fclose(self::$aPipes[0]);
|
||||||
|
fclose(self::$aPipes[1]);
|
||||||
|
proc_close(self::$rProcess);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user