Domoticz part 2: WiFi remote thermometer for weather station, dual digit precision – it’s ESP8266 for beginners

Last time we installed Domoticz, and soon we will move to Z-Wave, but first – let’s take a look at fantastic little gadget: ESP8266

What is an ESP8266?

ESP8266 (also called  ESP here) is a SoC – System on a Chip, which in our case is – CPU/RAM/FLASH with GPIO and WiFi interface – so another mini komputer with wireless interface. You can think of it as scaled down version of Raspberry Pi, less power hungry, but with own WLAN and a lot (minimum 2) GPIOs. Ad it runs it’s own WWW server!

  • CPU – 80MHz  (much faster than Arduino, much slower than Pi)
  • RAM – 64kB for instructions and 96kB
  • ROM – 64kB (just for boot)
  • FLASH: 4Mb (512kB)
  • WLAN: radio 2,4GHz – 802.11 b/g/n with WPA2
  • Power: 3,3V (just what we have available using PIN 1 in Raspbery Pi)
  • Interpreter and LUA compiler (sic!). Or pure C using Arduino IDE
  • Price: $3. Yes. 3 US dollars

The SoC’s manufacturer is Espressif, other companies produce ready boards with interfaces and antennas:

    • ESP-01 (v1 and v2) – you get pins for +3,3V, GND, TX,RX and GPIO 0 i GPIO 2 (they spawn pull-up). WiFi antenna is printed on the module. Very popular due to price, best for beginners – it’s easy to connect it to Pi
    • ESP-03 – we get 8x GPIO
    • ESP-12 – SoC with shielding, better antenna and 10x GPIO

But why?

Let’s summarize: we have a possibility to use two or more GPIOs on WiFi enabled device, using very little power (10x less than RPi) – ideal for a weather station sensor. We can write a small program that would update the values in Domoticz (i.e. sensors) – because we can not only use the internal Web server but also sent periodically data to Domoticz – using nodejs or JSON format URL that Domoticz understands well. The latter is much more stable – and it’s great for starters.
It’s decided then! We’re building remote thermometer – based on ready examples.


  • Raspberry Pi (any model – A, B, B+, 2 or 3 or even Pi Zero)

    Raspberyy Pi B+
    Raspberyy Pi B+
  • ESP8266 (any version, the best for start is ESP-01 with two GPIOs)

    ESP-8266 01 PINout
    ESP-8266 01 PINout
  • Dallas DS18b20 Thermometr – we can get chip or waterproof versions

    Dallas ds18b20 thermometr
    Dallas ds18b20 thermometer
  • 4,7k resistor – allows good readout from thermometer (pulls-up the DATA PIN), but if you are not getting results – change it to 2,2k:
    Rezystor 4,7k
  • OPTIONAL: Step-down module which will provide stable 3,3V out of input 5V (just make a search on your favorite portal for: step-down 3.3V)
  • OPTIONAL: One or two Li-Ion type 18650 batteries – you can extract them from old notebook battery packs or power banks – but be carefull when disasembling the pack – 18650 are very dangerous when short or punctured! It could also cell phone battery – any Li-Ion that you can easily set-up. Fully charged battery is about max 4,2V and total capacity of around 2300mAh-2500mAh
  • OPTIONAL: charging module for working at 5V to properly charge and protect Li-Ion battery – it has USB and micro-USB connectors for input and output and soldiering pads for 18650. Check on how you can attach 18650 (be extra careful when soldering!)

    Regulator i zasilacz dla baterii Li-Ion
    Charging module for Li-Ion batteries

Connecting the ESP8266 module and updating the firmware

The ESP8266 has a standard UART – with TX,RX PINs, 3V logic – and it’s great since we can use the Raspberry Pi as a console!. In my optionion this is the best way to deal with this module. Our Raspberry Pi UART port is by default used as RPi own system console, so we have to free it to use as communications channel to ESP8266. To do that we have to delete in /boot/cmdline.txt this part: console=/dev/ttyAMA0,115000. Now let’s reboot RPi.
We should install now:

Raspberry Pi + ESP8266
Raspberry Pi with ESP8266 connected

Since ESP8266 is often used as Arduino module it comes to us with a firmware that uses AT commands – just like modems do. We will use the NodeMCU firmware – that uses LUA intereter/compiler – another very nice BASIC-like type of software (very powerfull!). At the time of writting we had: nodemcu_integer_0.9.6-dev_20150704.bin version available with the tool – Let’s hook up the ESP8266 to Raspberry Pi:

  • We will be using 3,3V as VCC form RPi: +3,3V connecting to VCC and CH_PD on ESP (look at the picture). Now it’s not recommended for a longer period, because ESP8266 can draw 3x more than 3,3V PIN on RPi can support!
  • GND from RPi to GND at ESP
  • PIN 13 on RPi to TX on ESP, and PIN 14 on RPi to RX on ESP
  • Additionaly, we have to connect GPIO 0 to GND on ESP-01, to allow firmware upgrade (and re-power ESP after connecting). Upgrading is as easy as this:

Installing proper serial support library for python:

sudo apt-get install python-serial

Updating the firmware:

python -p /dev/ttyAMA0 write_flash 0x000000 nodemcu_integer_0.9.6-dev_20150704.bin

If GPIO0 is NOT connected to GND you will see this error:

pi@raspberrypi ~/esp8266 $ python -p /dev/ttyAMA0 write_flash 0x000000 nodemcu_integer_0.9.6-dev_20150704.bin
Traceback (most recent call last):
  File "", line 353, in 
  File "", line 138, in connect
    raise Exception('Failed to connect')
Exception: Failed to connect

If GPIO0 is connected to GND and re-powering of the ESP unit – firmware will be upgraded:

python -p /dev/ttyAMA0 write_flash 0x000000 nodemcu_integer_0.9.6-dev_20150704.bin
Erasing flash...
Writing at 0x00005800... (5 %)
Writing at 0x00031800... (45 %)
Writing at 0x00057c00... (80 %)
Writing at 0x0006dc00... (100 %)


After successful upgrade we should get to know our new toy. To do that we need serial console -let’s install picocom and enter:

picocom -b 9600 --omap crcrlf /dev/ttyAMA0

We can see the “>” prompt, so if you already know LUA you can start testing or use: official examples form NodeMCU..
First, let’s get IP address via WiFi, enter the commands line per line:


You need to change the SSID and password to correct values for your home network – and ESP will connec to Access Point and will ask for IP address via DHCP client. Great, we have IP address now. Now, let’s connect the Dallas DS18b20. It’s a very cheap sensor, that is supported by NodeMCU example – download from the module library the file : ds18b20.lua.
But we need changes, since we will get only single digit precision in Celsius mode – find the line:

 t = t / 10000

and replace with:

 t = t / 100

Double digit precision is ready! Changed file looks like this:

-- DS18B20 one wire module for NODEMCU
-- Vowstar <>
-- 2015/02/14 sza2 <> Fix for negative values

-- Set module name as parameter of require
local modname = ...
local M = {}
_G[modname] = M
-- Local used variables
-- DS18B20 dq pin
local pin = nil
-- DS18B20 default pin
local defaultPin = 9
-- Local used modules
-- Table module
local table = table
-- String module
local string = string
-- One wire module
local ow = ow
-- Timer module
local tmr = tmr
-- Limited to local environment
-- Implementation
C = 0
F = 1
K = 2
function setup(dq)
  pin = dq
  if(pin == nil) then
    pin = defaultPin

function addrs()
  tbl = {}
    addr =
    if(addr ~= nil) then
      table.insert(tbl, addr)
  until (addr == nil)
  return tbl

