Houseenergy e Virtmeter su metern 1.2 e contatore che misura contemporaneamente prelievi e immissioni

Discussioni relative al software di monitoraggio energetico METERN
sunpower327
Messaggi: 41
Iscritto il: 21/01/2018, 10:50

Houseenergy e Virtmeter su metern 1.2 e contatore che misura contemporaneamente prelievi e immissioni

Messaggioda sunpower327 » 22/08/2019, 22:26

Salve, dopo avere dato indicazioni ad un amico di fare installare il classico sdm mod bus sulla linea consumi l'elettricista lo ha montato diversamente cioè ha collegato in serie anche all'impianto di produzione,
praticamente non marca i consumi ma solo i prelievi o le immissioni cioè vi sono due contatori all'interno del SDM.
Ho quindi dovuto fare alcune modifiche all'immagine creata da Flavio.
dopo avere aggiornato il sistema e metern alla 1.2 ho visto che la comapps di esempio houseenergy non lavorava correttamente inoltre di default usava la lettura direttamente interrogando tramite sdm120c i contatori.
da qui ho fatto alcune modifiche al file pooler485.sh e qui chiedo a Flavio se nella prossima immagine può aggiungere l'interrogazione anche del registro di esportazione.
per evitare incompatibilità del pooler485 con un utilizzo eventuale di pooler consumi ho aggiunto nuovamente i due registri che per distiguenre tra import ed export ho messo le classiche sigle _EE _IE in coda al numero del metern mentre flavio a messo solo il numero del metern interrogando la sola energia importata e non dovendo distiguenrla dalla esportata.
volutamente ho inserito in coda l'energia esportata e nuovamente l'energia importata per mantenere la compatibilità con altre comapps

Codice: Seleziona tutto

#!/bin/bash

ADDRESSES="$1"
BAUD_RATE="$2"
DEVICE="$3"

ADDR_ARR=$(echo $ADDRESSES | tr "," "\n")

while [ true ]; do

    ID=0
    POWER=""
    ENERGY=""
    ENERGYEXP=""
    CHECK=""

    for ADDRESS in $ADDR_ARR
    do
    #((ID++))
    ID=$ADDRESS
   CMD="sdm120c -a ${ADDRESS} -b ${BAUD_RATE} -z 10 -i -e -p -v -c -f -g -P N -w 10 -j 10 -d 0 -q ${DEVICE}"

    #echo $CMD
   
    VALUE=`$CMD`
    VOLTAGE=$(echo ${VALUE}   | awk '{print $1}')
    CURRENT=$(echo ${VALUE}   | awk '{print $2}')
    POWER=$(echo ${VALUE}     | awk '{print $3}')
    FACTOR=$(echo ${VALUE}    | awk '{print $4}')
    FREQUENCY=$(echo ${VALUE} | awk '{print $5}')
    ENERGY=$(echo ${VALUE}    | awk '{print $6}')
    ENERGYEXP=$(echo ${VALUE} | awk '{print $7}')
    CHECK=$(echo ${VALUE}     | awk '{print $8}')
   
    if [ "$CHECK" = "OK" ]; then
        echo -e "$ID($POWER*W)\n$ID($ENERGY*Wh)\n${ID}_1($VOLTAGE*V)\n${ID}_2($CURRENT*A)\n${ID}_3($FREQUENCY*Hz)\n${ID}_4($FACTOR*F)\n${ID}_EE($ENERGYEXP*Wh)\n${ID}_IE($ENERGY*Wh)\n${ID}_P($POWER*W)" > /dev/shm/metern${ADDRESS}.txt
    else
        if [ -f /dev/shm/metern${ADDRESS}.txt ]; then
            POWER="0.00"
            ENERGY=`sed -n '2p' /dev/shm/metern${ADDRESS}.txt`
            ENERGYEXP=`sed -n '7p' /dev/shm/metern${ADDRESS}.txt`
            VOLTAGE="0.00"
       CURRENT="0.00"
       FREQUENCY="0.00"
       FACTOR="0.00"
            echo -e "$ID($POWER*W)\n$ENERGY\n${ID}_1($VOLTAGE*V)\n${ID}_2($CURRENT*A)\n${ID}_3($FREQUENCY*Hz)\n${ID}_4($FACTOR*F)\n${ID}_EE($ENERGYEXP)\n${ID}_IE($ENERGY)\n${ID}_P($POWER*W)" > /dev/shm/metern${ADDRESS}.txt
        fi
    fi
    sleep 0.2

    done

