Ga naar inhoud


Meter uitlezen 24/7 met Raspberry, hoe moet dat continu?


Con

Aanbevolen berichten

let ook op je rechten! als je tijdens je 'test' je script als root uitvoert, kan het goed zijn dat hij vanuit rc.local niet werkt, omdat dat standaard als 'nobody' wordt uitgevoerd.

Ik test het script gewoon onder mijn standaard gebruikersnaam, dus niet onder root.

Groet, Con. Gloeiende, gloeiende, een beetje humor moet kunnen, anders ga je maar ergens anders heen..
Sinds maart 2021 glasvezel via KPN.

Internet/PC: modem/router Fritzbox en TP-Link accesspoint, switch (8), switch (4)

Intel Nuc i7 met W10, Gigabyte Brix met Home Assistant, 17 Shelly's en 2 ESP-tjes.

Link naar reactie
Delen op andere sites


  • Reacties 76
  • Aangemaakt
  • Laatste reactie

Beste reacties in dit topic

Beste reacties in dit topic

Geplaatste afbeeldingen

Probeer eens domoticz.com, wat op een raspberry pi draait.

Deze software heeft oa een ingebouwde functie met grafieken voor een smart meter.

Je wil niet weten wat voor een vooronderzoek ik heb gedaan,

deze site ben ik echter niet tegengekomen en ziet er erg goed uit.

 

Mocht het nou helemaal niet lukken heb ik altijd nog een escape. Dank voor de tip.

Groet, Con. Gloeiende, gloeiende, een beetje humor moet kunnen, anders ga je maar ergens anders heen..
Sinds maart 2021 glasvezel via KPN.

Internet/PC: modem/router Fritzbox en TP-Link accesspoint, switch (8), switch (4)

Intel Nuc i7 met W10, Gigabyte Brix met Home Assistant, 17 Shelly's en 2 ESP-tjes.

Link naar reactie
Delen op andere sites

Blijft dit scriptje draaien of stopt het na het uitlezen?

Indien het stopt na het uitlezen en periodisch opnieuw gestart moet worden kan je dit inderdaad best als cronjob draaien.

Indien het continue draait (je krijgt geen promt terug) kan je het best draaien via "nohup <scriptje> &" zodat het zelfs na uitloggen blijft draaien.

Wil je dat het bij het opstarten van je RPi opstart dan moet je kijken hoe je distro dit afhandelt (sysvinit/systemctl...)

Voorlopig start het scriptje helemaal niet. Ik denk dat ik iets elementairs vergeet

maar ik ben ook een ongelofelijke beginner in Linux, Python en dan ook nog alles

met de cli. Dat valt niet mee . . .

Groet, Con. Gloeiende, gloeiende, een beetje humor moet kunnen, anders ga je maar ergens anders heen..
Sinds maart 2021 glasvezel via KPN.

Internet/PC: modem/router Fritzbox en TP-Link accesspoint, switch (8), switch (4)

Intel Nuc i7 met W10, Gigabyte Brix met Home Assistant, 17 Shelly's en 2 ESP-tjes.

Link naar reactie
Delen op andere sites

@mrbeam; wat als nadeel een laag leer gehalte heeft. Ik kan me goed voorstellen dat de topic starter dit doet om educatieve redenen.

Ach een beetje programmeren heeft iedereen wel eens gedaan. Als je dan naar veel voorbeeldprogrammas

kijkt en je googled je te pletter dan kom je daar wel uit.

 

Maar Linux is complex, zeker als je met weinig kennis in het diepe duikt tot bijna verdrinken toe.

 

Nee, ik doe het niet om educatieve redenen maar het is wel enorm kicken als het is gelukt

en dat is ook een beetje mijn drijfveer. Ik probeer me er dan ook helemaal in te bijten.

 

Maar de leercurve had voor mij wel wat minder stijl mogen zijn . . . . .

Groet, Con. Gloeiende, gloeiende, een beetje humor moet kunnen, anders ga je maar ergens anders heen..
Sinds maart 2021 glasvezel via KPN.

