CV-ketel temperaturen loggen met een Arduino, MySQL en Highcharts

Door ThinkPad op zaterdag 01 november 2014 09:49 - Reacties (42)
Categorie: Electronica, Views: 3.430

Om mijn gasverbruik zo laag mogelijk te houden ben ik druk bezig met het optimaal afstellen van mijn CV-ketel. Essentieel daarbij is dat je weet wat de ketel doet zodat je daarop kunt inspelen. Ik log hier voor de aanvoer- en retourtemperatuur van de ketel.

Ik zocht hiervoor een goedkope oplossing die weinig gebruiker-input vereist. Dit heb ik gevonden in de Arduino.

Uiteindelijk levert mijn setup dit soort plaatjes op:
http://tweakers.net/ext/f/UnrvGVR1L7Xd74RFEagw6373/full.png
De deltaT (oranje/gele lijn) is het resultaat van de aanvoer minus de retour.

De deltaT wil je het liefste rond de 15-20 graden hebben. Let op, het is geen echte temperatuur, maar een verschil tussen twee temperaturen (vandaar ook 'delta'). Het verschil tussen het warme water wat je ketel verlaat en het koelere water wat terugkomt van je radiatoren wil je dus 15-20 graden hebben. Verder wil je de retourtemperatuur liefst onder de 50 graden hebben, dan kan je ketel condenseren en in z'n HR-gebied werken. Dit is nog maar een klein stukje van de basis van CV-tuning. Meer lees je in het topic.

Omdat een aantal mensen mij hebben gevraagd hoe ik dat doe, heb ik besloten om er een blogpost aan te wijden.

Inhoudsopgave
Benodigde hardware
Arduino sketch
PHP-scripts
Database structuur
Nawoord

Benodigde hardware
Om de temperaturen te kunnen aflezen heb je wat hardware nodig:
  • Een Arduino + Ethernetshield. Ik gebruik een Arduino Nano van eBay, met een ENC28J60 Ethernet module.
  • DS18B20 temperatuursensoren. Deze kun je ook op eBay scoren. Je hebt ze in een waterdichte behuizing, of alleen de losse sensor. Voor gebruik binnenshuis op een leiding die droog blijft is de losse sensor in principe prima.
  • Een weerstand voor de 1-Wire verbinding naar de sensoren. Hier wordt meestal een 4K7 weerstand voor gebruikt. Als de afstand tussen Arduino en sensoren erg groot is dan is een lagere weerstandswaarde aan te raden
  • Een apparaat waar je een webserver, PHP, MySQL (of andere database) op hebt draaien. Ik gebruik hiervoor mijn Synology DS114 NAS
  • En verder nog wat basisspul zoals wat kabels, voeding voor de Arduino etc.
Arduino sketch
De basis voor de Arduino sketch is gebaseerd op deze sketch: https://www.jfkreuter.com/?p=9

Mijn sketch is als volgt:

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
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <UIPEthernet.h>           //library for ethernet functions
#include <DallasTemperature.h>  //library for temperature sensors
#include <OneWire.h>            //library for the onewire bus

#define ONE_WIRE_BUS     7        //the onewire bus is connected to pin 7 on arduino

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xBE };           
uint8_t ipaddr[4] = {
  192, 168, 4, 17};                    // IP-adress of arduino
uint8_t gwaddr[4] = {
  192, 168, 4, 1};                     // IP-adress of gateway ( for later DNS implementation)
uint8_t subnet[4] = {
  255, 255, 255, 0};                   // subnetmask           ( for later DNS implementation)
uint8_t serverip[4] = {
  192, 168, 4, 4};                   // IP-adress of server arduino sends data to
uint8_t serverport = 80;                                  // the port the arduino talks to

EthernetClient client;         // make a new instance from type "Client" named "client", giving it
// serverip and serverport

OneWire oneWire(ONE_WIRE_BUS);               // setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire);         // Pass our oneWire reference to Dallas Temperature
// variable to store the number of sensors
bool connected = false;                                   // yes-no variable (boolean) to store if the arduino is connected to the server
int i = 0;                                                // variable to count the sendings to the server
long previousMillis = 0;        // will store last time LED was updated
long interval = 60000;           // interval at which to send data (minutes)

//---------------------------------------------------------------------------------------------


void setup()                                  // setup-function (runs only at the startup of the arduino)
{
  Serial.begin(9600);                               // start the serial port
  Serial.println("I2C-to-Ethernet Bridge.");
  Serial.println("Initializing Ethernet.");

  Ethernet.begin(mac, ipaddr);                  // start up ethernet
  sensors.begin();                                  // start up the library
  int numSensors = sensors.getDeviceCount();        // store the number of sensors to the variable numSensors,
  float temparray[numSensors];            // array with "numSensors" storage places for the temperature of each sensor
  // "sensors.getDeviceCount" is a function in the library

  Serial.println("Enumerating and scanning for I2C sensors.");

  if(numSensors > 0)                      // if there is at least one sensor:
  {
    Serial.print("Enumerated ");            //print the number of sensors to serial port
    Serial.print(numSensors);
    Serial.println( " sensors.");

  }
  else                                      //if there is no sensor:
  {
    Serial.println("No sensors enumerated."); // tell the serial port
  }

}

//----------------------------------------------------------------------------------------------------------


void loop()                     // loop function (runs over and over again)
{
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > (interval) ) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;  


    if (!client.connect(serverip, 80)) {

      Serial.println("-> Connection failure detected: Resetting ENC!");  // only use serial when debugging

      Enc28J60.init(mac);
    } 
    else {
      client.stop();
    } 

    if (client.connect(serverip, 80)) 
    {
      Serial.println("-> Connected");  // only use serial when debugging 
      DoeJeDing();
    }
    else 
    {
      // you didn't get a connection to the server:
      Serial.println("--> connection failed !!");  // only use serial when debugging      
    }


  } //End of loop
  else
  {
    Ethernet.maintain();
  }
}
//----------------------------------------------------------------------------------------------------------