done 


ora per evitare che house energy interroghi direttamente tramite sdm120c ho modificato la comapps reqsdm.php sempre mantenendo le compatibilità, in quanto non ho niente altro che aggiunto parametri.
ecco il file reqsdm modificato

Codice: Seleziona tutto

#!/usr/bin/php
<?php
// This script will output a meterN compatible format for the main or live command
// You'll need to setup correct permission
// chmod +x reqsdm.php
// then
// ln -s /var/www/comapps/reqsdm.php /usr/local/bin/reqsdm
// Request command with 'reqsdm tensione' or 'reqsdm corrente' or ......

if (isset($_SERVER['REMOTE_ADDR'])) {
    die('Direct access not permitted');
}
if (!isset($argv[1])) {
   die("Abording: no valid argument given.\n");
      } elseif ($argv[1] == 'tensione') {
         $outstr =  exec('cat /dev/shm/metern2.txt | egrep "^2_1\(" | grep "*V)"');
      } elseif ($argv[1] == 'EIMP') {
         $outstr =  exec('cat /dev/shm/metern2.txt | egrep "^2_IE\(" | grep "*Wh)"');
      } elseif ($argv[1] == 'EEXP') {
         $outstr =  exec('cat /dev/shm/metern2.txt | egrep "^2_EE\(" | grep "*Wh)"');
      } elseif ($argv[1] == 'TOT') {
         $outstr =  exec('cat /dev/shm/metern2.txt | egrep "^2_P\(" | grep "*W)"');
      } elseif ($argv[1] == 'corrente') {
         $outstr =  exec('cat /dev/shm/metern2.txt | egrep "^2_2\(" | grep "*A)"');
      } elseif ($argv[1] == 'freq') {
         $outstr =  exec('cat /dev/shm/metern2.txt | egrep "^2_3\(" | grep "*Hz)"');
      } elseif ($argv[1] == 'cospi') {
         $outstr =  exec('cat /dev/shm/metern2.txt | egrep "^2_4\(" | grep "*F)"');
      } elseif ($argv[1] == 'cpu-temp') {
         $outstr =  exec('cat /sys/class/thermal/thermal_zone0/temp');
         $outstr = $outstr/1000;
         $outstr = "cpu($outstr*°C)";
      } elseif ($argv[1] == 'pdc-live') {
            $outstr =  exec('cat /dev/shm/metern8.txt | egrep "^8\(" | grep "*W)"');
      } elseif ($argv[1] == 'pdc-main') {
           $outstr =  exec('cat /dev/shm/metern8.txt | egrep "^8\(" | grep "*Wh)"');
      // and so on ....
   } else {
    die("Usage: reqsdm (tensione|corrente|freq|cospi|cpu-temp)\n");
   }
echo "$outstr";
?>

come si può vedere ho aggiunto EIMP EEXP e TOT
effettivamente potevo evitare di rindondare il dato di energia importata in pooler ma volevo vedere distintamente le lettere che indicano l'energia importata.
ora metto il file con piccole modifiche funzionante che nel sistema oggetto di configurazione ho rinominato houseenergy3.php

Codice: Seleziona tutto

#!/usr/bin/php
<?php
// A virtual meters example for meterN. This script will simulate a house consumption and selfconsumuption meter. You must own a total (import/export) and a production meter.
//                         _____ 
//                        /     \
//      +----------+     /       \                                  - ^ -
//      |Production| --> | House | <-- import ___ +-----------+ ___  /X\ Grid
//      +----------+     |_______| --> export     |Total meter|     /V V\
//                                                +-----------+
//               (consumption/selfconsumuption)
//
// ln -s /var/www/comapps/houseenergy3.php /usr/local/bin/houseenergy3
// houseenergy3 [ power | powerimp | powerexp | powerself | energy | self ]