Internet/PC: modem/router Fritzbox en TP-Link accesspoint, switch (8), switch (4)

Intel Nuc i7 met W10, Gigabyte Brix met Home Assistant, 17 Shelly's en 2 ESP-tjes.

Link naar reactie
Delen op andere sites

Voorlopig start het scriptje helemaal niet. Ik denk dat ik iets elementairs vergeet

maar ik ben ook een ongelofelijke beginner in Linux, Python en dan ook nog alles

met de cli. Dat valt niet mee . . .

Ik doelde als je het scriptje manueel uitvoert. Krijg je dan je prompt terug of blijft dat draaien tot je het stopt (control-C/logout)?

Link naar reactie
Delen op andere sites

Ik heb het als volgt draaien :

 

/usr/bin/python /var/bin/p1/P1uitlezer.py

 

#
# DSMR P1 uitlezer
# (c) 10-2012 - GJ - gratis te kopieren en te plakken

versie = "1.0"
import sys
import serial

################
#Error display #
################
def show_error():
    ft = sys.exc_info()[0]
    fv = sys.exc_info()[1]
    print("Fout type: %s" % ft )
    print("Fout waarde: %s" % fv )
    return


################################################################################################################################################
#Main program
################################################################################################################################################
##print ("DSMR P1 uitlezer",  versie)
##print ("Control-C om te stoppen")

#Set COM port config
ser = serial.Serial()
ser.baudrate = 9600
ser.bytesize=serial.SEVENBITS
ser.parity=serial.PARITY_EVEN
ser.stopbits=serial.STOPBITS_ONE
ser.xonxoff=0
ser.rtscts=0
ser.timeout=20
ser.port="/dev/P1"

#Open COM port
try:
    ser.open()
except:
    sys.exit ("Fout bij het openen van %s. Programma afgebroken."  % ser.name)
 p1_str=str(p1_raw)
    #p1_str=str(p1_raw, "utf-8")
    p1_line=p1_str.strip()
    stack.append(p1_line)
# als je alles wil zien moet je de volgende line uncommenten
#    print (p1_line)
    p1_teller = p1_teller +1

#Initialize
# stack_teller is mijn tellertje voor de 20 weer door te lopen. Waarschijnlijk mag ik die p1_teller ook gebruiken
stack_teller=0

while stack_teller < 20:
   if stack[stack_teller][0:9] == "1-0:1.8.1":
        print "daldag     ", stack[stack_teller][10:19]
   elif stack[stack_teller][0:9] == "1-0:1.8.2":
        print "piekdag    ", stack[stack_teller][10:19]
# Daltarief, teruggeleverd vermogen 1-0:2.8.1
   elif stack[stack_teller][0:9] == "1-0:2.8.1":
        print "dalterug   ", stack[stack_teller][10:19]
# Piek tarief, teruggeleverd vermogen 1-0:2.8.2
   elif stack[stack_teller][0:9] == "1-0:2.8.2":
        print "piekterug  ", stack[stack_teller][10:19]
# Huidige stroomafname: 1-0:1.7.0
   elif stack[stack_teller][0:9] == "1-0:1.7.0":
        print "afgenomen vermogen      ", int(float(stack[stack_teller][10:17])*1000), " W"
# Huidig teruggeleverd vermogen: 1-0:1.7.0
   elif stack[stack_teller][0:9] == "1-0:2.7.0":
        print "teruggeleverd vermogen  ", int(float(stack[stack_teller][10:17])*1000), " W"
# Gasmeter: 0-1:24.3.0
   elif stack[stack_teller][0:10] == "0-1:24.3.0":
 print "Gas                     ", int(float(stack[stack_teller+1][1:10])*1000), " dm3"
   else:
        pass
   stack_teller = stack_teller +1

#print (stack, "\n")

#Close port and show status
try:
    ser.close()
except:
    sys.exit ("Oops %s. Programma afgebroken." % ser.name )



Link naar reactie
Delen op andere sites

  • Moderator

