Page 1 of 2

World Cup Scoreboard - new version

Posted: Friday 15 June 2018 13:48
by elmortero
Hi all,

Not a real football fan myself but with the World Cup I make a little exception.
For that reason - and because I am always looking for data sources to play with the asynchronous http requests - I wrote this script.

The data are fetched from http://worldcup.sfg.io/ and they offer other data sets. I was only interested in the status of the current game.

changed: now using the /today endpoint. This way at the end of the game the winner is displayed


In the code below I check if one of the teams is a team I want notifications about. If you don't want to use that remove line 30 to 32 and 47 to 49

Code: Select all

return {
	on = {
		timer = { 'every 2 minutes' },
		httpResponses = { 'scoreboard2' } -- matches callback string below
	},
	
	execute = function(domoticz, triggerItem)
    local board = domoticz.devices('Scoreboard2')    --a virtual text sensor
    local prevboard = tostring(board.text)          --get current value of text sensor

		if (triggerItem.isTimer) then
			domoticz.openURL({
				url = 'http://worldcup.sfg.io/matches/today',
				method = 'GET',
				callback = 'scoreboard2'
			})
			
		elseif (triggerItem.isHTTPResponse) then

	local response = triggerItem
			if (response.ok and response.isJSON) then
			tl = #response.json
			tc = 1
			repeat
				local status = tostring(response.json[tc].status)
				local home = tostring(response.json[tc].home_team.country)
				local away = tostring(response.json[tc].away_team.country)
				local hgoal = tostring(response.json[tc].home_team.goals)
				local agoal = tostring(response.json[tc].away_team.goals)
					if away == 'Spain' or away == 'Belgium' or home == 'Spain' or home == 'Belgium' then
					 sender = true
					end
				show = (home..' '..hgoal..' - '..agoal..' '..away)

					if status == 'in progress' then tc = tl + 1 end
					if status == 'completed' then
						local score = (hgoal..' - '..agoal)
						local winner = tostring(response.json[tc].winner)
						show = ('Match won by '..winner..' with '..score)
						tc = tc + 1						
					end
					if status == 'future' then tc = tl + 1 end
				until tc > tl
					if show ~= prevboard then
					    print ('result '..show)
						board.updateText(show)
							if sender then
							 --put your notification method here (mine is telegram)
							end
					end			
			else
					print('**scoreboard2 failed to fetch info')
		end
		end
	end
}
The attachment Capture.JPG is no longer available

Re: World Cup Scoreboard

Posted: Friday 15 June 2018 13:58
by jia175891641
good work!

Re: World Cup Scoreboard

Posted: Friday 15 June 2018 14:01
by ulisesrdg
Very useful!!!, Thank you for sharing!

Re: World Cup Scoreboard

Posted: Friday 15 June 2018 15:54
by elmortero
Found an error (needed a match in progress to test)
it should be: if #response.json > 0 then and not > 1

Re: World Cup Scoreboard

Posted: Saturday 16 June 2018 12:26
by EdwinK
Screen Shot 2018-06-16 at 13.23.44.png
Screen Shot 2018-06-16 at 13.23.44.png (41.87 KiB) Viewed 3285 times
Thanks. I don't like soccer/football but this things are funny to play with.

Re: World Cup Scoreboard - new version

Posted: Sunday 17 June 2018 22:32
by corederoma82
Hi,
how is the procedure for installation?

Thanks

Re: World Cup Scoreboard - new version

Posted: Sunday 17 June 2018 23:21
by EdwinK
Copy the lines of the scripts in the events editor, make sure to select dzVents.

Make a text device and name it scoreboard.

That's all

Re: World Cup Scoreboard - new version

Posted: Monday 18 June 2018 13:49
by corederoma82
EdwinK wrote: Sunday 17 June 2018 23:21 Copy the lines of the scripts in the events editor, make sure to select dzVents.

Make a text device and name it scoreboard.

That's all
Ok
Thanks

Re: World Cup Scoreboard - new version