if (isset($_SERVER['REMOTE_ADDR'])) {
    die('Direct access not permitted');
}
// Set the new virtual meters
// Consumption
$HOUSEID     = '2'; // ID
$HOUSEmetnum = 2; // meter number
// Selfconsumption
$SELFID      = '5';
$SELFCmetnum = 5;

// Set up real meters
// Production
$PRODID       = '1'; // ID
$PRODcmd      = 'pooltot energy'; // Energy command
$POWERPRODcmd = 'pooltot power'; // Power
$PRODmetnum   = 1; // meter number
// TOT
$TPID         = '2_P';
$TOTPOWERcmd  = 'reqsdm TOT'; // return the total power (eg if import = 45W, export -55W)
//$TOTPOWERcmd  = 'sdm120c -a2 -P N -b9600 -2 -m -w10 -p /dev/ttyUSB0';
// Energy Imported
$IMPID        = '2_IE';
$IMPcmd    = 'reqsdm EIMP';
//$IMPcmd       = 'sdm120c -a2 -P N -b9600 -2 -m -w10 -i /dev/ttyUSB0';
$IMPmetnum    = 3;
// Energy Exported
$EXPID        = '2_EE';
$EXPcmd    = 'reqsdm EEXP';
//$EXPcmd       = 'sdm120c -a2 -P N -b9600 -2 -m -w10 -e /dev/ttyUSB0';
$EXPmetnum    = 4;

// Path to metern
$MNDIR = '/var/www/metern';

// No edit should be needed bellow
$MEMORY = 624;

function isvalid($id, $datareturn) //  IEC 62056 data set structure
{
    $regexp = "/^$id\(-?[0-9\.]+\*[A-z0-9³²%°]+\)$/i"; //ID(VALUE*UNIT)
    if (preg_match($regexp, $datareturn)) {
        $datareturn = preg_replace("/^$id\(/i", '', $datareturn, 1); // VALUE*UNIT)
        $datareturn = preg_replace("/\*[A-z0-9³²%°]+\)$/i", '', $datareturn, 1); // VALUE
        settype($datareturn, 'int');
    } else {
        $datareturn = null;
    }
    return $datareturn;
}

function retrievecsv($meternum, $csvarray, $passo, $datareturn) // Retrieve last know value in csv
{
    $datareturn = null;
    $contalines = count($csvarray);
    $j          = 0;
    while (!isset($datareturn)) {
        $j++;
        $array      = preg_split('/,/', $csvarray[$contalines - $j]);
        $datareturn = trim($array[$meternum]);
        if ($datareturn == '') {
            $datareturn = null;
        }
        if ($j == $contalines) {
            $datareturn = 0;
        }
    }
    if ($datareturn > $passo) {
        $datareturn -= $passo;
    }
    return $datareturn;
}

