Page 2 of 3

Re: daily live reading in index

Posted: Thu May 09, 2019 3:58 pm
by jeanmarc
You do not request a sdm right ? So why use this ?
You can have whatever command.. Put "dayval" as indicator command

Re: daily live reading in index

Posted: Thu May 09, 2019 10:58 pm
by giulio
with "dayval" command I get:


Command: dayval

loadcheck already running as pid 20318 so stopping now is not valid, the correct format is (1234.5 *)

Re: daily live reading in index

Posted: Fri May 10, 2019 6:37 am
by jeanmarc
:?: Can you send screenshot ? it's over my head

Re: daily live reading in index

Posted: Fri May 10, 2019 1:47 pm
by giulio
Image

https://drive.google.com/file/d/1DRd02I ... TR3hz/view


I'm sorry, but I can't insert an image differently

Re: daily live reading in index

Posted: Fri May 10, 2019 2:19 pm
by jeanmarc
:shock: What an odd error.. I don't know where that come from.
Did you encode your php in UTF-8 Linux encoding ? Does 'dayval' work from CLI ?

Re: daily live reading in index

Posted: Fri May 10, 2019 2:29 pm
by giulio
the dayval command returns information from another script of mine that starts with Metern "loadcheck.php" ..the pid is the same

I can not understand

Re: daily live reading in index

Posted: Fri May 10, 2019 2:32 pm
by jeanmarc
You have the same error in terminal ?

Re: daily live reading in index

Posted: Fri May 10, 2019 2:34 pm
by giulio
yes, the same error in terminal

Re: daily live reading in index

Posted: Fri May 10, 2019 2:42 pm
by jeanmarc
Can you post your other script loadcheck ?

Re: daily live reading in index

Posted: Fri May 10, 2019 2:58 pm
by giulio
It is a Flanesi script, which I modified to deactivate loads due to exceeding power

Code: Select all