void DoeJeDing(){ 
  int numSensors = sensors.getDeviceCount();
  float temparray[numSensors];          // array with "numSensors" storage places for the temperature of each sensor
  // "sensors.getDeviceCount" is a function in the dallas temperature library

  // if connected, set variable connected to "true" and
  connected = true;
  sensors.requestTemperatures();      // send the request for temperature to sensors (all sensors)
  delay(100);
  for(i=0; i<numSensors; i++)         // as long as "i" ( chosen number, starts at 0) is smaller than
    //numSensors" (number of sensors) do the "for" cycle
  {
    float temp = sensors.getTempCByIndex(i); // take temperature reading from sensor "i" and store it to the variable "temp"
    temparray[i] = temp;                   // store the temperature from sensor i to storage place i in the array

  }

  client.print("GET /www/artemp2/add_data.php?");
  Serial.print("GET /www/artemp2/add_data.php?");
  for (i=0; i<numSensors; i++)
  {
    client.print("t");
    Serial.print("t");
    client.print(i);
    Serial.print(i);
    client.print("=");
    Serial.print("=");
    client.print(temparray[i]);
    Serial.print(temparray[i]);
    if (i < numSensors-1)
    {
      client.print("&&");
      Serial.print("&&");
    }
    else
    {
    }
  }

  client.println(" HTTP/1.1");
  client.println("Host: 192.168.4.4");
  client.println("User-Agent: Arduino");
  client.println("Accept: text/html");
  client.println("Connection: close");
  client.println();
  client.println();
  client.stop(); 
  connected = false;                                          //  "connected" to false
}



Het IP-adres, DNS, gateway e.d. wil je waarschijnlijk aanpassen. Ook het IP-adres van je database e.d. wil je aanpassen. Mijn NAS heeft het IP-adres '192.168.4.4', dat moet je dus even aanpassen in de sketch.

PHP-scripts
add_data.php

PHP:
1
2
3
4
5
6
7
8
9
<?php
    // Connect to MySQL
    include("dbconnect.php");

$query = "INSERT INTO cvlogger(temp1, temp2) VALUES ('" . $_GET['t0'] . "', '" . $_GET['t1'] . "')";
$result = mysql_query($query) or die("Error in query: " . mysql_error());

mysql_close($link);
?>



dbconnect.php

PHP:
1
2
3
4
5
6
7
8
<?php
$MyUsername = "templogger";  // enter your username for mysql
$MyPassword = "templogger";  // enter your password for mysql
$MyHostname = "localhost";      // this is usually "localhost" unless your database resides on a different server

$dbh = mysql_pconnect($MyHostname , $MyUsername, $MyPassword);
$selected = mysql_select_db("artemp",$dbh);
?>



graph.php

PHP:
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
 <!DOCTYPE HTML>
 <html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta http-equiv="refresh" content="300"> <!-- reload page every 5 minutes !-->
  <title>CV Temperaturen</title>
  <?php
  $link = mysql_connect("localhost", "templogger", "templogger") or die("Error verbinden met DB: " . mysql_error());

  $db = mysql_select_db("artemp", $link);
  if (!$db) {
    mysql_close($link);
    die("Error selecteren DB: " . mysql_error());
  }

// Alle waardes ophalen voor AANVOER. Query haalt nu alle resultaten op. Met 'DATE_SUB' in query kunnen waarden beperkt worden.
  $result = mysql_query("SELECT unix_timestamp (date) AS ts, temp1, temp2, ROUND((temp1-temp2),1) as delta FROM cvlogger WHERE date >= DATE_SUB(CURDATE(), INTERVAL 3 WEEK)"); 
  if (!$result) {
    mysql_close($link);
    die("Error met query: " . mysql_error());
  }
  while ($row = mysql_fetch_array($result)) {
  $datetime = (($row['ts']) * 1000) + 7200000; // convert from Unix timestamp to JavaScript time
  $value1   = $row['temp1'];
  $value2   = $row['temp2'];
  $value3   = $row['delta'];

  $data1[] = "[$datetime, $value1]";
  $data2[] = "[$datetime, $value2]";
  $data3[] = "[$datetime, $value3]";
  
}

$data_1 = join($data1, ',');
$data_2 = join($data2, ',');
$data_3 = join($data3, ',');

?>

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
$(function () {
  $('#container').highcharts({
    chart: {
      zoomType: 'x'
    },
    title: {
      text: 'CV-systeem temperatuurlogger'
    },
    subtitle: {
      text: document.ontouchstart === undefined ?
      'Klik en sleep in de grafiek om in te zoomen' :
                      'Maak een knijpbeweging om in te zoomen' //only shown on touch (tablet) devices
                    },
                    xAxis: {
                      type: 'datetime',
                  minRange: 5 * 60 * 1000 // Smallest zoominterval (in miliseconds). 5 min. This is matched to the Arduino temperature interval. If your interval is 1 min, change first number to 1
                },
                yAxis: {
                  min: 0,    // Schaal instellen, uncomment de min en max voor automatisch    
                  //max: 80,
                  title: {
                    text: 'Temperatuur (įC)'
                  }
                },
                tooltip: {
                  valueSuffix: 'įC'
                },
                legend: {
                  layout: 'vertical',
                  align: 'right',
                  verticalAlign: 'middle',
                  borderWidth: 0
                },
                plotOptions: {
                  area: {
                    fillColor: {
                      linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1},
                      stops: [
                      [0, Highcharts.getOptions().colors[0]],
                      [1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
                      ]
                    },
                    marker: {
                      radius: 2
                    },
                    lineWidth: 1,
                    states: {
                      hover: {
                        lineWidth: 1
                      }
                    },
                    threshold: null
                  }
                },
                series: [{
                  name: 'Aanvoer',
                  pointInterval: 24 * 3600 * 1000,
                  color: '#E62E00', 
                  marker: {
                    enabled: false
                  },
                  data: [<?php
                  echo ($data_1);
                  ?>]
                }, 
                {
                  name: 'Retour',
                  color: '#003380', 
                  marker: {
                    enabled: false
                  },
                  data: [<?php
                  echo ($data_2);
                  ?>]
                },
                {
                  name: 'DeltaT',
                  color: '#FF9900', 
                  marker: {
                    enabled: false
                  },
                  data: [<?php
                  echo ($data_3);
                  ?>]
                }

                ]

              });
});
 <?