als je toch wilt monitoren en je zin hebt om het uit te zoeken, zou ik ook eens kijken naar munin.

 

die vraagt elke 5 minuten de waarde van iets op, en dat iets kan vanalles zijn.

 

krijg je dit soort grafiekjes uit, en maakt vanzelf een grafiek per week, maand en jaar, netjes in een webpagina. Als je raspbian draait zit ie meen ik in de repository. Screenshots zijn de uptime van mijn raspberry.

 

 

 

Selection_013.png

Selection_014.png

VU+ Duo2  met VTi  13 VU+ Uno met VTi  9.0.2

geen Canal Digitaal meer en geen Sparql iptv meer
Triax 78, astra 1,2,3, HB

Link naar reactie
Delen op andere sites

Ik kan geen Python; maar was er niet iets met de indentation dat belangrijk was? regel 73 b.v.?

 

Anyway, weet je zeker dat deze oneindig lang door blijft draaien? Nu print je de output naar de shell of naar een bestand? Ik zie nergens iets van een bestand staan.

 

Dus hij loopt waarschijnlijk wel, maar je output gaat 'standaard' naar /dev/null. Dus je gooit je output weg.

 

Je hebt 2 opties; output via screen, of output het na een bestand. python /1.py 1> /tmp/bestand 2> /tmp/bestand.err &

 

:)

 

P.S. standaard is de seriele poort /dev/ttyS0; P1 is een link die je zelf maakt? (of is dat een rpi iets)

Link naar reactie
Delen op andere sites

Ben geen Python-expert maar dat scriptje kan gewoon niet werken  :crazy:

 

Je opent je seriele poort (lijn 39) maar leest ze nergens uit en gaat dan op lijn 42 de vermoedelijke output van de seriele poort omzetten naar een string... Ben je zeker dat dat scriptje werkt? Ergens tussen lijn 39 en lijn 42 moet je nog een ser.readline doen vermoed ik.

 

Los daarvan. Het lijkt er op dat je scriptje 20 lijnen uit een stack wil lezen en daar de gewenste meterstanden van toont. Daarna stopt het scriptje. Je zal dergelijk scriptje dus inderdaad via een cronjob moeten draaien (genre */5 * * * * om het om de 5 minuten te draaien).

Link naar reactie
Delen op andere sites

Ik doelde als je het scriptje manueel uitvoert. Krijg je dan je prompt terug of blijft dat draaien tot je het stopt (control-C/logout)?

Het blijft lopen totdat ik een ^C geef inderdaad.

Groet, Con. Gloeiende, gloeiende, een beetje humor moet kunnen, anders ga je maar ergens anders heen..
Sinds maart 2021 glasvezel via KPN.

Internet/PC: modem/router Fritzbox en TP-Link accesspoint, switch (8), switch (4)

Intel Nuc i7 met W10, Gigabyte Brix met Home Assistant, 17 Shelly's en 2 ESP-tjes.

Link naar reactie
Delen op andere sites

Het blijft lopen totdat ik een ^C geef inderdaad.

 

nohup ./scriptje.py 2>&1 &

 

& op het einde laat het script in de achtergrond draaien

nohup zorgt dat het blijft draaien zelfs al je uitlogt

2>&1 stuurt de errors naar de standaard-out.

in de file nohup.out vind je dan alles wat het programma uitprint.

Link naar reactie
Delen op andere sites

 

nohup ./scriptje.py 2>&1 &

 

& op het einde laat het script in de achtergrond draaien

nohup zorgt dat het blijft draaien zelfs al je uitlogt

2>&1 stuurt de errors naar de standaard-out.

in de file nohup.out vind je dan alles wat het programma uitprint.

Kun je hier wat mee? python 1.py werkt als een speer 

Bij nohup ./scriptje.py 2>&1 &

na 1 minuut een enter te geven kreeg ik de prompt terug

er zijn geen waarden weggeschreven naar het bestand.

 

ls

