[PYTHON] Grafische Darstellung des Stromverbrauchs im Haushalt mit 3GPI und Raspeye

Befestigen Sie den Sensor zu Hause an der Verteilertafel und erstellen Sie eine solche Grafik.

メイン.gif

Auch die von jeder Schaltung verbrauchte Energiemenge.

回路ごと.gif

Einführung

Ich wollte wissen, wie viel Strom zu Hause verbraucht wird. Wenn unnötiger Standby-Strom vorhanden ist, möchte ich ihn reduzieren. Wenn ein Gerät Strom verschwendet, möchte ich ihn durch ein Produkt mit geringem Stromverbrauch ersetzen. Wenn Sie ein intelligentes Messgerät verwenden, können Sie den Übergang des Gesamtstromverbrauchs sehen, aber Sie können nicht den Verbrauch jedes vom Verteiler abzweigenden Stromkreises kennen. Ich möchte eine grafische Darstellung des Stromverbrauchs jeder Schaltung anzeigen.

Der Stückpreis für Strom wurde aufgrund der Ergebnisse meines Hauses im Jahr 2015 auf 25 Yen / kWh festgelegt.

spec

So berechnen Sie den Stromverbrauch

Leistungsaufnahme = Spannung x Strom x Zeit Bestimmt auf Spannung = 100 V. Aktuell = [quadratische mittlere Quadratwurzel] des gemessenen Wertes (https://ja.wikipedia.org/wiki/%E4%BA%8C%E4%B9%97%E5%B9%B3%E5%9D%87%E5% Verwenden Sie B9% B3% E6% 96% B9% E6% A0% B9) Zeit = Akkumulieren Sie die gemessenen Werte zu jedem Zeitpunkt

Aktuelle Messmethode

Die Messmethode bestand darin, den Ausgang des Stromsensors mit dem AD-Wandler zu verbinden, ohne einen Glättungs- oder Gleichrichterkreis zu durchlaufen. Ich erwarte, die Wellenform lesen zu können, wenn die Abtastgeschwindigkeit ausreichend ist.

Ich dachte, dass die Abtastgeschwindigkeit ungefähr 5 Abtastungen pro Halbzyklus betragen sollte. Um die Versorgungsfrequenz von 50 Hz und 60 Hz zu unterstützen, hätte ich gerne ungefähr 600 Samples pro Sekunde.

Design

Systemübersicht (frühes Entwicklungsbild)

構成図.png

Hardware-Design

Ausrüstung kaufen Insgesamt waren es 57.390 Yen. Für die Stromversorgung, das USB-Kabel, die Universalplatine, den Pin-Header, die Pin-Buchse und die Kabel habe ich den Überschuss zu Hause verwendet.

Dinge notwendig Was ich gekauft habe Geschäft Geldbetrag
3G-Kommunikationsmodul 3GPI Wissenschaft wechseln 29,800 Yen
Energieverwaltungsmodul slee-Pi Wissenschaft wechseln 11,800 Yen
Razz Pie Raspberry Pi 2 Model B Wissenschaft wechseln 5,940 Yen
WiFi Dongle GW-USNANO2A Wissenschaft wechseln 1,350 Yen
4 Stromsensoren SR-3702-150N/14Z Akizuki Electronics 3,920 Yen
1 AD-Wandler ADC1015-Modul Akizuki Electronics 1,280 Yen
4 Metallfilmwiderstände 100Ω 100 Stück Akizuki Electronics 300 Yen
SIM für die Kommunikation So-net 0 sim Sonett 3,000 Yen

Da es sich um eine Kombination von Modulteilen handelt, ist keine schwierige Schaltungskonstruktion oder -einstellung erforderlich. Die Strom-Spannungs-Wandlerplatine besteht aus einer Universalplatine.

Software

Da es viele Bibliotheken gibt, werden wir Python so oft wie möglich verwenden. Ich freue mich darauf, Python zum ersten Mal zu verwenden.

Der Server für die Datenverwaltung und -anzeige verwendet Sakura Rental Server Standard. Verwenden Sie für die Datenverwaltungsbibliothek RRDtool, das über eine Grafikausgabefunktion verfügt. Auf dem von mir gemieteten Server wurde es unter dem Namen rrdtool-fix installiert.

Ich werde immer mehr machen

  1. Stromsensor
  2. Kabelstecker
  3. AD-Konverter
  4. Razz Pie
  5. 3GPI
  6. Messwert-Sende- / Empfangsprogramm
  7. Grafikanzeigeprogramm

Stromsensor

Löten Sie es an das LAN-Kabel und installieren Sie es auf der Verteilerplatine.

2016_07_17_00845.JPG Im Hauptstromkreis installiert

Das Verteiler wird über drei Leitungen mit Strom versorgt: Rot, Schwarz und Weiß. Ich habe vier Sensoren wie folgt installiert.

Gemäß dem Spec Sheet (URD) eines ähnlichen Sensors, der ein Produkt eines anderen Unternehmens ist, Spannungsumwandlung mit einem Widerstand von 10 Ω Dann wird 60A in 0,2 V umgewandelt. Die Umrechnungsfunktion ist "Strom = Spannung * 300". Dies misst keine niedrigen Ströme, aber es scheint, dass 1-60 A ohne Verzerrung gemessen werden können. Die Spannungsumwandlung mit einem Widerstand von 100 Ω wandelt 60 A in 2,0 V um. Die Umrechnungsfunktion ist "Strom = Spannung * 30". Es scheint, dass es ab etwa 0,1 A gemessen werden kann.

Ich bin ratlos, aber die Spitze kann ein wenig verzerrt sein, also habe ich sie auf 100 Ω eingestellt, was einen niedrigen Strom anzeigen kann.

Obwohl es sich um ein Teil handelt, das tatsächlich verwendet wird, habe ich einen Widerstand mit einem Fehler von ± 1% gekauft. Ich habe den Widerstandswert mit einem Tester gemessen und vier gleiche Widerstandswerte nahe 100 Ω verwendet.

AD-Konverter

Entwerfen und bauen Sie die Schaltung.

電力量モニター回路図.png

habe es gerade geschafft. VDD wurde auf 3,3 V eingestellt.

ボード.JPG

Das AD-Wandlermodul hat eine Versorgungsspannung von 2-5 V und I2C-Geschwindigkeiten von 10 kHz bis 400 kHz sowie 3,4 MHz. Die I2C-Adresse kann am Ziel des ADDR-Pins von 0x48 auf 0x4B geändert werden. Es verfügt über einen eingebauten Verstärker, kann das negative Potential messen und die Verstärkung mit einem Mikrocomputer steuern. Die folgenden 6 Bereiche.

Bei Verwendung des ± 2,048-V-Bereichs (x2) mit PGA beträgt der vom Stromsensor gelesene Strom ± 61,44 A. Ich werde es im Bereich von ± 2,048 V versuchen. Eine negative Eingabe ist möglich, was zu bequem ist. Die Mindestauflösung beträgt 1 mV, was 30 mA Strom entspricht. Der Stromverbrauch beträgt 100V x 30 mA = 3 W.

Razz Pie

Für Messzwecke ist keine grafische Benutzeroberfläche erforderlich. Ich bin ein Konsolensüchtiger, also werde ich es über das Netzwerk einrichten. Ich freue mich darauf, Razpai zum ersten Mal zu berühren.

Installation

Ich habe Raspbian Jessie Lite (27.05.2016) auf die verbleibende SD-Karte (16 GB microSDHC Class4) gebrannt. Verbinden Sie einfach die von Ihnen hergestellte AD-Konverterkarte und das LAN-Kabel, erraten Sie die DHCP-Adresse und SSH. Es war zu leicht zu schlagen. Unten finden Sie die Installationsmethode.

#Deaktivieren Sie die WLAN-Energieverwaltung
sudo sh -c "echo options 8192cu rtw_power_mgnt=0 rtw_enusbss=1 rtw_ips_mode=1 > /etc/modprobe.d/8192cu.conf"

#SSH-Timeout verlängern
sudo sh -c "echo ClientAliveInterval 60 >> /etc/ssh/sshd_config"
sudo sh -c "echo ClientAliveCountMax 3 >> /etc/ssh/sshd_config"

#Paketaktualisierung
sudo apt-get update
sudo apt-get upgrade

# i2c-Werkzeuge installieren
sudo apt-get install i2c-tools

#Erhöhen Sie die i2c-Taktrate
sudo sh -c "echo dtparam=i2c_baudrate=300000 >> /boot/config.txt"

#i2c überprüfen(Wenn 0x48 antwortet, antwortet ADS1015.
i2cdetect -y 1 

#Installieren Sie die ADS1015-Bibliothek
sudo apt-get install git build-essential python-dev
git clone https://github.com/adafruit/Adafruit_Python_ADS1x15.git
cd Adafruit_Python_ADS1x15
sudo python setup.py install
sudo shutdown -h now

3GPI-Installation

Ziehen Sie den Netzstecker, wenn der Raspberry Pi stoppt. Schließen Sie den 3GPI an den Raspberry Pi an und schließen Sie das mit dem 3GPI gelieferte Netzteil an.

Weitere Informationen zu 3GPI finden Sie hier [http://mechatrax.github.io/) und GitHub. 3gpi2.jpg

3GPI-Installation


sudo bash -c 'echo "deb http://mechatrax.github.io/3gpi ./" > /etc/apt/sources.list.d/3gpi.list'
sudo apt-get update
sudo apt-get install 3gpi-archive-keyring
sudo apt-get install 3gpi-utils 3gpi-network-manager
sudo reboot

Stellen Sie den APN ein. SIM verwendet so-net 0sim. Es scheint besser, nicht verwendete APN-Informationen zu löschen.

APN-Einstellung


sudo nmcli con add type gsm ifname "*" con-name so-net apn so-net.jp user nuro password nuro
sudo nmcli c delete gsm-3gpi-iij
sudo nmcli c delete gsm-3gpi-soracom
sudo reboot

Damit konnte ich eine 3G-Verbindung herstellen. Es ist eine bewegende Sache. Langsames Ping ist auch ein Hinweis auf eine 3G-Verbindung. Ich bin glücklich!

Über 3G-Leitung


$ ping google.com -c 4
PING google.com (172.217.25.238) 56(84) bytes of data.
64 bytes from nrt12s14-in-f14.1e100.net (172.217.25.238): icmp_seq=1 ttl=50 time=377 ms
64 bytes from nrt12s14-in-f14.1e100.net (172.217.25.238): icmp_seq=2 ttl=50 time=386 ms
64 bytes from nrt12s14-in-f14.1e100.net (172.217.25.238): icmp_seq=3 ttl=50 time=366 ms
64 bytes from nrt12s14-in-f14.1e100.net (172.217.25.238): icmp_seq=4 ttl=50 time=404 ms

--- google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 366.570/383.838/404.300/13.866 ms

Über optische Leitung


$ ping google.com
PING google.com (172.217.25.238) 56(84) bytes of data.
64 bytes from nrt12s14-in-f14.1e100.net (172.217.25.238): icmp_seq=1 ttl=53 time=8.01 ms
64 bytes from nrt12s14-in-f14.1e100.net (172.217.25.238): icmp_seq=2 ttl=53 time=9.52 ms
64 bytes from nrt12s14-in-f14.1e100.net (172.217.25.238): icmp_seq=3 ttl=53 time=9.50 ms
64 bytes from nrt12s14-in-f14.1e100.net (172.217.25.238): icmp_seq=4 ttl=53 time=9.66 ms
64 bytes from nrt12s14-in-f14.1e100.net (172.217.25.238): icmp_seq=5 ttl=53 time=9.47 ms
^C
--- google.com ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4005ms
rtt min/avg/max/mdev = 8.017/9.238/9.668/0.614 ms

Mess- und Übertragungsprogramm

Berechnen Sie eine Richtlinie für den Verkehr. Dieses Programm sendet den Stromverbrauch jede Minute. Eine Nachricht drückt den Zeitstempel und den Stromverbrauch von 4 Kanälen in ASCII-Text aus, und die Größe der Nachricht beträgt ungefähr 50 Bytes. Nach dem Sammeln von 5 Minuten Informationen wurde bz2 komprimiert und gesendet. Da es in zwei Hälften komprimiert werden kann, beträgt die tatsächlich übertragene Menge ungefähr 120 Bytes, also ungefähr 3,2 Bit / s.

Angesichts des Overheads von TCP / IP, HTTP und SSL ist es schwer zu sagen, ohne tatsächlich zu kommunizieren.

0sim von so-net ist frei von Kommunikationsgebühren bis zu 500 MByte pro Monat. Umgerechnet auf 1493 Bit / s pro Sekunde.

Wenn viel Verkehr vorhanden ist, verlängern Sie das Übertragungsintervall, um damit umzugehen.

Zeigen Sie auf die 3GPI- und AD-Konverterplatine auf dem Raspeltorte und schreiben Sie das Programm.

sudo mkdir -p /opt/whmonitor/bin/
sudo vi /opt/whmonitor/bin/whmonitor.py
sudo chmod +x /opt/whmonitor/bin/whmonitor.py

/opt/whmonitor/bin/whmonitor.py


#!/usr/bin/python
# -*- coding: utf-8 -*-

import time
import math
from collections import deque
import copy
import sys
import datetime
import urllib
import urllib2
import bz2
import Adafruit_ADS1x15
import RPi.GPIO as GPIO


#Verwandte Konstanten für die Leistungsmessung
MEASURE_INTERVAL = 60
CHANNEL_CHANGE_INTERVAL = 10
CONVERSION_CONSTANT = 30 # 100 ohm
VOLTAGE = 100
TO_KILOWATT = 0.001

#Herzschlag-bezogene Konstanten( slee-Für Pi)
FLIP_INTERVAL = 500
HEARTBEAT_GPIO = 5

#ADC1015-bezogene Konstanten
I2C_BUSNUM = 1
ADS1015_I2C_BASE_ADDRESS = 0x48
SENSORS = 4
PGA_GAIN = 2
SAMPLING_RATE = 3300

#Datenübertragungsbezogene Konstanten
MINIMUM_UPLOAD_QUEUE_LENGTH = 5
UPLOAD_URL = "https://[Hostname des Datenempfangsservers]/whupdate.cgi"
BASICAUTH_ID = "[Grundlegende Authentifizierungs-ID]"
BASICAUTH_PASS = "[Grundlegendes Authentifizierungskennwort]"
COMPRESSION_LEVEL = 9



class Recorder:
    """Diese Klasse lädt Daten auf einen Webserver hoch.
Es hat eine Warteschlange und Aufzeichnungen()Enthält die von der Methode empfangene Liste.
Wenn die Warteschlange lang genug ist, werden die Daten an den Webserver gesendet.
Wenn die Übertragung fehlschlägt, wird die Übertragung zum nächsten Aufnahmezeitpunkt versucht.
    """

    def __init__(self, url, ba_id, ba_pass, minimum_upload_queue_length = 1):
        self.data_queue = deque()

        self.url = url
        self.ba_id = ba_id
        self.ba_pass = ba_pass
        self.compression_level = COMPRESSION_LEVEL
        self.minimum_upload_queue_length = minimum_upload_queue_length


    def record(self, data):
        self.data_queue.append(self.__build_message(data))
        tmp_queue=copy.deepcopy(self.data_queue)

        try:
            if self.minimum_upload_queue_length <= len(tmp_queue) :
                self.__send_queue(tmp_queue)
                for dummy in tmp_queue:
                    self.data_queue.popleft()
        except:
            print("===Die Daten konnten nicht gesendet werden.===")
            d=datetime.datetime.today()
            print d.strftime("%Y-%m-%d %H:%M:%S"),'\n'


    def __send_queue(self, queue):
        send_string = ""
        for data in queue:
            send_string += " " + data
        response=self.__send_string(send_string)


    def __send_string(self, message):

        pswd_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
        pswd_mgr.add_password(None, self.url, self.ba_id, self.ba_pass)
        opener = urllib2.build_opener(urllib2.HTTPSHandler(),
            urllib2.HTTPBasicAuthHandler(pswd_mgr))
        urllib2.install_opener(opener)

        request = urllib2.Request(self.url)
        request.add_data(bz2.compress(message,self.compression_level))

        response = urllib2.urlopen(request)
        return response.read()


    def __build_message(self, data):
        message = str(int(time.time()))
        for value in data:
            message += ":" + str(value)
        return message


class Knocker:
    """Diese Klasse ändert die Ausgangsspannung von GPIO.
    flip()Drehen Sie den Ausgang des angegebenen GPIO-Pins bei jedem Aufruf der Methode um.
    """

    def __init__(self, port):
        self.port = port
        GPIO.setwarnings(False)
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(port,GPIO.OUT)


    def flip(self):
        GPIO.output(self.port,(GPIO.input(self.port)+1)%2)



class IntervalTimer(object):
    """Diese Klasse ist Busyloop mit voller Geschwindigkeit()Führen Sie die Methode aus.
Führen Sie außerdem jede im Konstruktor angegebene Sekunde eine lange Schleife durch()Führen Sie die Methode aus
    """

    def __init__(self, interval = 1):
        self.interval = interval

    def busyloop(self):
        pass

    def longloop(self):
        print time.time()-self.start

    def loop(self):
        self.start=int(time.time())
        prev=self.start
        while True:
            while time.time()-prev < self.interval:
                self.busyloop()
            prev = int(time.time())
            self.longloop()


class Sampler(IntervalTimer):

    """Diese Klasse ist die Hauptklasse.
Verwaltet AD-Konverter, Datenübertragungen und Heartbeats.
    """

    def __init__(self,interval):
        super(Sampler, self).__init__(interval)
        self.knocker = Knocker(HEARTBEAT_GPIO)
        self.recorder = Recorder(UPLOAD_URL, BASICAUTH_ID, BASICAUTH_PASS, \
            MINIMUM_UPLOAD_QUEUE_LENGTH)
        self.adc = Adafruit_ADS1x15.ADS1015(\
            address=ADS1015_I2C_BASE_ADDRESS,busnum=I2C_BUSNUM)
        self.reset_valiables()


    def reset_valiables(self):
        self.sensor = 0
        self.samples = 0
        self.sample_buffer = [0]*SENSORS
        self.sample_length = [0]*SENSORS
        self.watt = [0]*SENSORS


    def busyloop(self):
        if self.samples%CHANNEL_CHANGE_INTERVAL == 0 :
            self.sensor=(self.samples/CHANNEL_CHANGE_INTERVAL)%SENSORS
            self.adc.start_adc(self.sensor, gain=PGA_GAIN, \
                data_rate=SAMPLING_RATE)
            time.sleep(2.0/SAMPLING_RATE)

        current=self.adc.get_last_result()*CONVERSION_CONSTANT

        self.sample_buffer[self.sensor] += current * current
        self.sample_length[self.sensor] += 1
        if self.samples%FLIP_INTERVAL == 0:
            self.knocker.flip()
        self.samples += 1



    def longloop(self):
        for self.sensor in range(SENSORS):
            if self.sample_length[self.sensor] == 0:
                self.watt[self.sensor]=0
            else:
                self.watt[self.sensor]=\
                    math.sqrt(self.sample_buffer[self.sensor]\
                    /self.sample_length[self.sensor])*VOLTAGE*TO_KILOWATT

        self.recorder.record(self.watt)
        self.reset_valiables()



sampler = Sampler(MEASURE_INTERVAL)
sampler.loop()

Serviceregistrierung

Erstellen Sie Serviceregistrierungsinformationen.

sudo vi /etc/systemd/system/whmonitor.service

Der Inhalt ist so. Selbst wenn das Programm stoppt, wird es automatisch neu gestartet.

/etc/systemd/system/whmonitor.service


[Unit]
Description = watt hour monitor

[Service]
ExecStart = /opt/whmonitor/bin/whmonitor.py
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target

Aktivieren Sie den Dienst und führen Sie ihn aus.

sudo systemctl enable whmonitor
sudo systemctl start whmonitor

Slee-Pi-Setup

sle-Pi überwacht die Lebendigkeit des Betriebssystems durch Installation der sleepi-Firmware. Mit der Standard-Firmware scheint das Betriebssystem HEARTBEAT an GPIO5 zu senden, und Slee-Pi überwacht dies. Wenn HEARTBEAT für einen bestimmten Zeitraum nicht bestätigt werden kann, wird der Raspberry Pi gestoppt oder neu gestartet.

Ich möchte Leben und Tod der Anwendung überwachen, daher storniere ich die Standard-Firmware. Durch Ein- und Ausschalten des GPIO5-Pins in der Schleife der Anwendung wird der Sleep-Pi auf Leben und Tod überwacht.

sudo bash -c 'echo "deb http://mechatrax.github.io/sleepi ./" > /etc/apt/sources.list.d/sleepi.list'
sudo apt-get update
sudo apt-get install sleepi-archive-keyring
sudo apt-get update
sudo apt-get install sleepi-firmware
sudo shutdown -h now
  1. Trennen Sie den Raspberry Pi (3GPI) vom Computer.
  2. Schließen Sie die Konverterplatine für Slee-Pi, 3GPI und AD an
  3. Schließen Sie die Stromversorgung an den Slee-Pi an
  4. Drücken Sie die Boot-Taste am Slee-Pi
#Beenden Sie das Monitorprogramm
sudo systemctl stop whmonitor.service
#Verringern Sie die i2c-Uhr
sudo rmmod i2c_bcm2708 
sudo modprobe i2c_bcm2708 baudrate=100000
#Überprüfen Sie die Timeout-Sekunden vom Ende des Herzschlags bis zum Herunterfahren
printf "%d\n" `i2cget -y 1 0x69 6 b`
#Stellen Sie das Zeitlimit auf 120 Sekunden ein
i2cset -y 1 0x69 6 120 
#Stellen Sie den Betriebsmodus auf "Neustart aktiviert, wieder einschalten, wenn keine Antwort erfolgt".
i2cset -y 1 0x69 5 1
#Erhöhen Sie die i2c-Uhr
sudo rmmod i2c_bcm2708
sudo modprobe i2c_bcm2708 baudrate=300000
#Programm zur Überwachung des Stromverbrauchs gestartet
sudo systemctl start whmonitor.service
# sleepi-Firmware deinstallieren
sudo apt-get remove sleepi-firmware
# reboot
sudo reboot

Datenbank und Empfänger

Erhalten Sie bei Sakura Internet-Mietserver "Standard".

Datenbankerstellung

create.sh


#!/bin/sh

/usr/local/bin/rrdtool-fix create  \
        /Datenbankspeicherverzeichnis/watt.rrd --step 60 \
        DS:sensor0:GAUGE:120:0:1000000 \
        DS:sensor1:GAUGE:120:0:1000000 \
        DS:sensor2:GAUGE:120:0:1000000 \
        DS:sensor3:GAUGE:120:0:1000000 \
        RRA:AVERAGE:0.5:1:1054080 \
        RRA:MAX:0.5:1:1054080 \
        RRA:MIN:0.5:1:1054080 \
        RRA:LAST:0.5:1:1054080

Empfangsprogramm

whupdate.cgi


#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import cgi
import cgitb
import os
import sys
import subprocess
import shlex
import bz2
import re

cgitb.enable()

if os.environ['REQUEST_METHOD'] != "POST":
    print 'invalid access'
    sys.exit()

rrd="/Datenbankspeicherverzeichnis/watt.rrd"
lines = bz2.decompress(sys.stdin.read())
if re.match("^[0-9 :\.]+$",lines):
    cmd='/usr/local/bin/rrdtool-fix update {rrd} {param}'.format(rrd=rrd,param=lines)
    ret=subprocess.check_output(shlex.split(cmd))

print ('Content-type: text/html; charset=UTF-8')
print ("\r\n\r\n")
print

Grafikanzeige

Laden Sie [IPA Font] herunter (http://ipafont.ipa.go.jp/old/ipafont/download.html). IPA Gothic (nicht P Gothic) wird empfohlen. Da die Schrift die gleiche Breite hat, sind die vertikalen Linien schwer zu reduzieren. Speichern Sie ipag.ttf im selben Verzeichnis wie das Diagrammanzeigeprogramm.

graph_total.cgi


#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import subprocess
import os
import shlex
import cgi
import config
import sys
import re

os.environ["RRD_DEFAULT_FONT"]="/Speicherverzeichnis für Schriftarten/ipag.ttf"
os.environ['LANG'] = 'ja_JP.UTF-8'

title=""
end="now"
start="now-12hour"
width=800
height=200


form=cgi.FieldStorage()
strnum=re.compile("^[0-9a-zA-Z\-]+$")

if form.has_key("title") and strnum.match(form["title"].value):
        title=" "+form["title"].value
if form.has_key("end") and strnum.match(form["end"].value):
    end=form["end"].value
if form.has_key("start") and strnum.match(form["start"].value):
        start=form["start"].value
if form.has_key("width") and form["width"].value.isdigit():
        width=form["width"].value
if form.has_key("height") and form["height"].value.isdigit():
        height=form["height"].value
if form.has_key("graph_id") and form["graph_id"].value.isdigit():
        graph_id=int(form["graph_id"].value)

cmd_src='/usr/local/bin/rrdtool-fix graph - \
            --start {start} --end {end} \
            --width {width} --height {height} \
            --title "Stromkosten{title}" \
            --font "DEFAULT:9:" \
            --font "TITLE:12:" \
            --font "LEGEND:12:" \
            --lower-limit 0 --step 60 --slope-mode \
            --vertical-label "Watt" \
            DEF:s0_avg={rrd}:sensor0:AVERAGE \
            DEF:s1_avg={rrd}:sensor1:AVERAGE \
            DEF:s0_max={rrd}:sensor0:MAX \
            DEF:s1_max={rrd}:sensor1:MAX \
            DEF:s0_min={rrd}:sensor0:MIN \
            DEF:s1_min={rrd}:sensor1:MIN \
            CDEF:main_avg=s0_avg,s1_avg,+ \
            CDEF:main_max=s0_max,s1_max,+ \
            CDEF:main_min=s0_min,s1_min,+ \
            CDEF:main_yps=main_avg,3600,1000,*,/,25,* \
            VDEF:main_yen=main_yps,TOTAL \
            LINE1:main_avg#00ff00ff:"" \
            AREA:main_avg#00ff0033:"" \
            COMMENT:" \\n" \
            GPRINT:main_yen:"Stromkosten%7.1lf Yen" '

rrd="/Datenbankspeicherverzeichnis/watt.rrd"
cmd=cmd_src\
    .format(rrd=rrd,width=width,height=height,start=start,end=end,title=title)
output=subprocess.check_output(shlex.split(cmd))

print ('Content-type: image/gif')
print
print output

graph_para.cgi


#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import subprocess
import os
import shlex
import cgi
import config
import sys
import re

os.environ["RRD_DEFAULT_FONT"]="/Verzeichnis, in dem Schriftarten gespeichert werden/ipag.ttf"
os.environ['LANG'] = 'ja_JP.UTF-8'

title=""
end="now"
start="now-12hour"
width=800
height=200
graph_id=0


form=cgi.FieldStorage()
strnum=re.compile("^[0-9a-zA-Z\-]+$")

if form.has_key("title") and strnum.match(form["title"].value):
        title=" "+form["title"].value
if form.has_key("end") and strnum.match(form["end"].value):
    end=form["end"].value
if form.has_key("start") and strnum.match(form["start"].value):
        start=form["start"].value
if form.has_key("width") and form["width"].value.isdigit():
        width=form["width"].value
if form.has_key("height") and form["height"].value.isdigit():
        height=form["height"].value
if form.has_key("graph_id") and form["graph_id"].value.isdigit():
        graph_id=int(form["graph_id"].value)

cmd_src='/usr/local/bin/rrdtool-fix graph - \
            --start {start} --end {end} \
            --width {width} --height {height} \
            --title "Stromverbrauch pro Stromkreis{title}" \
            --font "DEFAULT:9:" \
            --font "TITLE:12:" \
            --font "LEGEND:10:" \
            --lower-limit 0 --step 60 --slope-mode \
            --vertical-label "Watt" \
            DEF:s0_avg={rrd}:sensor0:AVERAGE \
            DEF:s1_avg={rrd}:sensor1:AVERAGE \
            DEF:s2_avg={rrd}:sensor2:AVERAGE \
            DEF:s3_avg={rrd}:sensor3:AVERAGE \
            DEF:s0_max={rrd}:sensor0:MAX \
            DEF:s1_max={rrd}:sensor1:MAX \
            DEF:s2_max={rrd}:sensor2:MAX \
            DEF:s3_max={rrd}:sensor3:MAX \
            DEF:s0_min={rrd}:sensor0:MIN \
            DEF:s1_min={rrd}:sensor1:MIN \
            DEF:s2_min={rrd}:sensor2:MIN \
            DEF:s3_min={rrd}:sensor3:MIN \
            CDEF:total_avg=s0_avg,s1_avg,+ \
            CDEF:total_max=s0_max,s1_max,+ \
            CDEF:total_min=s0_min,s1_min,+ \
            CDEF:total_yps=total_avg,3600,1000,*,/,25,* \
            VDEF:total_yen=total_yps,TOTAL \
            CDEF:others_avg=s0_avg,s1_avg,+,s2_avg,s3_avg,+,- \
            CDEF:others_min=s0_min,s1_min,+,s2_min,s3_min,+,- \
            CDEF:others_max=s0_max,s1_max,+,s2_max,s3_max,+,- \
            CDEF:s2_yps=s2_avg,3600,1000,*,/,25,* \
            VDEF:s2_yen=s2_yps,TOTAL \
            CDEF:s3_yps=s3_avg,3600,1000,*,/,25,* \
            VDEF:s3_yen=s3_yps,TOTAL \
            CDEF:others_yps=others_avg,3600,1000,*,/,25,* \
            VDEF:others_yen=others_yps,TOTAL \
            COMMENT:"__________\t_cost___ _cur_ _min_ _max_ _ave_"\
            COMMENT:"\\n" \
            LINE1:total_avg#00ff0077:"gesamt\t\g" \
            GPRINT:total_yen:"%7.1lf\g"  \
            GPRINT:total_avg:LAST:" %5.0lf\g"  \
            GPRINT:total_min:MIN:" %5.0lf\g"  \
            GPRINT:total_max:MAX:" %5.0lf\g"  \
            GPRINT:total_avg:AVERAGE:" %5.0lf\g"  \
            COMMENT:"\\n" \
            LINE1:s2_avg#00aa88:"Leben\t\g" \
            GPRINT:s2_yen:"%7.1lf\g"  \
            GPRINT:s2_avg:LAST:" %5.0lf\g"  \
            GPRINT:s2_min:MIN:" %5.0lf\g"  \
            GPRINT:s2_max:MAX:" %5.0lf\g"  \
            GPRINT:s2_avg:AVERAGE:" %5.0lf\g"  \
            COMMENT:"\\n" \
            LINE1:s3_avg#8800aa:"Küche\t\g" \
            GPRINT:s3_yen:"%7.1lf\g"  \
            GPRINT:s3_avg:LAST:" %5.0lf\g" \
            GPRINT:s3_min:MIN:" %5.0lf\g" \
            GPRINT:s3_max:MAX:" %5.0lf\g" \
            GPRINT:s3_avg:AVERAGE:" %5.0lf\g" \
            COMMENT:"\\n" \
            LINE1:others_avg#aa8800:"Andere\t\g" \
            GPRINT:others_yen:"%7.1lf\g"  \
            GPRINT:others_avg:LAST:" %5.0lf\g"  \
            GPRINT:others_min:MIN:" %5.0lf\g"  \
            GPRINT:others_max:MAX:" %5.0lf\g"  \
            GPRINT:others_avg:AVERAGE:" %5.0lf"  \
            '

rrd="/Datenbankspeicherverzeichnis/watt.rrd"
cmd=cmd_src\
    .format(rrd=rrd,width=width,height=height,start=start,end=end,title=title)
output=subprocess.check_output(shlex.split(cmd))


print ('Content-type: image/gif')
print
print output

Durchsuchen

Greifen Sie nach ca. 5 Minuten auf die folgende URL zu, um das Diagramm zu überprüfen.

http://[公開サーバー]/[ディレクトリ]/graph_total.cgi http://[公開サーバー]/[ディレクトリ]/graph_para.cgi

Komplett

Ich konnte das Diagramm im Browser anzeigen. Auf diese Weise können Sie Standby-Strom und großfressende Haushaltsgeräte freilegen.

graph_total.gif

graph_para.gif

Zusammenfassung

Ich werde die Gesamtzusammensetzung überprüfen.

Datenfluss

Der Datenfluss ist in zwei Systeme unterteilt. Hier wird es als Datenerfassungssystem und Datenanzeigesystem beschrieben.

Datenerfassungssystem

  1. Wandeln Sie Strom mit Stromsensor und Widerstand in Spannung um
  2. Verstärkt und mit ADS1015 abgetastet
  3. Holen Sie sich Abtastdaten mit Raspeye (unter Verwendung des I2C-Busses und der ADS1x15-Bibliothek).
  4. Berechnung 5.3 Über 3GPI an CGI auf dem Datenverwaltungsserver senden
  5. Von CGI empfangen und in der Round-Robin-Datenbank von RRDtool gespeichert

Datenanzeigesystem

  1. Der Browser fordert CGI auf, ein Diagramm anzuzeigen
  2. CGI veranlasst RRDtool, ein Diagramm zu generieren und an den Browser zu senden
  3. Im Browser anzeigen

Programme und Einstellungen

Sammeln Sie das entwickelte Programm, die Einstellungsdatei und die erforderlichen externen Dateien.

Razz Pie Seite

--Messprogramm whmonitor.py --Service-Konfigurationsdatei /etc/systemd/system/whmonitor.service

Serverseite

--RRDtool Datenbankgenerator create.sh --Datenempfangsprogramm whupdate.cgi

Impressionen

Sie können jetzt den Stromverbrauch sicher messen. 3G-Kommunikation war möglich, Überwachung des Anwendungsbetriebs war möglich, Stromverbrauch wurde gemessen und ein Diagramm konnte angezeigt werden. Die Messung des Stromverbrauchs ist eine empfohlene elektronische Arbeit, da die Hardware praktisch und einfach vorzubereiten ist. Seien Sie jedoch vorsichtig mit den Arbeiten am Verteiler und der Isolierung um den Sensor.

Es besteht Todesgefahr, z. B. Stromschlag während der Arbeit, Stromleckage an installierten Geräten oder Brand aufgrund eines Kurzschlusses. Ich kann nicht beurteilen, ob die Installation des Stromsensors auf dem Verteiler elektrischen Arbeiten entspricht, für die eine Lizenz erforderlich ist. Ich habe als Elektriker zweiter Klasse studiert, aber je nach Interpretation kann es als notwendig oder unnötig gelesen werden. In jedem Fall ist es besser, die Risiken zu verstehen, sodass es sicher ist, über das Wissen zu verfügen, das einem Elektriker zweiter Klasse entspricht. Die SHARP-Website bietet ein Beispiel für eine "kundensichere Installation". → Kann ich die Einkreis-CT-Sensoreinheit selbst installieren?

Über Messergebnisse

Als ich anfing, Daten zu sammeln, interessierte ich mich für Geräte mit hoher Spitzenleistung. Berechnen Sie die Stromgebühr pro Zeit. Der Stückpreis für Strom wird auf der Grundlage der tatsächlichen Ergebnisse im Jahr 2015 auf 25 Yen pro kWh festgelegt.

Gebrauchte Ausrüstung Durchschnittlicher Stromverbrauch[w] Durchschnittliche Nutzungsdauer[h] Energieverbrauch[kWh] Stromkosten[Kreis]
Mikrowelle 1500 0.033 0.050 1.3
Badezimmertrockner 800 4.0 3.2 80
Betttrockner 600 2.0 1.2 30
Verschiedene Standby-Stromversorgung 80 24 1.2 30

Zwei Wochen nach der Messung konnte ich den ungefähren Preis pro Tag sehen.

Artikel Durchschnittlicher Stromverbrauch[w] Durchschnittliche Nutzungsdauer[h] Energieverbrauch[kWh] Stromkosten[Kreis]
gesamt 250 24 6.0 150
Standby-Leistung 50 18 0.9 23

Demnach waren 15% Standby-Strom. Geräte, die als Standby-Strom gezählt werden, sind Mikrowellenherde, Reiskocher, Joghurthersteller, Bäckereien zu Hause, Fernseher, WLAN-Router, WLAN-Repeater, PC-Lautsprecher, externe Festplatten, Notebooks (ausgeschaltet), Desktop-PCs (ausgeschaltet), PCs. Monitor und Drucker. Es gibt einige zu listen, aber ich habe die Steckdosen angeschlossen gelassen, einschließlich derer, die ich nur gelegentlich benutze. Durch gründliches Herausziehen des Netzsteckers bei Nichtgebrauch wird Ihre Stromrechnung um 15% reduziert. Die jährliche Stromrechnung im Jahr 2015 betrug 60.000 Yen, sodass sie möglicherweise auf 51.000 Yen gesenkt wurde.

Ich war der Meinung, dass Standby-Strommaßnahmen die Stromkosten wirksam senken würden.

Informationen zu Stromverbrauchsdaten

Wenn ich mir das Muster zum Erhöhen / Verringern der Leistung ansehe, kann ich ungefähr verstehen, wann und was ich getan habe. Verwendung einer Klimaanlage. Benutzung einer Mikrowelle. Die Belastung des Kühlschranks aufgrund der Temperatur. Verwendung eines Reiskochers. Beleuchtung an. Weckzeit, Schlafenszeit. Zum Beispiel nachts auf die Toilette gehen. Mit der Verbreitung intelligenter Zähler können Stromversorger Änderungen im Stromverbrauch erfassen. Indem Sie den Stromverbrauchsstatus jedes Haushalts analysieren, können Sie verstehen, was zu Hause passiert. Besonders das Muster der Mikrowelle ist charakteristisch. Sie können Informationen darüber erhalten, wann und wie oft Sie es verwendet haben und wie oft Sie es täglich verwendet haben. Es können begehrte Daten für Haushaltsgerätehersteller sein.

Es scheint, dass der laufende Raspeltorte ungefähr 1600 Mal pro Sekunde abtasten kann. Selbst wenn die Versorgungsfrequenz 60 Hz beträgt, können Sie 26 Mal pro Zyklus abtasten. Ich denke, dass es möglich ist, die Wellenform irgendwie zu analysieren, so dass es möglich sein kann zu analysieren, ob die verbrauchte Ausrüstung eine Last wie ein Motor, ein Wechselrichter, eine Heizung usw. ist.

Über die Entwicklung

Ich habe Razzpie zum ersten Mal benutzt und es funktioniert ziemlich gut. Ich bin auch dankbar für die große Menge an Informationen. Ich danke meinen Vorfahren. Ich musste mir keine Sorgen machen, es kontinuierlich laufen zu lassen. Python war auch eine Menge Informationen und leicht zu erlernen. Es gibt viele Bibliotheken, und ich fühlte, warum sie so beliebt waren. Es ist mir ein wenig peinlich, weil ich nicht glaube, dass ich nach Pythons Manieren programmieren konnte.

Die Gesamtentwicklungszeit beträgt ca. 40 bis 50 Stunden. Die Hardwareentwicklung dauerte ca. 5 Stunden für die Auswahl, das Design und die Herstellung der Teile. Dank des ADS1015 ist es beeindruckend, dass die Hardwareentwicklungszeit sehr kurz war. Da der Umfang der Schaltung klein war, habe ich sie von Anfang an gelötet, aber ich denke, dass sie in kürzerer Zeit entwickelt werden kann, wenn sie mit einem Brotbrett zusammengebaut wird.

Ich habe den Eindruck, dass die Entwicklung der Software einige Zeit in Anspruch genommen hat. Ich war besonders süchtig nach RRDtool. Der Versuch, etwas Aufwändiges zu tun, erforderte wenig Informationen und Versuch und Irrtum. Insbesondere habe ich den Eindruck, dass es lange gedauert hat, die Verwendung der VDEF-Syntax herauszufinden. 3GPI ist sehr praktisch, weil es ohne nachzudenken funktioniert. Ich dachte, wenn ich NetworkManager verwenden könnte, könnte ich es fortgeschrittener verwenden, z. B. eine Backup-Leitung einrichten. Der Slee-Pi ist ursprünglich ein Gerät, das den Betrieb des Betriebssystems überwacht, aber ich wollte den Betrieb der Anwendung überwachen, daher habe ich den Treiber des Herstellers nicht verwendet. Da innerhalb der Schleife der Anwendung ein Herzschlag erzeugt wird, wird der Raspelkuchen automatisch neu gestartet, wenn die Anwendung gestoppt wird. Sie können auch die Watchdog-Funktion von Raspeye verwenden, es ist jedoch sicher, einen Neustart von außen zu erzwingen.

Vorsichtsmaßnahmen

Das Anbringen eines Sensors an der Verteilertafel birgt die Gefahr des Todes, wie z. B. eines Stromschlags während der Arbeit, einer elektrischen Leckage aufgrund installierter Geräte und eines Brandes aufgrund eines Kurzschlusses. Bitte seien Sie vorsichtig, wenn Sie eine Entscheidung treffen, einschließlich der Frage, ob sie umgesetzt werden kann oder nicht.

Recommended Posts

Grafische Darstellung des Stromverbrauchs im Haushalt mit 3GPI und Raspeye
Herstellung eines Temperaturregelungssystems mit Himbeerkuchen und ESP32 (1)
Messen und vergleichen Sie Temperaturen mit Raspberry Pi und generieren Sie automatisch Diagramme
Erstellen Sie einen Kanji-Kompass mit Raspberry Pi und Sense Hat
Haustierüberwachung mit Rekognition und Raspberry pi
Den Servomotor SG-90 mit Himbeer-Pi betreiben
Herstellung eines Temperaturregelungssystems mit Himbeerkuchen und ESP32 (2) Herstellung eines Übertragungsgeräts
MQTT Radicon Car mit Arduino und Himbeere
Schalten Sie Ihren PC mit Himbeer-Pi ein / aus
CSV-Ausgabe von Impulsdaten mit Raspberry Pi (CSV-Ausgabe)
Holen Sie sich CPU-Informationen von Raspberry Pi mit Python
Holen Sie sich Temperatur und Luftfeuchtigkeit mit DHT11 und Raspberry Pi
Messen Sie die CPU-Temperatur von Raspeye mit Python
Einfacher VPN-Aufbau eines IPSec-Gateways mit Ubuntu 20.04 und Raspberry Pi ―― 1. StrongSwan eingeführt
Stellen Sie eine Verbindung zur Raspberry PI-Konsole her und zeigen Sie lokale IP- und SD-Informationen an
Ich habe die Beleuchtungsstärke des Raumes mit Raspberry Pi, Arduino und einem optischen Sensor getwittert
Notieren Sie Temperatur und Luftfeuchtigkeit mit systemd auf Raspberry Pi
Maschinelles Lernen mit Raspberry Pi 4 und Coral USB Accelerator
Zeigen Sie eingebettete Bilder von MP3 und Flac mit Mutagen an
Einfaches IoT, um mit Raspeye und MESH zu beginnen
GPGPU mit Raspberry Pi
Einfacher VPN-Aufbau eines IPSec-Gateways mit CentOS 8 und openSUSE (Raspberry Pi) --1 Einführung von StrongSwan
Ermitteln Sie den Tragezustand der Maske mit OpenCV und Raspberry Pi
Nehmen Sie den Wert des SwitchBot-Thermo-Hygrometers mit Raspberry Pi
Messen Sie Temperatur und Luftfeuchtigkeit mit Raspberry Pi3 und visualisieren Sie mit Ambient
Umschalten der Bot-Thermo-Hygrometer-Werte mit Raspberry Pi
Ubuntu 20.04 auf Himbeer-Pi 4 mit OpenCV und mit Python verwenden
Steuern Sie das Ein- und Ausschalten des USB-Anschlusses des Raspberry Pi
DigitalSignage mit Raspberry Pi
Installation von Docker auf Raspberry Pi und L Chika
Einfacher VPN-Aufbau eines IPSec-Gateways mit Ubuntu 20.04 und Raspberry Pi - 2 StrongSwan VPN-Verbindungsbestätigung
Fehlerbehebung bei der Installation von OpenCV auf Raspberry Pi und der Erfassung
Zeigen Sie das Bild der USB-Kamera mit OpenCV von Python mit Raspeye an
Lassen Sie uns GPIO von Raspeye mit Python CGI betreiben
Erstellen Sie mit Raspberry Pi + DHT11 ganz einfach einen TweetBot, der Sie über Temperatur und Luftfeuchtigkeit informiert.
Steuern Sie die Anzeige des RGB LED Matirix Lightning Bulletin Boards mit Raspberry Pi 3B + frei
Einfache Einführung in Home Hack mit Raspberry Pi und discord.py
Erstellen Sie eine WEB-Überwachungskamera mit Raspberry Pi und OpenCV
Ich habe versucht, Movidius NCS mit Python von Raspberry Pi3 auszuführen
Erstellen Sie LCD-Spiele (16x2) mit Raspberry Pi und Python
Sehen Sie, wie schnell Sie mit NumPy / SciPy beschleunigen können
Ich habe versucht, Raspeye und conect + mit der Web-API zu verbinden
Mutter pflanzt mit Raspberry Pi
Bilderkennung von Müll mit Edge (Raspberry Pi) aus null Wissen mit AutoML Vsion und TPU
Messen Sie Temperatur, Luftfeuchtigkeit usw. mit SensorTag und senden Sie es über Raspberry Pi 3 an Ambient, um es Teil 2 grafisch darzustellen
Ich habe versucht, die Bewässerung des Pflanzgefäßes mit Raspberry Pi zu automatisieren
Weihnachtsklassiker (?) Einen Weihnachtsbaum mit Raspberry Pi und Philips Hue anzünden
Benachrichtigen Sie LINE über die Körpertemperatur vom BLE-Thermometer mit Raspeltorte Nr. 1
Benachrichtigen Sie LINE über die Körpertemperatur vom BLE-Thermometer mit Raspeltorte Nr. 2
Machen Sie ein Thermometer mit Raspberry Pi und machen Sie es im Browser Teil 4 sichtbar
Wiegeinstrument mit Himbeer-Pi und hx711 (GUI-Anzeige in Tkinter)
Protokollieren Sie die Omron-Umgebungssensorwerte regelmäßig mit Raspberry Pi
So fügen Sie OpenCV in Raspberry Pi ein und sammeln mit Python ganz einfach Bilder von Gesichtserkennungsergebnissen
Ich habe ein npm-Paket erstellt, um die ID der IC-Karte mit Raspberry Pi und PaSoRi zu erhalten
Lesen Sie die Daten des NFC-Lesegeräts, das mit Python an Raspberry Pi 3 angeschlossen ist, und senden Sie sie mit OSC an openFrameworks
[Raspberry Pi] Schrittmotorsteuerung mit Raspberry Pi
Verwenden Sie vl53l0x mit RaspberryPi (Python)
MQTT auf Raspberry Pi und Mac
Serielle Kommunikation mit Raspberry Pi + PySerial