// Nieuwste enkele waarde voor AANVOER ophalen
 $result = mysql_query("SELECT id as LATEST, temp1, temp2 FROM cvlogger ORDER BY id DESC LIMIT 1");
 if (!$result) {
  mysql_close($link);
  die("Error met query: " . mysql_error());
}
while ($row = mysql_fetch_array($result)) {
  $ketel_aanvoer = $row['temp1'];
  $ketel_retour = $row['temp2'];
 
  
}


?>    
</script>
<style type="text/css">
body {
  background-color: #FFFFFF;
  font-family: 'Helvetica, Arial, sans-serif';
  color: black;
  font-size: 20px;
  text-align: center;
}
p { 
  font-family: 'helvetica, arial, sans-serif';
}
</style>
</head>
<body>
  <script src="js/highcharts.js"></script>
  <script src="js/modules/exporting.js"></script>

  <div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
  <center>
  <table border="1" style="border-collapse:collapse;border:1px solid;color:#000000;width:40%" cellpadding="3" cellspacing="3">
  <tr>
    <th bgcolor="#909090"><b>Sensor</b></th>
    <th bgcolor="#909090"><b>In</b></th>
    <th bgcolor="#909090"><b>Uit</b></th>
    <th bgcolor="#909090"><b>DeltaT</b></th>
  </tr>
  <tr>
    <td>Ketel </td>
    <td><?php echo (number_format($ketel_aanvoer, 1)); ?></td>
    <td><?php echo (number_format($ketel_retour, 1)); ?></td>
    <td><?php echo (number_format($ketel_aanvoer-$ketel_retour, 1)); ?></td>
  </tr>
  <tr>

</table>
</center>
  <p style="font-family:helvetica, tahoma, sans-serif;">
    <br />
    <h2><a href='daggrafiek.php'>Temperaturen van alleen vandaag</></h2>
      <br>
    <span style="color: #000000";><font size="2">Laatste meting opgehaald om:</span> <br /> <?php echo $latest_measure; ?></font><br>
  </p>

<center>

</center>

  <?php
  mysql_close($link);
  ?>

</body>
</html>


Voor de 'graph.php' heb je Highcharts nodig. Deze kun je hier downloaden.
Je gooit alles in ťťn map, wat er dan zo uit ziet:
De Highcharts dingen moeten in de map 'js'

Database structuur
Ik heb een MySQL database met de naam 'artemp', hierin heb ik een tabel 'cvlogger'. Deze tabel ziet er als volgt uit:

code:
1
2
3
4
5
6
7
8
+-------+-------------+------+-----+-------------------+----------------+
| Field | Type        | Null | Key | Default           | Extra          |
+-------+-------------+------+-----+-------------------+----------------+
| id    | int(11)     | NO   | PRI | NULL              | auto_increment |
| date  | timestamp   | NO   |     | CURRENT_TIMESTAMP |                |
| temp1 | varchar(11) | NO   |     | NULL              |                |
| temp2 | varchar(11) | NO   |     | NULL              |                |
+-------+-------------+------+-----+-------------------+----------------+



Nawoord
Resultaat zou uiteindelijk moeten zijn dat de temperaturen elke minuut worden weggeschreven in de database.

Ik voorzie de Arduino van spanning door spanning van de CV-pomp af te tappen (mijn ketel heeft twee pompen, eentje voor tapwater, en eentje voor CV-pomp). Op die manier springt de Arduino aan als de ketel het huis moet verwarmen. Anders zou hij 24/7 blijven meten en heel veel onnodige waardes in m'n database gooien.
Aangezien je voor het aftappen van die spanning je ketel open moet maken en je daarbij kans hebt op kortsluiting en daarmee slopen van je CV-ketel laat ik dat aan je zelf over om op eigen risico uit te zoeken en te realiseren.

De sketch en alle code die hier staat beschreven kan vast beter, maar ik ben van beroep geen programmeur, dus dit is allemaal wat bij elkaar gestopte stukken code. Voor mij levert het bruikbare grafieken op, en dat is waar het mij om gaat. Voel je vrij om de code te herschrijven naar eigen wens.

Uitlezen van de slimme meter P1-poort met een Arduino en waarden opslaan in MySQL-database

Door ThinkPad op dinsdag 19 augustus 2014 12:53 - Reacties (12)
Categorie: Electronica, Views: 8.313

Zo, het is alweer een tijdje geleden dat ik een blogpost heb geschreven (vorige was in januari 2014 over het nut van een pompschakelaar voor je vloerverwarming. Energiebesparing much?)

Vandaag eentje over het uitlezen van een slimme energiemeter met een Arduino en het opslaan van de informatie in een MySQL-database.

Inhoudsopgave
Inleiding
Monitoren energieverbruik
Slimme meter
De oplossing
Arduino, PHP, MySQL-code
Hardware
Grafisch maken van de data
Gasverbruik uploaden naar Mindergas.nl
Todo list
Het eindresultaat

Inleiding
Ik ben de laatste tijd bezig geweest met het omlaag brengen van m'n energieverbruik. Toen ik samen met m'n vriendin in deze woning trok (nov. '13) heb ik gelijk overal LED-lampen ingedraaid en gezorgd dat de apparaten die veel energie gebruiken zoveel mogelijk A+ of beter zijn. Elektraverbruik is daarmee al best goed, we zitten op ~140 kWh per maand met z'n tweeŽn.

Gasverbruik heb ik ook zoveel mogelijk terug proberen te dringen, door gelijk toen ik hier kwam wonen de CV-ketel te tunen en de radiatoren waterzijdig inregelen.

Monitoren energieverbruik
Volgende stap was het monitoren van m'n energieverbruik, dit ging echter wat lastig. M'n woning (huurwoning uit 1988) beschikte nog over een ouderwetse draaischijf-kWh meter (1987) Deze viel nog wel uit te lezen door met een TCRT5000 IR-sensor te kijken wanneer de zwarte streep voorbij kwam. De gasmeter was echter zo oud (1987) dat deze 0,0 uitleesmogelijkheden had. Geen reflecterend vakje op het telwerk, geen magnetisch veld voor een reedcontact, NIKS.

Slimme meter
Daarom heb ik besloten om een slimme meter aan te vragen via prioriteitsplaatsing. Je betaalt dan §72,60 en dan wordt er een slimme meter bij je geplaatst.

Over de voor- en nadelen, privacy etc. van de slimme meter ga ik het hier niet hebben. Dat moet ieder voor zichzelf beslissen, en is genoeg informatie over te vinden op internet. Als je nu nog een oude draaischijfmeter hebt hangen en je hebt/wilt zonnepanelen dan kun je beter bij je huidige meter blijven omdat het salderen veel gunstiger is. Ik heb/wil geen zonnepanelen (want: huurflatje), en voor mij biedt de slimme meter een hoop mogelijkheden voor het nauwkeurig bijhouden van m'n energieverbruik.

Voordeel van de slimme meter is dat je je energieverbruik veel beter inzichtelijk kunt krijgen. De meter heeft namelijk een P1-poort waarover de meetgegevens via een seriŽle verbinding worden uitgestuurd. Deze poort kun je dan uitlezen met een commercieel product, of zelf iets bouwen. Mijn voorkeur ging uit naar het laatste. Ik ben niet vies van een beetje hobbyen, en een commerciŽle oplossing is vaak nogal aan de prijs (~§100).

Je kunt ook je slimme meter gratis op afstand laten uitlezen, bijvoorbeeld via Enelogic. Nadeel is echter dat je geen live verbruik hebt en je kunt pas een dag later het verbruik van afgelopen dag zien. Ook kun je niet zelf bij de data, een beetje lekker klooien met query's (hoe vaak zit m'n verbruik boven de XX watt, hoeveel kWh gebruik ik gemiddeld per dag?) is er dus niet bij.