function readNumber(addr, unit)
  result = nil
  flag = false
  if(addr == nil) then
    count = 0
      count = count + 1
      addr =
    until((addr ~= nil) or (count > 100))
  if(addr == nil) then
    return result
  crc = ow.crc8(string.sub(addr,1,7))
  if (crc == addr:byte(8)) then
    if ((addr:byte(1) == 0x10) or (addr:byte(1) == 0x28)) then
      -- print("Device is a DS18S20 family device.")
      ow.reset(pin), addr)
      ow.write(pin, 0x44, 1)
      -- tmr.delay(1000000)
      present = ow.reset(pin), addr)
      -- print("P="..present)
      data = nil
      data = string.char(
      for i = 1, 8 do
        data = data .. string.char(
      -- print(data:byte(1,9))
      crc = ow.crc8(string.sub(data,1,8))
      -- print("CRC="..crc)
      if (crc == data:byte(9)) then
        t = (data:byte(1) + data:byte(2) * 256)
        if (t > 32767) then
          t = t - 65536
        if(unit == nil or unit == C) then
          t = t * 625
        elseif(unit == F) then
          t = t * 1125 + 320000
        elseif(unit == K) then
          t = t * 625 + 2731500
          return nil
        t = t / 100
        -- print("Temperature="..t1.."."..t2.." Centigrade")
        -- result = t1.."."..t2
        return t
    -- print("Device family is not recognized.")
  -- print("CRC is not valid!")
  return result

function read(addr, unit)
  t = readNumber(addr, unit)
  if (t == nil) then
    return nil
    return t

-- Return module table
return M

Save it for later – we will upload this to ESP in a moment- first let’s see how to autostart programs on ESP

Autostarting programs on ESP8266


ESP8266 with NodeMCU firmware after booting executes the init.lua, which is residing on the flash. It is extremely important that init.lua is TESTED and won’t put the ESP in boot-loop. We all heard horror stories about bad loop that executes indefinitely. Rule of a thumb – our init.lua should be short, minimal. In our case – let’s just get IP address and run the domoticz.lua which will report the temperature back to domoticz. Also – let’s try to have a backup WiFi in case we cannot connect with main – we can use the second WiFi network for debug purposes. Another important part of init.lua is the pause. Before getting/asking for IP address we should have enough time to issue a command to delete the init.lua file, so we can replace it in case no WiFi network is available. Our init.lua should look like this example:

 wifi.setmode (wifi.STATION)
 wifi.sta.config("MAIN SSID 1","extra_secret_no_1")
 tmr.alarm(1, 6000, 1, function()
  if wifi.sta.getip()== nil then
  print("No IP address, trying again...")
  wifi.sta.config("BACKUP SSID","other_secret_pass")
 print("WiFi mode ESP8266: " .. wifi.getmode())
 print("MAC address ESP8266: " .. wifi.ap.getmac())
 print("Success, IP is: "..wifi.sta.getip())
 dofile ("domoticz.lua")

This init.lua changes ESP mode into AP client (ESP is also used as AP), sets the SSID, password and issues command to connect to home AP. Next – after 6000ms we check if wifi.sta.getip() returns something else than “nil” (nothing). If not – we move to configure backup network and we repeat that every 6000ms until ESP gets IP address. This 6000ms is here to login via serial console and delete the init.lua if we do not have any WiFi network. But if all goes well – ESP runs via  dofile, another script that does the readout of temperature and sends it to domoticz – it’s called:  domoticz.lua

Main temperature readout program, sending data to domoticz

gpio0 =3
gpio2 =4
print("RAW output from ds28b20:" .. t .. " C\n")
if(t==nil) then
tmr.alarm(0,240000, 1, function()
 temp=tpre .. "." .. tsub
 print("Sent temperature:" .. temp .. " C\n")
 conn=net.createConnection(net.TCP, 0)
 conn:on("receive", function(conn, payload) print(payload) end )
 conn:send("GET /json.htm?type=command¶m=udevice&idx=11&nvalue=0&svalue=" .. temp .. " HTTP/1.1\r\nHost: thermometer.sheed\r\n".."Connection: keep-alive\r\nAccept: */*\r\n\r\n")

This main program/script has the following structure; first it includes the attached previously library from NodeMCU (with the slight modification – remember?). Next it changes the GPIOs to allow for temperature readout in the Dallas mode – using GPIO2. For debugging we display both raw readout to check if we got 4 digits. This is the hack that allows for spliting the data into XY.ZW format and constructs simple HTTP request in JSON to send to domoticza, which has IP of and port 8080. Since we need a virtual sensor – we need to set proper IDX here, so the data land in proper place. Now – test and wait for negative temperatures to see what’s going to happen. Check the comments section to find out for an alternative version. Let’s put those file on ESP8266’s flash.

Uploading files to ESP8266

Thanks to another python program, that we downloaded – we can quickly put files onto ESP8266 – using

python -p /dev/ttyAMA0 --src init.lua --dest init.lua
python -p /dev/ttyAMA0 --src domoticz.lua --dest domoticz.lua
python -p /dev/ttyAMA0 --src ds18b20.lua --dest ds18b20.lua

Since we already connected via picocom, will just work. It’s a good idea to test init.lua NOW because we can later end up in a loop.

OPTIONAL: Powering via solar module with battery backup

As we said before the RPi is not a perfect way to power ESP, because it cannot sustain it (too much mAps are drawn). And more importantly – this is a remote temp sensor, so it should be in WiFi range but not next to RPi. Let’s build our solar powered system:

  • one, two or three Li-Ion type 18650 battery
  • integrated charge controller from power bank with 5V input
  • step down module with output of 500mA max 3,3V
  • solar panel of 5V and 400mAp
  • WARNING: Do not use if temperature is OUTSIDE the 18650 spec, this can be dangerous! Do not use the 18650 battery if any parameter is out of it’s spec.

Solar panel should be mounted on some pice of plastic and secured with glue to allow operation in different weather conditions. The perfect angle towards sun is 45 degrees.

Panel fotowoltaniczny 5V, zamontowany na pleksi
Photovoltanic panel, rated 5V, 400mAp

Gluing the panel (I know – lousy job here…):

Tył panelu fotowoltanicznego
Tył panelu fotowoltanicznego

And then we connect it to power back charge controller via USB:

ESP8266 na NodeMCU Amica Board z zasilaniem bateryjnym oraz czujnikiem DHT22
ESP8266 with NodeMCU on Amica Boardwith battery power and DHT22 sensor

Above you can see the next version of this project – moving to more advanced firmware and hardware – the ESPEasy on ESP-12E using Amica Board with +5V VCC.

OpenVPN Raspberry Pi – split-tunnel with Internet access

Would you like to connect from any place, usually using open WiFi network in town, at friends or airport – with your’re own home network? Virtual Private Network (VPN) is here to allow you to log-in securely to your home network, with additional perk of using it to get secure Internet access.

Raspberyy Pi B+
Raspberyy Pi B+

What will you need?


  • Rapberry Pi (A, A+ or B, B+, 2, Zero)
  • Home Router with Port Forwarding or Virtual Server support – any will do


  • Raspbian – standard Linux distribution for Raspberry Pi
  • OpenVPN – free OpenVPN server
  • OpenVPN – clients – different for Linux, Android, MS Windows etc.

As you see nothing fancy.


Let’s talk about how we should secure our access:

  • physical access to your Raspberry Pi should be controlled (only you)
  • access to /etc should be restricted to the user that OpenVPN is running under
  • the files with .key are TOTALLY SECRET
  • the certificate .crt or .crs – are to be sent, lost, revoked – could be always renewed.
  • each device connecting to OpenVPN server (PC, tablet, smartphone) has it’s own key/certificate pair

Let’s do it

Well, as always the first thing is to update out RPi – let’s login via ssh or console:

sudo apt-get update && sudo apt-get upgrade

Now, lets install OpenVPN package:
sudo apt-get install openvpn

All commands used require root privileges, so I suggest to enter:
sudo su -

Next we should configure the server, first to generate SSL certificates, that allow securing of the connection and also – authentication.
All files should be stored in /etc, let’s create appropriate folder and copy over the example files to create certs, which reside in Raspbianie Wheezy here:
cd /etc/openvpn
mkdir easy-rsa
cp -R /usr/share/doc/openvpn/examples/easy-rsa/2.0/* easy-rsa/

If you’re on the newer Jessie, as noted in comments by Dom/OloX – folder with examples is located in /usr/share:
cd /etc/openvpn
mkdir easy-rsa
cp -R /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/

Examples provided by easy-rsa package default to USA based data. Wait, what ? It’s all about the fact that the certificate has to have identification – who’s the authority that issued it. Since it’s going to be ours – we should put some familiar data here to identify it later.

Let’s edit the file ( or accept the fact that all certificates are from San Francisco…):

sudo nano /etc/openvpn/easy-rsa/vars

The changes are about the folder where we store the certs and keys, length of the asymetrical key – it’s usually1024 – but 2048 might be too much from RPi 1, or even 2 or 3. Let’s use the value of 1024:
export EASY_RSA=”/etc/openvpn/easy-rsa”
export KEY_SIZE=1024
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_CN=SerwerOVPN

Country code – PL,  county/voivodeship: WA and so on – use what you like or don’t, but the KEY_CN – this should be changed.
Let’s prepare to create the keys:
cd /etc/openvpn/easy-rsa
touch keys/index.txt
echo 01 > keys/serial
. ./vars  # set environment variables

Now we will build a certificate authority::

All you need to do is to confirm values previously entered in vars:
Generating a 1024 bit RSA private key
writing new private key to 'ca.key'
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [PL]

The folder keys will now have ca.key and ca.cert.

Now, important port – generating the key to our system:

./build-key-server server

We will be asked to provide password. STOP. OK, enter a password – but then you will also have to enter it with each connection. We can remove the password and lower our security – the choice is yours!
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:

Answer yes to remaining questions and you will get in folder keys new files: server.crt and server.key in (/etc/openvpn/easy-rsa/keys/), they will be signed with your root certificate.
Now let’s build the Diffie-Hellmann parameters required for client and server to talk to each other. The process is quite interesting – check out 

This produces 1024.pem file, change the name to dh1024.pem
Now lets build the pairs – files – for a client:
./build-key client1

…along with the password:
./build-key-pass client1

That’s nearly the end – now let’s generate common HMAC key for TLS:
openvpn --genkey --secret /etc/openvpn/easy-rsa/keys/tls.key

Let’s copy all the files /etc/openvpn/mykeys/
cd /etc/openvpn/easy-rsa/keys
mkdir -p /etc/openvpn/mykeys
cp dh1024.pem /etc/openvpn/mojeklucze
cp ca.crt /etc/openvpn/mojeklucze
cp server.crt /etc/openvpn/mojeklucze
cp server.key /etc/openvpn/mojeklucze
cp tls.key /etc/openvpn/mojeklucze

It’s time to configure our OpenVPN server using certificates and keys.
First create the /etc/openvpn/openvpn.conf file with following entries:
push "redirect-gateway"
push "dhcp-option DNS"
push "dhcp-option DNS"
dev tun
verb 5
proto udp
keepalive 10 120
port 1194
dh /etc/openvpn/mykeys/dh1024.pem
ca /etc/openvpn/mykeys/ca.crt
cert /etc/openvpn/mykeys/server.crt
key /etc/openvpn/mykeys/server.key

user nobody
group nogroup

status /var/log/openvpn-status.log
verb 3
log-append /var/log/openvpn

The configuration of the server will get all the traffic coming from it (apart from static routes on the client – accessing the other LAN) and steer it to tunnel. Thanks to this we will also have Internet access through our tunnel and VPN (but check below!). The resolvers for DNS operation – let’s use Google and our local as secondary. The important line is ‘server’ this creates a network used only for the actual connection – so use private network you don’t use anywhere. The port is 1194 – we will have to reconfigure our home router for connection – see below for Port Forwading options. The protocol used is UDP.

Port forwarding

The forwarding of the public port from your router to private port on Raspberry Pi is quite easy to configure:

Port Forwarding - Linksys
Port Forwarding – Linksys
Port Forwarding - D-Link DIR
Port Forwarding – D-Link DIR
Port Forwarding - Archer VR900
Port Forwarding – Archer VR900
Port Forwarding - TP-Link
Port Forwarding – TP-Link
Port Forwarding - TP-Link
Port Forwarding – TP-Link

Split-tunnel – safe access to Internet by means of VPN

To allow split-tunnel – we need to add configuration at the end of the /etc/rc.local file.
Do mind that you need to change the example RPi address of to yours, and as mentioned above – choose unused VPN – here:

The file should have following lines:

echo "Enabling routing for proper VPN operation..."
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "Remote port mapping for VPN service..."
iptables -t nat -A INPUT -i eth0 -p udp -m udp --dport 1194 -j ACCEPT
echo "SNAT of the VPN addresses to allow split-tunneling..."
iptables -t nat -A POSTROUTING -s -o eth0 -j SNAT --to-source

exit 0


Let’s configure the client – first mobile devices – Android. Download the OpenVPN (check for fakes!) and after installing – it’s going to ask for .ovpn file. Let’s create it, don’t forget to change the IP_ADDRESS_OR_FQDN_OF_THE_SERVER to your OpenVPN server.

Back to console of your Raspberry Pi:

cd /etc/openvpn/mojeklucze/
echo "client" > client.ovpn
echo "verb 4" >> client.ovpn
echo "dev tun" >> client.ovpn
echo "connect-retry-max 5" >> client.ovpn
echo "connect-retry 5" >> client.ovpn
echo "resolv-retry infinite" >> client.ovpn
echo "proto udp" >> client.ovpn
echo "remote IP_ADDRESS_OR_FQDN_OF_THE_SERVER 1194" >> client.ovpn
echo "nobind" >> client.ovpn
echo "persist-key" >> client.ovpn
echo "persist-tun" >> client.ovpn
echo "keepalive 10 900" >> client.ovpn
echo "inactive 3600" >> client.ovpn
echo "set CLIENT_CERT 0" >> client.ovpn
echo "<ca>;" >> client.ovpn
cat ca.crt | grep -A 100 "BEGIN CERTIFICATE" | grep -B 100 "END CERTIFICATE" >> client.ovpn
echo "</ca>" >> client.ovpn
echo "<cert>" >> client.ovpn
cat client1.crt | grep -A 100 "BEGIN CERTIFICATE" | grep -B 100 "END CERTIFICATE" >> client.ovpn
echo "</cert>" >> client.ovpn
echo "<key>" >> client.ovpn
cat client1.key | grep -A 100 "BEGIN PRIVATE KEY" | grep -B 100 "END PRIVATE KEY" >> client.ovpn
echo "</key>" >> client.ovpn

We got – client.ovpn. Rewiev the file, change: proto to udp, remote – IP address – to our public router address (or name if we have Dynamic DNS service), and enter the IP addresses into server line. Remove any ca cert key references to the files if they exist in imported example. The ready file goes to Android device – import, run connect and there it is!. Do mind that for mobile devices (i.e. Android/iOS- OpenVPN Connect requires the certificates to be embedded in the *.ovpn file!

Domoticz part 1: Relays, magnetic sensors, Wake-on-LAN and Z-Wave – Domoticz with Imperi Home serving your house

Domoticz on PI with relay
Domoticz on PI with relay

This entry was initially about single and simple purpose: how to quickly develop a solution that would open gate or garadge door by simulating the remote’s operation mode – pressing a button – but using smartphone, tablet, web browser, app. Domoticz is such an overkill and also blessing for such project – that it evolved into a lot of small sub-projects – more or less andvanced.

Direct inspiration was another entry by colleague on  MalinowePi Facebook group – Roman Kubat, who showed ImperiHome. This application has great interface but does not support press-type (dorbell) buttons. Hence the whole idea!

Continue reading Domoticz part 1: Relays, magnetic sensors, Wake-on-LAN and Z-Wave – Domoticz with Imperi Home serving your house