if (isset($argv[1])) {
    if ($argv[1] == 'power' || $argv[1] == 'powerimp' || $argv[1] == 'powerexp' || $argv[1] == 'powerself') {
        $datareturn = exec($TOTPOWERcmd);
        $datareturn = trim($datareturn);
        $totpower   = isvalid($TPID, $datareturn);
       
        $datareturn = exec($POWERPRODcmd);
        $datareturn = trim($datareturn);
        $prodpower  = isvalid($PRODID, $datareturn);
       
        $power = $prodpower + $totpower;
       
        if ($argv[1] == 'power') {
            $outstr = utf8_decode("$HOUSEID($power*W)\n");
        } else {
            if ($totpower > 0) { // Import
                $imppower = $power - $prodpower;
                $exppower = 0;
                $slfpower = $prodpower;
            } else { // Export
                $imppower = 0;
                $exppower = $prodpower - $power;
                $slfpower = $power;
            }
        }
        if ($argv[1] == 'powerimp') {
            $outstr = utf8_decode("$IMPID($imppower*W)\n");
        } elseif ($argv[1] == 'powerexp') {
            $outstr = utf8_decode("$EXPID($exppower*W)\n");
        } elseif ($argv[1] == 'powerself') {
            $outstr = utf8_decode("$SELFID($slfpower*W)\n");
        }
        echo "$outstr";
    } elseif ($argv[1] == 'energy' || $argv[1] == 'self') {
        define('checkaccess', TRUE);
        include("$MNDIR/config/config_main.php");
       
        include("$MNDIR/config/config_met$HOUSEmetnum.php");
        include("$MNDIR/config/config_met$SELFCmetnum.php");
        include("$MNDIR/config/config_met$IMPmetnum.php");
        include("$MNDIR/config/config_met$EXPmetnum.php");
        include("$MNDIR/config/config_met$PRODmetnum.php");
       
        ///// open shm memory
        @$shmid = shmop_open($MEMORY, 'a', 0, 0);
        if (!empty($shmid)) {
            $size = shmop_size($shmid);
            shmop_close($shmid);
           
            $shmid        = shmop_open($MEMORY, 'c', 0666, $size);
            $memarraydata = shmop_read($shmid, 0, $size);
            shmop_close($shmid);
            $memarray = json_decode($memarraydata, true);
        }
       
        if (!isset($memarray['prevHOUSE']) || !isset($memarray['prevSELF'])) { // At boot retrieve values in last csv
            $output = array();
            $output = glob($MNDIR . '/data/csv/*.csv');
            sort($output);
            $cnt = count($output);
           
            $lines = file($output[$cnt - 1]); // should be today
            if ($cnt > 0) {
                $contalines = count($lines);
                $lastarray  = preg_split("/,/", $lines[$contalines - 1]);
               
                $datareturn                = null;
                $memarray['prevIMPhouse']  = retrievecsv($IMPmetnum, $lines, ${'PASSO' . $IMPmetnum}, $datareturn);
                $datareturn                = null;
                $memarray['prevEXPhouse']  = retrievecsv($EXPmetnum, $lines, ${'PASSO' . $EXPmetnum}, $datareturn);
                $memarray['prevEXPself']   = $memarray['prevEXPhouse'];
                $datareturn                = null;
                $memarray['prevHOUSE']     = retrievecsv($HOUSEmetnum, $lines, ${'PASSO' . $HOUSEmetnum}, $datareturn);
      //
           //if ($memarray['prevHOUSE'] < 914292) {
           //   $memarray['prevHOUSE'] = 914292;   
           //}   
      
      //$pippo = $memarray['prevHOUSE'];
      //exec("echo 'prevhouse'.'$pippo' >> /var/logdebug/housebug1.txt");
      //
                $datareturn                = null;
                $memarray['prevSELF']      = retrievecsv($SELFCmetnum, $lines, ${'PASSO' . $SELFCmetnum}, $datareturn);
                $datareturn                = null;
                $memarray['prevPRODhouse'] = retrievecsv($PRODmetnum, $lines, ${'PASSO' . $PRODmetnum}, $datareturn);
                $memarray['prevPRODself']  = $memarray['prevPRODhouse'];
            } else { // no csv
                $memarray['prevIMPhouse']  = 0;
                $memarray['prevEXPhouse']  = 0;
                $memarray['prevEXPself']   = 0;
                $memarray['prevHOUSE']     = 0;
                $memarray['prevSELF']      = 0;
                $memarray['prevPRODhouse'] = 0;
                $memarray['prevPRODself']  = 0;
            }
        }
       
        // Now retrieve latest values
        $datareturn = null;
        $import     = null;
        $export     = null;
        $production = null;
        $outstr     = null;
        // latest import
        if ($argv[1] == 'energy') {
            exec($IMPcmd, $datareturn);
            $datareturn = trim(implode($datareturn));
            $import     = isvalid($IMPID, $datareturn);
       //exec("echo 'imp'.'$import' >> /var/logdebug/housebug1.txt");
        }
        // latest export
        $datareturn = null;
        exec($EXPcmd, $datareturn);
        $datareturn = trim(implode($datareturn));
        $export     = isvalid($EXPID, $datareturn);
        //exec("echo 'exp'.'$export' >> /var/logdebug/housebug1.txt");

       
        // latest production
        $datareturn = null;
        exec($PRODcmd, $datareturn);
        $datareturn = trim(implode($datareturn));
        $production = isvalid($PRODID, $datareturn);
       
        // energy
        if ($argv[1] == 'energy') {
            if (isset($import) && isset($export)) {
                // Some passover checks
                if ($export >= $memarray['prevEXPhouse']) {
                    $diffEXP = $export - $memarray['prevEXPhouse'];
                } else {
                    $diffEXP = $export + ${'PASSO' . $EXPmetnum} - $memarray['prevEXPhouse'];
                }
                if (isset($production)) {
                    if ($production >= $memarray['prevPRODhouse']) {
                        $diffPROD = $production - $memarray['prevPRODhouse'];
                    } else {
                        $diffPROD = $production + ${'PASSO' . $PRODmetnum} - $memarray['prevPRODhouse'];
                    }
                    settype($memarray['prevPRODhouse'], 'int');
                    $memarray['prevPRODhouse'] = $production;
                } else { // no production case
                    $diffPROD = 0;
                    $diffEXP  = 0;
                }
                if ($import >= $memarray['prevIMPhouse']) {
                    $diffIMP = $import - $memarray['prevIMPhouse'];
                } else {
                    $diffIMP = $import + ${'PASSO' . $IMPmetnum} - $memarray['prevIMPhouse'];
                }
                $difference = $diffIMP + $diffPROD - $diffEXP;
            } else { // no import/export values
                $difference = 0;
            }
            /*
            //  bug
            if ($difference < 0) {
                date_default_timezone_set($DTZ);
                $a   = $memarray['prevHOUSE'];
                $b   = $memarray['prevEXPhouse'];
                $c   = $memarray['prevPRODhouse'];
                $d   = $memarray['prevIMPhouse'];
                $dt  = date('Ymd H:i:s');
                $tut = "$dt \t diff $difference \n prevHOUSE $a\n export: $export $b\n prod: $production $c\n import: $import $d\n";
                //exec("echo '$tut' >> /srv/http/comapps/housebug2.txt");
               
                $difference = 0; // correction
            }
            */
            $memarray['prevHOUSE'] += $difference;
      
       //$tmp=$memarray['prevHOUSE'];
       //exec("echo '$tmp' >> /var/logdebug/housebug.txt");   

           
            if ($memarray['prevHOUSE'] >= ${'PASSO' . $HOUSEmetnum}) { // passed over
                $memarray['prevHOUSE'] -= ${'PASSO' . $HOUSEmetnum};
            }
      
               
            $val    = $memarray['prevHOUSE'];

       //exec("echo '$val' >> /var/logdebug/housebug.txt");
            $outstr = utf8_decode("$HOUSEID($val*Wh)\n");
           
            settype($memarray['prevIMPhouse'], 'int');
            $memarray['prevIMPhouse'] = $import;
            settype($memarray['prevEXPhouse'], 'int');
            $memarray['prevEXPhouse'] = $export;
            settype($memarray['prevHOUSE'], 'int');
        } else { // Self
            if (isset($export)) {
                // Some passover checks
                if ($export >= $memarray['prevEXPself']) {
                    $diffEXP = $export - $memarray['prevEXPself'];
                } else {
                    $diffEXP = $export + ${'PASSO' . $EXPmetnum} - $memarray['prevEXPself'];
                }
                if (isset($production)) {
                    if ($production >= $memarray['prevPRODself']) {
                        $diffPROD = $production - $memarray['prevPRODself'];
                    } else {
                        $diffPROD = $production + ${'PASSO' . $PRODmetnum} - $memarray['prevPRODself'];
                    }
                    settype($memarray['prevPRODself'], 'int');
                    $memarray['prevPRODself'] = $production;
                } else { // no production case
                    $diffPROD = 0;
                    $diffEXP  = 0;
                }
                $difference = $diffPROD - $diffEXP;
            } else { // no export values
                $difference = 0;
            }
           
            $memarray['prevSELF'] += $difference;
            if ($memarray['prevSELF'] >= ${'PASSO' . $SELFCmetnum}) {
                $memarray['prevSELF'] -= ${'PASSO' . $SELFCmetnum};
            }
            $val    = $memarray['prevSELF'];
            $outstr = utf8_decode("$SELFID($val*Wh)\n");
           
            settype($memarray['prevEXPself'], 'int');
            $memarray['prevEXPself'] = $export;
            settype($memarray['prevSELF'], 'int');
        }
       
        ///// save shm memory
        $data = json_encode($memarray);
        $size = mb_strlen($data, 'UTF-8');
        @$shmid = shmop_open($MEMORY, 'a', 0, 0);
        if (!empty($shmid)) {
            shmop_delete($shmid);
            shmop_close($shmid);
        }
        $shmid = shmop_open($MEMORY, 'c', 0666, $size);
        shmop_write($shmid, $data, 0);
        shmop_close($shmid);
       
        echo "$outstr";
    } elseif ($argv[1] == 'shm') {
        @$shmid = shmop_open($MEMORY, 'a', 0, 0);
        if (!empty($shmid)) {
            $size = shmop_size($shmid);
            shmop_close($shmid);
           
            $shmid        = shmop_open($MEMORY, 'c', 0666, $size);
            $memarraydata = shmop_read($shmid, 0, $size);
            shmop_close($shmid);
            $memarray = json_decode($memarraydata, true);
            print_r($memarray);
            echo "ps: Always clean the shm before using this script from meterN ! (ipcrm -M $MEMORY)\n";
        } else {
            echo "Empty shm ($MEMORY)\n";
        }
       
    } else {
        die("Abording: no valid argument given\n");
    }
} else {
    die("Usage: houseenergy3 { power | powerimp | powerexp | powerself | energy | self }\n");
}
?>