#!/usr/bin/php
<?php

    /**
     * Raspberry load check control & notify with RPInotify
     *
     * "loadcheck" Rev. 1.1
     *
     * Copyright (C) 2017 Flavio Anesi <www.flanesi.it>
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 2 of the License, or
     * (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     */

    /**
     * History
     *
     * 17-11-2017: Rilascio versione v1.0
	 *
	 * 24-05-2018: Vers. 1.1 : spostamento file di controllo .pid in cartella emporanea /dev/shm
     *
	
	 * Descrizione
	 *
	 * Il presente script, esegue un controllo dei consumi domestici e in caso di superamento delle varie soglie di intervento
	 * (descrite nel seguito) del contatore elettronico invia una notifica sul cellulare mediante il servizio gratuito RpiNotify
	 * Per il funzionamento è quindi necessario avere in funzione il servizio di monitoraggio con MeterN ed aver effettuato 
	 * una registrazione al servizio RpiNotify in modo da avere a disposizione il token rilasciato da RpiNotify e da inserire di seguito.
	 *	 

    /**
	 * Creare il symlink con:
	 * ln -s /var/www/MyScripts/loadcheck.php /usr/bin/loadcheck
	 *
     * Lo script puo' essere avviato in automatico all'avvio di MeterN (ver 0.8.4 e succ.), inserendo la seguente riga nel file 
	 * "/var/www/metern/config/config_daemon.php" nella sessione Start
	 *
	 * exec("loadcheck > /dev/null 2>/dev/null &");
	 *
	 * mentre nella sessione Stop
	 *
	 * exec("pkill -f loadcheck > /dev/null 2>&1 &"); 
     *
	 *
	 * A seguire alcune definizioni:
	 *
	 * Potenza contrattuale: 	la potenza richiesta all’atto della stipula di contratto e contrattualmente garantita.
								Nel caso di utenze domestiche è abitualmente 3 kW;
	 * Potenza disponibile: 	potenza contrattuale più 10%, nel caso di specie corrispondente a 3,3 kW;
	 * Potenza limite: 			potenza disponibile + 27%, nel caso di specie 4,2 kW.
	 *
	 * Le regole di intervento del contatore elettronico monofase GEM sono state tratte da questa guida presente in rete:
	 * http:\\www.flanesi.it\blog\download\Il-nuovo-contatore-elettronico.pdf
	 *
	 
     */

    /**
     * Imposta "error reporting"
     *
     * Turn off all error reporting         ---> level: 0
     * Report simple running errors         ---> level: E_ERROR | E_WARNING | E_PARSE
     * Reporting E_NOTICE can be good too   ---> level: E_ERROR | E_WARNING | E_PARSE | E_NOTICE
     * Report all errors except E_NOTICE    ---> level: E_ALL & ~E_NOTICE
     * Report all PHP errors                ---> level: E_ALL
     */
    error_reporting(0);

    /** Nome dello script  */
    $filename = basename(__FILE__, ".php");

    /** Percorso memorizzazione file pid */
    $pathname = '/dev/shm/'.$filename;

    /** Percorso e nome del "pid" file */
    $pidfile = $pathname . ".pid";

    /** Inizializza il "Task monitor signal event" */
    declare(ticks = 1);

    /** Registro funzione da eseguire all'arresto dell'esecuzione */
    register_shutdown_function("fatalErrorShutdown");

    /** Installo cattura dei segnali "Ctrl+C e kill SIGTERM" */
    pcntl_signal(SIGTERM, "sigintShutdown");
    pcntl_signal(SIGINT, "sigintShutdown");

    /** Controllo esistenza altro processo attivo */
    checkAlreadyRunning();

    /*******************************************************************************************************************
     * Configurazione script                                                                                           *
     *******************************************************************************************************************/

    /**
     * 
     *
     * Modificare la configurazione dello script in base alla propria installazione
     */

	 /**
     * Modalita' di funzionamento
     *
     * 0 = Disattiva il debug su terminale.
     * 1 = Attiva il debug su terminale se avvio dello script manualmente
     */
    const DEBUG_MODE = 0;
	 
	 
    /*******************************************************************************************************************
     * Configurazione fornitura                                                                                        *
     *******************************************************************************************************************/

    /** Potenza contrattuale in kW */
	
    const CONTRACT_POWER = 3;

	/*******************************************************************************************************************
     * Configurazione misuratori                                                                                       *
     *******************************************************************************************************************/

    /** Meter Id Prelievi */
	
    const METERN_PRELIEVI = 3;
	
	/** Tipo di misurazione dei Prelievi
	
	*	Impostare la variabile TYPE_IMP a seconda del metodo di calcolo/misura dei PRELIEVI
	*	0 se si utilizza di eflow
	*	1 se si utilizza virtmeter
	*	2 se si utilizza un contatore per le misura di prelievi / immissioni
	*	3 TEST - NO LETTURA (legge il valore da un file /var/www/MyScripts/testprel.txt)
							(il contenuto del file testperl deve essere nel formato es: 3(2500*W) )
	*/
	
	$TYPE_IMP = 0;
	
    /* Percorso e nome file destinazione per inserire un indicatore sullo stato dello script in MeterN 
     */
    $LOAD_FILE = $pathname . ".txt";	

	/* Percorso e nome file destinazione logger
     */
    const METERN_FILE_LOGGER = "/var/www/metern/data/events.txt";

	/*******************************************************************************************************************
     * Configurazione RpiNotify                                                                                      *
     *******************************************************************************************************************/

    /** Token RpiNotify per notifiche push*/
	
    const token = "*********************************************************************************************************************************************";
    const token2 = "********************************************************************************************************************************************";

    /*******************************************************************************************************************
     * Fine configurazione script                                                                                      *
     *******************************************************************************************************************/

    /*******************************************************************************************************************
     * Calcoli interni in base alla configurazione                                                                     *
     *******************************************************************************************************************/

    /** Potenza disponibile (Kw) */
    const AVAIL_POWER = CONTRACT_POWER * 1.1;

    /** Potenza limite (kW) */
    const LIMIT_POWER = AVAIL_POWER * 1.17;

    /** Potenza max per ditacco (kW) */
    const MAX_POWER = 14;

    /** Aggiunto */
    $LavanderiaOff = 'http://192.168.1.139/control?cmd=GPIO,12,1';
	$LavanderiaOn = 'http://192.168.1.139/control?cmd=GPIO,12,0';
    $StufaOff = 'https://maker.ifttt.com/trigger/Stufa bagno off/with/key/**********************';
 
	/** Se attivo DEBUG su terminale */
	if(DEBUG_MODE == 1)
	{
		/** Stampo informazioni di debug su terminale, visibili solo se avviato manualmente */

		printf("#########################################################\n");
		printf("Potenza CONTRATTUALE      : %8.02f kW\n", CONTRACT_POWER);
		printf("Potenza DISPONIBILE       : %8.02f kW\n", AVAIL_POWER);
		printf("Potenza LIMITE            : %8.02f kW\n", LIMIT_POWER);
		printf("Potenza MAX PRELEVABILE   : %8.02f kW\n", MAX_POWER);
	}
 
    /*******************************************************************************************************************
     * Fine calcoli interni in base alla configurazione                                                                *
     *******************************************************************************************************************/

    /** Logger event */
    logevents("Started Load check Script");
	
	/* stato load script */
    $buffer = sprintf("load(1*X)\n");
    /* Save file */
    file_put_contents($LOAD_FILE, $buffer);

    /** Loop infinito stile servizio */
    while (true)
    {
		/** Inizializzo prelievi */
		$prelievi = get_prelievi($TYPE_IMP);
		
		/** Se attivo DEBUG su terminale */
        if(DEBUG_MODE == 1)
        {
            printf("#########################################################\n");
            printf("Prelievi            : %8.02f W\n", $prelievi);
        }
				
		if ($prelievi > MAX_POWER*1000) // SUPERO POTENZA MASSIMA - distacco in 1-2 secondi
        {
			$msg = "Prelievi: " . $prelievi/1000 . "kW. Distacco imposto per supero potenza massima di " . MAX_POWER . "kW\n";
			if(DEBUG_MODE == 1)
			{
            printf($msg);
			}
			rpinotify(token, $msg);
			rpinotify(token2, $msg);
		}
        else
        {
		  if ($prelievi > LIMIT_POWER*1000) // SUPERO POTENZA LIMITE - distacco in 2 min
		  {			
			$ch = curl_init($LavanderiaOff);
	                curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 5000); // error
                	curl_exec($ch);
                	curl_close($ch);
					$msg = "Distacco lavanderia per supero potenza limite";
					rpinotify(token, $msg);
					rpinotify(token2, $msg);
					
                time.	sleep (15);
                
                
                
                if ($prelievi > LIMIT_POWER*1000) // LAVANDERIA NON ACCESA
                {
                    $ch = curl_init($StufaOff);
                    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 5000); // error
                    curl_exec($ch);
                    curl_close($ch);
                  $msg = "Distacco stufa per supero potenza limite";
			rpinotify(token, $msg);
			rpinotify(token2, $msg);
			$limit_time_start = microtime(true);
                    limit_power_control($limit_time_start, $TYPE_IMP);
                }
			sleep (600);
            $ch = curl_init($LavanderiaOn);
	                curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 5000); // error
                	curl_exec($ch);
                	curl_close($ch);
			$msg = "Riattivazione lavanderia - prelievi normali";
			rpinotify(token, $msg);
			rpinotify(token2, $msg);	
            }
            else
			{
				if ($prelievi > AVAIL_POWER*1000 && $prelievi < LIMIT_POWER*1000) // SUPERO POTENZA DISPONIBILE - distacco in 182 min
				{
					$avail_time_start = microtime(true);
					avail_power_control($avail_time_start, $TYPE_IMP);
				}
			}
		}
        /** Riduci il consumo della CPU, aggiungendo un ritardo fisso */
        sleep (5);
    }


    /**
     * Lettura prelievi istantanei
     *
     * @return float prelievi attuali
     */
    function get_prelievi($TYPE_IMP)
    {
        
		/** Richiedi valori di potenza */
        switch($TYPE_IMP)
        {
            case 0:	$cmd = "eflowlive whin";         							break;
            case 1:	$cmd = "virtmeter " . METERN_PRELIEVI . " 0 0 imppower 0"; 	break;
            case 2:	$cmd = "cat /dev/shm/metern".METERN_PRELIEVI.".txt | egrep \"^".METERN_PRELIEVI."\(\" | grep \"*W)\"";         break;
			case 3:	$cmd = "cat /var/www/MyScripts/testprel.txt";				break;
        }
		
        /** Esegui il comando di richiesta */
        $datareturn = shell_exec($cmd);

        /** Rimuovi spazi ridondanti */
        $datareturn = trim($datareturn);

        /** Rimuovi intestazione */
        $datareturn = preg_replace("/^" . METERN_PRELIEVI . "\(/i", "", $datareturn);

        /** Rimuovi finale */
        $datareturn = preg_replace("/\*[a-z0-9]+\)$/i", "", $datareturn);

        /** Converto stringa in floating point */
        $prelievi = floatval($datareturn);

        /** Esco con lettura prelievi istantanei */
        return $prelievi;
    }

	/**
     * Controllo supero potenza limite LIMIT_POWER
     */
	function limit_power_control($limit_time_start, $TYPE_IMP)
	{
		while (true)
		{
			$prelievi = get_prelievi($TYPE_IMP);
			if ($prelievi > LIMIT_POWER*1000)
			{
				$perc = (($prelievi / (LIMIT_POWER*1000)) - 1) * 100;
				$perc = round($perc, 0);
				$time_dist = 120 - (microtime(true) - $limit_time_start);
				$time_dist = round($time_dist, 0);
				$msg = "Prelievi: " . $prelievi/1000 . "kW. Rischio distacco per supero potenza limite (" . LIMIT_POWER . "kW)del " . $perc . "% - Distacco entro " .$time_dist. " secondi";
				if(DEBUG_MODE == 1)
				{
					printf("%s\n", $msg);
				}
				rpinotify(token, $msg);
				rpinotify(token2, $msg);
				sleep (9);
			} else { 
			break;
			}
		}
	}
	
	
	
	
	/**
     * Controllo potenza fra AVAIL_POWER e LIMIT_POWER
     */
	function avail_power_control($avail_time_start, $TYPE_IMP)
	{
		$check1=0;
		$check2=0;
		while (true)
		{
			$prelievi = get_prelievi($TYPE_IMP);
			if ($prelievi > AVAIL_POWER*1000 && $prelievi < LIMIT_POWER*1000)
			{
				
				$time_dist = (microtime(true) - $avail_time_start);
				$time_dist = round($time_dist, 0);
				if(DEBUG_MODE == 1)
				{
				printf("%u\n", $time_dist); //stampa a terminale i secondi trascorsi
				}
				if ($time_dist >= 120 && $check1 == 0 )
				{
					$msg = "Prelievi: " . $prelievi/1000 . "kW. Superata potenza disponibile di ". AVAIL_POWER ."kW. Possibile distacco fra 180 minuti. ";
					$check1=1;
					if(DEBUG_MODE == 1)
					{
						printf("%s\n", $msg); //stampa a terminale il messaggio di avviso
					}
					rpinotify(token, $msg);
				}
				if ($time_dist >= 5520 && $check2 == 0 )
				{
					$msg = "Prelievi:" . $prelievi/1000 . "kW. Superata potenza disponibile di ". AVAIL_POWER ."kW. Possibile distacco fra 90 minuti. ";
					$check2=1;
					if(DEBUG_MODE == 1)
					{
						printf("%s\n", $msg);
					}
					rpinotify(token, $msg);
				}	
				sleep (5);
			} else { 
			break;
			}
		}
	}
	
	
   /**
     * RpiNotify
     */
   function rpinotify($token, $msg)
	{
	$post['text'] = $msg;
    $ch = curl_init('https://api.rpinotify.it/message/' . $token . '/');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    $output = curl_exec($ch);
	if(DEBUG_MODE == 1)
		{
        printf("%s\n", $output);
		}
    curl_close($ch);
	}
   
    /**
     * Log Event
     *
     * @param $stringData string Stringa di testo da loggare
     */
    function logevents($stringData)
    {
        /** Data e ora attuale */
        $now = date("d/m/Y H:i:s");

        /** Se il file per logger non esiste */
        if (!file_exists(METERN_FILE_LOGGER))
        {
            /** Creo nuovo file vuoto */
            FileWriteWithLock(METERN_FILE_LOGGER, "");
        }

        /** Leggo il file interamente */
        $content = file_get_contents(METERN_FILE_LOGGER);

        /** Controllo lettura contenuto */
        if($content !== false)
        {
            /** Appendo all'inizio la nuova stringa di testo */
            $content = $now . "\t" . $stringData . " (" . getmypid() . ")\n\n" . $content;

            /** Salvo il file con accesso esclusivo */
            FileWriteWithLock(METERN_FILE_LOGGER, $content);
        }
    }

	
	/**
     * WriteWithLock
     *
     * Funzione per scrivere file con apertura esclusiva
     *
     * @param string $file Nome del file da scrivere
     * @param string $mode Modalita' di accesso al file
     * @param string $content Contenuto del file
     *
     * @return bool Stato della scrittura
     */
    function WriteWithLock($file, $mode, $content)
    {
        /** Apro il file nella modalita' richiesta */
        if ($handle = fopen($file, $mode))
        {
            /** Tempo di inizio lock del file*/
            $startTime = microtime(TRUE);
            do
            {
                /** Serializza l'accesso in scrittura */
                $canWrite = flock($handle, LOCK_EX);

                /** Se il blocco non e' stato ottenuto attendi 0 - 100 millisecondi, per evitare collisione e limitare il carico della CPU */
                if (!$canWrite)
                {
                    /** Rallenta la CPU casualmente */
                    usleep(round(rand(0, 100) * 1000));
                }
            }
            while ((!$canWrite) and ((microtime(TRUE) - $startTime) < 5));

            /** Il file e' stato bloccato in modo da poter memorizzare le informazioni */
            if ($canWrite)
            {
                /** Scri il file */
                fwrite($handle, $content);

                /** Scarico buffer scrittura */
                fflush($handle);

                /** Togli il lock dal file */
                flock($handle, LOCK_UN);

                /** Chiud il file */
                fclose($handle);

                /** Esci con successo */
                return (true);
            }

            /** Chiud il file */
            fclose($handle);

            /** Esci con error */
            return (false);
        }

        /** Esci con error */
        return (false);
    }

	
	 /**
     * FileWriteWithLock
     *
     * Funzione per scrivere file con apertura esclusiva
     *
     * @param string $file Nome del file da scrivere
     * @param string $content Contenuto del file
     *
     * @return bool Stato della scrittura
     */
    function FileWriteWithLock($file, $content)
    {
        /** Scrivi il vile in modalita "scrittura" */
        return WriteWithLock($file, "w", $content);
    }

	
	
    /**
     * Funzione per controllare processo univoco
     */
    function checkAlreadyRunning()
    {
        /** Variabili globali */
        global $filename, $pidfile;

        /** Inizializzo procesos non in running */
        $pid = false;
        $pid_running = false;

        /** Controllo esistenza "Process Id" file */
        if (file_exists($pidfile))
        {
            /** Se il file esiste, estrazione "Process Id" */
            $data = file($pidfile);

            /** Per ogni "Process Id", controllo se attualmente attivo */
            foreach ($data as $pid)
            {
                /** Estrazione "Process Id" */
                $pid = (int)$pid;

                /** Se "Process Id" valido e processo attivo */
                if ( ($pid > 0) && (file_exists("/proc/" . $pid)) )
                {
                    /** Salvo "Process Id" */
                    $pid_running = $pid;

                    /** Interrompo ricerca */
                    break;
                }
            }
        }

        /** Se trovato processo attivo */
        if ($pid_running && ($pid_running != getmypid()) )
        {
            /** Controllo esistenza "Process Id" file */
            if (file_exists($pidfile))
            {
                /** Inizializzo file "Process Id" */
                file_put_contents($pidfile, $pid);
            }

            /** Logger */
            print($filename . " already running as pid " . $pid . " so stopping now" . PHP_EOL);

            /** Esci */
            exit();
        }
        else
        {
            /** Ricavo "Process Id" */
            $pid = getmypid();

            /** Scrivo file "Process Id" */
            file_put_contents($pidfile, $pid);

            /** Logger */
            print($filename . " running with pid: " . $pid . PHP_EOL);
        }
    }

    /**
     * Funzione eseguita quando si verifica un errore fatale
     */
    function fatalErrorShutdown()
    {
        /** Estrazione nome del file */
        $filename = basename(__FILE__, ".php");

        /** Ricava ultimo errore */
        $lastError = error_get_last();

        /** Se presente errore, esci */
        if (!is_null($lastError) && $lastError['type'] === E_ERROR)
        {
            /** Logger */
            print($filename . " receive unexpected error: " . $lastError['message'] . PHP_EOL);
            /** Esci in modo sicuro */
            shutdown();
        }
    }

    /**
     * Funzione eseguita se lo script e' stato ucciso da:
     *
     * SIGINT: Ctrl+C
     * SIGTERM: kill
     *
     * @param int $signal
     */
    function sigintShutdown($signal)
    {
        /** Estrazione nome del file */
        $filename = basename(__FILE__, ".php");

        /** Ricevuto segnale SIGINT o SIGTERM */
        if ($signal === SIGINT || $signal === SIGTERM)
        {
            /** Logger */
            print($filename . " receive SIGINT or SIGTERM." . PHP_EOL);

            /** Esci */
            shutdown();
        }
    }

    /**
     * Funzione chiamata per uscita in modo sicuro
     */
    function shutdown()
    {
        /** Variabili globali */
        global $filename, $pidfile, $boiler_consumption;

        /** Controllo esistenza "Process Id" file */
        if (file_exists($pidfile))
        {
            /** Cancello "Process Id" file */
            unlink($pidfile);
        }

        /** Logger */
        print($filename . " quitting." . PHP_EOL);
		logevents("Stopped Load check Script");
		/* stato load script */
		$buffer = sprintf("load(0*X)\n");
		/* Save file */
		file_put_contents($LOAD_FILE, $buffer);

        /** Uscita */
        exit();
    }
?>