You are not logged in.

#1 2016-06-04 18:18:15

damo
....moderator....
Registered: 2015-08-20
Posts: 6,701

HowTo: Fix bunsenweather.sh, and use it in a Conky

BL ships with a Conky weather script: '.config/conky/scripts/bunsenweather.sh', which now requires an API key.

Here is an updated version, and how to get it working.

Get the API key
Set location

Location names mustn't have spaces, so "London,uk" is OK, but "New York" isn't.
id's can be used instead though, and obtained from http://bulk.openweathermap.org/sample/city.list.json.gz
Download and extract the json file, then simply search for an id with grep. For example:   

grep "New York" city.list.json

Different methods can be used with the script:

  1. Hardcode it in the script

    place="yourlocation"

    Several formats can be used (see: http://openweathermap.org/current#one, for usage)
    eg. "<city name>", "<city id>", "<zipcode>"

  2. Pass the location as a script parameter:

    /path/to/bunsenweather.sh "london,uk"
    or
    /path/to/bunsenweather.sh 5391997
  3. With no location specified, the script attempts to geolocate from the IP address

Formatting the output
printf "Location:%s\nTemp: %s\nWind %s from %s\n" "$city" "$temperature" "$windspeed" "$winddir"

This line produces the following output:

Location:London
Temp: +16.1°C
Wind 0.7 m/s from 206°

If the script is called from Conky with ${execpi}, then conky formatting can be added to the 'printf' command. For example

printf "%s: %s\n\${voffset 10}Wind: %d m/s, from %.3d°\nTemp:\${color red} %d°c\${color}" "$city" "$condition" "$windspeed" "$winddir" "$temperature" 2>/dev/null

NB Dont forget to escape special characters like "$"

${execpi 300 $HOME/.config/conky/scripts/bunsenweather.sh "charleston,usa"}

This produces output like:
jq-post.jpg

------------------------------------------------------------------------

'jq' is pre-installed and is a

lightweight and flexible command-line JSON processor
jq is like sed for JSON data – you can use it to slice
and filter and map and transform structured data with
the same ease that sed, awk, grep and friends let you
play with text.

jq Manual

------------------------------------------------------------------------

The modified bunsenweather.sh:
This updated version has a connection test, more error trapping, and the ability to pass name or id as script parameters.

#!/bin/bash
#
## bunsenweather.sh by <damo> June 2016
## Adapted from bunsenweather.sh, which was based on ideas from 
## weatherbang.sh version 1.0, 2013 by Ryan Fantus
##
## Requires:
##          'jq' (sudo apt-get install jq);
##          API Key from http://openweathermap.org/api
##
## USAGE: Call this script from Conky with ( replace "<t>" with the update interval)
##          ${execpi <t> /path/to/bunsenweather.sh [location]}


#### User configurables:  ##############################################

# Get API KEY by registering for one at http://openweathermap.org/api
#api="your very long api number"
api=""
# Either set the location manually here, or by passing it as a script parameter in the Conky.
# "yourlocation" must be a name (which doesn't have spaces), or a numeric id.
#
# id's can be obtained from http://bulk.openweathermap.org/sample/city.list.json.gz
# Download and extract the json file, then simply search for an id with grep. 
#   For example:   grep "New York" city.list.json
#
# If $place is not set, then the script attempts to get a geolocation from the IP address.

place="$1"              # Get $place from script parameter.
#place="yourlocation"   # Uncomment and add name or id. NB If the name has spaces, then you must use the id.

# Choose fahrenheit/Imperial or Celcius/metric:
#metric='imperial'
metric='metric'

#########################################################################
connectiontest() {
    local -i i attempts=${1-0}
    for (( i=0; i < attempts || attempts == 0; i++ )); do
        if wget -O - 'http://ftp.debian.org/debian/README' &> /dev/null; then
            return 0
        fi
        if (( i == attempts - 1 )); then # if last attempt
            return 1
        fi
    done
}

placeholder() {
    if (( $1 == 1 )) &>/dev/null;then
        echo "No internet connection"
        echo "Weather information unavailable"
    else
        echo "No API key"
        echo "Weather information unavailable"
    fi
}

if [[ $metric == metric ]] &>/dev/null;then
    scaleT="°C"
    scaleV="m/s"
else
    scaleT="°F"
    scaleV="mph"
fi

if [[ -z "$api" ]] &>/dev/null;then
    placeholder 0 && exit 1
else
    connectiontest 10
    
    # If latlong is preferred then don't set a value for $place
    if (( $? == 0 )) &>/dev/null;then
        if [[ -z $place ]] &>/dev/null;then
            # Geolocate IP:
            ipinfo=$(curl -s ipinfo.io)
            latlong=$(echo "$ipinfo" | jq -r '.loc')
            # Parse the latitude and longitude
            lat=${latlong%,*}
            long=${latlong#*,}
            location="lat=$lat&lon=$long"
        else
            # check if numeric id, or placename is being used
            [[ ${place##*[!0-9]*} ]] &>/dev/null && location="id=$place" || location="q=$place"
        fi

        # get json data from openweathermap:
        weather=$(curl -s http://api.openweathermap.org/data/2.5/weather\?APPID=$api\&"$location"\&units=$metric)
        city=$(echo "$weather" | jq -r '.name') # In case location has spaces in the name
        weather_desc=$(echo "$weather" | jq -r '.weather[0].description')   # In case description has spaces in the name

        # load values into array:
        all=($(echo "$weather" | jq -r '.coord.lon,.coord.lat,.weather[0].main,.main.temp,.main.pressure,.main.temp_min,.main.temp_max,.wind.speed,.wind.deg,.clouds.all,.sys.sunrise,.sys.sunset'))
        #                   ARRAY INDEX  0          1          2                3          4              5              6              7           8         9           10           11

        longitude=$(printf '%06.1f' ${all[0]})
        latitude=$(printf '%+.1f' ${all[1]})
        condition="${all[2]}"
        temperature=$(printf '%+.1f%s' ${all[3]} $scaleT)
        pressure=$(printf '%.f %s' ${all[4]} mb)
        temperature_min=$(printf '%+.1f%s' ${all[5]} $scaleT)
        temperature_max=$(printf '%+.1f%s' ${all[6]} $scaleT)
        windspeed=$(printf '%.1f %s' ${all[7]} $scaleV)
        winddir=$(printf '%3.f%s' ${all[8]} °)
        cloud_cover=$(printf '%d%s' ${all[9]} %)
        sunrise=$(date -d @${all[10]} +"%R")
        sunset=$(date -d @${all[11]} +"%R")
        description="$weather_desc"
        
        #Example format for output:
        #printf "%s; %s; %s %s" "$city" "$temperature" "$windspeed" "$winddir"

    else
        placeholder 1
    fi
fi

exit

Last edited by damo (2016-06-18 19:01:54)


Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt  «» BunsenLabs on DeviantArt

Offline

#2 2016-06-15 23:38:01

bra10n
Member
Registered: 2016-06-15
Posts: 22

Re: HowTo: Fix bunsenweather.sh, and use it in a Conky

Made some adjustments to bunsenweather.sh to add humidity & pressure;

#!/bin/bash
#
## bunsenweather.sh by <damo> June 2016
## based on ideas from weatherbang.sh version 1.0, 2013 by Ryan Fantus
##
## Requires:
##          'jq' (sudo apt-get install jq);
##          API Key from http://openweathermap.org/api
##
## USAGE: Call this script from Conky with ( replace "<t>" with the update interval)
##          ${execpi <t> $HOME/.config/conky/scripts/bunsenweather.sh [location]}


#### User configurables:  ##############################################

# Get API KEY by registering for one at http://openweathermap.org/api
api="cbcdd9a40999d5d68afc55145f756764"

# Either set the location manually here, or by passing it as a script parameter in the Conky
place="$1"
place="Sydney"

# Choose fahrenheit/Imperial or Celcius/metric:
#metric='imperial' && unit='F'
metric='metric' && unit='C'

########################################################################
# If latlong is preferred then don't set a value for $place
if [[ -z $place ]];then
    # Geolocate IP:
    ipinfo=$(curl -s ipinfo.io)
    latlong=$(echo $ipinfo | jq -r '.loc')
    # Parse the latitude and longitude
    lat=${latlong%,*}
    long=${latlong#*,}
    location="lat=$lat&lon=$long"
else
    location="q=$place"
fi

weather=$(curl -s http://api.openweathermap.org/data/2.5/weather\?APPID\=$api\&$location\&units\=${metric})
### TODO: better to try and put the output into a jq array, to reduce the processes :/ ###
city=$(echo $weather | jq -r '.name')
temperature=$(printf '%.0f' $(echo $weather | jq '.main.temp'))
condition=$(echo $weather | jq -r '.weather[0].main')
wind=$(echo $weather | jq '.wind.speed')
winddir=$(echo $weather | jq '.wind.deg')
humidity=$(echo $weather | jq '.main.humidity')
pressure=$(echo $weather | jq '.main.pressure') 

# Format the output with printf
printf "%s: %s\n\${goto 5}Wind: %d m/s, from %.3d°\n\${goto 5}Temp: %d°C\n\${goto 5}Humidity: %d%%\n\${goto 5}Pressure: %d hPa" "$city" "$condition" "$wind" "$winddir" "$temperature" "$humidity%" "$pressure" 2>/dev/null

exit

All credit to damo the scripts creator.

cheers

Offline

#3 2016-06-15 23:52:37

damo
....moderator....
Registered: 2015-08-20
Posts: 6,701

Re: HowTo: Fix bunsenweather.sh, and use it in a Conky

bra10n wrote:

....

All credit to damo the scripts creator.

cheers

Too kind smile

# based on ideas from weatherbang.sh version 1.0, 2013 by Ryan Fantus

I really should learn how to deal with arrays of values from jq  monkey  Having "echo | " for each value seems very inelegant and wasteful of resources sad
See post #5

Last edited by damo (2016-06-17 20:57:21)


Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt  «» BunsenLabs on DeviantArt

Offline

#4 2016-06-16 15:50:55

cloverskull
Member
Registered: 2015-10-01
Posts: 343

Re: HowTo: Fix bunsenweather.sh, and use it in a Conky

jq for the win! And thanks for the kudos/credit in your script!

Offline

#5 2016-06-17 20:54:52

damo
....moderator....
Registered: 2015-08-20
Posts: 6,701

Re: HowTo: Fix bunsenweather.sh, and use it in a Conky

Script update

  • Now you can pass id as well as name, as a script parameter.

  • More tests and error trapping.

  • Most of the available weather data values are stored in an array, to avoid multiple calls to 'jq'.
    The variables have been formatted already (including the metric/imperial symbols), so to output them just do:

    printf "%s" "$var"
    or
    echo "$var"

Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt  «» BunsenLabs on DeviantArt

Offline

#6 2018-01-29 08:40:33

martix
Kim Jong-un Stunt Double
Registered: 2016-02-19
Posts: 1,267

Re: HowTo: Fix bunsenweather.sh, and use it in a Conky

Just a short explanation I posted already, but it might be more useful here.

Originally in the shipped bunsenweather script there was no need for an api key, but openweathermap.org changed its service. It was required that users register and get an api key to use with the service.  The original - shipped - script needed some tweaking and the tweaked script looked like the one posted in the #2nd post here in the thread (with an api key).

In this version there is a remark: "### TODO: better to try and put the output into a jq array, to reduce the processes hmm ###"

The script at the end of the first post is damo's improved version with arrays and internet connection checking.

This script tries to connect to http://ftp.debian.org/debian/README. If there is a connection, it shows the weather data, otherwise a message: "No internet connection" "Weather information unavailable".

It also checks if there is a required api key. If not, the message is: "No API key" "Weather info unavailable".

To get this script working, make sure to uncomment "remove #" from the beginning of this line (around the end of the script): printf "%s; %s; %s %s" "$city" "$temperature" "$windspeed" "$winddir"

It will use the IP and location data from ipinfo.io to show the weather for your location. As in the OP and the script described, it's also possible to use a location name or id from openweathermap.org.

Offline

#7 2018-08-22 16:03:48

cherkie
Member
From: Poland
Registered: 2018-08-09
Posts: 107

Re: HowTo: Fix bunsenweather.sh, and use it in a Conky

Any idea how to implement forecast in the script? Openweather does provide forecast data but I am too big of a noob to know what to do with it. I would only need "few hours later" forecast, not a full blown table for entire week.

Thanks


I don't have patience or skill to dig deep enough every time system breaks itself or when I break something because of lack of patience and skill.
nore, 23 Feb 2019

Offline

#8 2018-08-22 19:12:52

damo
....moderator....
Registered: 2015-08-20
Posts: 6,701

Re: HowTo: Fix bunsenweather.sh, and use it in a Conky

You can get the details of the openweather JSON API here

The url is in the form "api.openweathermap.org/data/2.5/forecast...", so just change the curl line to use "forecast" instead of "weather".

However.....you now have to deal with 5days of 3hourly forecasts in the json stream, so it is time to read up on using jq! Here is somewhere to start: Parsing JSON with jq

An example of the returned JSON is here: JSON API response

The data has an array of the forecasts, so if you extract eg the 4th index (ie array[3]), that will give the 24hr forecast, which can then be processed as per the last part of the bunsenweather script.


Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt  «» BunsenLabs on DeviantArt

Offline

#9 2018-08-22 21:38:32

damo
....moderator....
Registered: 2015-08-20
Posts: 6,701

Re: HowTo: Fix bunsenweather.sh, and use it in a Conky

The following code gets the 4th index of the 5day forecast JSON array, which I think is maybe for midday on the following day. You can peek at the data to see all the time/date information, if you want to work it out yourself - get and save the whole lot with....

echo $weather5day | jq . > tempfile

Swap out the section in bunsenweather.sh with the following....

        # get json data from openweathermap:

        #weather=$(curl -s http://api.openweathermap.org/data/2.5/weather\?APPID=$api\&"$location"\&units=$metric)
        weather5day=$(curl -s http://api.openweathermap.org/data/2.5/forecast\?APPID=$api\&"$location"\&units=$metric)
        weather=$(echo "$weather5day" | jq '.list[3]')
        weather_desc=$(echo "$weather" | jq  '.weather[0].description')
        date_time=$(echo "$weather" | jq  '.dt_txt')

        # load values into arrays:
        place=($(echo "$weather5day" | jq  '.city.name,.city.coord.lat,.city.coord.long'))
        all=($(echo "$weather" | jq  '.main.temp,.main.pressure,.main.temp_min,.main.temp_max,.wind.speed,.wind.deg,.clouds.all,.sys.sunrise,.sys.sunset,.main.humidity'))

        #                       ARRAY INDEX  0          1          2                3          4              5              6         7           8         9
        city=${place[0]//'"'/''}
        longitude=${place[2]}
        latitude=${place[1]}
        conditions=${weather_desc//'"'/''}
        temperature="${all[0]} $scaleT"
        pressure="${all[1]} mb"
        temperature_min="${all[2]} $scaleT"
        temperature_max="${all[3]} $scaleT"
        windspeed="${all[4]} $scaleV"
        winddir="${all[5]} °"
        cloud_cover="${all[6]} %"
        sunrise=${all[7]}
        sunset=${all[8]}
        humidity="${all[9]}%"
        #description=${all[10]//'"'/''}
        dt=${date_time//'"'/''}

        #Example format for output:
        printf '%s %s: %s %s\n' "$dt" "$city" "$lat" "$long"
        printf "Windspeed: %s  Wind Direction: %s\n" "$windspeed" "$winddir"
        printf "Temp: %s\nHumidity: %s\n"  "$temperature" "$humidity"
        printf "Weather: %s\n" "$conditions"

You would have to use the original array setup if you go back to using the current weather data. It is probably easier to use another script instead though.

I haven't bothered with fiddling with the printf formatting hmm

Last edited by damo (2018-08-22 21:43:00)


Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt  «» BunsenLabs on DeviantArt

Offline

#10 2018-08-23 11:54:26

unklar
Back to the roots 1.9
From: #! BL
Registered: 2015-10-31
Posts: 1,545

Re: HowTo: Fix bunsenweather.sh, and use it in a Conky

damo is back! I am delighted   big_smile

Offline

#11 2021-05-17 05:42:57

mistik1
New Member
Registered: 2021-05-17
Posts: 1

Re: HowTo: Fix bunsenweather.sh, and use it in a Conky

While looking for a conky weather script I came across this post.
I've modified it for my own uses and thought it may help someone else as you helped me, mine uses FontAwesome to display a few icons including the Open Weather Map current icon.
The use of wget to do the connection test can be rather slow so I replaced that as well.

#!/bin/bash
#set -x
#
## bunsenweather.sh by <damo> June 2016
## based on ideas from weatherbang.sh version 1.0, 2013 by Ryan Fantus
##
## Requires:
##          'jq' (sudo apt-get install jq);
##          FontAwesome (apt install fonts-font-awesome)
##          API Key from http://openweathermap.org/api
##
## USAGE: Call this script from Conky with ( replace "<t>" with the update interval)
##          ${execpi <t> $HOME/.config/conky/scripts/bunsenweather.sh [location]}


#### User configurables:  ##############################################

# Get API KEY by registering for one at http://openweathermap.org/api
api=""

# Either set the location manually here, or by passing it as a script parameter in the Conky
# If using city name set place="CityName" for city ID use place="12423938"
place="$1"
#place="Moneague"

# Choose fahrenheit/Imperial or Celcius/metric:
metric='imperial' && unit='F' && unitS='mph'
#metric='metric' && unit='C' && unitS='m/s'

# The icon position is a little tricky in conky so you can turn that off
# by setting useicon=0
useicon=1
# Set basedir to download icons as weather changes
icondir="${HOME}/.config/conky/weather/images"
# Set the X,Y position of the weather icon
# WARNING This is the position in the entire conky window
# does not work very well below items that dynamicly resize vertically
# best at the top of conky or in its own session
iconpos="0,73"

########################################################################
connectiontest() {
    value=1
    ifaces=$(ip link | grep -Po --regexp "(?<=[0-9]: ).*")
    while IFS= read -r line; do
        echo $line | grep -q "<BROADCAST"
        if [[ $? == 0 ]]; then
            value=0
            break
        fi
    done <<< $ifaces
    return $value
}

placeholder() {
    if (( $1 == 1 )) &>/dev/null;then
        echo -e "\${goto 10}\${font FontAwesome}  \${font}No internet connection\n\${goto 10}Weather information unavailable"
    else
        echo -e "\${goto 10}\${font FontAwesome}  \${font}No API key\n\${goto 10}Weather information unavailable"
    fi
}

downloadimage() {
    iconpath=$1
    iconurl=$2
    if [[ ! -f $iconpath ]]; then
       curl --create-dirs -o $iconpath $iconurl &> /dev/null
    fi
}

degree_to_text() {
    #arr=("N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW")
    deg=${1}
    if (( $deg >= 360 || $deg <= 21 )); then
        deg="N"
    elif (( $deg >= 22 && $deg <= 44 )); then
        deg="NNE"
    elif (( $deg >= 45 && $deg <= 66 )); then
        deg="NE"
    elif (( $deg >= 67 && $deg <= 89 )); then
        deg="ENE"
    elif (( $deg >= 90 && $deg <= 111 )); then
        deg="E"
    elif (( $deg >= 112 && $deg <= 134 )); then
        deg="ESE"
    elif (( $deg >= 135 && $deg <= 156 )); then
        deg="SE"
    elif (( $deg >= 157 && $deg <= 179 )); then
        deg="SSE"
    elif (( $deg >= 180 && $deg <= 201 )); then
        deg="S"
    elif (( $deg >= 202 && $deg <= 224 )); then
        deg="SSW"
    elif (( $deg >= 225 && $deg <= 246 )); then
        deg="SW"
    elif (( $deg >= 247 && $deg <= 269 )); then
        deg="WSW"
    elif (( $deg >= 270 && $deg <= 291 )); then
        deg="W"
    elif (( $deg >= 292 && $deg <= 314 )); then
        deg="WNW"
    elif (( $deg >= 315 && $deg <= 336 )); then
        deg="NW"
    elif (( $deg >= 337 && $deg <= 359 )); then
        deg="NNW"
    else
        deg="N/A"
    fi
    echo $deg
}

# If latlong is preferred then don't set a value for $place
if [[ -z $place ]];then
    # Geolocate IP:
    ipinfo=$(curl -s ipinfo.io)
    latlong=$(echo $ipinfo | jq -r '.loc')
    # Parse the latitude and longitude
    lat=${latlong%,*}
    long=${latlong#*,}
    location="lat=$lat&lon=$long"
else
    [[ ${place##*[!0-9]*} ]] &>/dev/null && location="id=$place" || location="q=$place"
fi

if [[ -z "$api" ]] &>/dev/null;then
    placeholder 0 && exit 1
else
    connectiontest 10
    if (( $? == 0 )) &>/dev/null;then
        weather=$(curl -s http://api.openweathermap.org/data/2.5/weather\?APPID\=$api\&$location\&units\=${metric})
        json=$(echo "$weather" | jq -r '.coord.lon,.coord.lat,.weather[0].main,.main.temp,.main.pressure,.main.temp_min,.main.temp_max,.wind.speed,.wind.deg,.clouds.all,.sys.sunrise,.sys.sunset,.main.humidity,.name,.weather[0].description,.weather[0].icon')
        declare -a all
        i=0
        # XXX Process with read to handle values with spaces
        while IFS= read -r line; do
            all[$i]=$line
            ((i++))
        done <<< $json

        city=${all[13]}
        temperature=$(printf '%.0f' ${all[3]})
        condition=${all[2]}
        wind=${all[7]}
        winddir=$(degree_to_text ${all[8]})
        humidity=${all[12]}
        pressure=${all[4]}
        sunrise=$(date -d @${all[10]} +"%I:%M%p")
        sunset=$(date -d @${all[11]} +"%I:%M%p")
        description="${all[14]}"
        iconurl=$(printf 'http://openweathermap.org/img/w/%s.png' ${all[15]})
        iconpath=$(printf "${icondir}/%s.png" ${all[15]})
        if [[ $useicon == 1 ]]; then
            downloadimage $iconpath $iconurl

            # Format the output with printf
            printf "\${goto 10}\${image %s -p ${iconpos}}\${goto 60}\${font :size=14}%s\${font} \${font FontAwesome}  \${font}%s  \${font FontAwesome} \${font}%s\n\${goto 10}Weather: %s\n\${goto 10}Wind: %d ${unitS}, from %s\n\${goto 10}Temp: %d°${unit}\n\${goto 10}Humidity: %d%%\n\${goto 10}Pressure: %d hPa" "$iconpath" "$city" "$sunrise" "$sunset" "$description" "$wind" "$winddir" "$temperature" "$humidity%" "$pressure" 2>/dev/null
        else
            printf "\${goto 10}\${font FontAwesome}  \${font} \${font :size=14}%s\${font} \${font FontAwesome}  \${font}%s  \${font FontAwesome} \${font}%s\n\${goto 10}Weather: %s\n\${goto 10}Wind: %d ${unitS}, from %s\n\${goto 10}Temp: %d°${unit}\n\${goto 10}Humidity: %d%%\n\${goto 10}Pressure: %d hPa" "$city" "$sunrise" "$sunset" "$description" "$wind" "$winddir" "$temperature" "$humidity%" "$pressure" 2>/dev/null
        fi
        exit
    else
        placeholder 1
    fi
fi

I also implemented it as a lua script
Save the results somewhere like ${HOME}/.config/conky/userFunc.lua
Edit to set the values for api_key etc
load info conky as follows:

conky.config {
     lua_load = '~/.config/conky/userFunc.lua',
     lua_draw_hook_pre = 'main',
....rest of config
};
conky.text = [[
     ${lua_parse owmweather}
]];

userFunc.lua

weather_text = ''
-- Can be a text name of city or city ID number
WEATHER = {
    api_key = "",
    location = "Moneague",
    units = "imperial",
    units_temp = "F",
    units_speed = 'mph',
    icondir = "${HOME}/.config/conky/weather/images",
    iconpos = "0,73",
    useicon = 1
}

-- Conky main function
function conky_main()
    if conky_window == nil then
        return
    end
    local cs = cairo_xlib_surface_create(conky_window.display,
                                         conky_window.drawable,
                                         conky_window.visual,
                                         conky_window.width,
                                         conky_window.height)
    cr = cairo_create(cs)
    
    cairo_destroy(cr)
    cairo_surface_destroy(cs)
    cr=nil
end

-- Start of openweathermap API weather app
function conky_owmweather()
    local weather
    local all = {}
    local values
    local lat
    local long
    local location
    if WEATHER.api_key == nil or WEATHER.api_key == "" then
        weather_text = placeholder(0)
    else
        if network_up() == 1 then
            --Do the bussiness
            if WEATHER.location == nil or WEATHER.location == '' then
                -- Geolocate IP:
                local ipinfo = io.popen("curl -s ipinfo.io")
                local info = trim(ipinfo:read("*a"))
                ipinfo:close()
                local latlong = io.popen("echo '" .. info .. "' | jq -r '.loc'")
                local geo = {}
                for l in latlong:lines() do
                    table.insert(geo, l)
                end
                latlong:close()
                -- Parse the latitude and longitude
                lat = geo[1]
                long = geo[2]
                location = "lat=".. lat .."&lon=" .. long
            else
                -- check if numeric id, or placename is being used
                if tonumber(WEATHER.location) == nil then
                    location="q=" .. WEATHER.location
                else
                    location="id=" .. WEATHER.location
                end
            end
            local uri = "http://api.openweathermap.org/data/2.5/weather\?APPID\=" .. WEATHER.api_key .. "&" .. location .. "&units=" .. WEATHER.units
            --print(uri)
            local query = io.popen("curl -s '" .. uri .. "'")
            weather = trim(query:read("*a"))
            query:close()
            --print(weather)
            -- load values into array:
            values = io.popen("echo '" .. weather .."' | jq -r '.coord.lon,.coord.lat,.weather[0].main,.main.temp,.main.pressure,.main.temp_min,.main.temp_max,.wind.speed,.wind.deg,.clouds.all,.sys.sunrise,.sys.sunset,.main.humidity,.name,.weather[0].description,.weather[0].icon'")
            for l in values:lines() do
                table.insert(all, l)
            end
            values:close()
            
            local city = all[14]
            local temperature = string.format('%.0f', all[4])
            local condition = all[3]
            local wind = string.format('%d', all[7])
            local winddir = degree_to_text(tonumber(all[9]))
            local humidity = all[13]
            local pressure = all[5]
            local sunrise = os.date("%I:%M%p", all[11])
            local sunset = os.date("%I:%M%p", all[12])
            local description = all[15]
            local iconurl = string.format('http://openweathermap.org/img/w/%s.png', all[16])
            local iconpath = string.format(WEATHER.icondir..'/%s'..'.png', all[16])


            -- Format the output
            if WEATHER.useicon == 1 then
                downloadimage(iconpath, iconurl)
                weather_text = "${goto 10}${image "..iconpath.." -p "..WEATHER.iconpos.."}${goto 70}${font :size=14}"..city.."${font} ${font FontAwesome}  ${font}"..sunrise.."  ${font FontAwesome} ${font}"..sunset.."\n${goto 10}Weather: "..description.."\n${goto 10}Wind: " .. wind .. " " .. WEATHER.units_speed .. " " .. winddir .. "\n${goto 10}Temp: " .. temperature .. "°" .. WEATHER.units_temp .."\n${goto 10}Humidity: " .. humidity .. "%\n${goto 10}Pressure: " .. pressure .. " hPa"
            else
                weather_text = "${goto 10}${font FontAwesome}  ${font}${font :size=14}" .. city .."${font} ${font FontAwesome}  ${font}"..sunrise.."  ${font FontAwesome} ${font}"..sunset.."\n${goto 10}Weather: "..description.."\n${goto 10}Wind: " .. wind .. " " .. WEATHER.units_speed .. " " .. winddir .. "\n${goto 10}Temp: " .. temperature .. "°" .. WEATHER.units_temp .."\n${goto 10}Humidity: " .. humidity .. "%\n${goto 10}Pressure: " .. pressure .. " hPa"
            end
        else
            weather_text = placeholder(1)
        end
    end
    return weather_text
end

-- Return compass direction in text from degrees
function degree_to_text(deg)
    local val = math.ceil((deg/22.5)+.5)
    local arr = {"N","NNE","NE","ENE","E","ESE", "SE", "SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"}
    return arr[(val % 16)]
end

function network_up()
    local active_ifaces = {}
    if active_network_interface == false or tonumber(conky_parse("$updates")) % 2 == 0 then
        local ifaces = io.popen('ip link | grep -Po --regexp "(?<=[0-9]: ).*"')
        for line in ifaces:lines() do
            if string.find(line, "<BROADCAST") then
                local iface = string.gsub(string.match(line, "^.*:"), ":", "")
                table.insert( active_ifaces, iface)
            end
        end
        ifaces:close()
        if table.maxn(active_ifaces) >= 1 then
            return 1
        else
            return 0
        end
    else
        return 1
    end
end

function placeholder(n) 
    local text
    if n == 1 then
        text = "${goto 10}${font FontAwesome}  ${font} No internet connection\n${goto 10}Weather information unavailable"
    else
        text = "${goto 10}${font FontAwesome}  ${font} No API key\n${goto 10}Weather information unavailable"
    end
    return text
end

function downloadimage(iconpath, iconurl)
    local file_found=io.open(iconpath, "r")
    if file_found==nil then
        local img = io.popen("curl --create-dirs -o " .. iconpath .. " " .. iconurl)
        img:close()
    end
    file_found:close()
end

-- End of OpenWeatherMap app

-- Trims given string and returns
function trim(s)
   return s:gsub("^%s+", ""):gsub("%s+$", "")
end

Look at it Here


Thanks for sharing guys

Last edited by mistik1 (2021-05-17 06:07:26)

Offline

Board footer

Powered by FluxBB