virtmeter mi sembra di avere capito che non può sostituire un contatore reale e volendo creare un contatore reale dei consumi ho dovuto usare la base di house energy
comunque virt meter lo ho utilizzato per i contatori consumi immissioni e autoconsumo

per capire la configurazione metto le configurazioni che ho fatto su metern
tanto per cambiare ci sono due inverter quindi li ho messo sul 6 e 7 i contatori reali e con pooltot ho ricreato il contatore di produzione.
ecco il pooltot

Codice: Seleziona tutto

#!/usr/bin/php
<?php
if (isset($_SERVER['REMOTE_ADDR'])) {
    die('Direct access not permitted');
}
// If you own several production or consumption meters, this script will simulate a total production or consumption meter .
//
// How-to :
// 1) Make a link : ln -s /var/www/comapps/pooltot.php /usr/local/bin/pooltot
// 2) In meterN, set your real meters as 'Elect' 'House production | House consumption'
// 3) Then, set this virtual meter in meterN. The type should be 'Elect Other' with a passover value like 100000
//    Request the 'Main command' with 'pooltot energy' and 'Live command' with 'pooltot power'
// 4) Configure the script

// meterN config
$pathtomn  = '/var/www/metern'; // without / at the end
// This virutal total meter config
$WHICHTYPE = 1; // Set to 1 for a virtual production meter and 2 for a consumption
$METERID   = 1; // this vitual meter ID
$METERNUM  = 1; // this vitual meterN meter number

