// Abstract ------------------------------------------------------------------------------------------------------------------------------
This sample fetchs data from openweathermap.org (as JSON) and import it as knowledge. You will need an API key (free) to try/use this sample (see http://openweathermap.org/appid)
// Examples ------------------------------------------------------------------------------------------------------------------------------
$
./fizz.x64 ./etc/samples/weather.fizz -c api.key=\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"
fizz 0.2.0-X (20180218.1219) [x64|8|w]
load : loading ./etc/samples/weather.fizz ...
load : loaded ./etc/samples/weather.fizz in 0.088s
repeal: city.weather.latest(5808079, _)
assert: city.weather.latest(5808079, 1519150500)
assert: city.weather.stamp(5808079, 1519150500)
assert: city.name(5808079, Redmond)
assert: weather.condition(600, Snow, "light snow")
assert: weather.condition(701, Mist, mist)
assert: city.weather.details(5808079, 1519150500, temp, -0.130000)
assert: city.weather.details(5808079, 1519150500, pressure, 1022)
assert: city.weather.details(5808079, 1519150500, humidity, 86)
assert: city.weather.condition(5808079, 1519150500, 600)
assert: city.weather.details(5808079, 1519150500, temp_min, -2)
assert: city.weather.condition(5808079, 1519150500, 701)
assert: city.weather.details(5808079, 1519150500, temp_max, 1)
Redmond: light snow
Redmond: mist
Redmond: -0.130000
repeal: city.weather.latest(5856195, _)
assert: city.weather.latest(5856195, 1519153020)
assert: city.weather.stamp(5856195, 1519153020)
assert: city.name(5856195, Honolulu)
assert: weather.condition(801, Clouds, "few clouds")
assert: city.weather.details(5856195, 1519153020, temp, 21.650000)
assert: city.weather.condition(5856195, 1519153020, 801)
assert: city.weather.details(5856195, 1519153020, pressure, 1015)
assert: city.weather.details(5856195, 1519153020, humidity, 64)
assert: city.weather.details(5856195, 1519153020, temp_min, 20)
assert: city.weather.details(5856195, 1519153020, temp_max, 23)
Honolulu: 21.650000
Honolulu: few clouds
repeal: city.weather.latest(2988507, _)
assert: city.weather.latest(2988507, 1519153200)
assert: city.weather.stamp(2988507, 1519153200)
assert: city.name(2988507, Paris)
assert: weather.condition(500, Rain, "light rain")
assert: weather.condition(615, Snow, "light rain and snow")
assert: city.weather.details(2988507, 1519153200, temp, 4.120000)
assert: city.weather.details(2988507, 1519153200, pressure, 1019)
assert: city.weather.condition(2988507, 1519153200, 500)
assert: city.weather.details(2988507, 1519153200, humidity, 75)
assert: city.weather.details(2988507, 1519153200, temp_min, 3)
assert: city.weather.condition(2988507, 1519153200, 615)
assert: city.weather.details(2988507, 1519153200, temp_max, 5)
Paris: 4.120000
Paris: light rain
Paris: light rain and snow
repeal: city.weather.latest(5808079, _)
assert: city.weather.latest(5808079, 1519154880)
assert: city.weather.stamp(5808079, 1519154880)
assert: city.name(5808079, Redmond)
assert: weather.condition(600, Snow, "light snow")
assert: weather.condition(701, Mist, mist)
assert: city.weather.details(5808079, 1519154880, temp, 0.550000)
assert: weather.condition(500, Rain, "light rain")
assert: city.weather.details(5808079, 1519154880, pressure, 1022)
assert: city.weather.details(5808079, 1519154880, humidity, 100)
assert: city.weather.condition(5808079, 1519154880, 600)
assert: city.weather.details(5808079, 1519154880, temp_min, -1)
assert: city.weather.details(5808079, 1519154880, temp_max, 2)
assert: city.weather.condition(5808079, 1519154880, 701)
assert: city.weather.condition(5808079, 1519154880, 500)
Redmond: 0.550000
Redmond: light snow
Redmond: mist
Redmond: light rain
repeal: city.weather.latest(2988507, _)
assert: city.weather.latest(2988507, 1519155000)
assert: city.weather.stamp(2988507, 1519155000)
assert: city.name(2988507, Paris)
assert: weather.condition(500, Rain, "light rain")
assert: weather.condition(615, Snow, "light rain and snow")
assert: city.weather.details(2988507, 1519155000, temp, 4.130000)
assert: city.weather.condition(2988507, 1519155000, 500)
assert: city.weather.details(2988507, 1519155000, pressure, 1019)
assert: city.weather.details(2988507, 1519155000, humidity, 75)
assert: city.weather.condition(2988507, 1519155000, 615)
assert: city.weather.details(2988507, 1519155000, temp_min, 3)
assert: city.weather.details(2988507, 1519155000, temp_max, 5)
Paris: 4.130000
Paris: light rain
Paris: light rain and snow
save : completed in 0.016s.
// Code ----------------------------------------------------------------------------------------------------------------------------------
// query the latest temperature for a given city
weather.temp {
(:name,:v) :- #city.name(:id,:name),
#city.weather.latest(:id,:dt),
#city.weather.details(:id,:dt,temp,:v);
}
// query the latest conditions for a given city
weather.cond {
(:name,:d) :- #city.name(:id,:name),
#city.weather.latest(:id,:dt),
#fzz.collect([],city.weather.condition(:id,:dt,:l),_,{tmo=0.1}),
#code.to.desc(:l,:d);
}
// wrap the primitive 'assert' so that what is being asserted during execution can be more easily seen (in the console)
assert {
(:f) :- console.puts("assert: ",:f), assert(:f);
}
// wrap the primitive 'repeal' so that what is being repealed during execution can be more easily seen (in the console)
repeal {
(:f) :- console.puts("repeal: ",:f), repeal(:f);
}
// a ticking elemental (10s interval) used to automatically save the data received so far
auto.save.tick {class = FZZCTicker, tick = 10} {
}
// performs the automatic saving of all weather data knowledge
auto.save {
() :- @auto.save.tick(:n,_),
console.exec(save("weather.data.fizz",city.name,city.weather.stamp,city.weather.latest,city.weather.condition,city.weather.details,weather.condition));
}
// will store the city-id / city-name mapping
city.name {
}
// will store the latest stamp received for a city
city.weather.latest {
}
// will store the time-stamp received per city, we will it to ignore the data retrieved from the service when they haven't changed
city.weather.stamp {
class = MRKCLettered,
no.match = fail
} {
}
// will store a city's weather conditions (over time)
city.weather.condition {
}
// will store a city's weather details (temperature, pressure ...)
city.weather.details {
}
// will store the condition-id / condition-description mapping
weather.condition {
}
// a web API puller elemental, fetching data every 5 seconds
web.weather.puller {
class = FZZCWebAPIPuller,
tick = 5.0,
url.host = "http://api.openweathermap.org",
url.path = "/data/2.5/weather",
url.query = { q = Redmond, units = metric, APPID = $api.key }
} {
}
// a web API puller elemental, fetching data every 5 seconds
web.weather.puller {
class = FZZCWebAPIPuller,
tick = 5.0,
url.host = "http://api.openweathermap.org",
url.path = "/data/2.5/weather",
url.query = { q = Honolulu, units = metric, APPID = $api.key }
} {
}
// a web API puller elemental, fetching data every 5 seconds
web.weather.puller {
class = FZZCWebAPIPuller,
tick = 5.0,
url.host = "http://api.openweathermap.org",
url.path = "/data/2.5/weather",
url.query = { q = Paris, units = metric, APPID = $api.key }
} {
}
// the main entry point for the data pulled from the web sites
web.weather.input {
() :- @web.weather.puller(:t,:s?[neq(200)],_,:content),
frm.fetch(:content,message,:message),
console.puts("pulling error: ",:s," ",:message);
() :- @web.weather.puller(:t,200,_,:content),
frm.fetch(:content,id,:id),
frm.fetch(:content,name,:city),
frm.fetch(:content,dt,:dt),
!#city.weather.stamp(:id,:dt),
change([city.weather.latest(:id,_)],[city.weather.latest(:id,:dt)]),
#assert(city.weather.stamp(:id,:dt)),
#assert(city.name(:id,:city)),
frm.fetch(:content,:key,:value),
#web.weather.parse(:id,:dt,:key,:value);
}
// parse some of the data received from the web service
web.weather.parse {
(:city.id,:dt,weather,:l?[is.list])^ :- #web.weather.parse.weather(:city.id,:dt,:l);
(:city.id,:dt,main,:f?[is.frame])^ :- #web.weather.parse.main(:city.id,:dt,:f);
}
// parse the weather condition and assert the corresponding statements
web.weather.parse.weather {
(:city.id,:dt,:l) :- lst.item(:l,_,:f),
frm.fetch(:f,id,:i), frm.fetch(:f,main,:m), frm.fetch(:f,description,:d),
#assert(weather.condition(:i,:m,:d)),
#assert(city.weather.condition(:city.id,:dt,:i));
}
// parse the weather details
web.weather.parse.main {
(:city.id,:dt,:f)^ :- frm.fetch(:f,:label,:value), #assert(city.weather.details(:city.id,:dt,:label,:value));
}
// display (on the console) the temperature and weather condition for each city, whenever we receive new data
web.weather.watcher {
() :- @city.weather.details(:id,_,temp,:v), #city.name(:id,:n), console.puts(:n,": ",:v);
() :- @city.weather.condition(:id,_,:c), #city.name(:id,:n), #weather.condition(:c,_,:d), console.puts(:n,": ",:d);
}
// convert a list of condition codes to a list of descriptions
code.to.desc {
([],[]) ^:- true;
([:e],[:f]) ^:- #weather.condition(:e,_,:f);
([:h|:t],[:h2|:t2]) ^:- #code.to.desc(:t,:t2), #weather.condition(:h,_,:h2);
}
// ---------------------------------------------------------------------------------------------------------------------------------------
[Home] [Email] [Twitter] [LinkedIn]