1.pi  3.py       hello.sh   MyFirst.sh   P1uitlezen.py         switchip.sh
1.py  4.py       indiecity  myscript.sh  python P1uitlezen.py
1.sh  Desktop    meter      nohup.out    Scratch
2.py  Documents  meter.txt  ocr_pi.png   squeak
 
pi@raspberrypi ~ $ cat nohup.out
 
./1.py: 3: ./1.py: versie: not found
./1.py: 4: ./1.py: import: not found
./1.py: 5: ./1.py: import: not found
./1.py: 6: ./1.py: import: not found
./1.py: 7: ./1.py: import: not found
from: too many arguments
./1.py: 9: ./1.py: Syntax error: "(" unexpected

Groet, Con. Gloeiende, gloeiende, een beetje humor moet kunnen, anders ga je maar ergens anders heen..
Sinds maart 2021 glasvezel via KPN.

Internet/PC: modem/router Fritzbox en TP-Link accesspoint, switch (8), switch (4)

Intel Nuc i7 met W10, Gigabyte Brix met Home Assistant, 17 Shelly's en 2 ESP-tjes.

Link naar reactie
Delen op andere sites

 

Kun je hier wat mee? python 1.py werkt als een speer 

Bij nohup ./scriptje.py 2>&1 &

na 1 minuut een enter te geven kreeg ik de prompt terug

er zijn geen waarden weggeschreven naar het bestand.

 

ls

1.pi  3.py       hello.sh   MyFirst.sh   P1uitlezen.py         switchip.sh
1.py  4.py       indiecity  myscript.sh  python P1uitlezen.py
1.sh  Desktop    meter      nohup.out    Scratch
2.py  Documents  meter.txt  ocr_pi.png   squeak
 
pi@raspberrypi ~ $ cat nohup.out
 
./1.py: 3: ./1.py: versie: not found
./1.py: 4: ./1.py: import: not found
./1.py: 5: ./1.py: import: not found
./1.py: 6: ./1.py: import: not found
./1.py: 7: ./1.py: import: not found
from: too many arguments
./1.py: 9: ./1.py: Syntax error: "(" unexpected

 

Had niet gezien dat er geen hashbang aan het begin van je script staat. Het systeem weet niet dat het om een python-script gaat en denk dat het een gewoon shell-script is, vandaar die errors. 2 mogelijke oplossingen:

 

1. nohup python ./1.py 2>&1 &

hiermee geef je aan dat python het script moet interpreten

 

2. op de 1e lijn van je script zet je #!/usr/bin/env python

hiermee geef je in het script aan welk binary het script moet interpreten.

 

de 2e oplossing vind ik de elegantste. dan kan je gewoon ./1.py doen ipv python 1.py (minder typwerk)  :/

Link naar reactie
Delen op andere sites

Ik kan geen Python; maar was er niet iets met de indentation dat belangrijk was? regel 73 b.v.?

 

Anyway, weet je zeker dat deze oneindig lang door blijft draaien? Nu print je de output naar de shell of naar een bestand? Ik zie nergens iets van een bestand staan.

 

Dus hij loopt waarschijnlijk wel, maar je output gaat 'standaard' naar /dev/null. Dus je gooit je output weg.

 

Je hebt 2 opties; output via screen, of output het na een bestand. python /1.py 1> /tmp/bestand 2> /tmp/bestand.err &

 

:)

 

P.S. standaard is de seriele poort /dev/ttyS0; P1 is een link die je zelf maakt? (of is dat een rpi iets)

Dit is iig mijn script dat continue blijft uitlezen;

 

# DSMR P1 uitlezen © 10-2012 - GJ - gratis te kopieren en te plakken 
# © 07-2013 - ccvd - aanpassingen basisprogramma
versie = "1.0"
import sys
import serial
import time
import datetime
from time import strftime
f=open('meter.txt', 'a')
##############################################################################
#Main program
##############################################################################
# print ("DSMR P1 uitlezen",  versie)
print ("Control-C om te stoppen")
# print ("Pas eventueel de waarde ser.port aan in het python script")
 