// No edit should be needed bellow
$prevfile = '/dev/shm/prevpooltot.json';
$verbose  = false; //debug

function getvalue($id, $cmd) //  Get data and validate with IEC 62056 data set structure
{
    $datareturn = null;
    $giveup     = 0;
    $regexp     = "/^$id\(-?[0-9\.]+\*[A-z0-9³²%°]+\)$/i"; //ID(VALUE*UNIT)
   
    while (!isset($datareturn) && $giveup < 3) { // Try 3 times
        exec($cmd, $datareturn);
        $datareturn = trim(implode($datareturn));
       
        if (preg_match($regexp, $datareturn)) {
            $datareturn = preg_replace("/^$id\(/i", '', $datareturn, 1); // VALUE*UNIT)
            $datareturn = preg_replace("/\*[A-z0-9³²%°]+\)$/i", '', $datareturn, 1); // VALUE
            settype($datareturn, 'int');
        } else {
            $datareturn = null;
        }
        $giveup++;
    }
    return $datareturn;
}

function retrievecsv($meternum, $csvarray, $passo, $datareturn) // Retrieve last know value in latest csv
{
    $datareturn = null;
    $contalines = count($csvarray);
    $j          = 0;
    while (!isset($datareturn)) {
        $j++;
        $array      = preg_split('/,/', $csvarray[$contalines - $j]);
        $datareturn = (int) trim($array[$meternum]);
        if ($datareturn == '') {
            $datareturn = null;
        }
        if ($j == $contalines) {
            $datareturn = 0;
        }
    }
    if ($datareturn > $passo) {
        $datareturn -= $passo;
    }
    return $datareturn;
}