Posted: Monday 18 June 2018 14:48
by CaesarPL
Thank you very much. Just curious - as I am still on last stable - will it work on old dzVents?

Re: World Cup Scoreboard - new version

Posted: Monday 18 June 2018 15:06
by MikeF
I've just set this up as described, but I'm getting this dzVents error:

Code: Select all

Error: dzVents: Error: ...omoticz/scripts/dzVents/generated_scripts/scoreboard.lua:11: attempt to index local 'triggerItem' (a nil value)

Re: World Cup Scoreboard - new version

Posted: Monday 18 June 2018 19:18
by elmortero
MikeF wrote: Monday 18 June 2018 15:06 I've just set this up as described, but I'm getting this dzVents error:

Code: Select all

Error: dzVents: Error: ...omoticz/scripts/dzVents/generated_scripts/scoreboard.lua:11: attempt to index local 'triggerItem' (a nil value)
That means that you are on a dzVents version prior to 2.4

Re: World Cup Scoreboard - new version

Posted: Monday 18 June 2018 19:54
by MikeF
Well, that's a shame - yes, I'm on version 2.2, with Domoticz stable 3.8153. I believe I would need to upgrade to Domoticz beta in order to get dzVents 2.4.

Re: World Cup Scoreboard - new version

Posted: Monday 18 June 2018 20:45
by elmortero
MikeF wrote: Monday 18 June 2018 19:54 Well, that's a shame - yes, I'm on version 2.2, with Domoticz stable 3.8153. I believe I would need to upgrade to Domoticz beta in order to get dzVents 2.4.
You should, there are some nice features in the later versions of dzVents.

Meanwhile, I took the time to make a pre-httpresponse version of the script. Should work, have not domoticz running on an older version to check all functions.

