Upload data from Domoticz wind station to Windguru

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
javalin
Posts: 80
Joined: Tuesday 30 April 2019 16:06
Target OS: Raspberry Pi
Domoticz version: 4.10717
Location: Portugal
Contact:

Upload data from Domoticz wind station to Windguru

Post by javalin »

Hello,

If you have a wind station working in Domoticz then you can connect your station using Windguru upload API with this script. Before you start uploading data, you must register your station in Windguru, choose "Other (upload API)" as station type here: https://stations.windguru.cz/register.php?id_type=16

The script must be configured with your wind station Domoticz device number, your windguru station ID and password.

Important, the wind data must be sent in knots.
Important: this script only works on linux type systems with an available md5sum executable, in my case a raspberry.

Script:

Code: Select all

--Device attributes: wind.speed, wind.gust, wind.direction, wind.directionString

return
{
    on =
    {
        devices =
        {
            295, --script is executed every change of state of the weather station, must be your wind station device number  
        },
    },

    logging =
    {
        level = domoticz.LOG_ERROR,
		marker = 'windGuru',
    },

    execute = function(dz, item)
        local wind = item                   -- your wind station device number, wind station have to work with knots units
        local uid = 'your_id'              -- your Windguru station id 
        local station_pass = 'your_pass'    -- your Windguru station password 
        local time_stamp = dz.time.dDate
        local wind_speed = dz.utils.round(wind.speed,2)
        local wind_gust = dz.utils.round(wind.gust*1.943,2)
        local wind_direction = math.floor(wind.direction)
        local wind_directionString = wind.directionString
        local mySecret = time_stamp .. uid .. station_pass
        
        local function osCommand(cmd)
            dz.log('Executing Command: ' .. cmd,dz.LOG_DEBUG)
            local fileHandle = assert(io.popen(cmd .. ' 2>&1 || echo ::ERROR::', 'r'))
            local commandOutput = assert(fileHandle:read('*a'))
            local returnTable = {fileHandle:close()}
            if commandOutput:find '::ERROR::' then     -- something went wrong
               dz.log('Error ==>> ' .. tostring(commandOutput:match('^(.*)%s+::ERROR::') or ' ... but no error message ' ) ,dz.LOG_ERROR)
            else -- all is fine!!
                dz.log('ReturnCode: ' .. returnTable[3] .. '\ncommandOutput:\n' .. commandOutput, dz.LOG_DEBUG)
            end
            return commandOutput,returnTable[3] -- rc[3] contains returnCode
        end

	local hash = osCommand('echo -n ' .. mySecret .. ' | md5sum'):match("(%w+)")
        dz.log("md5Hash of " ..mySecret .. " is " ..  hash , dz.LOG_DEBUG )
		dz.openURL( 'http://www.windguru.cz/upload/api.php?uid='..uid..'&salt='..time_stamp..'&hash=' ..
					hash..'&wind_avg='..wind_speed..'&wind_max='..wind_gust..'&wind_direction='..wind_direction)
	end
}

Data station will be uploaded via HTTP GET requests to: http://www.windguru.cz/upload/api.php
More info: https://stations.windguru.cz/upload_api.php

Kind regards.
Last edited by javalin on Sunday 21 February 2021 0:08, edited 5 times in total.
User avatar
waaren
Posts: 7910
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: MD5 hash algorithm?

Post by waaren »

javalin wrote: Monday 15 February 2021 15:52 I am building a dzvents code to upload my wind station data to Windguru. In the process I need to create a hash calculated as MD5 to send data via HTTP GET. My doubt is, Dzvents is able to create an MD5 hash from a string?
you wil see

Code: Select all

2021-02-15 16:29:00.227 Status: dzVents: !Info: md5Hash: md5Hash of 20180214171400stationXYsupersecret is c9441d30280f4f6f4946fe2b2d360df5
when executing below script

Code: Select all

return
{
    on =
    {
        timer =
        {
            'every minute',
        },
    },

    logging =
    {
        level = domoticz.LOG_ERROR,
        marker = 'md5Hash',
    },

    execute = function(dz)

       local function osCommand(cmd)
            dz.log('Executing Command: ' .. cmd,dz.LOG_DEBUG)

            local fileHandle = assert(io.popen(cmd .. ' 2>&1 || echo ::ERROR::', 'r'))
            local commandOutput = assert(fileHandle:read('*a'))
            local returnTable = {fileHandle:close()}

            if commandOutput:find '::ERROR::' then     -- something went wrong
               dz.log('Error ==>> ' .. tostring(commandOutput:match('^(.*)%s+::ERROR::') or ' ... but no error message ' ) ,dz.LOG_ERROR)
            else -- all is fine!!
                dz.log('ReturnCode: ' .. returnTable[3] .. '\ncommandOutput:\n' .. commandOutput, dz.LOG_DEBUG)
            end

            return commandOutput,returnTable[3] -- rc[3] contains returnCode
        end


        local mySecret = '20180214171400stationXYsupersecret'

        dz.log("md5Hash of " ..mySecret .. " is " .. osCommand('echo -n ' .. mySecret .. ' | md5sum |  cut -d " " -f1'), dz.LOG_FORCE )
    end
}

Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Toulon7559
Posts: 1031
Joined: Sunday 23 February 2014 17:56
Target OS: Raspberry Pi
Domoticz version: mixed
Location: Hengelo(Ov)/NL
Contact:

Re: MD5 hash algorithm?

Post by Toulon7559 »

Do you need online Hash-coding, or only a onetime Hash-coding for your password?
In the latter case plenty of tools available at internet, such as https://www.md5hashgenerator.com/

Small advantage that you keep your 'open' secret key outside your script.
:( On the other hand, using a public internet-tool for crypting is not really safe either.

Mod 16Feb2021
The inclusion of 'salt' as variable required for each upload means that this 'external' solution cannot be used:
the implementation must be included within the script.
Last edited by Toulon7559 on Tuesday 16 February 2021 13:43, edited 1 time in total.
Set1 = RPI-Zero+RFXCom433+S0PCM+Shield for BMP180/DS18B20/RS485+DDS238-1ZNs
Set2 = RPI-3A++RFLinkGTW+ESP8266s+PWS_WS7000
Common = KAKUs+3*PVLogger+PWS_TFA_Nexus
plus series of 'satellites' for dedicated interfacing, monitoring & control.
javalin
Posts: 80
Joined: Tuesday 30 April 2019 16:06
Target OS: Raspberry Pi
Domoticz version: 4.10717
Location: Portugal
Contact:

Re: MD5 hash algorithm?

Post by javalin »

Thank you waaren works, but the 'hash function' finish creating a new line after show the hash. In others words, this is my result:

Code: Select all

 2021-02-15 18:26:10.318 Status: dzVents: Debug: md5Hash: OpenURL: url = http://www.windguru.cz/upload/api.php?uid=IDstation&salt=1613413570&hash=d41d8cd98f00b204e9800998ecf8427e
2021-02-15 18:26:10.318 &wind_avg=6.8&wind_max=5.51&wind_dir=191 
Should something like this:

Code: Select all

 2021-02-15 18:26:10.318 Status: dzVents: Debug: md5Hash: OpenURL: url = http://www.windguru.cz/upload/api.php?uid=IDstation&salt=1613413570&hash=d41d8cd98f00b204e9800998ecf8427e&wind_avg=6.8&wind_max=5.51&wind_dir=191 
I have tried fix the issue without success
Toulon7559 wrote: Monday 15 February 2021 17:05 Do you need online Hash-coding, or only a onetime Hash-coding for your password?
In the latter case plenty of tools available at internet, such as https://www.md5hashgenerator.com/

Small advantage that you keep your 'open' secret key outside your script.
:( On the other hand, using a public internet-tool for crypting is not really safe either.
Thanks for the tip, the hash must be calculated every minute or every update value with my user, pass and time span, I have a node red flow working very well for a year, but I would prefer migrate to dzvents. Don´t care to much about security, this is just a wind satiton, not my bank or email account. ;)
User avatar
waaren
Posts: 7910
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: MD5 hash algorithm?

Post by waaren »

javalin wrote: Monday 15 February 2021 19:30 works, but the 'hash function' finish creating a new line after show the hash.
Can you try again after changing line

Code: Select all

     dz.log("md5Hash of " ..mySecret .. " is " .. osCommand('echo -n ' .. mySecret .. ' | md5sum |  cut -d " " -f1'), dz.LOG_FORCE )
 
to

Code: Select all

        dz.log("md5Hash of " ..mySecret .. " is " ..  osCommand('echo -n ' .. mySecret .. ' | md5sum'):match("(%w+)")  , dz.LOG_FORCE )
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
javalin
Posts: 80
Joined: Tuesday 30 April 2019 16:06
Target OS: Raspberry Pi
Domoticz version: 4.10717
Location: Portugal
Contact:

Re: MD5 hash algorithm?

Post by javalin »

Can you try again after changing line
Now is working waaren. Thank you. This is the code, I would like to share in first post after your review ;)

Code: Select all

