Christian Fetzer 2024-02-11T20:04:47+00:00 https://fetzerch.github.io Christian Fetzer [email protected] Sun and Moon Datasource Plugin for Grafana 2016-07-03T00:00:00+00:00 https://fetzerch.github.io/2016/07/03/grafana-sunandmoon-datasource <p>While working on <a href="/2015/05/20/atmeteo/">atMETEO</a>, I found it useful to bring the measured temperature and atmospheric pressure values into relation with the position of the sun or the current moon phase and see how they correlate. Back then when <a href="https://grafana.com">Grafana</a> only supported the <a href="https://graphiteapp.org">Graphite</a> datasource this was done with a simple script that calculated those values every minute and stored them in the Graphite database along with the other measurements.</p> <p>Now that Grafana supports a sophisticated plugin framework (<a href="https://grafana.com/blog/2016/05/11/grafana-3.0-stable-released">starting with v3.0</a>), I have created the <a href="https://grafana.com/grafana/plugins/fetzerch-sunandmoon-datasource"><em>Sun and Moon Datasource Plugin for Grafana</em></a> which uses <a href="https://github.com/mourner/suncalc">SunCalc</a> to calculate the position of sun and moon on demand when rendering on the frontend. Additional features are the calculation of the moon illumination and annotations for various events such as sunrise or sunset.</p> <p><a href="/assets/grafana-sunandmoon-datasource.png" data-lightbox="Sun and Moon Datasource Plugin for Grafana" title="Grafana screenshot showing the Sun and Moon Datasource Plugin."> <img src="/assets/grafana-sunandmoon-datasource.png" alt="Grafana screenshot showing the Sun and Moon Datasource Plugin." /> </a></p> <p>Like all Grafana plugins the <a href="https://grafana.com/grafana/plugins/fetzerch-sunandmoon-datasource"><em>Sun and Moon Datasource Plugin</em></a> is now hosted on <a href="https://grafana.com">Grafana.net</a> and the source code is available in a <a href="https://github.com/fetzerch/grafana-sunandmoon-datasource">GitHub repository</a>. An <a href="https://grafana.com/grafana/dashboards/630">example dashboard</a> can be found as well.</p> <h2 id="technical-aspects">Technical aspects</h2> <p>The main advantage of doing the calculation in a datasource on the client side is that the values don’t have to be pregenerated which is not optimal with Graphite because it does not allow to submit future values and therefore the calculation has to be done just in time.</p> <p>From a technical point of view the plugin is interesting because as of today it is the only Grafana plugin that doesn’t rely on a server providing the data. Therefore it might be a useful example for new plugin authors.</p> <h2 id="feedback">Feedback</h2> <p>When submitting the plugin to <a href="https://grafana.com">Grafana.net</a> I received very positive feedback from <a href="https://raintank.io">raintank</a>, the company behind Grafana and <a href="https://github.com/torkelo">Torkel Ödegaard</a> even demoed the datasource in his talk at this year’s <a href="https://monitorama.com">Monitorama</a> which happened to take place two days after I created the Pull Request on GitHub. Thanks for this! A recording is available on <a href="https://www.youtube.com/embed/1SlljMU9V5k?start=6748&amp;end=6810">YouTube</a>.</p> <h2 id="outlook-and-further-work">Outlook and further work</h2> <p>The current version of the plugin implements all features that <a href="https://github.com/mourner/suncalc">SunCalc</a> currently offers. Nevertheless there are already a few ideas for future improvements.</p> <p>I could imagine that the plugin might be useful when monitoring photovoltaic systems (maybe even solar parks). For this the calculation of the clear sky radiation could be added. Additionally the annotations could be extended to be able to show additional astronomic events such as full and new moon or solstices/equinoxes and perihelion/aphelion.</p> <p>If you have additional ideas or want to help out for example with the calculation of the mentioned values, please use the <a href="https://github.com/fetzerch/grafana-sunandmoon-datasource/issues">issue tracker on GitHub</a>.</p> Monitoring sensor values of an HP ProLiant MicroServer G7 N54L 2015-11-15T00:00:00+00:00 https://fetzerch.github.io/2015/11/15/hp-n54l-drivers <p>I’m running a small Linux server (<em>HP ProLiant MicroServer G7 N54L</em>) in my home network as backup drive for desktops and notebooks. The health of the server is critical and therefore I wanted to keep track of some system metrics such as temperatures, voltages and system fan speed in the hope that they can detect hardware problems in advance.</p> <p>These metrics are typically offered by hardware monitor chips and can be accessed in Linux with the <em>lm-sensors</em> utilities (<code class="language-plaintext highlighter-rouge">sensors-detect</code> and <code class="language-plaintext highlighter-rouge">sensors</code>). Unfortunately <code class="language-plaintext highlighter-rouge">sensors-detect</code> was not able to detect the respective chip (<em>Nuvotem/Winbond W83795ADG</em>). After a bit of research, it turned out that the SMBus/I2C driver for the chipset failed to detect the sensor. Luckily there was already a <a href="https://www.mail-archive.com/[email protected]/msg06757.html">patch</a> available that fixed the driver but supported only an older kernel version. The patch was never merged into the mainline Linux kernel and meanwhile a few things have changed in that module. Since I think it’s a valuable change, I ported it to the current kernel version, cleaned it up and re-sent it to the <a href="http://vger.kernel.org/vger-lists.html#linux-i2c">mailing list</a> where it’s currently being reviewed. (<em>UPDATE</em>: The patch has been merged and is included in Linux 4.5.)</p> <p>For the time being, the patched driver can be found in this <a href="https://github.com/fetzerch/hp-n54l-drivers">GitHub repository</a> including a more detailed description and installation instructions. This should make it simple for anyone interested to test it and use it on their systems.</p> <p>After installation of the updated driver and loading the modules, <code class="language-plaintext highlighter-rouge">sensors</code> is able to show the measurements:</p> <div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dg-i2c-1-2f Adapter: SMBus PIIX4 adapter SDA2 at 0b00 Vcore: +0.88 V (min = +0.50 V, max = +1.40 V) Vdimm: +1.51 V (min = +1.42 V, max = +1.57 V) +3.3V: +3.30 V (min = +2.96 V, max = +3.63 V) 3VSB: +3.26 V (min = +2.96 V, max = +3.63 V) System Fan: 679 RPM (min = 329 RPM) CPU Temp: +34.8°C (high = +109.0°C, hyst = +109.0°C) (crit = +109.0°C, hyst = +109.0°C) sensor = thermal diode NB Temp: +43.2°C (high = +105.0°C, hyst = +105.0°C) (crit = +105.0°C, hyst = +105.0°C) sensor = thermal diode MB Temp: +20.8°C (high = +39.0°C, hyst = +39.0°C) (crit = +44.0°C, hyst = +44.0°C) sensor = thermistor </code></pre></div></div> <p>The sensor readings can be easily aggregated with <a href="https://collectd.org">collectd’s</a> <a href="https://collectd.org/wiki/index.php/Plugin:Sensors">sensor</a> plugin. Unfortunately the current version of the plugin has one minor limitation and tracks the sensor readings only by metric names (e.g “temp1”) but not by the more descriptive labels (e.g. “CPU Temp”). To address this shortcoming I’ve created a <a href="https://github.com/collectd/collectd/pull/1239">pull request on GitHub</a>. (<em>UPDATE</em>: The pull request has been merged and the feature is included in collectd 5.6.0.)</p> <p>The following <a href="https://grafana.com">grafana</a> screenshot shows the result:</p> <p><a href="/assets/hp-n54l-drivers_grafana.png" data-lightbox="Monitoring sensor values of an HP ProLiant MicroServer G7 N54L" title="Grafana screenshot showing sensor data from an HP ProLiant MicroServer G7 N54L"> <img src="/assets/hp-n54l-drivers_grafana.png" alt="Grafana screenshot showing sensor data from an HP ProLiant MicroServer G7 N54L" /> </a></p> <p>The drive temperatures were collected using the <a href="https://collectd.org/wiki/index.php/Plugin:HDDTemp">HDDTemp</a> plugin.</p> atMETEO - An ATmega based weather station 2015-05-20T00:00:00+00:00 https://fetzerch.github.io/2015/05/20/atmeteo <p>Besides logging and visualizing <a href="/2014/08/23/fritzcollectd/">internet connection statistics</a> I wanted to track also local weather conditions and later eventually integrate the data into a home automation system. While today there are proprietary and free projects available that facilitate this, the topic seemed to be a perfect candidate for a small spare time open source project, which I called <em><a href="https://github.com/fetzerch/atMETEO">atMETEO</a></em>.</p> <p><a href="/assets/atmeteo_logo.svg" data-lightbox="atMETEO - An ATmega based weather station" title="atMETEO - An ATmega based weather station"> <img src="/assets/atmeteo_logo.svg" alt="atMETEO - An ATmega based weather station" /> </a></p> <h2 id="project-goals-and-introduction">Project goals and introduction</h2> <p>Programming an ATmega based weather station not only allowed to deepen my knowledge in electronics and microcontrollers, at the same time the project served as practical accompaniment while reading Modern C++ Design and C++ Templates and enabled me to explore the advantages and limits of <em>modern C++ on 8 bit hardware</em>.</p> <p>The essential concept of <em>atMETEO</em> is to read and interpret data from sensors connected to the microcontroller and to transfer this information to a connected PC for further processing, storing and visualization.</p> <p>Ideally <em>atMETEO</em> should hereby be able to access my already existing Hideki TS53 RF sensors. Therefore a preliminary step was to <a href="/2014/11/15/reveng433/">reverse engineer</a> their data format.</p> <p>Conducting test automation is essential in order to develop a stable product which can be left running unattended. For this purpose a <a href="https://www.jenkins.io">Jenkins</a> server has been set up that runs <a href="https://clang-analyzer.llvm.org/">Clang Static Analyzer</a>, builds all commits and executes unit tests (including code coverage generation). In addition it flashes new software periodically and maintains statistics on successful and failed attempts to read sensor data for a given time range to identify possible race conditions.</p> <h2 id="technical-aspects">Technical aspects</h2> <p>Even though microcontroller projects are usually hardware centric, the main emphasis has been placed on the software part. My current setup utilizes an <a href="https://docs.arduino.cc/hardware/uno-rev3">Arduino Uno</a>, but <em>atMETEO</em> is prepared to be built for different ATmega boards with only minor adaption. Currently there are 5 sensor types supported: Hideki TS53 Thermo/Hygrometer, DHT22 / AM2302 temperature and humidity module, Bosch BMP180 Digital pressure sensor, Melexis MLX90614 Infrared thermometer and Figaro TGS 2600 air contaminant sensor. The RF receiver as well as the other sensors are connected to the microcontroller as shown in the following breadboard circuit (created with <a href="https://fritzing.org">Fritzing</a>).</p> <p><a href="/assets/atmeteo_breadboard.png" data-lightbox="atMETEO - An ATmega based weather station" title="atMETEO sensor setup on breadboard"> <img src="/assets/atmeteo_breadboard.png" alt="atMETEO sensor setup on breadboard" /> </a></p> <p>On the software side the project is divided into two main parts. A <em>libsensors</em> library contains the target / platform independent functionality and algorithms and ships with unit tests that can be executed on the host. All utilities for accessing ATmega hardware features (such as pins, timers, UART, I2C (TWI), SPI) as well as an Ethernet driver (WIZnet W5100) are part of <em>libtarget</em>. The main application makes then use of both libraries in order to send the measured sensor data in JSON format over UART or Ethernet (UDP) to the host.</p> <p><em>atMETEO</em> uses the <a href="https://www.cmake.org">CMake</a> build system which controls cross compilation (including flashing) as well as unit tests (including code coverage generation) and <a href="https://www.doxygen.nl/index.html">Doxygen</a> documentation.</p> <p>Detailed information can be found in the project’s <a href="https://github.com/fetzerch/atMETEO/blob/master/README.md">readme</a> and the <a href="https://fetzerch.github.io/atMETEO">documentation</a>.</p> <h2 id="graphical-user-interface">Graphical user interface</h2> <p><a href="https://graphiteapp.org">Graphite</a> and <a href="https://grafana.com">grafana</a> are two excellent tools for logging and graphing time series data. With the command line client <em>atMETEO</em> integrates nicely into this setup as it can be configured to transfer measurements to graphite’s carbon daemon.</p> <p>The following screenshot shows the <em>atMETEO</em> dashboard I am using to access the measurements from PC, tablet or phone.</p> <p><a href="/assets/atmeteo_grafana.png" data-lightbox="atMETEO - An ATmega based weather station" title="Grafana screenshot showing data from atMETEO"> <img src="/assets/atmeteo_grafana.png" alt="Grafana screenshot showing data from atMETEO" /> </a></p> <h2 id="outlook-and-further-work">Outlook and further work</h2> <p><em>atMETEO</em> provides weather data now since more than 10 months, even though hardware and circuit are still just built on a breadboard. One of the very next steps therefore is to solder the sensors on a circuit board and fit everything into a small enclosure.</p> <p>The measurements are transferred to the host in JSON format. While this is relatively easy to generate on the microcontroller, it requires to run an <em>atMETEO</em> client application on the host to interpret the data and process it. Therefore it would be beneficial to switch to a standard format such as <a href="https://en.wikipedia.org/wiki/MQTT">MQTT</a>.</p> <h2 id="links">Links</h2> <ul> <li><a href="https://fetzerch.github.io/atMETEO">Documentation</a></li> <li><a href="https://github.com/fetzerch/atMETEO">GitHub repository</a></li> </ul> Reverse engineering 433 MHz sensors 2014-11-15T00:00:00+00:00 https://fetzerch.github.io/2014/11/15/reveng433 <p>This article focuses on how to decode data sent by proprietary RF 433 MHz sensors using the example of a wireless thermo/hygrometer. Understanding how the sensor works is a first step towards logging and analyzing the data on a computer.</p> <p>Note that there are already implementations for many popular sensors available online so that there’s a good chance that you will not have to reverse engineer or implement anything on your own.</p> <h2 id="visualizing-the-data">Visualizing the data</h2> <p>At the very beginning it is essential to understand how the basic RF signal being transmitted looks like. This can be accomplished either with an oscilloscope/logic analyzer or simply with a sound card, <a href="https://www.audacityteam.org/">Audacity</a> and a voltage divider circuit limiting the 5V from the RF receiver to &lt;1V.</p> <p><a href="/assets/reveng433-receiver.jpg" data-lightbox="Reverse engineering 433 MHz sensors" title="RF 433 MHz receiver for analyzing with Audacity (with an Arduino Uno as 5V power supply)"> <img src="/assets/reveng433-receiver.jpg" alt="RF 433 MHz receiver for analyzing with Audacity (with an Arduino Uno as 5V power supply)" /> </a></p> <p>When the experimental setup is functional the first step is to collect a set of meaningful samples for the subsequent analysis. An essential part thereby is that the original receiver is available so that the samples can be annotated with the reference values from the receiver’s display. It proved to be useful to record samples that differentiate only in exactly one value. This technique allows to easily isolate length and position of that metric in the raw signal. Assuming that the length of a metric remains constant for the whole message it can be used to split the message into blocks.</p> <p>For the example sensor the first analysis reveals the position of temperature and humidity as well as a block size which is illustrated by reference lines in the figure below. It is also noticeable that the two last blocks change as soon as temperature or humidity changes. This indicates that these blocks contain CRC values.</p> <p><a href="/assets/reveng433-audacity.png" data-lightbox="Reverse engineering 433 MHz sensors" title="Audacity showing the recorded RF 433 MHz signal"> <img src="/assets/reveng433-audacity.png" alt="Audacity showing the recorded RF 433 MHz signal" /> </a></p> <p>The recordings should also give a good overview on how often the sender transmits and in which time periods. The exemplary thermo/hygrometer sensor sends three times in a row every 43 seconds.</p> <h2 id="modulation-bit-decoding-and-interpreting-the-payload">Modulation, bit decoding and interpreting the payload</h2> <p>The next step in the analysis is to determine which modulation is used. Typically RF 433 MHz sensors use line codes such as <a href="https://en.wikipedia.org/wiki/Manchester_encoding">Manchester</a>, <a href="https://en.wikipedia.org/wiki/Biphase_mark_code">Differencial Manchester</a> or <a href="https://en.wikipedia.org/wiki/Biphase_mark_code">Biphase Mark</a> coding. Other sensors use <a href="https://en.wikipedia.org/wiki/On-off_keying">On-off keying</a>.</p> <p>Decoding the particular sections from the example above using <a href="https://en.wikipedia.org/wiki/Biphase_mark_code">Biphase Mark coding</a>, where a long pulse represents a binary 1 and a short pulse a binary 0, yields the following results.</p> <div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>111110010 000001001 011100111 011110011 001010101 010000111 101001001 110111111 000111001 011111100 111110010 000001001 011100111 011110011 001010101 010000111 011001001 110111111 110111001 101111010 111110010 000001001 011100111 011110011 011010100 010000111 011001001 110111111 100111000 101100100 </code></pre></div></div> <p>The binary representation consists of ten blocks each with nine bits, which indicates that there are eight data bits followed by one parity bit. A cross check reveals that even parity is used.</p> <p>Subsequently the binary representation has to be transformed into data bytes by applying the correct bit numbering such as <a href="https://en.wikipedia.org/wiki/Bit_numbering">MSB</a> or <a href="https://en.wikipedia.org/wiki/Bit_numbering">LSB</a>. Electronic systems commonly use <a href="https://en.wikipedia.org/wiki/Binary-coded_decimal">Binary-coded decimal</a> encoding a decimal digit in four bits (nibble). Therefore bit numbering variants with reversed nibbles are further viable options.</p> <table> <thead> <tr> <th style="text-align: right">#1</th> <th style="text-align: center">Display</th> <th style="text-align: center">MSB 0</th> </tr> </thead> <tbody> <tr> <td style="text-align: right">1</td> <td style="text-align: center">25.4° - 25%</td> <td style="text-align: center"><code class="language-plaintext highlighter-rouge">F9 04 73 79 2A 43 A4 DF 1C 7E</code></td> </tr> <tr> <td style="text-align: right">2</td> <td style="text-align: center">25.4° - 26%</td> <td style="text-align: center"><code class="language-plaintext highlighter-rouge">F9 04 73 79 2A 43 64 DF DC BD</code></td> </tr> <tr> <td style="text-align: right">3</td> <td style="text-align: center">25.6° - 26%</td> <td style="text-align: center"><code class="language-plaintext highlighter-rouge">F9 04 73 79 6A 43 64 DF 9C B2</code></td> </tr> </tbody> </table> <table> <thead> <tr> <th style="text-align: right">#2</th> <th style="text-align: center">Display</th> <th style="text-align: center">MSB 0 (reversed nibbles)</th> </tr> </thead> <tbody> <tr> <td style="text-align: right">1</td> <td style="text-align: center">25.4° - 25%</td> <td style="text-align: center"><code class="language-plaintext highlighter-rouge">9F 40 37 97 A2 34 4A FD C1 E7</code></td> </tr> <tr> <td style="text-align: right">2</td> <td style="text-align: center">25.4° - 26%</td> <td style="text-align: center"><code class="language-plaintext highlighter-rouge">9F 40 37 97 A2 34 46 FD CD DB</code></td> </tr> <tr> <td style="text-align: right">3</td> <td style="text-align: center">25.6° - 26%</td> <td style="text-align: center"><code class="language-plaintext highlighter-rouge">9F 40 37 97 A6 34 46 FD C9 2B</code></td> </tr> </tbody> </table> <table> <thead> <tr> <th style="text-align: right">#3</th> <th style="text-align: center">Display</th> <th style="text-align: center">LSB 0</th> </tr> </thead> <tbody> <tr> <td style="text-align: right">1</td> <td style="text-align: center">25.4° - 25%</td> <td style="text-align: center"><code class="language-plaintext highlighter-rouge">F9 02 EC E9 45 2C 52 BF 83 E7</code></td> </tr> <tr> <td style="text-align: right">2</td> <td style="text-align: center">25.4° - 26%</td> <td style="text-align: center"><code class="language-plaintext highlighter-rouge">F9 02 EC E9 45 2C 62 BF B3 DB</code></td> </tr> <tr> <td style="text-align: right">3</td> <td style="text-align: center">25.6° - 26%</td> <td style="text-align: center"><code class="language-plaintext highlighter-rouge">F9 02 EC E9 65 2C 62 BF 93 D4</code></td> </tr> </tbody> </table> <table> <thead> <tr> <th style="text-align: right">#4</th> <th style="text-align: center">Display</th> <th style="text-align: center">LSB 0 (reversed nibbles)</th> </tr> </thead> <tbody> <tr> <td style="text-align: right">1</td> <td style="text-align: center">25.4° - 25%</td> <td style="text-align: center"><code class="language-plaintext highlighter-rouge">9F 20 CE 9E 54 C2 25 FB 38 7E</code></td> </tr> <tr> <td style="text-align: right">2</td> <td style="text-align: center">25.4° - 26%</td> <td style="text-align: center"><code class="language-plaintext highlighter-rouge">9F 20 CE 9E 54 C2 26 FB 3B BD</code></td> </tr> <tr> <td style="text-align: right">3</td> <td style="text-align: center">25.6° - 26%</td> <td style="text-align: center"><code class="language-plaintext highlighter-rouge">9F 20 CE 9E 56 C2 26 FB 39 4D</code></td> </tr> </tbody> </table> <p>For the LSB bit numbering a closer look on the values in hex shows already the expected decimal values. The humidity can be found in byte seven (0x25 for 25%) and the temperature is located in bytes five and six. Therefore LSB 0 with reversed nibbles seems to be the appropriate candidate for all further proceedings.</p> <p>The step of working out the correct modulation and bit numbering can be very time consuming because the process only succeeds when at the end a correlation between the byte value and the reference data can be found. This can make several iterations with different parameter combinations necessary.</p> <p>At the end of this process the complete user payload can be decoded which lays the foundation for starting a basic implementation. The transmitted data typically contains more information which can make the implementation simpler or more robust. Examples of this are described in the next section.</p> <h2 id="additional-information-encoded-in-the-payload">Additional information encoded in the payload</h2> <h3 id="header">Header</h3> <p>RF 433 MHz receivers usually perform automatic gain control to adjust the reception level to a suitable value. While this is needed to receive data over longer distances and to support weaker signals, it also increases the noise level and complicates detecting the beginning of a message. Especially because messages are only transmitted rarely in order to save energy. To compensate this effect the messages are usually prefixed by a static pattern. For the exemplary sensor every message starts with 0x9F.</p> <h3 id="distinguishing-sensors">Distinguishing sensors</h3> <p>If the original proprietary receiver supports multiple senders at the same time, the protocol needs to be capable of distinguishing sensors using an ID. The thermo/hygrometer sensor sends its ID in the second byte. The ID changes when the battery is removed or when pushing the sensor’s reset button.</p> <h3 id="checksums-crcs">Checksums (CRCs)</h3> <p>CRCs are used to ensure that the data has been received correctly. Depending on the used algorithms, they not only allow to recognize transmission errors but also in which area of the payload it appeared and in some cases CRCs even allow to recalculate the correct bit value. These criteria makes it interesting trying to reverse engineer the CRCs as well.</p> <p>An indication for a CRC value is a byte that changes as soon as any other bit in the payload changes. For the exemplary sensor, this is true for the last two bytes.</p> <p>The CRC mechanisms being used can be reverse engineered using <a href="https://sourceforge.net/projects/reveng">CRC RevEng</a> by just feeding the tool with some recorded samples.</p> <p>Using the example data from the thermo/hygro sensor to decipher first CRC1 in byte nine and then CRC2 in byte ten outputs the following CRC algorithms that can later be implemented as explained in <a href="https://barrgroup.com/Embedded-Systems/How-To/CRC-Calculation-C-Code">this article</a>.</p> <div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ reveng -w8 -s 9F20CE9E54C225FB38 9F20CE9E54C226FB3B 9F20CE9E56C226FB39 width=8 poly=0x01 init=0x9f refin=false refout=false xorout=0x00 check=0xae name=(none) width=8 poly=0x01 init=0xf9 refin=true refout=true xorout=0x00 check=0xae name=(none) $ reveng -w8 -s 9F20CE9E54C225FB387E 9F20CE9E54C226FB3BBD 9F20CE9E56C226FB394D width=8 poly=0x07 init=0xf9 refin=true refout=true xorout=0x00 check=0x58 name=(none) </code></pre></div></div> <h3 id="sensor-specific-data">Sensor specific data</h3> <p>In addition to the fields mentioned above proprietary RF 433 MHz protocols eventually contain more data. These are highly sensor specific so that there is no general approach for reverse engineering those. The data includes:</p> <ul> <li>Sensor type (for generic protocols supporting different sensor types)</li> <li>Payload length (if sensor sends different message types)</li> <li>Sensor status</li> <li>Battery information</li> <li>Message id (current number of message for repeated transmission)</li> </ul> <h2 id="conclusion">Conclusion</h2> <p>Reverse engineering proprietary RF 433 MHz sensors is possible even with basic knowledge in electronics if the illustrated aspects are taken into account. Especially for a first preliminary implementation not all the protocol details are required and it is often enough to start with only the reference data decoded. More advanced specifics like CRCs can be introduced in a later step or left out completely if the implementation matches the quality criteria.</p> fritzcollectd - A collectd plugin to monitor FRITZ!Box routers 2014-08-23T00:00:00+00:00 https://fetzerch.github.io/2014/08/23/fritzcollectd <p>Recently I set up <a href="https://collectd.org">collectd</a>, <a href="https://graphiteapp.org">graphite</a> and <a href="https://grafana.com">grafana</a> to gather and visualize statistics for the home network.</p> <p>At this, I was particularly interested in monitoring my AVM FRITZ!Box router, especially because I experience some stability problems lately.</p> <p>The router exposes its status information via UPnP and fortunately there was already a Python package available which allows to access the data from Python scripts: <a href="https://github.com/kbr/fritzconnection">fritzconnection</a>. Hence I decided to implement a module that can feed the data into collectd for further processing: <a href="https://github.com/fetzerch/fritzcollectd">fritzcollectd</a>. (see the <a href="https://github.com/fetzerch/fritzcollectd">GitHub page</a> for installation instructions)</p> <p>Since a picture is worth a thousand words, this is how it looks:</p> <p><a href="/assets/fritzcollectd_grafana.png" data-lightbox="fritzcollectd - A collectd plugin to monitor FRITZ!Box routers" title="Grafana screenshot showing data from fritzcollectd"> <img src="/assets/fritzcollectd_grafana.png" alt="Grafana screenshot showing data from fritzcollectd" /> </a></p> <p>This dashboard is accessible on <a href="https://grafana.com/grafana/dashboards/713">Grafana.net</a>.</p> <h2 id="alternatives">Alternatives</h2> <p>At the time of writing, there were mainly two alternative approaches documented that are worth mentioning.</p> <p>At first, there was only a snippet available which is based on a Perl script. Besides the statistics available over UPnP the example also collects additional data scraped from the router’s web interface. Unfortunately even the simple version wasn’t fast enough in my environment to retrieve the data reliably using a 10 second interval.</p> <p>Secondly, if you cannot use Python or Perl plugins it is also possible to use collectd’s <a href="https://github.com/collectd/collectd/wiki/Plugin-cURL-XML-Config#fritzbox-internet-router">cURL-XML</a> plugin to call the respective SOAP actions directly and parse the results with XPath.</p>