De oplossing
Er zijn al een hoop hobbyisten die mij zijn voorgegaan hiermee. Vaak wordt er dan naar een Raspberry Pi gegrepen. Leuk, maar in mijn ogen redelijk overkill (een Raspberry draait een Linux omgeving, terwijl ik alleen wat waarden uit een serieel ontvangen bericht wil halen, wat ook prima met een Arduino kan). Ik wilde daarom graag iets bouwen met Arduino gezien de leuke prijs hiervan. Ik heb al een NAS (Synology DS114) draaien waar ook al een webserver + MySQL-database op draait. Een plek om de ontvangen data op te slaan was er dus al.

Voor een Arduino Duemilanove en een W5100 Ethernet shield was ik op eBay samen zo'n 18 euro kwijt. De helft van wat een Raspberry Pi kost :) Dan nog wat klein spul (RJ11 connector, stukje snoer, transistor) wat <3 euro is.

Arduino code
Op basis van bestaande code heb ik een sketch gemaakt die de P1-poort uitleest en de waarden in een MySQL-database op m'n NAS opslaat.

De basis was deze code. Die heb ik aangepast om tot onderstaande code te komen (met dank aan mede-tweakers die mij in m'n topic geholpen hebben!)


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
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/* Arduino 'slimme meter' P1-port reader.
 
 This sketch reads data from a Dutch smart meter that is equipped with a P1-port.
 Connect 'RTS' from meter to Arduino pin 5
 Connect 'GND' from meter to Arduino GND
 Connect 'RxD' from meter to Arduino pin 0 (RX)
 
 Baudrate 115200, 8N1.
 BS170 transistor & 10k resistor is needed to make data readable if meter spits out inverted data
 
 A .php file is requested (with consumption numbers in the GET request) every minute (interval set at line #52)
 created by 'ThinkPad' @ Tweakers.net, september 2014
 
 http://gathering.tweakers.net/forum/list_messages/1601301
 */

#include <AltSoftSerial.h>
#include <SPI.h>
#include <Ethernet.h>
// AltSoftSerial always uses these pins:
//
// Board          Transmit  Receive   PWM Unusable
// -----          --------  -------   ------------
// Teensy 2.0         9        10       (none)
// Teensy++ 2.0      25         4       26, 27
// Arduino Uno        9         8         10
// Arduino Mega      46        48       44, 45
// Wiring-S           5         6          4
// Sanguino          13        14         12

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0x30, 0x32, 0x31};
IPAddress ip(192,168,4,7);
IPAddress server(192,168,4,4);
EthernetClient client;

const int requestPin =  5;         
char input; // incoming serial data (byte)
bool readnextLine = false;
#define BUFSIZE 75
char buffer[BUFSIZE]; //Buffer for serial data to find \n .
int bufpos = 0;
long mEVLT = 0; //Meter reading Electrics - consumption low tariff
long mEVHT = 0; //Meter reading Electrics - consumption high tariff
long mEAV = 0;  //Meter reading Electrics - Actual consumption
long mG = 0;   //Meter reading Gas

long lastTime = 0;        // will store last time 
long interval = 60000;           // interval at which to blink (milliseconds)

void setup() {
  Serial.begin(115200);
  delay(1000);
  Ethernet.begin(mac, ip);
  delay(1000);
  pinMode(4, OUTPUT);                  // SD select pin
  digitalWrite(4, HIGH);               // Explicitly disable SD

  //Set RTS pin high, so smart meter will start sending telegrams
  pinMode(requestPin, OUTPUT);
  digitalWrite(requestPin, HIGH);
}

void loop() {

  decodeTelegram();

  if(millis() - lastTime > interval) {
    lastTime = millis();   
    //send data to PHP/MySQL
    httpRequest();
    //Reset variables to zero for next run
    mEVLT = 0;
    mEVHT = 0;
    mEAV = 0;
    mG = 0;
    //Stop Ethernet
    client.stop();
  }
} //Einde loop

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 AltSerial.available'
} //Einde 'decodeTelegram()' functie

void httpRequest() {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    client.print("GET /www/slimmemeter/p1.php?mEVLT=");
    client.print(mEVLT);
    client.print("&mEVHT=");
    client.print(mEVHT);
    client.print("&mEAV=");
    client.print(mEAV);
    client.print("&mG=");
    client.print(mG);
    client.println(" HTTP/1.1");
    client.println("Host: 192.168.4.4");
    client.println("User-Agent: arduino-ethernet");
    client.println("Connection: close");
    client.println();
    //Request complete; empty recieve buffer
    while (client.available()) { //data available
      char c = client.read(); //gets byte from ethernet buffer
    }
    client.println();
  } 
  else {
    client.stop();
  }
}


Pas indien gewenst het MAC-adres en IP-adres van de Arduino aan (regel 32 & 33). Ook wil je waarschijnlijk het IP-adres van het apparaat waar je MySQL op draait aanpassen (regel 34 & 142).

