Introductionmeteo raspberry

This article describe how to configure Raspberry PI3 with Raspbian+Domoticz to work with a USB weather station.

Well tested weather stations, that works with Raspberry/Domoticz, can be purchased from us (Italy) by clicking on https://store.creasol.it/en/domotics/38-weather-station-for-raspberry.html

Raspberry PI3 is a cheap single-board computer running Raspbian, a Debian GNU/Linux distribution for Raspberry.
Domoticz is a web application designed to control a domotic system.

The middleware weeWX will be used to get data from the USB weather station and generate a XML file with all data, that will be accumulated by Domoticz through a LUA script, and shown in nice graphs.

Information are taken from the following links:
http://www.weewx.com/docs/debian.htm
https://easydomoticz.com/forum/viewtopic.php?t=3623

weeWX installation and configuration

From root prompt on Raspberry, type:

[code]wget -qO - http://weewx.com/keys.html | sudo apt-key add -
wget -qO - http://weewx.com/apt/weewx.list | sudo tee /etc/apt/sources.list.d/weewx.list
apt-get update
mkdir -p /var/www/html/weewx
apt-get install weewx[/code]

The installation script will ask you to insert the location, coordinates, and define the weather station type, in my case Fine Offset USB weather station, model WH1080.

For our purpose, apache2 webserver is not needed, because we just want that weeWX generate a XML file, and don't need to read graphs and pages generated by weeWX.

Now we have to put an extension into the weewx user directory and modify the weewx.conf configuration file:

[code]sed -i "s:self\.archive_interval = self\.engine\.\(.*\):self.archive_interval = software_interval #Creasol - do not set to self.engine.\1 because too long:" /usr/share/weewx/weewx/engine.py
cd /usr/share/weewx/user
wget https://raw.githubusercontent.com/weewx/weewx/master/examples/stats.py
cd /etc/weewx
nano weewx.conf[/code]

 Inside the section [StdReport] you can find the following subsections: [[StandardReport]], [[FTP]] and [[RSYNC]] : after the latter section, before the line ###############################, add the following section:

[[Domoticz]]
skin = Domoticz
[[[Units]]]
[[[[Groups]]]]
group_altitude = meter
group_speed2 = km_per_hour2
group_pressure = mbar
group_rain = mm
group_rainrate = mm_per_hour
group_temperature = degree_C
group_degree_day = degree_C_day
group_speed = km_per_hour

and save with ctrl-x , y , enter.

Now type the following commands:

[code]mkdir skins/Domoticz
echo "[CheetahGenerator]
    encoding = html_entities
    search_list_extensions = user.stats.MyStats

    [[ToDate]]
        [[[Domoticz]]]
            template = domoticz.xml.tmpl

[Generators]
    generator_list = weewx.cheetahgenerator.CheetahGenerator
" >skins/Domoticz/skin.conf

echo '
<weewx>
     <data realtime="temp">$current.outTemp.formatted<!--Outdoor temperature--></data>
     <data realtime="hum">$current.outHumidity.formatted<!--Outdoor humidity--></data>
     <data realtime="inTemp">$current.inTemp.formatted<!--Indoor temperature--></data>
     <data realtime="inHum">$current.inHumidity.formatted<!--Indoor humidity--></data>
     <data realtime="auxTemp">$current.extraTemp1.formatted<!--Aux temperature--></data>
     <data realtime="auxHum">$current.extraHumid1.formatted<!--Aux humidity--></data>
     <data realtime="barometer">$current.barometer.formatted<!--Barometer--></data>
     <data realtime="wind">$current.windSpeed.formatted<!--Wind speed--></data>
     <data realtime="Winddir">$current.windDir.formatted<!--Wind direction--></data>
     <data realtime="Windgust">$current.windGust.formatted<!--Wind gust speed--></data>
     <data realtime="Windcomp">$current.windDir.ordinal_compass<!--Wind compas--></data>
     <data realtime="WindChill">$current.windchill.formatted<!--Windchill--></data>
     <data realtime="rainrate">$current.rainRate.formatted<!--Rain rate--></data>
     <data realtime="Rain">$alltime.rain.sum.formatted<!-- Total rain--></data>
</weewx>
' >skins/Domoticz/domoticz.xml.tmpl
/etc/init.d/weewx restart[/code]

Please note that weather station must be connected to Raspberry, if you want that weewx start! Check /var/log/syslog to look for any errors, for example you can type the command tail -f /var/log/syslog |grep weewx to monitor only the log for weewx excluding all other services.

