Bash: get current weather data

226 views
Skip to first unread message

Ramesh Rasappan

unread,
Oct 3, 2019, 10:01:58 AM10/3/19
to weewx-user

My current setup pulls weather data from Offset console using weewx-wh23xx driver. I want to run a bash script that can get the current weather and send me a notification if it meets the criteria.


I could probably get the weather data directly from PWS console using weewx-wh23xx driver but I can't figure out this!! Of course one could use sqlite3 to pull the data from either weewx database (/var/lib/weewx/weewx.sdb) but it looks complicated for me that I have to run some complex script to retrieve the current data!


Can you share some script that can pull the current data from either weewx database or from the console? thank you



Thomas Keffer

unread,
Oct 3, 2019, 10:54:58 AM10/3/19
to weewx-user
Have you looked at the "alarm" example? It is included in the "examples" subdirectory. Documentation in the Customizing Guide.

--
You received this message because you are subscribed to the Google Groups "weewx-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to weewx-user+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/weewx-user/47ab7379-e50b-4309-a2ce-ba1857a6cbd6%40googlegroups.com.

Pila

unread,
Oct 4, 2019, 7:49:09 AM10/4/19
to weewx...@googlegroups.com
If you really want notification, it can generate email.

I use data to close shutters if it rains from the west half. I simply parse generated page and extract data I need. All from shell script. 5 lines of code to extract 8 variables. My Zero jest closed shutters since it was sunset.
--
Poslano sa mog Android uređaja sa K-9 Mail. Molim vas oprostite na mojoj sažetosti.

Ramesh Rasappan

unread,
Oct 5, 2019, 12:32:10 PM10/5/19
to weewx-user
Thanks Thomas, the documentation says; place the python files under "user" directory, also one can find examples of python script under examples folder! But where are these user and examples folders? I don't find them under /var/www/html/weex, not under /var/lib/weewx also not under /etc/weewx/

So where to place the python script?


On Thursday, October 3, 2019 at 8:24:58 PM UTC+5:30, Thomas Keffer wrote:
Have you looked at the "alarm" example? It is included in the "examples" subdirectory. Documentation in the Customizing Guide.

On Thu, Oct 3, 2019 at 7:02 AM Ramesh Rasappan <prra...@gmail.com> wrote:

My current setup pulls weather data from Offset console using weewx-wh23xx driver. I want to run a bash script that can get the current weather and send me a notification if it meets the criteria.


I could probably get the weather data directly from PWS console using weewx-wh23xx driver but I can't figure out this!! Of course one could use sqlite3 to pull the data from either weewx database (/var/lib/weewx/weewx.sdb) but it looks complicated for me that I have to run some complex script to retrieve the current data!


Can you share some script that can pull the current data from either weewx database or from the console? thank you



--
You received this message because you are subscribed to the Google Groups "weewx-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to weewx...@googlegroups.com.

Ramesh Rasappan

unread,
Oct 5, 2019, 12:34:06 PM10/5/19
to weewx-user
do you parse the html page? could you please share the shell script? thanks

gjr80