if (isset($argv[1]) && ($argv[1] == 'power' || $argv[1] == 'energy')) {
    define('checkaccess', TRUE);
    include("$pathtomn/config/config_main.php");
    include("$pathtomn/config/memory.php");
    for ($i = 1; $i <= $NUMMETER; $i++) {
        include("$pathtomn/config/config_met$i.php");
    }
    date_default_timezone_set($DTZ);
   
    if ($argv[1] == 'power') {
        $nowUTC  = strtotime(date("Ymd H:i:s"));
        ///// open mN shm live memory
        $data    = file_get_contents($LIVEMEMORY);
        $livemem = json_decode($data, true);
        if ($nowUTC - $livemem['UTC'] > 30) {
            die("Abording: Too late mN live values\n");
        }
    } else { // energy
        // Retrieve previous virtual meter value
        if (file_exists($prevfile)) {
            $data     = file_get_contents($prevfile);
            $previous = json_decode($data, true);
        }
       
        if (!isset($previous['KWHtot'])) { // At boot retrieve values in last csv
            $output = array();
            $output = glob($pathtomn . '/data/csv/*.csv');
            sort($output);
            $cnt = count($output);
           
            if ($cnt > 0) {
                $lines              = file($output[$cnt - 1]);
                $contalines         = count($lines);
                $lastarray          = preg_split("/,/", $lines[$contalines - 1]);
                $datareturn         = null;
                $previous['KWHtot'] = retrievecsv($METERNUM, $lines, ${'PASSO' . $METERNUM}, $datareturn);
                if ($verbose) {
                    $t = $previous['KWHtot'];
                    echo "Retrieve KWHtot value in last csv : $t kWh\n";
                }
            } else { // no csv, starting from scratch !
                $previous['KWHtot'] = 0;
                if ($verbose) {
                    echo "Starting from scratch !\n";
                }
            }
        } elseif ($verbose) {
            $t = $previous['KWHtot'];
            echo "Previous KWHtot value : $t kWh\n";
        }
    }
   
    $GPtot = 0;
    $diff  = 0;
    // Retreiving latest values
    for ($i = 1; $i <= $NUMMETER; $i++) {
        $value = null;
        if (${'TYPE' . $i} == 'Elect' && ${'PROD' . $i} == $WHICHTYPE && $i != $METERNUM && !${'SKIPMONITORING' . $i}) {
            if ($argv[1] == 'power') {
                if (isset(${'LIVECOMMAND' . $i}) && isset($livemem["${'METNAME'.$i}$i"])) {
                    $GPtot += $livemem["${'METNAME'.$i}$i"];
                }
                if ($verbose) {
                    $t = $livemem["${'METNAME'.$i}$i"];
                    echo "\nPower #$i ${'METNAME'.$i} : $t W\n";
                }
            } else {
                $value = getvalue(${'ID' . $i}, ${'COMMAND' . $i});
                if ($verbose) {
                    echo "\nGetting latest energy for #$i (${'METNAME'.$i}) : $value kWh\n";
                }
                if (isset($value)) {
                    if (isset($previous["prevTotalcounter$i"])) {
                        if ($verbose) {
                            $t = $previous["prevTotalcounter$i"];
                            echo "Previous value: $t kWh\n";
                        }
                        // Some passover checks
                        if ($value >= $previous["prevTotalcounter$i"]) {
                            $diff = $value - $previous["prevTotalcounter$i"];
                        } else {
                            if ($verbose) {
                                echo "passover: $value < ${'PASSO' . $PRODmetnum} \n";
                            }
                            $diff = $value + ${'PASSO' . $PRODmetnum} - $previous["prevTotalcounter$i"];
                        }
                    }
                    settype($previous["prevTotalcounter$i"], 'int');
                    $previous["prevTotalcounter$i"] = $value;
                    if ($verbose) {
                        echo "The difference is $diff, saving as prev value $value for #$i (${'METNAME'.$i})\n";
                    }
                    $previous['KWHtot'] += $diff;
                }
            }
        }
    }
    // Output
    if ($argv[1] == 'power') {
        if ($GPtot > 1000) {
            $GPtot = round($GPtot, 0);
        } else {
            $GPtot = round($GPtot, 1);
        }
        echo "$METERID($GPtot*W)\n";
    } else { // energy
        if ($verbose) {
            $t = $previous['KWHtot'];
            echo "\nSaving total #$METERNUM ($METERID) : $t kWh\n--\n";
        }
        if ($previous['KWHtot'] >= ${'PASSO' . $METERNUM}) { // virtual meter passed over
            $previous['KWHtot'] -= ${'PASSO' . $METERNUM};
            if ($verbose) {
                $t = $previous['KWHtot'];
                echo "Total passover $METERID :  $t > ${'PASSO' . $METERNUM}\n";
            }
        }
        // Save previous values
        $data = json_encode($previous);
        file_put_contents($prevfile, $data);
       
        $KWHtot = $previous['KWHtot'];
        echo "$METERID($KWHtot*Wh)\n";
    }
} else {
    echo "Usage: pooltot { power | energy }\n";
    die($prevfile);   
    if (file_exists($prevfile)) {
        $data     = file_get_contents($prevfile);
        $previous = json_decode($data, true);
        print_r($previous);
    }
}
?>