--Device attributes: wind.speed, wind.gust, wind.direction, wind.directionString
return
{
    on =
    {
        devices =
        {
            295, --script is executed every change of state of the weather station, must be your wind station device number  
        },

    },

    logging =
    {
        level = domoticz.LOG_ERROR ,
    },

    execute = function(dz, item)
        local wind = dz.devices(295)      -- your wind station device number, wind station have to work with knots units
        local uid = 'your_id'                    -- your Windguru station id 
        local station_pass = 'your_pass'   -- your Windguru station password 
        local time_stamp = dz.time.dDate
        local wind_speed = dz.utils.round(wind.speed,2)
        local wind_gust = dz.utils.round(wind.gust,2)
        local wind_direction = math.floor(wind.direction)
        local wind_directionString = wind.directionString
        local mySecret = time_stamp..uid..station_pass
        
        local function osCommand(cmd)
            dz.log('Executing Command: ' .. cmd,dz.LOG_DEBUG)
            local fileHandle = assert(io.popen(cmd .. ' 2>&1 || echo ::ERROR::', 'r'))
            local commandOutput = assert(fileHandle:read('*a'))
            local returnTable = {fileHandle:close()}
            if commandOutput:find '::ERROR::' then     -- something went wrong
               dz.log('Error ==>> ' .. tostring(commandOutput:match('^(.*)%s+::ERROR::') or ' ... but no error message ' ) ,dz.LOG_ERROR)
            else -- all is fine!!
                dz.log('ReturnCode: ' .. returnTable[3] .. '\ncommandOutput:\n' .. commandOutput, dz.LOG_DEBUG)
            end
            return commandOutput,returnTable[3] -- rc[3] contains returnCode
        end
        dz.log("md5Hash of " ..mySecret .. " is " ..  osCommand('echo -n ' .. mySecret .. ' | md5sum'):match("(%w+)")  , dz.LOG_DEBUG )
        local hash = tostring(osCommand('echo -n ' .. mySecret .. ' | md5sum'):match("(%w+)"))

	    if (item.isDevice) then 
        dz.openURL({
                url = 'http://www.windguru.cz/upload/api.php?uid='..uid..'&salt='..time_stamp..'&hash='..hash..'&wind_avg='..wind_speed..'&wind_max='..wind_gust..'&wind_dir='..wind_direction,
                method = 'GET',
        })
        return
        end
end
}
User avatar
waaren
Posts: 7910
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: MD5 hash algorithm?

Post by waaren »

javalin wrote: Monday 15 February 2021 22:06 Now is working waaren. Thank you. This is the code, I would like to share in first post after your review ;)
Seems ok. I propose some small changes (see below) and maybe you could add a clarification on what the script is for and that it only works on linux type systems with an available md5sum executable

Code: Select all

--Device attributes: wind.speed, wind.gust, wind.direction, wind.directionString

return
{
    on =
    {
        devices =
        {
            295, --script is executed every change of state of the weather station, must be your wind station device number  
        },
    },

    logging =
    {
        level = domoticz.LOG_ERROR,
		marker = 'windGuru',
    },

    execute = function(dz, item)
        local wind = item                   -- your wind station device number, wind station have to work with knots units
        local uid = 'your_id'                    -- your Windguru station id 
        local station_pass = 'your_pass'   -- your Windguru station password 
        local time_stamp = dz.time.dDate
        local wind_speed = dz.utils.round(wind.speed,2)
        local wind_gust = dz.utils.round(wind.gust,2)
        local wind_direction = math.floor(wind.direction)
        local wind_directionString = wind.directionString
        local mySecret = time_stamp .. uid .. station_pass
        
        local function osCommand(cmd)
            dz.log('Executing Command: ' .. cmd,dz.LOG_DEBUG)
            local fileHandle = assert(io.popen(cmd .. ' 2>&1 || echo ::ERROR::', 'r'))
            local commandOutput = assert(fileHandle:read('*a'))
            local returnTable = {fileHandle:close()}
            if commandOutput:find '::ERROR::' then     -- something went wrong
               dz.log('Error ==>> ' .. tostring(commandOutput:match('^(.*)%s+::ERROR::') or ' ... but no error message ' ) ,dz.LOG_ERROR)
            else -- all is fine!!
                dz.log('ReturnCode: ' .. returnTable[3] .. '\ncommandOutput:\n' .. commandOutput, dz.LOG_DEBUG)
            end
            return commandOutput,returnTable[3] -- rc[3] contains returnCode
        end

	local hash = osCommand('echo -n ' .. mySecret .. ' | md5sum'):match("(%w+)")
        dz.log("md5Hash of " ..mySecret .. " is " ..  hash , dz.LOG_DEBUG )
		dz.openURL( 'http://www.windguru.cz/upload/api.php?uid='..uid..'&salt='..time_stamp..'&hash=' ..
					hash..'&wind_avg='..wind_speed..'&wind_max='..wind_gust..'&wind_dir='..wind_direction)
	end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests