Open-conso

De LOAD.

Sommaire

Présentation

Ce nouveau projet fait suite à plusieurs idées de suivis de consommation EDF au niveau du compteur électrique d'une maison.

Les objectifs

- afficher la conso instantanée
- obtenir l'historique de sa consommation sur au moins 1an avec un détail à la minute.
- mesure en Watts et en VA (donc mesure courant et tension)
- interface d'exploitation des données "user friendly" avec des graphes sur période choisie
- Supporte les coupure de courant

Solutions

Nous allons nous orienter vers 2 solutions :
- pour les compteur linky (solution 1) : un module sans fil à brancher sur la sortie de donnée du compteur + un module "pc" qui se charge du stockage et affichage des données.
- pour les compteurs classiques (solution 2) : un module raspberry pi wifi + sonde sans contact de courant + transfo de mesure de tension qui se charge de la collecte, stockage et serveur web des données.

Les 2 solutions devraient pouvoir utiliser la même partie logiciel pour le stockage et exploitation des données (mysql + php ?)

Matériel pour la solution 2

- un raspeberry Pi + carte SD + dongle wifi + alim 5V
- un convertisseur analogique numérique MCP3008 (pas cher sur ebay si on en achète plusieurs)
- une sonde de courant non intrusive, existe en 2 modèle : la 100A, SCT-013-000 ou alors la 30A (chez seedstudio)
la 100A nécessite une résistance de 39ohms sur ces broches, la 30A a la résistance intégrée.
- un petit transfo classique plus un pont diviseur pour la mesure de la tension.

Liste du matériel

commandé :
- raspeberry Pi B amazon : 37
- dongle usb wifi amazon : 8.38
- SD card 8go class10 amazon : 6.75
- alim 220-5V 1A amazon : 4.49
- mcp3008 (CAN SPI) ebay : 3
- sonde courant 30A robotshop : 9.11

Total sans frais de port : 68€

matériel sorti de derrière les fagots :
- un petit transfo 220/5V pour mesure de la tension (ancien chargeur nokia)

Comment interfacer le mcp3008 :

http://hertaville.com/2013/07/24/interfacing-an-spi-adc-mcp3008-chip-to-the-raspberry-pi-using-c/

Une librairie sympa pour graphe :

http://www.highcharts.com/

filtrage des capteurs :

Pour filtrer les données j'ai choisit un filtre passe bas du 1er ordre de fréquence de coupure 73Hz (réalisé par une résistance de 2.2K et un condensateur de 1µF)
Cela conduit à une atténuation d'un signal 50Hz de 1.69dB soit un rapport de tension de 0.823
Cette atténuation sera compensé par un ampliOp permettant de profiter de toute la plage de mesure du CAN.
Le gain de l'ampli Op sera réglé sur 3.67 (résistance de 2.2k +0.470k et résistance de 1k)
Ainsi un courant de 30A crete en sortie de filtre vaudra 0.823V puis 3.02V en sortie d'AOP
En alimentant le mcp3008 par le 3.3V régulé du raspeberryPi on obtient une valeur numérique de (1024*3020/3300) 937
le même filtre sera appliqué sur le transfo de mesure de tension, mais auparavant le signal passera dans un diviseur de tension pour pouvoir mesurer des pointes de >400V
puis un AOP sera utilisé en suiveur pour fournir une source d'impédance faible au filtre RC
sortie max du transfo : 427/25 = 17.1V, rapport du pont diviseur 5.7 (résistance de 1K et 4.7K) sortie max de l'aop 3V
valeur numérique pour 311V : (311*0.823*1024/(25*5.7*3.3)) 419
L’utilisation du même filtre sur la partie mesure courant et mesure tension permet de s’affranchir de calcul de compensation du déphasage induit par ces filtres
la partie négative des signaux est ignoré pour les mesures
Un max660 sera utilisé pour génerer une tension négative de -5V pour le bon fonctionnement des AOP.
Un tl082 sera utilisé en tant que double aop.

Simulation (sous Qucs) avec un courant variant à 547hz :
Fichier:simu_conso_1.png

état du projet (schema + typon)

attente des composants ;)
22/11/2013 : sonde SCT013 30A/1V de chez seedstudio reçue.
23/11/2013 : MCP3008 recus.
25/11/2013 : raspeberryPi + alim + dongle wifi recus.

test de la sonde sur un pc en charge (environ 350W) (un bug sur l'oscillo éronne les mesures) :
Fichier:sonde_courant.png
interprétation :
En jaune c'est la tension image du courant mesuré par la sonde, son amplitude représente le courant consommé.
Réglage de l'oscillo ici sur 50mV par division.
Ont peut voir que le courant atteint un pic d'un peut plus de 100mV mesuré.
Comme j'utilise une sonde sct13 30A/1V ça donne un courant de pointe de 100*(30/1000)=3A
Si on prend en hypothèse que la forme du courant est sinusoïdale alors la valeur rms vaut 3/√2 = 2.12A
Donc le PC consomme 508VA (2.12*240V)
La ligne bleu c'est la tension du secteur qui est passé dans un petit transfo 220/5V car mon oscillo peut mesurer 80V maxi.
comme je ne connait pas le ratio exacte de mon transfo la valeur sur l'axe Y ne peut pas être interprété directement.
Par contre je sais grâce à mon onduleur et à mon voltmètre que la tension qui arrive dans mes prises et de 240Vrms soit 240*√2 = 339V en pointe.
Sur le graphe bleu on voit une pointe à 13.6V donc le ratio de mon transfo est de 339/13.6 = 25
Après on peut essayer de mesurer le cos Phi :
L'oscillo est sur 5ms/division, on voit que la courbe jaune devrait "avancer" d'environ 1.5ms pour être en phase.
donc Phi vaut : 360*(1.5/20) = 27°
ça fait un cos Phi de 0.89
et donc une puissance de 508*0.89=452W

mesure sur un autre pc possédant une alim à PFC passif :
Fichier:pc-pfc-passif.png
ici 2 tour ont été fait autour de la sonde pour améliorer la sensibilité, ont mesure un courant rms de 0.87A soit 209VA
le déphasage peut-être estimé à 1.8ms soit 32.4° donc 176W
Ont constate la moindre efficacité du pfc passif vs actif : rapport de 4:1 entre le courant crête et la valeur rms alors que seulement 1.4:1 dans le 1er cas.

montage filtrage réalisé sur une platine d'essais, voici le résultat du filtre sur la sonde de courant
Fichier:courant_avant_apres_filtre.png

Troisième version du schéma + pcb, modification de la valeurs des résistances de gain sur le filtrage du courant pour mesurer 42A crete (soit 30A rms)
Fichier:openconso_schema_v1.jpg
Vue 3d du circuit
Fichier:openconso_pcb_v1.jpg
Le typon, dimension imprimé : 46,7 par 40,15mm
Fichier:openconso_typon.png
Le montage finale
Fichier:Montage_finale.jpg

Configuration Raspberry Pi

La distribution arch linux a été utilisé.

Rajout de paquets

Grâce à pacman (le gestionnaire de paquet)

pacman -Syu (synchro puis upgrade generale)
pacman -S cifs-utils (pour pouvoir monter des partage réseaux windows avec mount -v -o guest -t cifs //[IP du partage]/ /[chemin où monter]/

Configuration de l'horloge

timedatectl set-timezone Europe/Paris

configurer le wifi pour une connexion automatique

ajout des driver du dongle wifi wn725n v2

systemctl enable dkms 

reboot

pacman -S dkms-8188eu 


pacman -S wireless_tools

utiliser wifi-menu pour générer la config (attention pas de - dans le nom du wifi)

ip link set dev wlan0 up
dhcpcd wlan0
netctl enable [nom du wifi]

Il semblerait qu'avec cette config le wifi se reconnecte en cas de perte du signal, mais ne se connecte pas si le wifi n'est pas présent au moment du boot.

ajouter une IP statique pour le lan en cas de défaut du wifi

First create configuration file for the systemd service, replace <interface> with proper interface name:
/etc/conf.d/network@<interface>

address=192.168.1.55
netmask=24
broadcast=192.168.1.255
gateway=192.168.4.254


Create a systemd unit file:
/etc/systemd/system/network@<interface>.service

[Unit]
Description=Network connectivity (%i)
Wants=network.target
Before=network.target
BindsTo=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/etc/conf.d/network@%i

ExecStart=/usr/bin/ip link set dev %i up
ExecStart=/usr/bin/ip addr add ${address}/${netmask} broadcast ${broadcast} dev %i
ExecStart=/usr/bin/ip route add default via ${gateway}

ExecStop=/usr/bin/ip addr flush dev %i
ExecStop=/usr/bin/ip link set dev %i down

[Install]
WantedBy=multi-user.target

Enable the unit and start it, passing the name of the interface:

# systemctl enable network@eth0.service
# systemctl start network@eth0.service

installer LAMP (linux apache mysql php)

pacman -S apache php php-apache mariadb 

You can start the MariaDB daemon with:

systemctl enable mysqld


config :

mysql_secure_installation


Une fois PHP installé, il nous faut configurer ce dernier pour prendre en compte MariaDB. Dé-commenter (enlevez le ; au début) la ligne suivante:

Fichier: /etc/php/php.ini

extension=mysql.so


Il faut désactiver les log binaires de mysql pour éviter d'user inutilement la caret SD :

vi /etc/mysql/my.cnf
commenter # log-bin=mysql-bin


Il ne reste plus qu'à configurer le serveur Apache pour prendre en compte PHP, pour cela, Rajoutez:
À la fin des chargements de modules (la liste des LoadModule):
Fichier: /etc/httpd/conf/httpd.conf

# Load php5 module
LoadModule php5_module modules/libphp5.so


À la fin des inclusions de fichiers de configuration (la liste des Include):
Fichier: /etc/httpd/conf/httpd.conf

# PHP settings
Include conf/extra/php5_module.conf


Pour démarrer automatiquement le serveur Apache :

systemctl enable httpd


tests :

mysql -p[password]

Pour Apache et PHP, rajoutez le fichier suivant dans /srv/http:
Fichier: /srv/http/test.php

<?php  phpinfo ();?>

Puis allez sur http://localhost/test.php

le programme de capture

Celui est décomposé en 5 parties :
open_conso.cpp : fichier principal
mcp3008Spi.cpp et h : librairie d'utilisation Spi
can_spi.cpp et h : classe de capteur mcp3008
calculs.cpp et h : calculs de valeurs electriques (rms ...)
fct_sql.cpp et h : fonction de sauvegardes des valeurs en BDD
Dossier du projet
Un makefile est utilisé pour la compilation.

auto lancement au boot

//-------------------- auto lancement d'openconso --------------// Create a systemd unit file:
/etc/systemd/system/openconso.service

[Unit]
Description=OpenConso
Requires=mysqld.service ntpd.service httpd.service
After=mysqld.service ntpd.service httpd.service

[Service]
Type=simple
RemainAfterExit=yes
ExecStart=/home/openconso/open_conso 1 root openconso 86 90

[Install]
WantedBy=multi-user.target


Enable the unit and start it, passing the name of the interface:

  1. systemctl enable openconso.service
  2. systemctl start openconso.service

Format Base De Donnée

Le format suivant est utilisé en base de donnée :

CREATE TABLE IF NOT EXISTS openconso.hist_value (
 ID int(11) NOT NULL AUTO_INCREMENT,
 volt int(11) NOT NULL DEFAULT '220',
 amp int(11) NOT NULL DEFAULT '0',
 cos float NOT NULL DEFAULT '1',
 VA int(11) NOT NULL DEFAULT '0',
 W int(11) NOT NULL DEFAULT '0',
 `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 PRIMARY KEY (ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

et

CREATE TABLE IF NOT EXISTS openconso.last_value (
 ID int(11) NOT NULL AUTO_INCREMENT,
 volt int(11) NOT NULL DEFAULT '220',
 amp int(11) NOT NULL DEFAULT '0',
 cos float NOT NULL DEFAULT '1',
 VA int(11) NOT NULL DEFAULT '0',
 W int(11) NOT NULL DEFAULT '0',
 `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 PRIMARY KEY (ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

Soit 2 tables de même structure : une pour l'historique et une pour la dernière valeur à jour.
Ces tables contiennent les champs suivants :

- un ID auto incrémenté
- la tension en Volt arrondi à 1
- l'intensité en miliAmpere
- le cos_phi (exemple 0.975)
- la mesure en VA
- la mesure en Watt
- le timestamp de la mesure

Visualisation des données

La visualisation des données se fait au travers d'un navigateur en pointant l'adresse qui héberge le serveur LAMP.
La page de visualisation est basée sur du javascript (calendrier de sélection + graphique)
dossier du serveur web

Exemple réel

Les statistiques relevées par mon montage sont visibles là :
OpenConso LIVE
un exemple de relevé journalier de conso :
exemples_de_conso.png

Liens de DL

Dernières versions :
Openconso pour raspberry soft + site
projet Kicad


ADENDUM !

Une précision : le montage n’ayant pas de compensation d'offset il faut sélectionner l'ampliOp de manière à ce que lorsqu'on mesure un courant null openconso affiche 0A.
(certains ampliOp ayant un offset positif et d'autre négatif on à une chance sur 2)
Pour la tension cela n'a pas d'importance vu le schéma utilisé.

Ajouter un index sur le champs date améliore grandement la vitesse d'affichage du graphique :
create unique index date_r on hist_value(date);
puis faites un dump avec mysqldump, supprimer la database, recréer là, puis import du fichier dump, ça recréera les enregistrements avec l'indexation du champs date.

Outils personnels