CO2 Meter met MH-Z19

Door balk op zondag 9 april 2017 21:00 - Reacties (1)
Categorie: -, Views: 1.187

DEZE BLOG IS NOG NIET AF

maar er was wat vraag naar. dus ik heb em maar online gezet

In dit topic wordt veel gesproken over het uitlezen van CO2 sensoren en met name de MH-Z19 is populair. Op het grote wijde web kon ik echter niet heel duidelijk vinden hoe ik het nou aan de praat kan krijgen.

Wat ik heb:
- een Wemos D1 mini
- een MH-Z19b
- een computer (Mac)
- een Linux server met een MQTT service
Die laatste twee zijn optioneel

Je kunt ook een andere ESP module gebruiken, dan moet je de pin nummers even corrigeren in de code.

Stap 1 - Prepareer software

Installeer de Arduino IDE op je computer (1.8.2 op dit moment, ik kreeg de online versie niet aan de praat). Genoeg howtos te vinden. Als je beginneling bent is het verstandig om eerst met de Wemos te spelen die sketches als Blink te laden.

Stap 2 - Sluit de sensor aan

Sluit de sensor en de Wemos op elkaar aan als volgt:
MH-Z19 Tx→ Wemos pin D8
MH-Z19 Rx→ Wemos pin D7
MH-Z19 gnd→ Wemos gnd pin
MH-Z19 vcc→ Wemos 3.3V pin

Het moet er dan ongeveer zo uit zien:

Stap 3 - Laad de software

Ik ben begonnen met deze sketch, en heb er de LCD support uit gesloopt.

Laad dit in de Arduino software. In de Arduino IDE kun je een serial terminal openen en de bezigheden van je thing volgen:

Stap 4 (optioneel) - Een stapje verder

Ik wil graag met MQTT aan de slag. Daarom gebruik ik Homie. Download hier de dev branch, en plaats deze in de Arduino library directory.

Vervolgens kun je verder met het script van Houthakker. Download deze sketch en library.

Laad nu deze sketch. Ik had wat problemen met het aanpassen van de settings van Homie. Door deze instructies te volgen kun je vanuit de Arduino IDE op de Wemos laden. In de serial monitor kun je nu volgen waar er gebeurt.

Stap 5

Op mijn Linux server draait Mosquitto. De Wemos poept nu elke zoveel seconden via MQTT een gemeten CO2 waarde uit. Die waarde wordt door Home Assistant opgepikt. Uiteindelijke doel is om mechanische ventilatie er mee te sturen.

Script om P1 metingen in MySQL database naar DSMR-Reader API te sturen

Door balk op vrijdag 27 januari 2017 13:19 - Reacties (5)
Categorie: -, Views: 4.698

Ik heb een script geschreven om P1 meet data uit een MySQL database te trekken en naar een DSMR-reader database te sturen.

/edit: ik heb de code een beetje aangepast want de overgang van winter naar zomertijd liep niet lekker. Dus nu maar handmatig de overgang ingevuld. Voor een jaar data moet je het script misschien wel drie keer draaien, telkens met een andere set datums. Op de nacht van de overgang van zomer naar wintertijd of andersom knip ik van middernacht tot zeven uur 's ochtends er uit. Gewoon om er zeker van te zijn dat het goed gaat.


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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/python
import MySQLdb
import MySQLdb.cursors
import sys
from datetime import datetime
import time
import requests  # Tested with requests==2.9.1




db = MySQLdb.connect(host="localhost",    # your host, usually localhost
                     user="root",         # your username
                     passwd="xxx",  # your password
                     db="p1",cursorclass=MySQLdb.cursors.SSCursor)        # name of the data base

# you must create a Cursor object. It will let
#  you execute all the queries you need
cur = db.cursor()

nmin = 0
nmax = 5 # used for testing; I did not want to print 400,000 records every time :-)


# Select the latest meter readings from database
query = ("SELECT `p1_timestamp`, `p1_meterreading_in_1`, `p1_meterreading_in_2`, `p1_current_tariff`, `p1_current_power_in`, `p1_channel_1_timestamp`,`p1_channel_1_meterreading` FROM `p1_log` WHERE `p1_timestamp` BETWEEN %s AND %s ")


datum1 = datetime(2016,10,31,7)
datum2 = datetime(2017,2,1,0)


