Acties:
  • 0 Henk 'm!

  • WoBBeL
  • Registratie: Juni 2004
  • Laatst online: 11-09 13:01
Er zijn veel topics over P1 poorten uitlezen van Slimme meters, veel problemen gevonden over onjuiste settings of kabels/chips die het signaal niet inverten maar ik lijk toch echt iets anders te hebben :? . Ik heb zelf een Raspberry Pi B+ en daarop de kabel P1 Converter Cable V2. Via Python met het script van Gejanssen.com kan ik het uitlezen, maar dit gaat lang niet altijd goed :? Soms komt er maar de helft binnen en dan begint ie opnieuw totdat het script hem terminate.

Output goed: http://i.imgur.com/aIzK9Dx.png
Output fout: http://i.imgur.com/j5qttrt.png
Output via minicom (gaat altijd goed): http://i.imgur.com/8KcQrGd.png

Alle settings voor m'n meter moeten goed staan (parity, baud rate, bytesize) anders zou ik de juiste pogingen ook niet binnen moeten krijgen :+ ook rebootje gedaan, alles nagelopen :F met minicom krijg ik netjes alle data binnen elke keer precies zoals het bij "Output goed" gaat.

Script in Python
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import sys
import serial

ser = serial.Serial()
ser.baudrate = 115200
ser.bytesize=serial.EIGHTBITS
ser.parity=serial.PARITY_NONE
ser.stopbits=serial.STOPBITS_ONE
ser.xonxoff=0
ser.rtscts=0
ser.timeout=30
ser.port="/dev/ttyUSB0"

try:
    ser.open()
except:
    sys.exit ("Fout bij het openen van %s."  % ser.name)      


p1_teller=0

while p1_teller < 28:
    p1_line=''
    try:
        p1_raw = ser.readline()
    except:
        sys.exit ("Seriele poort %s kan niet gelezen worden." % ser.name )      
    p1_str=str(p1_raw)
    p1_line=p1_str.strip()
    print (p1_line)
    p1_teller = p1_teller +1

try:
    ser.close()
except:
    sys.exit ("Programma afgebroken. Kon de seriele poort %s niet sluiten." % ser.name )

[ Voor 6% gewijzigd door WoBBeL op 13-10-2015 19:43 ]


Acties:
  • 0 Henk 'm!

  • ThinkPad
  • Registratie: Juni 2005
  • Laatst online: 15:15
Wat voor meter heb je? Voor de E350 is volgens mij nog een weerstand (1k tussen Vcc en RxD dacht ik) nodig om goede output te krijgen.

Acties:
  • 0 Henk 'm!

  • WoBBeL
  • Registratie: Juni 2004
  • Laatst online: 11-09 13:01
ThinkPadd schreef op woensdag 14 oktober 2015 @ 10:31:
Wat voor meter heb je? Voor de E350 is volgens mij nog een weerstand (1k tussen Vcc en RxD dacht ik) nodig om goede output te krijgen.
Ik gebruik de Smartmetershop kabel zodat het niet meer zou hoeven, maar dat verklaart niet waarom minicom het wel laat zien?!

Ik probeer nu de output van CU wel, die lijkt het wel de hele tijd te doen ;)

Acties:
  • 0 Henk 'm!

  • Puch-Maxi
  • Registratie: December 2003
  • Laatst online: 14-09 17:07
Ben zelf niet zo'n hele sterke programmeur hoor, ik vroeg me af waar '< 28' voor was? Mijn gok is dat er ergens bij het uitlezen van de data iets niet helemaal goed gaat, is de lengte daarvan soms variabel?

Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import sys
import serial

def connectToSerial():
    "Function for opening a serial connection."
    ser = serial.Serial()
    ser.baudrate = 115200
    ser.bytesize=serial.EIGHTBITS
    ser.parity=serial.PARITY_NONE
    ser.stopbits=serial.STOPBITS_ONE
    ser.xonxoff=0
    ser.rtscts=0
    ser.timeout=30
    ser.port="/dev/ttyUSB0"

    try:
        ser.open()
    except:
        sys.exit ("Fout bij het openen van %s."  % ser.name)      

def main():
    # Open de seriele verbinding.
    ser = connectToSerial()

    # Init p1 counter.
    p1_teller=0

    while p1_teller < 28:
        p1_line=''
        try:
            p1_raw = ser.readline()
        except:
            sys.exit ("Seriele poort %s kan niet gelezen worden." % ser.name )

    # Zet de ruwe data om naar een string.        
    p1_str=str(p1_raw)

    # Remove whitespace.
    p1_line=p1_str.strip()
    print (p1_line)

    # increment p1 counter
    p1_teller += 1

main()