#Set COM port config
ser = serial.Serial()
ser.baudrate = 9600
ser.bytesize=serial.SEVENBITS
ser.parity=serial.PARITY_EVEN
ser.stopbits=serial.STOPBITS_ONE
ser.xonxoff=0
ser.rtscts=0
ser.timeout=20
ser.port="/dev/ttyUSB0"
print "                       Gebruikt     geleverd         huidig"
print " Datum       tijd     dal   piek   dal   piek   verbruik geleverd"
#Open COM port
try:
    ser.open()
except:
    sys.exit ("Fout bij het openen van %s. Aaaaarch."  % ser.name)
 
 
#Initialize
#p1_teller is mijn tellertje voor van 0 tot 20 te tellen
p1_teller=0
 
# p1_teller == 0 om het uitlezen te continueren, waarschijnlijk onorthodox maar het werkt (Con).
 
while p1_teller == 0:
    p1_line=''
#Read 1 line van de seriele poort
    try:
        p1_raw = ser.readline()
    except:
        sys.exit ("Seriele poort %s kan niet gelezen worden. Aaaaaaaaarch." % ser.name )
    p1_str=str(p1_raw)
    p1_line=p1_str.strip()
 
    if "1.8.1" in p1_line:
        print strftime("%Y-%m-%d %H:%M:%S"),
        f.write(str(strftime("%Y-%m-%d %H:%M:%S")))
        f.write(' ')
        print int (1000 * float(p1_line[10:19])),
        f.write(str(int (1000 * float(p1_line[10:19]))))
        f.write(' ')
    if "1.8.2" in p1_line:
        print int (1000 * float(p1_line[10:19])),
        f.write(str(int (1000 * float(p1_line[10:19]))))
        f.write(' ')
    if "2.8.1" in p1_line:
        print int (1000 * float(p1_line[10:19])),
        f.write(str(int (1000 * float(p1_line[10:19]))))
        f.write(' ')
    if "2.8.2" in p1_line:
        print int(1000 * float(p1_line[10:19])),"    ",
        f.write(str(int (1000 * float(p1_line[10:19]))))
        f.write(' ')
    if "1.7" in p1_line:
        print int(1000*float(p1_line[10:17])),"    ",
        f.write(str(int (1000 * float(p1_line[10:17]))))
        f.write(' ')
    if "2.7" in p1_line:
        print int(1000*float(p1_line[10:17]))
        f.write(str(int (1000 * float(p1_line[10:17]))))
        f.write('\n')
 
#:   print (p1_str)
#    if p1_line[0:1] == "/":
#        p1_telegram = True
 
 
 
 
#if   (p1_line)[:] == '1.8.1':    print  (p1_line)[10:19]
#    1.8.1 in p1_line :    print  (p1_line)[10.19]
#string.find('Wo')
#    p1_teller = p1_teller +1
 
#Close port and show status
try:
    ser.close()
except:
    sys.exit ("Oops %s. Programma afgebroken. Kon de seriele poort niet sluiten." % ser.name )

Groet, Con. Gloeiende, gloeiende, een beetje humor moet kunnen, anders ga je maar ergens anders heen..
Sinds maart 2021 glasvezel via KPN.

Internet/PC: modem/router Fritzbox en TP-Link accesspoint, switch (8), switch (4)

Intel Nuc i7 met W10, Gigabyte Brix met Home Assistant, 17 Shelly's en 2 ESP-tjes.

Link naar reactie
Delen op andere sites

 

Dit is iig mijn script dat continue blijft uitlezen;

 

# DSMR P1 uitlezen © 10-2012 - GJ - gratis te kopieren en te plakken 
# © 07-2013 - ccvd - aanpassingen basisprogramma
versie = "1.0"
import sys
import serial
import time
import datetime
from time import strftime
f=open('meter.txt', 'a')
##############################################################################
#Main program
##############################################################################
# print ("DSMR P1 uitlezen",  versie)
print ("Control-C om te stoppen")
# print ("Pas eventueel de waarde ser.port aan in het python script")
 