cur = db.cursor()
results = cur.execute(query, (datum1,datum2))

rows = cur.fetchone()
n = 0
while rows is not None:
    n = n+1

    if n >= nmin: #and n <= nmax:

            p1_timestamp = rows[0]
            p1_meterreading_in_1 = rows[1]
            p1_meterreading_in_2 = rows[2]
            p1_current_tariff = rows[3]
            p1_current_power_in = rows[4]
            p1_channel_1_timestamp = rows[5]
            p1_channel_1_meterreading = rows[6]
           
            # create timestamps in the right format
            eyear = p1_timestamp.strftime("%Y")[2:4]
            emonth = p1_timestamp.strftime("%m")
            eday = p1_timestamp.strftime("%d")
            ehour = p1_timestamp.strftime("%H")
            emin = p1_timestamp.strftime("%M")
            esec = p1_timestamp.strftime("%S")
            gyear = p1_channel_1_timestamp.strftime("%Y")[2:4]
            gmonth = p1_channel_1_timestamp.strftime("%m")
            gday = p1_channel_1_timestamp.strftime("%d")
            ghour = p1_channel_1_timestamp.strftime("%H")
            gmin = p1_channel_1_timestamp.strftime("%M")
            gsec = p1_channel_1_timestamp.strftime("%S")
            
           # create meter readings in the right format
            p1_meterreading_in_1 = "{:.3f}".format(p1_meterreading_in_1).rjust(9, '0')
            p1_meterreading_in_2 = "{:.3f}".format(p1_meterreading_in_2).rjust(9, '0')
            p1_current_power_in = "{:.3f}".format(p1_current_power_in).rjust(6, '0')
            p1_current_tariff =str(p1_current_tariff)
            p1_channel_1_meterreading = "{:.3f}".format(p1_channel_1_meterreading).rjust(9, '0')
            gtime = gyear+gmonth+gday+ghour+gmin+esec

            
           # create the telegram (DSMR 2.2!)
            telegram_string = ''.join([
                "/XMX5XMXABCE000043811\r\n",
                "\r\n",
                "0-0:1.0.0("+etime+")\r\n",
                "0-0:96.1.1(xxx)\r\n",
                "1-0:1.8.1("+p1_meterreading_in_1+"*kWh)\r\n",
                "1-0:1.8.2("+p1_meterreading_in_2+"*kWh)\r\n",
                "1-0:2.8.1(00000.000*kWh)\r\n",
                "1-0:2.8.2(00000.000*kWh)\r\n",
                "0-0:96.14.0(000"+p1_current_tariff+")\r\n",
                "1-0:1.7.0("+p1_current_power_in+"*kW)\r\n",
                "1-0:2.7.0(0000.00*kW)\r\n",
                "0-0:96.13.1()\r\n",
                "0-0:96.13.0()\r\n",
                "0-1:96.1.0(xxx)\r\n",
                "0-1:24.1.0(03)\r\n",
                "0-1:24.3.0("+gtime+")(00)(60)(1)(0-1:24.2.0)(m3)\r\n",
                "("+p1_channel_1_meterreading+")\r\n",
                "!000\r\n",



            ])

            #print telegram_string

                #Register telegram by simply sending it to the application with a POST request.
                response = requests.post(
                    'http://192.168.0.8/api/v1/datalogger/dsmrreading',
                    headers={'X-AUTHKEY': 'xxx'},
                    data={'telegram': telegram_string},

                # You will receive a status 200 when successful.
                if response.status_code != 200:
                    # Or you will find the error (hint) in the reponse body on failure.
                    print('Error: {}'.format(response.text))

                
    #            print "end of telegram: ", n


    rows = cur.fetchone()
    #rows = cur.fetchmany(size=100)
cur.close()
db.close()

Thermodynamisch model van je huis

Door balk op woensdag 18 januari 2017 02:29 - Reageren is niet meer mogelijk
Categorie: -, Views: 295

Ik wil in deze post een theoretisch thermodynamisch model beschrijven van een huis. Wellicht kan iemand dit gebruiken om z'n eigen thermostaat te tunen. Let wel: ik heb dit niet zelf geļmplementeerd!

Warmtebalans

Over elk object kun je een wamtebalans opstellen, dus ook over een huis:

code:
1
Qin - Quit = accumulatie , deltaQ, toename van wamteinhoud (1)


Waarbij Q = warmtestroom [Watt]
Wat? Alles wat er in gaat, en er niet uit gaat, hoopt er in op. Als je huis 15°C is, heb je veel energie nodig om je huis en alles er in op te warmen. Als je huis op temperatuur is hoeft de cv ketel maar een beetje te stoken. Dat komt omdat deltaQ dan 0 is. Er is geen toename meer van de warmteinhoud van je huis. Alle warmte die je in je huis stopt verlies je ook weer aan de omgeving.

Warmteverlies Quit

Warmteverlies is een functie van drie factoren:

code:
1
Quit = U * A * deltaT (2)


Waarbij
  • U = warmteoverdrachtscoefficient [Joule/m2/°C], afhankelijk van hoe goed je huis is geļsoleerd en van de windsnelheid buiten, en onbekend.
  • A = oppervlak van je huis [m2], ligt vast (tenzij je een verbouwing uitvoert of een extra kamer gaat verwarmen)
  • deltaT = temperatuur verschil tussen binnen en buiten [°C], kun je meten
  • Quit = warmteverlies [W]
Hoe kunnen we Quit en U bepalen?

Warmtetoevoer [Qin]

Wanneer een huis in steady-state is (constante temperatuur), zal Quit gelijk zijn aan Qin volgens (1). En Qin kun je berekenen aan de hand van het gasverbruik! Tijdens een periode van constante temperatuur dien je het verbruik te meten, en de buitentemperatuur. De energetische onderwaarde (LHV) van Slochters aardgas is 31,65 MJ/m3. Dus als je in twee uur 0,1 m3 hebt verbruikt komt dat neer op een gasverbruik van 440 Watt. Bij een rendement van de ketel van 107% (ja dat kan!) heb je dus een warmtetoevoer Qin van 470 Watt. En dat is ook je Quit. Doe hetzelfde bij een andere kamertemperatuur en bij voorkeur met behulp van een stookseizoen aan data. Zorg dat je geen douche of kookactiviteiten hebt tijdens de meting.

Warmteoverdracht U*A

Bereken nu voor elk datapunt, met behulp van de binnen- en buitentemperatuur. Daarmee kun je U*A berekenen. Je zult zien dat dit geen constante is. Als het waait zal je meer warmte verliezen. Dus eigenlijk wil je voor elk datapunt ook de windsnelheid wx hebben. Die kun je met de wunderground API binnentrekken of zelf meten.
code:
1
Q= U*A*c*wx * deltaT

zou dan moeten kloppen. Hier is c een empirische factor.

Als je je warmteoverdracht kunt voorspellen weet je dus ook hoeveel energie je verliest op een willekeurige dag.

Accumulatie

Hoeveel warmte heb je nodig om van de ene stabiele temperatuur naar de andere te gaan? Je moet een deel van de lucht in het huis opwarmen. Bijvoorbeeld de woonkamer en keuken naar 20°C en de overige vertrekken naar gemiddeld 18°C. De warmte capaciteit Cp van droge lucht is 1,006 kJ/kg/°C, de dichtheid van droge lucht is in dit temperatuur gebied ongeveer 1,21 kg/m3. Dus om 100 m3 droge lucht 5°C op te warmen heb je 608,6 kJoule nodig. Als je dit in een half uur doet is dat 338 Watt. Maar lucht is niet droog. Lucht van 20°C en 60% vochtigheid bevat 0,010 kg waterdamp per kubieke meter. Dat is 1 kg in onze ruimte van 100 m3 en kost 9300 kJ om 5°C op te warmen. Als die hoeveelheid energie in een half uur aanvoert is dat 5 Watt.

Zo kun je ook verder gaan voor muren, ramen, waterbedden en andere grote objecten.

Toepassing

Wat kun je hier nu mee?
  1. Een schatting maken van de tijd die een ketel nodig heeft om bij een vast vermogen een huis op te warmen. Of
  2. Een schatting maken van het benodigde vermogen van de ketel om in een bepaalde tijd het huis op te warmen.
En dat natuurlijk als functie van de buitentemperatuur, binnentemperatuur, luchtvochtigheid en windsnelheid.


code:
1
Afgegeven vermogen Qin [W] = warmteverlies Quit [W] + opwarmwarmte Hacc [J] / opwarmtijd t [s]



Het hangt af van je ketel of je een vermogen kunt regelen zodat je met een vaste opwarmtijd kunt werken, of dat je ketel volle bak gaat bij warmtevraag (aan/uit regeling bijvoorbeeld), of volgens een voorspelbare curve.

Ik hoop dat dit wat inzicht geeft in huis tuin en keuken thermodynamica en dat iemand zijn of haar voordeel er mee kan doen. Vragen? Opmerkingen? Onduidelijkheden?

NAS aan en uit wanneer MacBook aan en uit is

Door balk op zaterdag 7 januari 2017 13:50 - Reacties (10)
Categorie: -, Views: 4.686

Ik heb een Intel D510MO met twee HDD's draaiend op Debian. Dit ding is vooral een backup server voor de MacBook die hier in huis rondslingert. Het verbruik is ongeveer 20W en dat zijn natuurlijk weggegooide wattjes wanneer we slapen of werken.

Vanaf de Mac stuur ik elk uur een incremental backup met behulp van CCC naar de NAS. Het ene uur grote bestanden naar een share. Het andere uur kleine bestanden naar een image op een share. Kleine files? zaken als de Aperture library van 90 GB en enkele 100.000en files. Grote files? zaken als de raw foto bestanden.

Ik had eens ergens een script vandaan gehaald dat zorgde dat de NAS automatisch aan gaat als een bepaalde computer aan gaat, aan blijft als deze aan is, en weer uit gaat als die computer uit gaat. Bron is weg, dus ik herhaal hier schaamteloos de scriptjes.

1. Wake on Lan

In het BIOS van mijn NAS moest ik Wake On Lan activeren.

2. Wek de NAS wanneer MacBook ontwaakt

Met behulp van Sleepwatcher laat ik een script draaien wanneer de laptop wakker wordt. Dit staat in het bestand ~/.wakeup.

code:
1
2
3
4
5
6
7
8
9
#!/bin/bash


/usr/bin/perl /path/to/wol.pl --mac xx:xx:xx:xx:xx:xx

/bin/sleep 120

# vul IP van server in
/usr/bin/ssh 192.x.x.x '/bin/echo $(/bin/date +%s)  > /path/to/folder/wake/upmark'



Dit [url=]http://www.cpan.org/authors/id/S/SR/SRAMKI/]Wake on lan script[/] heb je nodig om met perl de NAS te WoL'en. Dit script heeft enkele dependencies. Installeer die ook.

Op de NAS moet je ook een (door de user beschrijfbare) directory aanmaken. Die van mij staat in ~/wake. Maak daarin een bestand upmark:
touch ~/wake/upmark

Bovenstaand script zal de NAS wakker schudden en twee minuten later de tijd schrijven naar ~/wake/upmark.

3. Hou de NAS wakker (kant van de Mac)

Ik heb op de Mac het volgende script: ticker.sh

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

ip="192.168.0.NAS" # IP of NAS

if ! ping -c 1 -W 5 "$ip" &>/dev/null ; then

echo "$ip is down, they're all going to laugh at you!"
/usr/bin/perl /path/to/wol.pl --mac xx:xx:xx:xx:xx:xx
/bin/sleep 120
else
echo "$ip is up"
fi

/usr/bin/ssh 192.168.0.NAS '/bin/echo $(/bin/date +%s)  > /path/to/wake/upmark'
#$(/bin/date +%s)


Met behulp van Launcontrol roep ik elk kwartier dit script aan:
ticker.sh

4. Hou de NAS wakker (kant van de NAS)

Op de NAS, installeer pm-utils en test de correcte werking. Het laat je NAS hibernaten, dit schrijft de inhoud van je RAM naar schijf en de NAS gaat helemaal uit.

Creėer het bestand /path/to/wake/keepawake.sh

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
#!/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

file="/path/to/wake/upmark"
LOGPATH="/path/to/wake/log_wake.log"

timestamp() {
  /bin/date
}

mactime=$(/bin/cat "$file")
now=$(/bin/date +%s)

#deltat=`/usr/bin/expr $(/bin/date +%s)-$mactime`
deltat=$(($now  - $mactime))
limit=1200

/bin/echo $deltat
/bin/echo $limit

if (( deltat > limit ));
then
        # hibernate
        /bin/echo "$(timestamp): system hibernated" >> $LOGPATH
#       /bin/systemctl hibernate
        /usr/bin/sudo /usr/sbin/pm-hibernate
        exit
else
        # do nothing
        
        /bin/echo "$(timestamp): system kept awake, delta is $deltat" >> $LOGPATH
        exit
fi


Als user:
crontab -e


code:
1
5,20,35,50 * * * * /path/to/wake/keepawake.sh


Dit roept elk uur, 5 minuten nadat er een ticker binnen is gekomen van de Mac, het script op dat de huidige tijd met de ticker tijd vergelijkt. Is er geen ticker binnengekomen? Dan is de Mac offline en kan de NAS gaan slapen.

Opentherm Gateway via WiFi naar Domoticz

Door balk op vrijdag 6 mei 2016 10:31 - Reacties (13)
Categorie: -, Views: 12.747

Ik was al een tijdje aan het denken over een slimme thermostaat of in ieder geval een manier om van buitenaf mijn verwarming te kunnen bedienen. Ik was wel geļnteresseerd in de Thermosmart maar de prijs stond mij tegen. Toen kwam ik een post tegen over de Opentherm Gateway. Dit heeft meerdere voordelen:
  • Een hobbyproject, lekker solderen! Nooit gedaan, wel leuk
  • Goedkoop, kosten waren ¤30,- ongeveer, plus ¤10,- voor de ESP
  • Oude vertrouwde thermostaat, beter voor de acceptatie door medebewoners
Mijn situatie:
  • Remeha Calenta boven in huis
  • iSense versie 23
  • Raspberry Pi in de meterkast
  • Domoticz op Raspbian
  • P1 poort wordt uitgelezen
OTGW in elkaar gesoldeerd
Na veel lezen door dit topic en bovengenoemde website besloot ik de componenten te bestellen. Ik besloot om een iets zwaardere voeding te bestellen zodat ik een ESP8266 er op aan kon sluiten. Kortom, wachten op de levering, en solderen maar!
Communicatie (hardware)
Op de route tussen thermostaat en CV ketel kom ik nergens een ethernetkabel tegen dus ik moest iets anders bedenken om de OTGW te laten praten met de Rapberry Pi. De OTGW praat serieel (USB of RS232) en gelukkig bestaan er ESP8266 chips die serieel naar WiFi praten. Ik heb deze ESP12 besteld. Dit is een ESP12 op een bordje met wat extra's, zoals een reset knop, breakout pins en een 5V --> 3,3V conversie.
ESP12
Deze module heb ik als volgt aangesloten op de OTGW. Ik moest ook twee bruggetjes maken om de signalen van de PIC naar de connector te sturen.
http://static.tweakers.net/ext/f/rQwOnDqYWKo7LNyoznOSW48s/medium.jpg
OTGW met ESP module
Ook heb ik een el-cheapo USB 2 serial kabel gekocht.
Communicatie (software)
De ESP is een chip die serieel omzet in WiFi, en weer terug. Er bestaan verschillende firmware projecten die je kunnen helpen. Ik koos voor ESP-Link want die zou moeten werken. Met behulp van ESP-Tool en de el-cheapo serieel-USB kabel heb ik deze firmware op de ESP geladen. Daarna is de ESP een access point waarop je in kan loggen, een lokaal wifi netwerk kiezen en dan is tie verbonden.

Vervolgens de ESP aangesloten op de OTGW en dan krijg je iets als dit:
ESP Console
Ik zie dus alle codes die de OTGW uitspuugt! :)
Dit is gewoon good old Telnet en ook te benaderen op poort 23. In Domoticz was het daarna niet moeilijker dan dit invullen:
http://static.tweakers.net/ext/f/0o8eze3GPwK9ODI63TjdE2zE/medium.png
Het werkt! Althans, bijna alles. Ik kan de gegevens uitlezen maar de temperatuur nog niet aanpassen.

Op mijn Remeha iSense thermostaat moest ik nog een instelling veranderen,

code:
1
Instellingen --> Installateur --> Externe Ingang --> Toestaan



En nu kan ik via Domoticz de gewenste temperatuur instellen!