[ Voor 15% gewijzigd door Puch-Maxi op 16-10-2015 14:10 ]

My favorite programming language is solder.


Acties:
  • 0 Henk 'm!

  • kzin
  • Registratie: Oktober 2003
  • Laatst online: 14:32
Mijn gok is dat het in de str() functie fout gaat.
Probeer eens helemaal bovenin de volgende regel op te nemen (als eerste regel)
code:
1
# -*- coding: utf-8 -*-

Daarmee dwing een bepaalde coding af (unicode, ascii).
Eigenlijk hoort daarvoor nog de volgende regel te staan:
code:
1
#!/usr/bin/python

Mits jouw python in /usr/bin staat. Dat kun je controleren door op de command line in te typen: which python. Controleer dan ook gelijk even je python versie (gewoon intypen: python -V). Veel scripts die je vindt werken alleen goed met python 2.7, en niet met 3.x

Acties:
  • 0 Henk 'm!

  • Puch-Maxi
  • Registratie: December 2003
  • Laatst online: 14-09 17:07
Ah ik heb nog even op de site van Gé Janssen gekeken (http://gejanssen.com/howto/Slimme-meter-uitlezen/index.html) Die gebruikt dus 20 regels voor zijn data, waarom heb jij er 28?

My favorite programming language is solder.


Acties:
  • 0 Henk 'm!

  • DigiK-oz
  • Registratie: December 2001
  • Laatst online: 13:42
Het aantal regels wat je terugkrijgt kan verscillen, in ieder geval per installatie, omdat er bij de ene een gasmeter aanhangt en bij de andere niet bijvoorbeeld. Dus uitgaan van een fixed aantal regels is wat tricky.

De eerste regel van een telegram begint met een /, de laatste regel begint met een ! , daar kun je beter op checken dan uitgaan van een vast aantal regels.

Zo draait het bij mij al bijna een jaar stabiel.

Whatever


Acties:
  • 0 Henk 'm!

  • ThinkPad
  • Registratie: Juni 2005
  • Laatst online: 15:15
Afgaan op het aantal regels is toch sowieso een ranzige oplossing? Kun je niet beter zoeken naar de veld-indicatoren? (1.8.1 voor elektra laagtarief geloof ik). Zo deed ik het met Arduino ook: ThinkPad's Tweakblog: Uitlezen van de slimme meter P1-poort met een Arduino en waarden opslaan in MySQL-database

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
void decodeTelegram() {
  long tl = 0;
  long tld =0;

  if (Serial.available()) {
    input = Serial.read();
    char inChar = (char)input;
    // Fill buffer up to and including a new line (\n)
    buffer[bufpos] = input&127;
    bufpos++;

    if (input == '\n') { // We received a new line (data up to \n)
      if (sscanf(buffer,"1-0:1.8.1(%ld.%ld" ,&tl, &tld)==2){
        tl *= 1000;
        tl += tld;
        mEVLT = tl;
      }

      // 1-0:1.8.2 = Elektra verbruik hoog tarief (DSMR v4.0)
      if (sscanf(buffer,"1-0:1.8.2(%ld.%ld" ,&tl, &tld)==2){
        tl *= 1000;
        tl += tld;
        mEVHT = tl;
      }

      // 1-0:1.7.0 = Electricity consumption actual usage (DSMR v4.0)
      if (sscanf(buffer,"1-0:1.7.0(%ld.%ld" ,&tl , &tld) == 2)
      { 
        mEAV = (tl*1000)+tld;
      }

      // 0-1:24.2.1 = Gas (DSMR v4.0) on Kaifa MA105 meter
      if (strncmp(buffer, "0-1:24.2.1", strlen("0-1:24.2.1")) == 0) {
        if (sscanf(strrchr(buffer, '(') + 1, "%d.%d", &tl, &tld) == 2) {
          mG = (tl*1000)+tld; 
        }
      }

      // Empty buffer again (whole array)
      for (int i=0; i<75; i++)
      { 
        buffer[i] = 0;
      }
      bufpos = 0;
    }
  } //Einde 'if Serial.available'
} 


Als je trouwens het uitlezen toch al op een Raspberry Pi doet, waarom dan niet gelijk Domoticz draaien? Die kun je met een paar klikken instellen om de slimme meter uit te lezen. En je kunt gelijk de grafieken bekijken e.d. :)

[ Voor 66% gewijzigd door ThinkPad op 15-10-2015 11:34 ]


Acties:
  • 0 Henk 'm!

  • WoBBeL
  • Registratie: Juni 2004
  • Laatst online: 11-09 13:01
kzin schreef op woensdag 14 oktober 2015 @ 22:01:
Mijn gok is dat het in de str() functie fout gaat.
Probeer eens helemaal bovenin de volgende regel op te nemen (als eerste regel)
code:
1
# -*- coding: utf-8 -*-