#Set COM port config
ser = serial.Serial()
ser.baudrate = 9600
ser.bytesize=serial.SEVENBITS
ser.parity=serial.PARITY_EVEN
ser.stopbits=serial.STOPBITS_ONE
ser.xonxoff=0
ser.rtscts=0
ser.timeout=20
ser.port="/dev/ttyUSB0"
print "                       Gebruikt     geleverd         huidig"
print " Datum       tijd     dal   piek   dal   piek   verbruik geleverd"
#Open COM port
try:
    ser.open()
except:
    sys.exit ("Fout bij het openen van %s. Aaaaarch."  % ser.name)
 
 
#Initialize
#p1_teller is mijn tellertje voor van 0 tot 20 te tellen
p1_teller=0
 
# p1_teller == 0 om het uitlezen te continueren, waarschijnlijk onorthodox maar het werkt (Con).
 
while p1_teller == 0:
    p1_line=''
#Read 1 line van de seriele poort
    try:
        p1_raw = ser.readline()
    except:
        sys.exit ("Seriele poort %s kan niet gelezen worden. Aaaaaaaaarch." % ser.name )
    p1_str=str(p1_raw)
    p1_line=p1_str.strip()
 
    if "1.8.1" in p1_line:
        print strftime("%Y-%m-%d %H:%M:%S"),
        f.write(str(strftime("%Y-%m-%d %H:%M:%S")))
        f.write(' ')
        print int (1000 * float(p1_line[10:19])),
        f.write(str(int (1000 * float(p1_line[10:19]))))
        f.write(' ')
    if "1.8.2" in p1_line:
        print int (1000 * float(p1_line[10:19])),
        f.write(str(int (1000 * float(p1_line[10:19]))))
        f.write(' ')
    if "2.8.1" in p1_line:
        print int (1000 * float(p1_line[10:19])),
        f.write(str(int (1000 * float(p1_line[10:19]))))
        f.write(' ')
    if "2.8.2" in p1_line:
        print int(1000 * float(p1_line[10:19])),"    ",
        f.write(str(int (1000 * float(p1_line[10:19]))))
        f.write(' ')
    if "1.7" in p1_line:
        print int(1000*float(p1_line[10:17])),"    ",
        f.write(str(int (1000 * float(p1_line[10:17]))))
        f.write(' ')
    if "2.7" in p1_line:
        print int(1000*float(p1_line[10:17]))
        f.write(str(int (1000 * float(p1_line[10:17]))))
        f.write('\n')
 
#:   print (p1_str)
#    if p1_line[0:1] == "/":
#        p1_telegram = True
 
 
 
 
#if   (p1_line)[:] == '1.8.1':    print  (p1_line)[10:19]
#    1.8.1 in p1_line :    print  (p1_line)[10.19]
#string.find('Wo')
#    p1_teller = p1_teller +1
 
#Close port and show status
try:
    ser.close()
except:
    sys.exit ("Oops %s. Programma afgebroken. Kon de seriele poort niet sluiten." % ser.name )

is ook een ander programma dan je initieel postte. hier heb je een continue while loop (p1_teller == 0 en je wijzigt nooit zijn waarde). En er is nu ook een ser.readline om je seriele poort te lezen.

 

De laatste regels van je programma doen trouwens niks. Je komt nooit zover gezien je in een loop zit en bij afbreken (control-C) gewoon je code stopt. Ik hoop/vermoed dat python dan zo vriendelijk is om zelf de open file-handle naar je seriele poort te sluiten.

aangepast door bunbun
Link naar reactie
Delen op andere sites

Maak een account aan of log in om te reageren

Je moet een lid zijn om een reactie te kunnen achterlaten

Account aanmaken

Registreer voor een nieuwe account in onze community. Het is erg gemakkelijk!

Registreer een nieuwe account

Inloggen

Heb je reeds een account? Log hier in.

Nu inloggen
  • Wie is er online   0 leden

    • Er zijn geen geregistreerde gebruikers deze pagina aan het bekijken
×
×
  • Nieuwe aanmaken...