Téléinformation depuis le raspberry

A/ Liens utiles

D'autres l'ont déja fait :

  1. Laurent Huet
  2. Magdiblog
  3. Frinux
  4. Hallard

Les spécifications d'ERDF sur la téléinformation

  1. ERDF (v5)

B/ Prérequis

Le seul vrai prérequis est que le compteur EDF envoie ce type d'information. Et d'après ce que j'ai lu :

Pour ma part, étant dans la deuxième catégorie, j'ai contacté ERDF qui, n'ayant pas réussi à m'activer la téléinformation, a changé le compteur.

Prix de l'intervention : 30,70 € (ce qui raisonnable)

Ensuite, il faut donc un octocoupleur SFH620A, une résistance 1.2 kΩ et une résistance 3.3 kΩ

Enfin, n'étant pas doué pour la soudure, j'ai acheté une breadboard et du cable supplémentaire

Prix du matos : 17 €

C/ Montage

1 Schéma électrique

schema
(*) Impossible de trouver l'auteur de ce schéma très présent sur le web

2. Schéma avec le raspberry

schema

3. Résultat final

schema
(*) Concernant l'octocoupleur, il y a un sens de pose ... :-) Si mauvais sens, pas de réception de données ...

Les fils sont donc à brancher sur les deux sorties l1 et l2 situées en bas à droite du compteur (il faut enlever le cache).

D/ Raspberry

Le cmdline.txt est un fichier contenant des paramètres qui seront passés au kernel au moment du boot. Il faut donc désactiver l'écriture sur le port série en supprimant les lignes :

console=ttyAMA0,115200 kgdboc=ttyAMA0,115200

A noter, qu'on peut le faire depuis l'écran de configuration

sudo raspi-config (option 8 : Adbvanced puis A8)

Ensuite il faut désactiver le login sur le port série en commentant la ligne suivante dans le fichier /etc/inittab

#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100  /etc/inittab :

un petit redémarrage ...

shutdown -r now

.. et sans attendre, un premier test, en écoutant sur le port série après l'avoir configuré la ligne

Les caractéristiques sont 1200 bauds, 7 bits de données, parité paire, 1 bit stop. Cela donne donc :

stty -F /dev/ttyAMA0 1200 sane evenp parenb cs7 -crtscts
cat /dev/ttyAMA0

1. Script

Ce que je voulais faire, c'était récupérer ces informations pour les stocker dans une base de données externe.

Externe dans le sens "pas sur la carte", car d'après ce que j'ai lu, il faut éviter autant que possible les opérations trop fréquentes d'écriture sur une carte SD.

En l'occurence, j'ai ouvert un compte chez MongoLab.

Le plus simple pour lire des données, les formatter et les déverser dans une base, c'est certainement de faire du python.

Ma version du script (inspiré d'autres scripts et certainement à améliorer) :

 #!/usr/bin/env python
# NAME: teleinfoERDF.py
# AUTHOR: Lionel Capdecomme
# DATE  : 24/01/2016
# COMMENT: Lecture des trames Teleinformation et sauvegarde dans BD MongoLab

import serial, json, sys, pymongo, datetime
from pymongo import MongoClient

# 0. Init variable 
SERIAL = '/dev/ttyAMA0'
MONGODB_URI = 'mongodb://user:password@adresseServeur:portServeur/nomDB' 
MONGODB_COLLECTION='nomCollection'

# 1. Ouverture du port serie
try:
  ser = serial.Serial(
    port=SERIAL,
    baudrate = 1200,
    parity=serial.PARITY_EVEN,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.SEVENBITS,
    timeout=1)
except:
  print "Impossible d'ouvrir le port serie" + SERIAL
  print sys.exc_info()
  sys.exit(1)

# 2. Lecture d'une trame complete
data = {}
while True :
 line=ser.readline().strip()
 array = line.split(' ')
 if len(array)>1 :
  header, value = array[0], array[1]
  # Si ADCO 2 fois alors tour complet
  if header == "ADCO" : 
    if 'adresseConcentrateur' in data : break 
    data['adresseConcentrateur']=value
  elif header == "OPTARIF" : data['optionTarif']=value
  elif header == "PTEC" : data['periodeTarifaire']=value
  elif header == "IINST" : data['intensiteInstant']=value
  elif header == "ADPS" : data['avertissementDepassement']=value
  elif header == "PAPP" : data['puissanceApparente']=value
  elif header == "IMAX" : data['intensiteMaximum']=value
  elif header == "ISOUSC" : data['intensiteSouscrit']=value
  elif header == "HCHC" : data['heuresCreuses']=value
  elif header == "HCHP" : data['heuresPleines']=value

data['date']=datetime.datetime.now()

#3. Sauvegarde dans le compte mongolab
client = pymongo.MongoClient(MONGODB_URI)
db = client.get_default_database()
# Choix de la collection 
teleinfo = db[MONGODB_COLLECTION]
teleinfo.insert(data)
Code python mis en forme par pygments