Daarmee dwing een bepaalde coding af (unicode, ascii).
Eigenlijk hoort daarvoor nog de volgende regel te staan:
code:
1
#!/usr/bin/python

Mits jouw python in /usr/bin staat. Dat kun je controleren door op de command line in te typen: which python. Controleer dan ook gelijk even je python versie (gewoon intypen: python -V). Veel scripts die je vindt werken alleen goed met python 2.7, en niet met 3.x
Dat ga ik eens proberen. Ik draai Python 2.7 en niet de 3.
Puch-Maxi schreef op woensdag 14 oktober 2015 @ 22:05:
Ah ik heb nog even op de site van Gé Janssen gekeken (http://gejanssen.com/howto/Slimme-meter-uitlezen/index.html) Die gebruikt dus 20 regels voor zijn data, waarom heb jij er 28?
Omdat ik een andere meter heb die meer informatie laat zien en ik ook een gasmeter heb.

Maar de conclusie hiero geeft aan dat ik op een andere manier zou moeten programmeren. Dat ga ik eens proberen vanavond :) het is inderdaad veel netter het op een andere manier te doen, maar dit was m'n eerste Python ervaring :D
ThinkPadd schreef op donderdag 15 oktober 2015 @ 11:32:
Afgaan op het aantal regels is toch sowieso een ranzige oplossing? Kun je niet beter zoeken naar de veld-indicatoren? (1.8.1 voor elektra laagtarief geloof ik). Zo deed ik het met Arduino ook: ThinkPad's Tweakblog: Uitlezen van de slimme meter P1-poort met een Arduino en waarden opslaan in MySQL-database

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
void decodeTelegram() {
  long tl = 0;
  long tld =0;

  if (Serial.available()) {
    input = Serial.read();
    char inChar = (char)input;
    // Fill buffer up to and including a new line (\n)
    buffer[bufpos] = input&127;
    bufpos++;

    if (input == '\n') { // We received a new line (data up to \n)
      if (sscanf(buffer,"1-0:1.8.1(%ld.%ld" ,&tl, &tld)==2){
        tl *= 1000;
        tl += tld;
        mEVLT = tl;
      }

      // 1-0:1.8.2 = Elektra verbruik hoog tarief (DSMR v4.0)
      if (sscanf(buffer,"1-0:1.8.2(%ld.%ld" ,&tl, &tld)==2){
        tl *= 1000;
        tl += tld;
        mEVHT = tl;
      }

      // 1-0:1.7.0 = Electricity consumption actual usage (DSMR v4.0)
      if (sscanf(buffer,"1-0:1.7.0(%ld.%ld" ,&tl , &tld) == 2)
      { 
        mEAV = (tl*1000)+tld;
      }

      // 0-1:24.2.1 = Gas (DSMR v4.0) on Kaifa MA105 meter
      if (strncmp(buffer, "0-1:24.2.1", strlen("0-1:24.2.1")) == 0) {
        if (sscanf(strrchr(buffer, '(') + 1, "%d.%d", &tl, &tld) == 2) {
          mG = (tl*1000)+tld; 
        }
      }

      // Empty buffer again (whole array)
      for (int i=0; i<75; i++)
      { 
        buffer[i] = 0;
      }
      bufpos = 0;
    }
  } //Einde 'if Serial.available'
} 


Als je trouwens het uitlezen toch al op een Raspberry Pi doet, waarom dan niet gelijk Domoticz draaien? Die kun je met een paar klikken instellen om de slimme meter uit te lezen. En je kunt gelijk de grafieken bekijken e.d. :)
Ik ben PHP programmeur en wil alles in m'n eigen schil kunnen kwakken met statistiekjes, grafiekjes, berekeningen, SMS waarschuwingen etc :)

Thanks voor het meedenken zover!!

Acties:
  • 0 Henk 'm!

Verwijderd

Aangezien je de kabel bij smartmeterdashboard.nl weg hebt zou ik beginnen met hun logger: http://www.smartmeterdashboard.nl/downloads en dan de P1 Datalogger V7.

Zo ben ik toen ook begonnen was toen ook een python script welke of naar console, csv of mysql kon loggen, als ik me dat goed herinner.

Acties:
  • 0 Henk 'm!

  • WoBBeL
  • Registratie: Juni 2004
  • Laatst online: 11-09 13:01
Verwijderd schreef op donderdag 15 oktober 2015 @ 16:38:
Aangezien je de kabel bij smartmeterdashboard.nl weg hebt zou ik beginnen met hun logger: http://www.smartmeterdashboard.nl/downloads en dan de P1 Datalogger V7.