Try it if you want and let me know if it gives issues (the first time it runs you might get an error about the /tmp file not being available, on the second run it should be ok.

Code: Select all

local scorefile = '/tmp/score.json'
local fetchIntervalMins = 3     -- interval to check the info (don't set to lower than 3)
return {
active = true,
on = {
	timer = { 'every minute' },
		},
execute = function(domoticz, device)
local callUrl = false
	if (os.date('*t').min % fetchIntervalMins) == 0 then
	callUrl = true
	elseif ((os.date('*t').min -1) % fetchIntervalMins) ~= 0 then
	return
	end
local board = domoticz.devices('Scoreboard')
local prevboard = tostring(board.text)
local linker = tostring('http://worldcup.sfg.io/matches/today')
	if callUrl then
	os.execute('curl -s "'..linker..'" > '..scorefile..'&')
	 print('json written to file')
	return -- Nothing more to do for now, we'll be back in a minute to read the data!
	end	
		local function readLuaFromJsonFile(fileName)
		local file = io.open(fileName, 'r')
				if file then
				package.path = './scripts/lua/?.lua;'..package.path
				local jsonParser = require('JSON')
				local _json = file:read('*a')
				local json = jsonParser:decode(_json)
				io.close(file)
				return json
				end
		return nil
		end
local scoreData = readLuaFromJsonFile(scorefile)

	if not scoreData then
	print('** Scoreboard// Could not read scoreData from file: '.. scorefile)
	return
	end
--
	tl = #scoreData
	if tl > 0  then
			tc = 1
			repeat
				local status = tostring(scoreData[tc].status)
				local home = tostring(scoreData[tc].home_team.country)
				local away = tostring(scoreData[tc].away_team.country)
				local hgoal = tostring(scoreData[tc].home_team.goals)
				local agoal = tostring(scoreData[tc].away_team.goals)

				show = (home..' '..hgoal..' - '..agoal..' '..away)

					if status == 'in progress' then tc = tl + 1 end
					if status == 'completed' then
						local score = (hgoal..' - '..agoal)
						local winner = tostring(scoreData[tc].winner)
						if winner == 'Draw' then 
						   show = ('Draw '..home..' '..hgoal..' - '..agoal..' '..away)
						   else 
						   show = ('Match won by '..winner..' with '..score)
						 end
						tc = tc + 1						
					end
					if status == 'future' then tc = tl + 1 end
				until tc > tl
					if show ~= prevboard then
					    print ('result '..show)
						board.updateText(show)
					end			

    end
end
}

Re: World Cup Scoreboard - new version

Posted: Monday 18 June 2018 22:07
by LennartIsHigh
elmortero wrote: Monday 18 June 2018 20:45 Try it if you want and let me know if it gives issues (the first time it runs you might get an error about the /tmp file not being available, on the second run it should be ok.
I don't have a clue about what version I've got running but this version of yours works for me.
Thanks!

Re: World Cup Scoreboard - new version

Posted: Monday 18 June 2018 23:39
by MikeF
elmortero wrote: Monday 18 June 2018 20:45 Meanwhile, I took the time to make a pre-httpresponse version of the script. Should work, have not domoticz running on an older version to check all functions.

Try it if you want and let me know if it gives issues
Thanks for taking the time to do this - works well for me. :D

Re: World Cup Scoreboard - new version

Posted: Tuesday 19 June 2018 11:07
by MikeF
I've made a change (to the pre-HTTPresponse version) to show kick-off time for future matches:
Spoiler: show

Code: Select all

local scorefile = '/tmp/score.json'
local fetchIntervalMins = 3     -- interval to check the info (don't set to lower than 3)
return {
active = true,
on = {
	timer = { 'every minute' },
		},
execute = function(domoticz, device)
local callUrl = false
	if (os.date('*t').min % fetchIntervalMins) == 0 then
	callUrl = true
	elseif ((os.date('*t').min -1) % fetchIntervalMins) ~= 0 then
	return
	end
local board = domoticz.devices('Scoreboard')
local prevboard = tostring(board.text)
local linker = tostring('http://worldcup.sfg.io/matches/today')
	if callUrl then
	os.execute('curl -s "'..linker..'" > '..scorefile..'&')
	 print('json written to file')
	return -- Nothing more to do for now, we'll be back in a minute to read the data!
	end	
		local function readLuaFromJsonFile(fileName)
		local file = io.open(fileName, 'r')
				if file then
				package.path = './scripts/lua/?.lua;'..package.path
				local jsonParser = require('JSON')
				local _json = file:read('*a')
				local json = jsonParser:decode(_json)
				io.close(file)
				return json
				end
		return nil
		end
local scoreData = readLuaFromJsonFile(scorefile)

	if not scoreData then
	print('** Scoreboard// Could not read scoreData from file: '.. scorefile)
	return
	end
--
	tl = #scoreData
	if tl > 0  then
			tc = 1
			repeat
				local status = tostring(scoreData[tc].status)
				local date = tostring(scoreData[tc].datetime)
				local home = tostring(scoreData[tc].home_team.country)
				local away = tostring(scoreData[tc].away_team.country)
				local hgoal = tostring(scoreData[tc].home_team.goals)
				local agoal = tostring(scoreData[tc].away_team.goals)
				
				local pattern = "(%d+)%-(%d+)%-(%d+)T(%d+):(%d+):(%d+)"
				local year, month, day, hour, minute, seconds = date:match(pattern)
				hour = hour + 1

				show = (home..' '..hgoal..' - '..agoal..' '..away)

					if status == 'in progress' then tc = tl + 1 end
					if status == 'completed' then
						local score = (hgoal..' - '..agoal)
						local winner = tostring(scoreData[tc].winner)
						if winner == 'Draw' then 
						   show = ('Draw '..home..' '..hgoal..' - '..agoal..' '..away)
						   else 
						   show = ('Match won by '..winner..' with '..score)
						 end
						tc = tc + 1						
					end
					if status == 'future' then 
					    show = (show..' KO '..hour..':'..minute)
					    tc = tl + 1 
					end
				until tc > tl
					if show ~= prevboard then
					    print ('result '..show)
						board.updateText(show)
					end			

    end
end
}
Image

Line 56 (hour = hour + 1) should be changed for different timezones (mine is UK BST).

Re: World Cup Scoreboard - new version

Posted: Tuesday 19 June 2018 15:39
by MikeF
I've added the elapsed match time - although this will lag, as the script runs every 3 minutes:
Spoiler: show

Code: Select all

local scorefile = '/tmp/score.json'
local fetchIntervalMins = 3     -- interval to check the info (don't set to lower than 3)
return {
active = true,
on = {
	timer = { 'every minute' },
		},
execute = function(domoticz, device)
local callUrl = false
	if (os.date('*t').min % fetchIntervalMins) == 0 then
	callUrl = true
	elseif ((os.date('*t').min -1) % fetchIntervalMins) ~= 0 then
	return
	end
local board = domoticz.devices('Scoreboard')
local prevboard = tostring(board.text)
local linker = tostring('http://worldcup.sfg.io/matches/today')
	if callUrl then
	os.execute('curl -s "'..linker..'" > '..scorefile..'&')
	 print('json written to file')
	return -- Nothing more to do for now, we'll be back in a minute to read the data!
	end	
		local function readLuaFromJsonFile(fileName)
		local file = io.open(fileName, 'r')
				if file then
				package.path = './scripts/lua/?.lua;'..package.path
				local jsonParser = require('JSON')
				local _json = file:read('*a')
				local json = jsonParser:decode(_json)
				io.close(file)
				return json
				end
		return nil
		end
local scoreData = readLuaFromJsonFile(scorefile)

	if not scoreData then
	print('** Scoreboard// Could not read scoreData from file: '.. scorefile)
	return
	end
--
	tl = #scoreData
	if tl > 0  then
			tc = 1
			repeat
				local status = tostring(scoreData[tc].status)
				local date = tostring(scoreData[tc].datetime)
				local time = tostring(scoreData[tc].time)
				local home = tostring(scoreData[tc].home_team.country)
				local away = tostring(scoreData[tc].away_team.country)
				local hgoal = tostring(scoreData[tc].home_team.goals)
				local agoal = tostring(scoreData[tc].away_team.goals)
				
				local pattern = "(%d+)%-(%d+)%-(%d+)T(%d+):(%d+):(%d+)"
				local year, month, day, hour, minute, seconds = date:match(pattern)
				hour = hour + 1

				show = (home..' '..hgoal..' - '..agoal..' '..away)

					if status == 'in progress' then 
					    show = (show..' '..time)
					    tc = tl + 1 
					    end
					if status == 'completed' then
						local score = (hgoal..' - '..agoal)
						local winner = tostring(scoreData[tc].winner)
						if winner == 'Draw' then 
						   show = ('Draw '..home..' '..hgoal..' - '..agoal..' '..away)
						   else 
						   show = ('Match won by '..winner..' with '..score)
						 end
						tc = tc + 1						
					end
					if status == 'future' then 
					    show = (show..' KO '..hour..':'..minute)
					    tc = tl + 1 
					end
				until tc > tl
					if show ~= prevboard then
					    print ('result '..show)
						board.updateText(show)
					end			

    end
end
}
Image

Re: World Cup Scoreboard - new version

Posted: Tuesday 19 June 2018 20:45
by freakshock
Thanks for the scripts elmortero & mike! :P

Re: World Cup Scoreboard - new version

Posted: Friday 22 June 2018 19:04
by MikeF
I'm now getting this error when I run this (the pre-HTTPresponses version):

Code: Select all

2018-06-22 18:01:04.516 Error: dzVents: Error: An error occured when calling event handler scoreboarrd
2018-06-22 18:01:04.516 Error: dzVents: Error: Lua script execution exceeds maximum number of lines 
Any clues? Is it looping (more than it should!)?

Re: World Cup Scoreboard - new version

Posted: Friday 22 June 2018 19:22
by MikeF
There are problems with the feed today. The matches are in the wrong order, with the wrong times, and the 3rd match (which appears second) is showing a status of 'pending correction' - which the dzVents script doesn't recognise.