unread,
Oct 5, 2019, 4:23:20 PM10/5/19
to weewx-user
As usual the documentation is your friend. Have a look at the ‘Where to find things’ section (http://weewx.com/docs/usersguide.htm#Where_to_find_things) in the User’s Guide.

Gary

RobbH

unread,
Oct 5, 2019, 5:03:39 PM10/5/19
to weewx-user
Is archive data adequate for your needs? (Typically updates every five minutes, although you can set the archive period to something else.) Or do you need to use loop data, which is nearly real-time?

If archive data will work, the simplest (not necessarily best) way to do what you ask is to add a simple template for a plain text file to the active skin, specifying the data you want. Then your Bash script simply reads the file after every archive period, like so:

newdata=$(cat <filename>)

If you need loop data, it's a bit more complicated.

Pila

unread,
Oct 7, 2019, 8:52:01 AM10/7/19
to weewx...@googlegroups.com
If you really want just to send a notification, use alarm.Py.

If you want to base automation on this data, I can provide example how I did it. But you would still need to solve sending e-mails on your own since my RPI Zero uses my router to do so.
Message has been deleted

Ramesh Rasappan

unread,
Oct 8, 2019, 12:25:25 PM10/8/19
to weewx-user

@Pilla, although I got it working (see above), I am still interested to see your script! maybe you are handling it in a better way! (you could send it to me: chittukuruvii  at.   gmail)

Ramesh Rasappan

unread,
Oct 8, 2019, 12:30:38 PM10/8/19
to weewx-user

thank you all, I got it working in a couple of ways; i. use in-built alarm.py ii. install extension crt: Cumulus Real-Time to get real-time data and parse it with a bash script. I am sharing here my work (could be useful for some noob like me!).


My earlier post got deleted where I did share my bash script and installation guidelines

Pila

unread,
Oct 8, 2019, 4:06:08 PM10/8/19
to weewx...@googlegroups.com
You still did not say do you really need only notification or want something done based on that data!

My Zero today took the sunset time and external temperature directly from WeeWX report, and since it was less than 15C, closed shutters, emailed us and logged that fact.

Did not need alarm.Py, no extensions, no Home automation server, no Node-Red, no MQTT. All in my tiny script. Plus of course WeeWX.

In the morning (after the sunrise), when it gets over 18C, it will open shutters. Unless it rains, of course.

If you need something like that, I can help.

Ramesh Rasappan

unread,
Oct 8, 2019, 10:47:27 PM10/8/19
to weewx-user
Based on the data, I want to get a few works done. At the moment, I have a couple of job running and the third one is planned.

i. Bash: executes audio warning when the heat index goes beyond certain value (my place gets too hot with high humidity)
ii. Bash: push email notification when there is heavy wind or rain
iii. Bash: this is yet to be done: When the temperature difference (outdoor vs indoor) exceeds 5 degrees (oC) during the night then my bedroom AC turns on (although a window is always open for airflow, still the room gets hotter than outside)

Is there any skin that has an interactive graph? at the moment what I see is just an image graph.

This is my bash script

#!/bin/bash

var=$(cat /var/www/html/PWS/realtime.txt)
vars=( $var )
MPHR=60    # Minutes per hour.
current_time=$(date +%s)
#echo "Temperature: '${vars[2]}'"
#echo "Heat index: '${vars[41]}'"
#echo "Wind speed: '${vars[5]}'"
#echo "Rain rate: '${vars[8]}'"
#echo "Rain fall: '${vars[9]}'"
heat_index=${vars[41]%.*} #convert into integer
if (("$heat_index" > 32 && "$heat_index" < 39))
then
last_run=$(cat /home/pi/bin/announcements/heat_index_1)
last_run_minutes=$(( ($current_time - $last_run) / $MPHR ))
if (("$last_run_minutes" > 60))
then
/home/pi/bin/relay_on_off on
/bin/sleep 1
/usr/bin/omxplayer -o local /home/pi/Music/announcement.mp3
/usr/bin/espeak -s 150 -g 30mS blablabla
/home/pi/bin/relay_on_off off
echo "Heat index: '${vars[41]}'"
/bin/date +%s > /home/pi/bin/announcements/heat_index_1
else
echo "Ran less than $last_run_minutes minutes"
fi
elif (("$heat_index" > 38 && "$heat_index" < 45))
then
last_run=$(cat /home/pi/bin/announcements/heat_index_2)
last_run_minutes=$(( ($current_time - $last_run) / $MPHR ))
if (("$last_run_minutes" > 30))
then
/home/pi/bin/relay_on_off on
/bin/sleep 1
/usr/bin/espeak xxxxxxxxxxxx
/home/pi/bin/relay_on_off off
echo "Heat index: '${vars[41]}'"
/bin/date +%s > /home/pi/bin/announcements/heat_index_2
else
echo "Ran less than $last_run_minutes minutes"
fi
elif (("$heat_index" > 45))
then
last_run=$(cat /home/pi/bin/announcements/heat_index_3)
last_run_minutes=$(( ($current_time - $last_run) / $MPHR ))
if (("$last_run_minutes" > 15))
then
/home/pi/bin/relay_on_off on
/bin/sleep 1
/usr/bin/espeak xxxxxxxxxxx
/home/pi/bin/relay_on_off off
echo "Heat index: '${vars[41]}'"
/bin/date +%s > /home/pi/bin/announcements/heat_index_3
else
echo "Ran less than $last_run_minutes minutes"
fi
else
true
fi
rain_rate=${vars[8]%.*} #convert into integer
if (("$rain_rate" > 1 && "$heat_index" < 2))
then
last_run=$(cat /home/pi/bin/announcements/rain_rate_1)
last_run_minutes=$(( ($current_time - $last_run) / $MPHR ))
if (("$last_run_minutes" > 60))
then
printf "Subject: Light Rain $rain_rate at MIR\n\nIt's raining" | ssmtp email
/bin/date +%s > /home/pi/bin/announcements/rain_rate_1
else
echo "Ran less than $last_run_minutes minutes"
fi
elif (("$rain_rate" > 2 && "$heat_index" < 7))
then
last_run=$(cat /home/pi/bin/announcements/rain_rate_2)
last_run_minutes=$(( ($current_time - $last_run) / $MPHR ))
if (("$last_run_minutes" > 30))
then
printf "Subject: Moderate Rain $rain_rate at MIR\n\nIt's raining" | ssmtp email
/bin/date +%s > /home/pi/bin/announcements/rain_rate_2
else
echo "Ran less than $last_run_minutes minutes"
fi
elif (("$rain_rate" > 7 && "$heat_index" < 20))
then
last_run=$(cat /home/pi/bin/announcements/rain_rate_3)
last_run_minutes=$(( ($current_time - $last_run) / $MPHR ))
if (("$last_run_minutes" > 15))
then
printf "Subject: Heavy Rain $rain_rate at MIR\n\nIt's raining" | ssmtp email
/bin/date +%s > /home/pi/bin/announcements/rain_rate_3
else
echo "Ran less than $last_run_minutes minutes"
fi
elif (("$rain_rate" > 20))
then
last_run=$(cat /home/pi/bin/announcements/rain_rate_4)
last_run_minutes=$(( ($current_time - $last_run) / $MPHR ))
if (("$last_run_minutes" > 15))
then
printf "Subject: Violent Rain $rain_rate at MIR\n\nIt's raining" | ssmtp email
/bin/date +%s > /home/pi/bin/announcements/rain_rate_4
else
echo "Ran less than $last_run_minutes minutes"
fi
else
true
fi

Pila

unread,
Oct 10, 2019, 3:08:24 AM10/10/19
to weewx-user
If your code works well, than all is well. If I may offer advice: whenever you have repeated code, separate it into a funciton. When testing, one test must include >= or <= e.g. if heat_index is 45, nothing will get done. If rain is 0,9 or lower, it will be ignored. As lazy as I am, I hate criptic things like '${vars[41]}'. Luckily, your script does not need complex logic but a simple stright flow of not multiply correlated rules.

You may find it usefull how parsing WeeWX variables is done in my script. My parsing directly produces integers when needed, fixes the above problem with the rain below 0,99 being ignored plus leaves items which should be left alone. I will mostly not translate Croatian words to avoid creating mistakes, but that should not present a problem.

I did manual install of WeeWX to RPi Zero and use RPi Zero as a root user, so paths and rights may need to be adjusted for others. Most will say it is impossible to set bash variables from awk, but I do not care. Nor about comments on eval. Nor about using root account on Zero. Such comments are not how security is assured.

1) prepare a WeeWX report we will be parsing. I modified this file, but can be any skin:

/home/weewx/skins/Seasons/skin.conf

and added there
    [[VremStanica]]
        encoding
= strict_ascii
       
template = VremStanica.txt.tmpl

then I created the file:
/home/weewx/skins/Seasons/VremStanica.txt.tmpl

and placed into it data I want extracted from WeeWX; adjust as needed. Name in the first colument will automatically become the variable name in the script. Note raw (epoch) times and lack of labels. It simplifes parsing when labels are stuck to the numbers.

Time        $current.dateTime.raw
InTemp      $current.inTemp.format(add_label=False)
OutTemp     $current.outTemp.format(add_label=False)
Dewpoint    $current.dewpoint.format(add_label=False)
Humidity    $current.outHumidity.format(add_label=False)
WindSpeed   $current.windSpeed
WindCardinal    $current.windDir.ordinal_compass
WindDirection    $current.windDir
RainRate    $current.rainRate.format(add_label=False)
Sunrise     $almanac.sun.rise.raw
Sunset      $almanac.sun.set.raw

After every report generation, we have the file with the last set of data created. For my manual install, it is located at:

/home/weewx/public_html/VremStanica.tx

2) parse generated data into variables in a bash script.

Oneliner awk with just the single last else print statement from bellow will parse all the WeeWx data from above and automatically assign variable names from that same file. My locale is using comma as a decimal separator. I round up RainRate so a 0,1 does not get integered to 0 - no rain. Cardinal wind directions I leave unchanged (as letters). All other values get converted to integers (no decimal separator).

eval $(awk '
{
    if ($1 == "RainRate" && $2 > "0,0")
        print ""$1"=\""int ($2+1)"\""
    else if ($1 == "WindCardinal") # leave original
        print ""$1"=\""$2"\""
    else    # convert to integer
        print ""$1"=\""int ($2)"\""
}'
/home/weewx/public_html/VremStanica.txt)

The above converts the entire VremStanica.txt into bash variables with the same names. We can use them normally in the script without any extra work.

3) automate based on the parsed data. SmartHome needs complicated rules wich must work together: 5 rules can close a shutter and overlap (closed manually, it is raining, it is sunset, it is cold, strong wind...). Which rule and when is allowed to lift the shutter? They all must cooperate perfectly. That would be out of scope in this group.

The following system can be well used for lower amount of events that need tracking. Easy to read and use.

# setup initial location for the flag file RoletaKisaFlag
RoletaKisaFlag="/root/RoletaKisaFlag"

# write the single piece of data $RoletaDignuta into a flag file, creating it; Filename stands for its function (in my case: ShuttersRainFlag). File iself can also be used as a timestamp for the action. After the } a distinguishing addition (1,2,3 or a,b,c, or Kitchen, Balcony...) can be made for similar flags.
echo "$RoletaDignuta" > "${RoletaKisaFlag}"

# make a timestamp when (a RoletaKisa rule was activated and) the particular flag used
touch "${RoletaKisaFlag}"

# read in the timestamp from the particular flag
RoletaKisaFlagAge=$(date -r "${RoletaKisaFlag}" +%s)

Reply all
Reply to author
Forward
0 new messages