metern è configurato con sette contatori i pool123suno e pool123sdue sono sosia di pool123s solo che puntano a due inverter diversi
la configurazione dei meters è così riassunta

Codice: Seleziona tutto

 1 produzione  elect other             1 pooltot energy                     pass over 0 1 pooltot power
 2 consumo     elect house consumption 2   houseenergy3 energy         pass over 0 2 houseenergy3 power
 3 prelievi    elect other             3 virtmeter 3 0 0 impenergy 0        pass over 0 3 virtmeter 3 0 0 imppower 0
 4 immissioni  elect other             4 virtmeter 4 0 0 expenergy 0        pass over 0 4 virtmeter 4 0 0 exppower 0
 5 autoconsumo elect other             5 virtmeter 5 0 0 selfcenergy 0      pass over 0 5 virtmeter 5 0 0 selfcpower 0
 6 prodsudest  elect house production  6 pool123suno energy                 pass over 0 6 pool123suno power
 7 prodsudovest elect house production 7 pool123sdue energy                 pass over 0 6 pool123sdue power


il codice indicato è dei rispettivi proprietari che ringrazio pubblicamente.
ho messo questo post perchè non ho visto sdm120c montati elettricamente come questo.
se avete suggerimenti .


sunpower327
Messaggi: 41
Iscritto il: 21/01/2018, 10:50

Re: Houseenergy e Virtmeter su metern 1.2 e contatore che misura contemporaneamente prelievi e immissioni

Messaggioda sunpower327 » 27/08/2019, 22:59

purtroppo ho trovato in houseenergy delle instabilità , da prima ho provato a sostituire pooltot con virtmetern.
cercando un po sul forum ho preso atto che quasi tutti usano il SDM per il rilievo dei soli consumi.
si sono verificate alcune instabilita, ho provato a fermare sia metern che 123solar eliminare la cartella csv di metern e a riavviare il raspberry alla fine dopo avere perso un pò di tempo comunque dopo i primi 2 giorni di assestamento ho comunque trovato instabile il funzionamento di house energy con scarocciamenti vari dei totli nel cruscotto, scrivo del file houseenergy così come ho postato, quindi ho deciso di spostare fisicamente i cavi del misuratore sdm del mio amico su solo i consumi ed ho sostituito quindi houseenergy con poolerconsumi.


Torna a “MeterN”

Chi c’è in linea

Visitano il forum: Nessuno e 11 ospiti