Het resultaat van bovenstaande sketch is dat er zodra een telegram binnenkomt bij de Arduino, hij de interessante waarden hieruit haalt en daarna elke minuut het PHP bestand op m'n NAS aanroept via een GET-request. In de URL staan de verbruikscijfers uit het P1-telegram.
Oorspronkelijk had ik de sketch zo gebouwd dat van elk telegram wat binnenkwam op de Arduino de waarden werden weggeschreven naar de database. De slimme meter spuugt echter iedere 10 sec. een nieuw telegram uit. Dit zorgt voor enorm veel data (8.640 rijen per dag, 3,15 miljoen per jaar!). Een interval van 1 minuut is ook prima, dat gebruiken veel commerciŽle uitleesoplossingen ook. Mocht je wel willen dat voor elk telegram de waarden worden weggeschreven, dan kun je de originele code nog terugvinden hier: http://pastebin.com/N7jHBTDu

Let er overigens op dat als je de code upload naar de Arduino, je de hardware van pin 0 loskoppelt. Anders gaan zaken conflicteren met elkaar. Na het uploaden van de sketch kun je het weer aansluiten. Ik heb zelf een 'shield' gemaakt d.m.v. gaatjesprint en header-pinnen. Het shield kan ik zo van de Arduino af trekken en na uploaden er weer op prikken.

Het PHP bestand bevat de volgende code:
p1.php

PHP:
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
<?php
error_reporting(E_ALL);

//Connect to database
$MyUsername = "p1logger";  // enter your username for mysql
$MyPassword = "p1logger";  // enter your password for mysql
$MyHostname = "localhost";      // this is usually "localhost" unless your database resides on a different server

$dbh = mysql_pconnect($MyHostname , $MyUsername, $MyPassword);
$selected = mysql_select_db("p1",$dbh);

//Waardes van vorige wegschrijf actie ophalen
$query = mysql_query("SELECT laag_tarief, hoog_tarief, huidig_verbruik, gas FROM `readings` ORDER BY `readings`.`time`  DESC LIMIT 1");
$row = mysql_fetch_array($query);
$previous_laag_tarief = $row[0];
$previous_hoog_tarief = $row[1];
$previous_huidig = $row[2];
$previous_gas = $row[3];
$min_vermogen = 0;
$max_vermogen = 230*25; //Maximale vermogen = 230V * vermogen hoofdzekering (1x25A)

//Alle opgehaalde variabelen op type 'INTEGER' zetten ivm vergelijken zometeen
settype($previous_elektra, "integer");
settype($previous_huidig, "integer");
settype($previous_gas, "integer");

//GET variabelen naar andere variabele schrijven
$mEVLT = $_GET["mEVLT"];
$mEVHT = $_GET["mEVHT"];
$mEAV = $_GET["mEAV"];
$mG = $_GET["mG"];

//GET variabelen op 'integer' zetten
settype($mEVLT, "integer");
settype($mEVHT, "integer");
settype($mEAV, "integer");
settype($mG, "integer");


//Checken of binnengekomen standen voldoen aan eisen (meterstand = hoger dan vorige, huidig verbruik > minimale vermogen, kleiner dan maximale vermogen) om incorrecte waarden te negeren
if (
    $mEVLT >= $previous_laag_tarief
    && $mEVHT >= $previous_hoog_tarief 
    && $mG >= $previous_gas //Inkomende meterstand moet groter zijn dan vorige meterstand
    && $mG <= ($mG + 6000) //Gasmeter is type 'G6', which stands for max. 6m3/hour. So value can never be bigger than value + 6000
    && $mEAV >= $min_vermogen //Huidig verbruik moet groter zijn dan minimale verbruik (nachtverbruik)
    && $mEAV <= $max_vermogen //Huidig verbruik moet kleiner zijn dan max. vermogen 1fase aansluiting
    ) 
{ 
    $SQL = "INSERT INTO p1.readings (id, time, laag_tarief, hoog_tarief, huidig_verbruik, gas) VALUES (NULL, NULL, '".$mEVLT."', '".$mEVHT."', '".$mEAV."', '".$mG."')";     
    mysql_query($SQL);
}
else { 

    //Foutieve waarden wegschrijven naar tabel voor latere debugging
    $SQL = "INSERT INTO p1.faulty_readings (id, time, laag_tarief, hoog_tarief, huidig_verbruik, gas) VALUES (NULL, NULL, '".$mEVLT."', '".$mEVHT."', '".$mEAV."', '".$mG."')";    
    mysql_query($SQL);
}


?>


Let niet op de PHP code, dit is erg ranzig bij elkaar gehackt. Het werkt voor mij iig wel. Het zorgt ervoor dat incorrecte waarden zoveel mogelijk worden genegeerd.
Heb je een beter idee dan hoor ik dat graag.

De database (p1) heeft ťťn tabel ('readings'), welke er als volgt uitziet:

code:
1
2
3
4
5
6
7
8
9
10
+-----------------+-----------+------+-----+-------------------+----------------+
| Field           | Type      | Null | Key | Default           | Extra          |
+-----------------+-----------+------+-----+-------------------+----------------+
| id              | int(11)   | NO   | PRI | NULL              | auto_increment |
| time            | timestamp | NO   |     | CURRENT_TIMESTAMP |                |
| laag_tarief     | int(11)   | NO   |     | NULL              |                |
| hoog_tarief     | int(11)   | NO   |     | NULL              |                |
| huidig_verbruik | int(4)    | NO   |     | NULL              |                |
| gas             | int(11)   | NO   |     | NULL              |                |
+-----------------+-----------+------+-----+-------------------+----------------+



Hardware

De hardware is niet heel moeilijk:
Je prikt het Ethernetshield op de Arduino en sluit een kabel vanaf de slimme meter op je Arduino aan.
De P1-poort van de slimme meter gebruikt eigenlijk gewoon een RJ11 telefoonconnector. Je kunt hiervoor eenvoudig zelf een kabel maken. De pinout vind je hier.

De kabel sluit je op de volgende manier op je Arduino aan:

code:
1
2
3
4
5
6
7
+--------------+---------+
| Slimme meter | Arduino |
+--------------+---------+
| RTS (2)      | D5      |
| GND (3)      | GND     |
| RxD (5)      | 0 (RX)  |
+--------------+---------+