Domoticz configuration

From the domoticz web panel, select Setup -> Hardware and create a virtual hardware: Enabled: yes, Name: Meteo station, type: Dummy (Does nothing, use for virtual switches only) and click on Add button.
Then, a new line appears in the hardware list above, named Meteo station: click on the Create virtual sensors button to create the following virtual sensors:

  • Name: Meteo outdoor (roof), Sensor Type: Temp+Hum+Baro
  • Name: Meteo indoor (Raspberry room), Sensor Type: Temp+Hum
  • Name: Wind (roof), Sensor Type: Wind
  • Name: Rain, Sensor Type: Rain

Now go to Setup -> Devices and annotate the idx for the newly created sensors

Create the script script_time_weewx.lua into domoticz/scripts/lua directory:

[code]cd /home/pi/domoticz/scripts/lua
nano script_time_weewx.lua[/code]

and put inside the following text:

[code]-- Title: script_device_weewx.lua
-- Date: 2019-02-04
-- Original author: domcars0
-- Modified by: Creasol https://www.creasol.it
-- This script read the xml file generated by weeWX with meteo sensors values
-- More info at https://www.creasol.it/support/domotics-home-automation-and-diy/128-usb-weather-station-connected-to-raspberry-pi-and-domoticz
--  
--      8.5
--      73.2
--      19.5
--      53.2
--      1025.5
--      ......
--  
--
--
commandArray = {} -- reset commandArray, an associative array that will contain the list of commands for Domoticz.

-- ------------------------------- Config --------------------------------

-- DEBUG: comment the following line (-- return) to enable parsing of this file, but first you have to modify the next section!
-- return commandArray

-- MODIFIFY THE FOLLOWING SECTION specifying the idx of each variable that you have created in Domoticz
local debug=0    -- 1=log verbose information. 0=do not log anything
local wind_sensor_name="Wind (roof)"        -- name of wind sensor
local outdoor_device_idx = 43    -- Domoticz idx of outdoor sensors (Temperature+Humidity+Pressure)
local indoor_device_idx = 44    -- Domoticz idx of indoor sensors (Temperature+Humidity)
local wind_device_idx = 45    -- Domoticz idx of wind sensor
local rain_device_idx = 46    -- Domoticz idx of rain sensor
local aux_device_idx = 255    -- Domoticz idx of aux sensors, if available. If not available, specify 255 (to disable it)
local infilename="/var/www/html/weewx/domoticz.xml"    -- set to the local domoticz.xml file generated by weewx
local infileurl="" -- set to "" if weewx file is local
-- local infilename="" -- set to "" if weewx file is downloaded from another website
-- local infileurl="http://www.weewxsite.com/domoticz.xml" -- URL of the file generated by weewx

-- --------------------------- End of Config -----------------------------