Zo ben ik toen ook begonnen was toen ook een python script welke of naar console, csv of mysql kon loggen, als ik me dat goed herinner.
Ik heb alles al in een huis (raspberry over) om het op deze manier te doen. De hele interface om de MySQL data weer te geven is geen probleem dat kan ik zelf, alleen het loggen ging niet altijd goed ;)

Acties:
  • 0 Henk 'm!

Verwijderd

xost schreef op donderdag 15 oktober 2015 @ 17:58:
[...]


Ik heb alles al in een huis (raspberry over) om het op deze manier te doen. De hele interface om de MySQL data weer te geven is geen probleem dat kan ik zelf, alleen het loggen ging niet altijd goed ;)
Dan zou ik die smartmeterdashboard logger gebruiken, naar mijn weten logt die netjes alles. Kun je die gebruiken om het in mysql te pompen en anders is het script leesbaar genoeg om je eigen te maken.

Acties:
  • 0 Henk 'm!

  • ThinkPad
  • Registratie: Juni 2005
  • Laatst online: 15:15
Die van Smartmeterdashboard doet het op eenzelfde manier als ik het met de Arduino deed zie ik:

Python:
1
2
3
4
5
6
7
8
9
10
11
        elif p1_line[4:9] == "1.8.1":
#Meter Reading electricity delivered to client (normal tariff)
#eg. 1-0:1.8.1(00721.000*kWh) (DSMR 3)
#eg. 1-0:1.8.1(000038.851*kWh) (DSMR 4)
#        p1_meterreading_in_1=float(p1_line[10:19])
#        p1_unitmeterreading_in_1=p1_line[20:23]
            p1_lastpos=len(p1_line)-1
            p1_num_start = p1_line.find("(") +1
            p1_num_end = p1_line.find("*")
            p1_meterreading_in_1=float(p1_line[p1_num_start:p1_num_end])        
            p1_unitmeterreading_in_1=p1_line[p1_num_end+1:p1_lastpos]

Acties:
  • 0 Henk 'm!

  • DigiK-oz
  • Registratie: December 2001
  • Laatst online: 13:42
Ik heb dat via een regex gedaan (werkt voor mijn DSMR3, geen idee of dat ook op oudere/nieuwere werkt):

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
                for line in telegram.splitlines():
                        match=re.search("(\d-\d:\d+\.\d+\.\d+)\(([-+]?[0-9]*\.?[0-9WS]+).*?\)(?:\((.*?)\*m3\))?",line)
                        if match:
                                if match.group(1) == "0-0:1.0.0": # elec time
                                        elecdate=match.group(2)[:6]
                                        electime=match.group(2)[6:-1]
                                if match.group(1) == "1-0:1.8.1": # elec low in
                                        eleclowin=float(match.group(2))
                                if match.group(1) == "1-0:2.8.1": # elec low out
                                        eleclowout=float(match.group(2))
                                if match.group(1) == "1-0:1.8.2": # elec high in
                                        elechighin=float(match.group(2))
                                if match.group(1) == "1-0:2.8.2": # elec high out
                                        elechighout=float(match.group(2))
                                if match.group(1) == "1-0:1.7.0": # current in
                                        currentin=float(match.group(2))
                                if match.group(1) == "1-0:2.7.0": # current out
                                        currentout=float(match.group(2))
                                if match.group(1) == "0-1:24.2.1": # gas
                                        gasdate=match.group(2)[:6]
                                        gastime=match.group(2)[6:-1]
                                        gas=float(match.group(3))


De gegevens stop ik in een lokale MySQL database. Iedere 10 seconden de current values in een in-memory tabel die de laatste 12 uur bevat, ieder uur de totalen in een "echte" tabel. Die in-memory tabel is natuurlijk weg bij een restart van de Pi, maar die gebruik ik alleen om een grafiekje te toveren van recent gebruik. De historische data zit dan veilig in de per-uur tabel.

[ Voor 8% gewijzigd door DigiK-oz op 16-10-2015 11:45 ]

Whatever


Acties:
  • 0 Henk 'm!

  • RvvO72
  • Registratie: Maart 2018
  • Laatst online: 28-09-2022
Ik heb met mijn RPI en kabel van sossolutions precies hetzelfde probleem als deze topic starter.
Met cu en minicom een prachtig rijtje met alle waardes en gegevens, met het python script soms de output goed en soms de output fout.
Zie afbeeldingen eerste topic.

Is er al iemand die weet waar dit aan zou kunnen liggen?
Ik vind Ge Jansen zijn script erg leesbaar en wil dit gebruiken de data in mijn eigen sql database te zetten, samen met die van mijn zonnepanelen.

Groeten Robert.
Pagina: 1