Mijn meter (Kaifa MA105) spuugt de data echter geÔnverteerd uit, dus ik moest nog een oplossing maken met een transistor (BS170) en een 10k weerstand. Ook spuugt mijn meter de data uit @ 115200 baud ipv 9600. Start/stop bits is 8N1 bij mijn meter. Als jouw meter 7N1 gebruikt zul je dat even weer in moeten bouwen adhv de voorbeeldsketch waar ik bovenaan naar link.

Om de data weer terug te inverteren moet je een hardware oplossing maken. Dit kan zoals hierboven genoemd met een simpele transistor (BC547 of BS170) en een weerstand van 10k (schema).

Grafisch maken van de data
Nu de Arduino aan het loggen is wil je natuurlijk ook zien wat je energieverbruik is. Een tabel vol met cijfertjes zegt je waarschijnlijk weinig. Ik heb voor mijzelf een opzetje gemaakt met Highcharts. Met Highcharts kun je redelijk eenvoudig grafieken tonen.

Om deze blogpost niet teveel te vervuilen met lange lappen code heb ik de code voor het tonen van de grafiek hier geplaatst. De code zal vast niet heel netjes zijn opgesteld (ik ben geen fulltime programmeur, puur hobby dit) maar voor mijn doeleinde werkt het prima. Ook is alleen het huidige elektraverbruik zichtbaar. Gasverbruik doe ik nog niks mee.

Gasverbruik uploaden naar Mindergas.nl
Ik hield voorheen altijd handmatig mijn gasverbruik bij via www.mindergas.nl . Mindergas heeft ook een API. Nu met deze P1-uitleesmogelijkheid upload ik elke avond automatisch de meterstand naar Mindergas. De code hiervoor kun je vinden in dit topic: http://gathering.tweakers...message/42816734#42816734
Het is alleen nog niet 100% betrouwbaar, zoals hieronder ook is vermeld komen er soms niet kloppende waarden in de MySQL-database te staan. Ik ben nog bezig om uit te zoeken hoe ik dit kan oplossen.

Todo list
- Iets verzinnen dat ik nog wel steeds elke 10sec het huidige verbruik kan blijven opvragen na aanpassen wegschrijf-interval naar 1 min. Misschien huidig verbruik via JSON uitspugen als bepaalde URL van Arduino wordt opgevraagd. Is wat efficiŽnter dan elke 10 sec. MySQL lastigvallen.
- Kijken of ik een watchdog kan implementeren. Hoewel de Arduino nu al meer dan een maand zonder storingen de gegevens logt, wil ik de sketch zo maken dat hij 24/7/365 kan loggen zonder menselijk ingrijpen. Automatisch resetten bij vastlopen zou dan handig zijn.

Ik ben dit nog aan het uitzoeken, discussie daarover loopt in het topic. Opmerkingen of verbeteringen mbt de Arduino code ook graag daar plaatsen. Reacties op de PHP/MySQL/grafiek mogen hier, dat staat los van de Arduino sketch.

Eindresultaat
http://tweakers.net/ext/f/0pEEUggSwMhBxjb5JFqIUnhh/full.png
Het eindresultaat. Ik kan rechts kiezen of ik alleen gisteren wil zien, alleen vandaag, of allebei. De regelmatig terugkomende piekjes in het gele gedeelte is m'n koelkast, mocht je je dat afvragen ;)

Disclaimer:
Ik ben niet verantwoordelijk voor schade aan je slimme meter, jezelf, je Arduino of andere zaken betrokken in dit project. Uitvoeren op eigen risico!

Waarom een pompschakelaar op je vloerverwarming zin heeft

Door ThinkPad op vrijdag 24 januari 2014 10:37 - Reacties (21)
Categorie: Tips & Tricks, Views: 12.145

Mijn ouders hebben vloerverwarming in hun huis. Om het water rond te pompen door de leidingen zit er op het vloerverwarming (VV)-systeem een pomp. Ik kwam een tijdje terug op internet een site tegen over energie besparen. Hier stond dat VV-pompen vaak 24/7 draaien. Ook bij mijn ouders was dat het geval.

In de oude situatie draaide de pomp 24/7 @ 67W. Dat is goed voor 587 kWh per jaar, en kost dan §130 op jaarbasis (bij een prijs van §0,22/kWh)
Omdat de installatie bij mijn ouders maar uit 3 leidinglussen bestaat bleek na enig onderzoek dat de pomp ook wel een stand lager kon omdat er dan nog steeds genoeg stroming was door de leidingen. Het verbruik is hierdoor al gezakt naar 53W. Dit bespaart al 27 euro op jaarbasis!
De pomp draaide echter nog steeds 24/7. Ik vroeg mij af: "Als de ketel geen warm water aanvoert, waarom is het dan nodig om de pomp het water te laten circuleren?"

Oplossing hiervoor werd gevonden in een pompschakelaar (ECO Pump Switch HY-02). De pompschakelaar steek je in het stopcontact, de stekker van de pomp in de schakelaar en de bijgeleverde temperatuursensor klem je op de leiding die het warme water vanaf de ketel aan de VV-verdeler voedt (even voelen welke buis het warmste is als CV-ketel aanstaat). Wat de pompschakelaar doet is simpelgezegd:
IF aanvoerleiding >= '33 graden' THEN pomp = aan, ELSE pomp = uit
In de zomer staat de verwarming uit en de pomp dus ook. Je hebt daarom kans dat de pomp intern gaat roesten en daardoor vast gaat zitten. Een simpele tijdschakelaar gebruiken om de pomp te schakelen is hierdoor af te raden. Om vastzitten te voorkomen zal bovengenoemde pompschakelaar de pomp eens in de 24h even laten draaien om dit te voorkomen.
Inpluggen en nooit meer naar om hoeven te kijken dus!

Het aantal draaiuren van de pomp is nu lastiger te berekenen, maar als we uitgaan dat de ketel tussen 6:00 - 22:00 gebruikt zal worden (dat is het klokprogramma wat in de kamerthermostaat zit) dan kom je op 16 uur.

53W bij 16 uur per dag is op jaarbasis 310 kWh, en kost dan §68,20. Het verbruik is dus bijna gehalveerd ten opzichte van de oude situatie waarin de pomp 24/7 stond te draaien!
En dit is dus een groffe berekening van 16 uur op een dag. In werkelijkheid zal het veel minder zijn omdat de ketel immers niet 16 uur staat te draaien. Ook draait in de zomermaanden de verwarming niet, en zou het dus zomaar kunnen zijn dat hij 3 maanden niet gebruikt wordt. Het daadwerkelijke verbruik is dus veel minder.

Al met al is de conclusie dat je een pompschakelaar binnen de kortste keren hebt terugverdiend!! (in ons geval een halfjaar). Als je pomp een hoger vermogen heeft is dit nog sneller, de besparing is dan immers groter.
En een tweede voordeel is dat het comfort er ook wat op vooruit gaat. Het warme water blijft nu in de vloer aanwezig nadat de ketel weer is uitgeschakeld. In de originele situatie (pomp 24/7 aan) werd het water constant rondgepompt waardoor de vloer sneller weer afkoelde dan nu het geval is.

Wat ook wel handig is om te weten, is dat sommige ketels zijn uitgerust met een connector waar je een tweede pomp op kan aansluiten. Je zou daar de pomp van de vloerverwarming mee kunnen laten schakelen. Op die manier draait hij alleen als de CV-ketel in bedrijf is. Onze ketel (Remeha Calenta) heeft dit helaas niet, je moet dan een extra module inbouwen. Die module is duurder dan deze pompschakelaar dus vandaar dat we hiervoor hebben gekozen. Ook is een pompschakelaar die op temperatuur werkt universeel, mocht er ooit een andere ketel komen dan hoeft er aan deze setup niks gewijzigd te worden. Kijk even in je handleiding van je ketel of jouw ketel de mogelijkheid heeft voor een externe pomp. Scheelt weer het aanschaffen van een pompschakelaar. Wel even opletten dat het relais in je ketel het pompvermogen aankan!

Bij ons is de VV-verdeler geplaatst in een koude garage, op de planning staat nog om de blootliggende leidingen te voorzien van buisisolatie. Op die manier kan er nog een paar % gas bespaard worden. Om de verdeler zit al wel een omkasting met dik isolatiemateriaal.

Trek ook eens het schot van je berging o.i.d. open waar je VV-installatie zit en onderzoek hoe het bij jou thuis geregeld is!
d:)b d:)b d:)b

Laat weten wat je van deze blogpost vind door te stemmen
http://codecaster.nl/got/rmb/star1.gifhttp://codecaster.nl/got/rmb/star2.gifhttp://codecaster.nl/got/rmb/star3.gifhttp://codecaster.nl/got/rmb/star4.gifhttp://codecaster.nl/got/rmb/star5.gifhttp://codecaster.nl/got/rmb/stats.gif
Met dank aan CodeCaster

Server status stoplicht met Arduino

Door ThinkPad op maandag 29 april 2013 22:13 - Reacties (8)
Categorie: Electronica, Views: 2.670

Inleiding
Ik heb al een tijdje het pakket "PRTG" draaien. Dit is een handig pakket om diverse apparaten mee te monitoren. Ik heb het programma ingesteld naar wens, en een notificatie ingesteld zodat ik een mailtje krijgt als er iets mis is.

Voor elk apparaat dat je monitored kun je triggers instellen, zo heb ik bijv. een trigger ingesteld dat er een waarschuwing moet worden geven als een bepaalde SMB share van m'n fileserver offline is (anders kan de rest van het gezin geen film kijken haha :+ ). Of een trigger die continu naar poort 1723 van m'n VPN virtuele machine luistert, om te kijken of m'n VPN verbinding nog online is. Of een trigger die kijkt of de Crashplan service op een bepaalde VM nog draait, en indien dat niet zo is; automatisch herstart. Mocht het dan nog niet werken > alarm.

Het leuke van PRTG is dat de mogelijkheden eindeloos zijn. Je kunt op heel veel manieren informatie opvragen, en mocht jouw functionaliteit er niet tussen zitten dan zou je zelf een PHP scriptje o.i.d. kunnen maken, en dmv een HTTP sensor de informatie daarvan opvragen.

Oke, maar je had het over Arduino? Hoe/wat dan?

Terug naar het project: Notificaties kreeg ik dus al via de mail. Ik ben sindskort echter ook wat beginnen te spelen met Arduino, en het leek mij wel leuk om in ťťn oogopslag te kunnen zien hoe mijn apparatuur er voor staat. PRTG kent van zichzelf al 3 categorien: OK, Warning, Critical. Dit valt natuurlijk prima te vertalen naar een stoplicht! (Groen, Oranje, Rood). Ik heb eventjes op Marktplaats gekeken voor een echt stoplicht, maar dan praat je over een unit van een meter hoog, dat werd mij toch iets te gek :D

Vandaar dat ik dit heb gemaakt, dit komt in een hoek van m'n kamer te hangen, en zo kan ik ook zonder een PC scherm voor m'n neus te hebben, zien hoe m'n apparatuur er voor staat.

De hardware

De hardware is eigenlijk best simpel:
  • 1x een Arduino Nano
  • 3x TIP120 NPN transistor
  • 1x ENC28J60 Ethernet shield
  • 3x LED Indicator Pilot Signal Light Lamp 12V
  • 1x voeding voor het geheel
  • 1x Lasdoos om het geheel netjes in weg te werken
  • 3x 100-220 Ohm weerstanden om tussen Arduino en transistoren te plaatsen
Meeste komt vanuit China via eBay, voor een habbekrats.

Het hardware verhaal is niet heel interessant om te vertellen, het is eigenlijk gewoon dit schema: https://learn.adafruit.com/assets/2693 maar dan met een losse voeding voor de LEDs. De grijze draad naar de Arduino gebruik ik dus niet, deze komt rechtstreeks vanaf mijn voeding. Denk erom dat je de GND van de voeding ook aan de GND van de Arduino aansluit, anders werkt het niet.

Werking van het geheel

Het idee is dat PRTG een bepaalde URL aanroept op de Arduino met een bepaalde GET parameter. De Arduino zal vervolgens actie ondernemen, en de desbetreffende LED inschakelen. Bij het opstarten van de Arduino laat hij 1 voor 1 alle lampen even branden zodat je weet dat ze alle 3 nog werken ;) Daarna springt hij standaard op groen, totdat hij een verzoek binnenkrijgt.