local filename = "/tmp/domoticz_converted.xml"
local infile
if (infilename~='') then
    infile=io.open(infilename,"r")
    if (infile~=nil) then
        -- input file exists
        io.close(infile)
        os.execute('sed s:,:.: '..infilename..' |sed s:N/A:0: > '..filename) -- convert file translating , in .
        if (debug==0) then os.remove(infilename) end
    else
        -- input file does not exist: return (waiting that new file will be generated by weewx
        return commandArray
    end
elseif (infileurl~='') then
    -- remote file: should be downloaded using wget, and converted
    
    os.execute('wget '..infileurl..' -O - | sed s:,:.: > '..filename)
end



local line , tempdevice = ''
local temperature,humidity,pressure,inhumidity,intemperature,auxhumidity,auxtemperature,rain,rainrate,wind,winddir,windgust,windchill = 0
local windcomp =  'N'

for line in io.lines(filename) do
   if string.find(line,"\"temp\"") then
      temperature=tonumber(string.match(line, "%-?%d+.?%d*"))
      if (debug) then print('temp='..temperature) end
   elseif string.find(line,"\"hum\"") then
      humidity=tonumber(string.match(line, "%d+"))
      if (debug) then print('humidity='..humidity) end
   elseif string.find(line,"\"inTemp\"") then
      intemperature=tonumber(string.match(line, "%-?%d+.?%d*"))
      if (debug) then print('intemperature='..intemperature) end
   elseif string.find(line,"\"inHum\"") then
      inhumidity=tonumber(string.match(line, "%d+"))
      if (debug) then print('inhumidity='..inhumidity) end
      --[[
   elseif string.find(line,"\"auxTemp\"") then
      auxtemperature=tonumber(string.match(line, "%-?%d+.?%d*"))
      if (debug) then print('auxtemperature='..auxtemperature) end
   elseif string.find(line,"\"auxHum\"") then
      auxhumidity=tonumber(string.match(line, "%d+"))
      if (debug) then print('auxhumidity='..auxhumidity) end
      ]]
   elseif string.find(line,"\"barometer\"") then
      pressure=tonumber(string.match(line, "%d+"))
      if (debug) then print('pressure='..pressure) end
   elseif string.find(line,"\"rainrate\"") then
      rainrate=100 * tonumber(string.match(line, "%d+.?%d*"))
      if (debug) then print('rainrate='..rainrate) end
   elseif string.find(line,"\"Rain\"") then
      rain=tonumber(string.match(line, "%d+.?%d*"))
      if (debug) then print('rain='..rain) end
   elseif string.find(line,"\"wind\"") then
      wind=tonumber(string.match(line, "%d+"))
      if (debug) then print('wind='..wind) end
   elseif string.find(line,"\"Winddir\"") then
      winddir=string.match(line, "%d+")
      if (debug) then print('winddir='..winddir) end
   elseif string.find(line,"\"Windgust\"") then
      windgust=tonumber(string.match(line, "%d+"))
      if (debug) then print('windgust='..windgust) end
   elseif string.find(line,"\"Windcomp\"") then
      windcomp=string.match(line, "Windcomp\">([NESW0]+)<!--")
      if (debug) then print('windcomp='..windcomp) end
   elseif string.find(line,"\"WindChill\"") then
      windchill=tonumber(string.match(line, "%-?%d+.?%d*"))
      if (debug) then print('windchill='..windchill) end
   end
end

--[[
-- Si la vitesse du vent est nulle winddir et windcomp garde la valeur précédente
if ( wind == 0  or wind == nil ) then
        winddir,windcomp = prev_wind:match("([^;]+);([^;]+)")
        wind = 0
end
]]

-- A l'initialisation du device domoticz on peut avoir des valeurs farfelues
if winddir == nil then
        winddir = 0
end
if  windcomp =='0'  then
        windcomp = 'N'
end

if windchill == nil then
        windchill = 0
end

if windgust== nil then
        windgust= 0
end

-- Conversion de win et wingust (domoticz attend 10 * Winspeed [m/s] -- weewx nous donne Winspeed [km/h]
wind = math.ceil(wind / 0.36)
windgust = math.ceil(windgust / 0.36)

-- Raspberry room
if not ( inhumidity == nil or intemperature == nil ) then
        tempdevice = indoor_device_idx..'|0|'..intemperature..';'..inhumidity..';0'
        commandArray[1]={['UpdateDevice'] = tempdevice }
end
-- Outdoor place where Meteo station is placed
if not ( humidity == nil or temperature == nil or pressure == nil ) then
        tempdevice = outdoor_device_idx..'|0|'..temperature..';'..humidity..';0;'..pressure..';0'
        commandArray [2] = {['UpdateDevice'] = tempdevice }
end

-- Rain
if not ( rainrate == nil or rain == nil ) then
        tempdevice = rain_device_idx..'|0|'..rainrate..';'..rain
        commandArray [3] = {['UpdateDevice'] = tempdevice }
end

-- Wind
if not (  temperature == nil ) then
    tempdevice = wind_device_idx..'|0|'..winddir..';'..windcomp..';'..wind..';'..windgust..';'..temperature..';'..windchill
    commandArray [4] = {['UpdateDevice'] = tempdevice }
end

-- Aux sensor, if supported by the weather station
if not ( auxhumidity == nil or auxtemperature == nil or aux_device_idx == 255 ) then
        tempdevice = aux_device_idx..'|0|'..auxtemperature..';'..auxhumidity..';0'
        commandArray [5] = {['UpdateDevice'] = tempdevice }
end
return commandArray[/code]

and edit the first section to specify the right idx of the virtual sensors.

Some pictures

temperature

barometer

rain

wind speed

wind direction

 

Well tested weather stations, that works with Raspberry/Domoticz, can be purchased from us (Italy) by clicking on https://store.creasol.it/en/domotics/38-weather-station-for-raspberry.html

Need help about DomBus protocol and devices? join the DomBus channel on Telegram!

Troubleshooting

weewx does not start?

Check with the command

ps ax|grep weewx |grep -v grep

to see if weewx is active.

If not, from root sheel, type

weewxd

to check for any error executing the weewx daemon.