Let's play with Dinfio!
This is fun and great project using Raspberry Pi and Dinfio. Let's build DIY analogue clock featured the following widgets:
clock.fio
file and weather_icons
directory. Open Terminal and run the project:
$ dinfio clock.fio
' Clock with prayer times and weather widgets using Dinfio
import time
import gui, math, string
import url, json
import fileio
var name = "Your name"
var city = "Depok"
var country = "Indonesia"
var kemenag_city = "1225" ' Depok, ID. Please see https://bit.ly/API-myQuran-v2
var latitude = -6.3658284
var longitude = 106.8163953
var api_key = "Your OpenWeather API Key"
var current_day = get_day()
var current_hour = get_hour()
var current_minute = -1
var panel_index = 0
var total_panels = 4
var width = 200, height = 200
var window_width = width + 256
var window_height = height + 128
var center_x = width / 2, center_y = height / 2
var radius = center_x
var colour_window = colour.hex("10061c")
var colour_line = colour.hex("404040")
var colour_line_alt = colour.hex("404040")
var colour_back = colour.hex("c0c0c0")
var colour_title = colour.hex("a0a0a0")
var colour_label = colour.hex("a0a0a0")
var colour_weather = colour.hex("e0e0e0")
var dir = getfoldername(getcurrentfile())
var prayer_times = [
["Fajr", "", 0],
["Dhuhr", "", 0],
["Asr", "", 0],
["Maghrib", "", 0],
["Isha", "", 0]
]
' Weather data will not be updated in this hours for the energy saver
var sleep_hours = [
22, 23, 0, 1, 2, 3, 4
]
var weather_request = {
lat: latitude,
lon: longitude,
units: "metric",
exclude: "minutely,daily",
appid: api_key
}
start
window = gui_window("Clock + Prayer Times", window_width, window_height)
canvas = gui_panel(window, 20, 78, width + 5, height + 5, true)
label_title = gui_label("Clock Widget using Dinfio", window, 20, 14)
timer = gui_timer(1000, draw())
' This is using Kemenag RI (Indonesia only) API,
' use load_prayertimes() if you want to connect to international aladhan.com API instead
timer_load = gui_timer(1000, load_prayertimes_kemenag_ri())
timer_load_weather = gui_timer(2000, load_weather())
panel = []
panel[0] = gui_panel(window, 250, 68, window_width, window_height)
panel[1] = gui_panel(window, 250, 68, window_width, window_height)
panel[2] = gui_panel(window, 250, 68, window_width, window_height)
panel[3] = gui_panel(window, 250, 68, window_width, window_height)
left = 0
top = 0
margin = 28
margin_alt = 52
' Prayer times
label_closest = gui_label("Getting data...", panel[0], left, top)
label_header_fajr = gui_label("", panel[0], left, label_closest.gety() + margin_alt)
label_header_dhuhr = gui_label("", panel[0], left, label_header_fajr.gety() + margin)
label_header_asr = gui_label("", panel[0], left, label_header_dhuhr.gety() + margin)
label_header_maghrib = gui_label("", panel[0], left, label_header_asr.gety() + margin)
label_header_isha = gui_label("", panel[0], left, label_header_maghrib.gety() + margin)
label_fajr = gui_label("", panel[0], left + 100, label_closest.gety() + margin_alt)
label_dhuhr = gui_label("", panel[0], left + 100, label_header_fajr.gety() + margin)
label_asr = gui_label("", panel[0], left + 100, label_header_dhuhr.gety() + margin)
label_maghrib = gui_label("", panel[0], left + 100, label_header_asr.gety() + margin)
label_isha = gui_label("", panel[0], left + 100, label_header_maghrib.gety() + margin)
label_temp = gui_label("", panel[0], left, label_header_isha.gety() + margin + 20)
' Weather
label_weather = gui_label("Getting data...", panel[1], left, top + 94)
image_weather = gui_imagebox(dir & "/weather_icons/01d.png", panel[1], left, top)
label_weather_detail = gui_label("", panel[1], left, top + 140, 180, 120)
' Hourly forecast
label_hourly_title1 = gui_label("Hourly Forecast", panel[2], left, top)
label_hourly_title2 = gui_label("Hourly Forecast", panel[3], left, top)
label_hourly1 = gui_label("", panel[2], left, label_hourly_title1.gety() + margin_alt, 180, 300)
label_hourly2 = gui_label("", panel[3], left, label_hourly_title2.gety() + margin_alt, 180, 300)
' Styles
window.setbackgroundcolour(colour_window)
canvas.setbackgroundcolour(colour_window)
panel[0].setbackgroundcolour(colour_window)
panel[1].setbackgroundcolour(colour_window)
panel[2].setbackgroundcolour(colour_window)
panel[3].setbackgroundcolour(colour_window)
panel[0].setvisible(false)
panel[1].setvisible(true)
panel[2].setvisible(false)
panel[3].setvisible(false)
label_title.setfontsize(20)
label_title.setfontbold(true)
label_title.setforegroundcolour(colour_weather)
label_closest.setfontsize(18)
label_closest.setfontbold(true)
label_closest.setforegroundcolour(colour_weather)
label_header_fajr.setfontsize(14)
label_header_dhuhr.setfontsize(14)
label_header_asr.setfontsize(14)
label_header_maghrib.setfontsize(14)
label_header_isha.setfontsize(14)
label_fajr.setfontsize(14)
label_dhuhr.setfontsize(14)
label_asr.setfontsize(14)
label_maghrib.setfontsize(14)
label_isha.setfontsize(14)
label_header_fajr.setforegroundcolour(colour_label)
label_header_dhuhr.setforegroundcolour(colour_label)
label_header_asr.setforegroundcolour(colour_label)
label_header_maghrib.setforegroundcolour(colour_label)
label_header_isha.setforegroundcolour(colour_label)
label_fajr.setforegroundcolour(colour_label)
label_dhuhr.setforegroundcolour(colour_label)
label_asr.setforegroundcolour(colour_label)
label_maghrib.setforegroundcolour(colour_label)
label_isha.setforegroundcolour(colour_label)
label_temp.setfontsize(10)
label_temp.setforegroundcolour(colour_label)
label_weather.setfontsize(18)
label_weather.setfontbold(true)
label_weather.setforegroundcolour(colour_weather)
label_weather_detail.setfontsize(14)
label_weather_detail.setforegroundcolour(colour_label)
label_hourly_title1.setfontsize(18)
label_hourly_title1.setfontbold(true)
label_hourly_title1.setforegroundcolour(colour_weather)
label_hourly_title2.setfontsize(18)
label_hourly_title2.setfontbold(true)
label_hourly_title2.setforegroundcolour(colour_weather)
label_hourly1.setfontsize(14)
label_hourly1.setforegroundcolour(colour_label)
label_hourly2.setfontsize(14)
label_hourly2.setforegroundcolour(colour_label)
window.addevent(event.mouseleftdown, toggle_fullscreen())
window.setfullscreen(true)
window.show()
timer.run()
timer_load.run()
timer_load_weather.run()
if !in_sleep_hours()
label_title.settext(datetime("%A, %e %B %Y"))
toggle_widget_enable = true
else
label_title.settext("Good night, " & name & ".")
toggle_widget_enable = false
panel[0].setvisible(true)
panel[1].setvisible(false)
panel[2].setvisible(false)
panel[3].setvisible(false)
endif
draw()
stop
function draw()
seconds = get_second() * 6 - 90
minutes = (get_minute() + get_second() / 60) * 6 - 90
hours = (get_hour() + get_minute() / 60) * 30 - 90
canvas.draw_clear()
canvas.draw_setpen(colour_line_alt, 0)
canvas.draw_setbrush(colour_back)
canvas.draw_circle(center_x, center_y, radius)
canvas.draw_setpen(colour_line, 0)
canvas.draw_setbrush(colour_line)
canvas.draw_circle(center_x, center_y, 7)
for i, 30, 360, 30
if i != 360 && i != 90 && i != 180 && i != 270
canvas.draw_circle((radius - 20) * cosd(i) + center_x, (radius - 20) * sind(i) + center_y, 2)
endif
endfor
canvas.draw_setpen(colour_line, 6)
canvas.draw_line(center_x, center_y, (radius - 48) * cosd(hours) + center_x, (radius - 48) * sind(hours) + center_y)
canvas.draw_setpen(colour_line, 4)
canvas.draw_line(center_x, center_y, (radius - 24) * cosd(minutes) + center_x, (radius - 24) * sind(minutes) + center_y)
canvas.draw_setpen(colour_line, 2)
canvas.draw_line(center_x, center_y, (radius - 20) * cosd(seconds) + center_x, (radius - 20) * sind(seconds) + center_y)
canvas.draw_line(center_x, center_y, 18 * -cosd(seconds) + center_x, 18 * -sind(seconds) + center_y)
canvas.draw_settextcolour(colour_line)
canvas.draw_setfont(14)
canvas.draw_text("12", (radius - 20) * cosd(-90) + center_x - 10, (radius - 20) * sind(-90) + center_y - 10)
canvas.draw_text("6", (radius - 20) * cosd(90) + center_x - 5, (radius - 20) * sind(90) + center_y - 10)
canvas.draw_text("3", (radius - 20) * cosd(0) + center_x - 5, (radius - 20) * sind(0) + center_y - 10)
canvas.draw_text("9", (radius - 20) * cosd(180) + center_x - 5, (radius - 20) * sind(180) + center_y - 10)
canvas.refresh()
calculate_closest()
stop
function load_prayertimes_kemenag_ri()
timer_load.pause()
date = datetime("%Y/%m/%d")
response = url.get("https://api.myquran.com/v2/sholat/jadwal/" & kemenag_city & "/" & date)
if response.code == 200
data = json.decode(response.body)
if data.status == true
timings = data.data.jadwal
prayer_times[0][1] = timings.subuh
prayer_times[1][1] = timings.dzuhur
prayer_times[2][1] = timings.ashar
prayer_times[3][1] = timings.maghrib
prayer_times[4][1] = timings.isya
prayer_times[0][2] = getnumber(replace(timings.subuh, ":", ""))
prayer_times[1][2] = getnumber(replace(timings.dzuhur, ":", ""))
prayer_times[2][2] = getnumber(replace(timings.ashar, ":", ""))
prayer_times[3][2] = getnumber(replace(timings.maghrib, ":", ""))
prayer_times[4][2] = getnumber(replace(timings.isya, ":", ""))
label_header_fajr.settext("Fajr:")
label_header_dhuhr.settext("Dhuhr:")
label_header_asr.settext("Asr:")
label_header_maghrib.settext("Maghrib:")
label_header_isha.settext("Isha:")
label_fajr.settext(prayer_times[0][1])
label_dhuhr.settext(prayer_times[1][1])
label_asr.settext(prayer_times[2][1])
label_maghrib.settext(prayer_times[3][1])
label_isha.settext(prayer_times[4][1])
calculate_closest()
else
label_closest.settext("API Error")
endif
elseif response.code != 0
label_closest.settext("Error: HTTP " & response.code)
else
label_closest.settext(response.error_string)
endif
stop
function load_prayertimes()
timer_load.pause()
request = {
city: city,
country: country,
method: 4 ' Umm al-Qura University, Makkah
}
response = url.get("https://api.aladhan.com/v1/timingsByCity", request)
if response.code == 200
data = json.decode(response.body)
timings = data.data.timings
prayer_times[0][1] = timings.fajr
prayer_times[1][1] = timings.dhuhr
prayer_times[2][1] = timings.asr
prayer_times[3][1] = timings.maghrib
prayer_times[4][1] = timings.isha
prayer_times[0][2] = getnumber(replace(timings.fajr, ":", ""))
prayer_times[1][2] = getnumber(replace(timings.dhuhr, ":", ""))
prayer_times[2][2] = getnumber(replace(timings.asr, ":", ""))
prayer_times[3][2] = getnumber(replace(timings.maghrib, ":", ""))
prayer_times[4][2] = getnumber(replace(timings.isha, ":", ""))
label_header_fajr.settext("Fajr:")
label_header_dhuhr.settext("Dhuhr:")
label_header_asr.settext("Asr:")
label_header_maghrib.settext("Maghrib:")
label_header_isha.settext("Isha:")
label_fajr.settext(prayer_times[0][1])
label_dhuhr.settext(prayer_times[1][1])
label_asr.settext(prayer_times[2][1])
label_maghrib.settext(prayer_times[3][1])
label_isha.settext(prayer_times[4][1])
calculate_closest()
elseif response.code != 0
label_closest.settext("Error: HTTP " & response.code)
else
label_closest.settext(response.error_string)
endif
stop
function load_weather()
timer_load_weather.pause()
response = url.get("https://api.openweathermap.org/data/2.5/onecall", weather_request)
if response.code == 200
data = json.decode(response.body)
temperature = round(data.current.temp, 0) & "°C"
description = data.current.weather[0].description
description = ucase(substring(description, 0, 1)) & substring(description, 1)
icon = data.current.weather[0].icon
label_weather.settext(data.current.weather[0].main & " / " & temperature)
label_weather_detail.settext(description & "\n" & city)
image_weather.setimage(dir & "/weather_icons/" & icon & ".png")
' Hourly forecast
hourly = data.hourly
hourly1 = ""
hourly2 = ""
for i, 0, 5
hour = datetime("%H:00", hourly[i].dt)
pop = round(hourly[i].pop * 100) & "%"
hourly1 = hourly1 & hour & " " & hourly[i].weather[0].main & " " & pop & "\n"
endfor
for i, 6, 11
hour = datetime("%H:00", hourly[i].dt)
pop = round(hourly[i].pop * 100) & "%"
hourly2 = hourly2 & hour & " " & hourly[i].weather[0].main & " " & pop & "\n"
endfor
label_hourly1.settext(hourly1)
label_hourly2.settext(hourly2)
elseif response.code != 0
label_weather.settext("Error: HTTP " & response.code)
else
label_weather.settext(response.error_string)
endif
stop
function calculate_closest()
if prayer_times[0][1] != ""
closest = inf
index = 0
hour = get_hour()
minute = get_minute()
minute = iif(minute < 10, "0" & minute, minute)
for i, 0, 4
dist = prayer_times[i][2] - getnumber(hour & minute)
if dist < closest && dist >= 0
closest = dist
index = i
endif
endfor
label_closest.settext(prayer_times[index][0] & ": " & prayer_times[index][1])
endif
if get_day() != current_day
current_day = get_day()
label_closest.settext("Getting data...")
timer_load.run()
endif
if get_hour() != current_hour
current_hour = get_hour()
if !in_sleep_hours()
label_title.settext(datetime("%A, %e %B %Y"))
toggle_widget_enable = true
label_weather.settext("Getting data...")
timer_load_weather.run()
else
label_title.settext("Good night, " & name & ".")
toggle_widget_enable = false
panel[0].setvisible(true)
panel[1].setvisible(false)
panel[2].setvisible(false)
panel[3].setvisible(false)
endif
endif
if get_minute() != current_minute
current_minute = get_minute()
label_temp.settext("CPU Temp: " & get_temperature() & "°C")
endif
if toggle_widget_enable
if get_second() % 10 == 0
toggle_widget()
endif
endif
stop
function in_sleep_hours()
hour = get_hour()
yield false
for i, 0, size(sleep_hours) - 1
if hour == sleep_hours[i]
return true
endif
endfor
stop
function get_temperature()
return round(getnumber(filecontent("/sys/class/thermal/thermal_zone0/temp")) / 1000, 1)
stop
function toggle_widget()
for i, 0, total_panels - 1
panel[i].setvisible(false)
endfor
panel_index += 1
if panel_index >= total_panels; panel_index = 0; endif
panel[panel_index].setvisible(true)
stop
function toggle_fullscreen()
window.setfullscreen(!window.isfullscreen())
stop