Instellen van de triggers/notificaties

Het aanmaken van een trigger in PRTG is simpel, ga hiervoor naar "Setup" > "Account instellingen " > "Notificaties"

Daar maken we voor elke 'state' een notificatie aan:

Naam notificatieGebruikte URL
Arduino stoplicht state=criticalhttp://<arduino_ip>/?state=critical
Arduino stoplicht state=warninghttp://<arduino_ip>/?state=warning
Arduino stoplicht state=okhttp://<arduino_ip>/?state=ok


Daarna kunnen we voor een apparaat, of een hele groep de notificaties instellen, ik heb dit als volgt gedaan voor de groep waar al mijn apparaten zich in bevinden:
  • Als sensor is Fout voor 60 seconden, voer uit Arduino stoplicht state=critical
  • Als conditie blijft bestaan voor 300 seconden, voer uit Arduino stoplicht state=critical en herhaal elke 1 minuten
  • Als conditie verdwijnt, voer uit Arduino stoplicht state=ok
Hierna maak je nog een trigger, ditmaal voor 'warning', maar uiteraard stel je dan in de bovenste 2 regels 'warning' in, ipv 'critical' ;) Ik heb er voor gekozen om de trigger elke minuut te herhalen, mocht de Arduino z'n voeding kwijtraken dan springt hij binnen een minuut weer op de juiste status (anders zou hij op groen blijven staan)

Je kunt bij het aanmaken van de notificaties ook gelijk een test doen, probeer dit even, anders heb je nog niks aan dit hele verhaal :+
Eindresultaat

Arduino stoplicht
Klik voor groter


Arduino stoplicht
Klik voor groter

Totale kosten waren rond de 19 euro. Arduino rond de 10 euro, lampjes 5 euro, netwerkmodule 4 euro. En dan nog wat klein spul zoals bedrading, lasdoos etc.

To-do list/wish list
  • Op dit moment schakel ik de stroom gewoon uit 's avonds, misschien dat ik daar nog wat anders op ga verzinnen, al werkt het voor nu prima. Geen idee of het kwaad kan voor de Arduino namelijk
  • Het script werkt nu nog maar een kant op, het werkt alleen als de PRTG server impulsen blijft sturen. Ik wil het nog zo maken dat de Arduino de PRTG server ook om de minuut een ping stuurt, en als dat niet lukt > rode lamp aan
Arduino CODE: http://pastebin.com/QNY4Sxib
Mijn dank gaat uit naar foekie01 voor het meedenken: http://gathering.tweakers...message/40168331#40168331

Je hebt ook de ENC28J60 library nodig, die kun je hier vinden: http://jeelabs.net/projects/ethercard/wiki

Laat weten wat je van deze blogpost vind door te stemmen
http://codecaster.nl/got/rmb/star1.gifhttp://codecaster.nl/got/rmb/star2.gifhttp://codecaster.nl/got/rmb/star3.gifhttp://codecaster.nl/got/rmb/star4.gifhttp://codecaster.nl/got/rmb/star5.gifhttp://codecaster.nl/got/rmb/stats.gif
Met dank aan CodeCaster

HOWTO: Batterijniveau van een UPS aangesloten via USB uitlezen met WMI

Door ThinkPad op dinsdag 05 februari 2013 19:28 - Reacties (0)
Categorie: WMI, Views: 3.532

In m'n vorige blog (ThinkPad's TweakBlog: HOWTO: Hardware temperaturen monitoren met PRTG onder Windows schreef ik over het uitlezen van hardware temperaturen via WMI (aangeleverd door Open Hardware Monitor).

Ik heb aan m'n thuisserver een UPS hangen, voor het geval dat de stroom uitvalt. Dit is een Back-UPS 500. Deze is aangesloten via USB. Mijn server draait op Windows Server 2008 R2 x64, en als je dan een Back-UPS hebt is dat een vrij vervelende situatie. Het zit namelijk zo:
Als je onder Server 2008 een APC UPS wilt uitlezen dan kun je dat doen met PowerChute Business Edition. Deze software sluit dan netjes je PC af als hij een stroomstoring detecteert. De Business versie ondersteunt alleen geen UPS'en van de Back-UPS serie. Eigenlijk is de Back-UPS ook een thuismodel ;)

De Back-UPS lees je normaal gesproken (op een OS voor thuisgebruik zoals XP, Win 7) uit met PowerChute Personal Edition. Maar die versie wil weer niet draaien op Server 2008. Ik zat dus een beetje in de knoop. Gelukkig heeft Windows zelf ook een basic UPS service draaien waarmee het afsluiten prima gedaan wordt.

Maar een echte Tweaker wil natuurlijk specs!!1111!!einzz. En dat lukt met de standaard Windows UPS service niet.

Gelukkig houdt Windows via WMI ook allerlei dingen bij. En ook het batterijniveau e.d.

Door de query
SQL:
1
SELECT EstimatedChargeRemaining FROM Win32_Battery
nu als Custom WMI Sensor in PRTG toe te voegen kunnen we heel makkelijk het batterijniveau uitlezen. Nog even een notificatie instellen (zodat PRTG een waarschuwing geeft als het batterij niveau onder de ingestelde threshold is), en klaar is kees!

Hoe je een Custom WMI Sensor aan PRTG toe kunt voegen kun je in m'n vorige blogpost lezen (je moet onder andere .wql bestand aanmaken met daarin de query)

Resultaat: http://tweakers.net/ext/f/X9cDbuzXasBFeTQoldhlPmNB/full.png (UPS is bezig met opladen).

Als je een Smart-UPS hebt gaat dit verhaal niet echt op natuurlijk, dan kun je gewoon de APC PowerChute Business Edition gebruiken, of als je een UPS hebt met netwerkkaart dan kun je die in PRTG uitlezen via SNMP

Laat weten wat je van deze blogpost vind door te stemmen
http://codecaster.nl/got/rmb/star1.gifhttp://codecaster.nl/got/rmb/star2.gifhttp://codecaster.nl/got/rmb/star3.gifhttp://codecaster.nl/got/rmb/star4.gifhttp://codecaster.nl/got/rmb/star5.gifhttp://codecaster.nl/got/rmb/stats.gif
Met dank aan CodeCaster