{"id":2659,"date":"2018-02-26T19:00:55","date_gmt":"2018-02-26T17:00:55","guid":{"rendered":"http:\/\/www.hjgode.de\/wp\/?p=2659"},"modified":"2018-02-27T16:20:47","modified_gmt":"2018-02-27T14:20:47","slug":"fhem-home-automation-remote-display-using-small-oled-and-mqtt","status":"publish","type":"post","link":"http:\/\/www.hjgode.de\/wp\/2018\/02\/26\/fhem-home-automation-remote-display-using-small-oled-and-mqtt\/","title":{"rendered":"FHEM: Home Automation remote display using small OLED and MQTT"},"content":{"rendered":"<p>I wanted to have a small display with some essential Home Automation data. So I buy an 1.3&#8243; OLED display with I2C interface and started to look for some existing code for an ESP8266. The display should be feed using WiFi and be portable, so I can place it where needed.<\/p>\n<p>I started with ESPeasy, as there is already support for multiple pages with text lines. Unfortunately the code is written to show sensor data of directly connected sensor only. No option to publish free text or data from a Home Automation system. The ESPeasy code will save the text to flash memory on every change when using the Web GUI. The flash memory would wear out after some month with my use case.<\/p>\n<p>Finally I decided to start my own code. First I had to find out that the OLED display is not an SD1306 but a SH1106 one. Although some people state that these are more or less the same, the SD1306 libraries did not work for me. Then I found\u00a0https:\/\/github.com\/ThingPulse\/esp8266-oled-ssd1306 which works well for me.<\/p>\n<p>Starting with\u00a0SSD1306UiDemo.ino I added WiFi and MQTT libaries and code.<\/p>\n<p>My code will show 6 lines of text on two frames (3 lines each). The frames will change every 5 seconds. The content of the text lines is published by a FHEM server. As there was no easy way to integrate the display using a MQTT_DEVICE definition in FHEM, I wrote my own perl mqttmsg sub function and used the FHEM notify definition to publish changes to the display.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/github.com\/hjgode\/SH1106_mqtt_display\/blob\/master\/fritzing_mqtt_oled_nodemcu.png?raw=true\" width=\"689\" height=\"386\" \/><\/p>\n<p>a small video<\/p>\n<div style=\"width: 432px;\" class=\"wp-video\"><!--[if lt IE 9]><script>document.createElement('video');<\/script><![endif]-->\n<video class=\"wp-video-shortcode\" id=\"video-2659-1\" width=\"432\" height=\"368\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"http:\/\/www.hjgode.de\/wp\/wp-content\/uploads\/2018\/02\/mqtt_display_2ns.mp4?_=1\" \/><a href=\"http:\/\/www.hjgode.de\/wp\/wp-content\/uploads\/2018\/02\/mqtt_display_2ns.mp4\">http:\/\/www.hjgode.de\/wp\/wp-content\/uploads\/2018\/02\/mqtt_display_2ns.mp4<\/a><\/video><\/div>\n<p><!--more--><\/p>\n<p>The FHEM raw code for one of these notifications is:<\/p>\n<pre style=\"padding-left: 30px;\">defmod nTerrasse notify SD_WS07_TH_2:temperature:.* { mqttmsg (\"display1\/text4\", \"Terrass \". ReadingsVal('SD_WS07_TH_2','temperature', '0').'\u00b0C');;;; }<\/pre>\n<p>The mqttmsg code is inserted in the 99_myUtils.pm FHEM modul file. The MQTT messages are published with retain flag set, so they will persist and immediately published to any subscriber.<\/p>\n<pre style=\"padding-left: 30px;\">package main;\r\nuse strict;\r\nuse warnings;\r\nuse POSIX;\r\nuse Time::Local;\r\n...\r\nsub mqttmsg{\r\n my @args = @_;\r\n my $topic=$args[0];\r\n my $msg=\"\";\r\n my $cnt=scalar @args;\r\n foreach my $i (1..$#args){\r\n    $msg.=\" \".$args[$i];\r\n }\r\n $msg =~ s\/^\\s+|\\s+$\/\/g;\r\n qx(\/usr\/bin\/mosquitto_pub -h 192.168.0.40 -t '$topic' -m '$msg' -q 1 -r);\r\n}\r\n...\r\n1;<\/pre>\n<p>The\u00a0SH1106_mqtt_display.ino code uses 6 separate text variables (and one for the clock text). I know that there are better ways, but that is easy to code and understand:<\/p>\n<pre style=\"padding-left: 30px;\">...\r\nString myText1;\r\nString myText2;\r\nString myText3;\r\nString myText4;\r\nString myText5;\r\nString myText6;\r\nString myClockText;\r\n...\r\nvoid msOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {\r\n display-&gt;setTextAlignment(TEXT_ALIGN_RIGHT);\r\n display-&gt;setFont(ArialMT_Plain_10);\r\n String rssi=\"dbm \";\r\n rssi+=String(WiFi.RSSI());\r\n display-&gt;drawString(128, 0, rssi);\r\n display-&gt;setTextAlignment(TEXT_ALIGN_LEFT);\r\n display-&gt;drawString(0, 0, myClockText);\r\n \r\n}\r\n...\r\nvoid drawFrame2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {\r\n display-&gt;setTextAlignment(TEXT_ALIGN_LEFT);\r\n y*=3;\r\n \/\/display-&gt;setFont(ArialMT_Plain_10);\r\n display-&gt;setFont(myFont);\/\/ArialMT_Plain_16);\r\n \r\n display-&gt;drawString(0 + x, 10 + y, myText1);\/\/ \"Arial 10\");\r\n\r\ndisplay-&gt;drawString(0 + x, 24 + y, myText2);\r\n\r\n\/\/display-&gt;setFont(ArialMT_Plain_24);\r\n display-&gt;drawString(0 + x, 38 + y, myText3);\r\n}\r\n...\r\nvoid callback(char* topic, byte* payload, unsigned int length) {\r\n Serial.print(\"Message arrived [\");\r\n Serial.print(topic);\r\n \r\n Serial.print(\"] \");\r\n display.clear();\r\n String msg;\r\n for (int i = 0; i &lt; length; i++) {\r\n Serial.print((char)payload[i]);\r\n \/\/display.clear();\r\n msg += (char)payload[i];\r\n }\r\n \/\/assign text lines?\r\n String topicS=\"\";\r\n topicS+=topic;\r\n if(topicS.indexOf( \"text1\" )&gt;0)\r\n myText1=msg;\r\n else if(topicS.indexOf( \"text2\" )&gt;0)\r\n myText2=msg;\r\n else if(topicS.indexOf( \"text3\" )&gt;0)\r\n myText3=msg;\r\n else if(topicS.indexOf( \"text4\" )&gt;0)\r\n myText4=msg;\r\n else if(topicS.indexOf( \"text5\" )&gt;0)\r\n myText5=msg;\r\n else if(topicS.indexOf( \"text6\" )&gt;0)\r\n myText6=msg;\r\n else if(topicS.indexOf( \"clock\" )&gt;0)\r\n myClockText=msg;\r\n...\r\n client.publish(\"display1\/ip\", (char*) payload.c_str(), true);\r\n \r\n \/\/ ... and resubscribe\r\n client.subscribe(\"display1\/#\",1);\r\n...<\/pre>\n<p>At the top row the OLED display will show the date and time on the left, updated every minute fro the FHEM server using an &#8216;at&#8217; definition. On the right the top line will show the RSSI of the WiFi signal.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I wanted to have a small display with some essential Home Automation data. So I buy an 1.3&#8243; OLED display with I2C interface and started to look for some existing code for an ESP8266. The display should be feed using WiFi and be portable, so I can place it where needed. I started with ESPeasy, [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[542,411,3],"tags":[549,543,563],"class_list":["post-2659","post","type-post","status-publish","format-standard","hentry","category-fhem","category-linux","category-programming","tag-esp-8266","tag-fhem","tag-mqtt"],"_links":{"self":[{"href":"http:\/\/www.hjgode.de\/wp\/wp-json\/wp\/v2\/posts\/2659"}],"collection":[{"href":"http:\/\/www.hjgode.de\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.hjgode.de\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.hjgode.de\/wp\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/www.hjgode.de\/wp\/wp-json\/wp\/v2\/comments?post=2659"}],"version-history":[{"count":9,"href":"http:\/\/www.hjgode.de\/wp\/wp-json\/wp\/v2\/posts\/2659\/revisions"}],"predecessor-version":[{"id":2674,"href":"http:\/\/www.hjgode.de\/wp\/wp-json\/wp\/v2\/posts\/2659\/revisions\/2674"}],"wp:attachment":[{"href":"http:\/\/www.hjgode.de\/wp\/wp-json\/wp\/v2\/media?parent=2659"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.hjgode.de\/wp\/wp-json\/wp\/v2\/categories?post=2659"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.hjgode.de\/wp\/wp-json\/wp\/v2\/tags?post=2659"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}