-
+
+
-
+
diff --git a/src/programy/clients/webchat/static/y-bot.js b/src/programy/clients/webchat/static/y-bot.js
index 57e25f67b..3bdb25c69 100644
--- a/src/programy/clients/webchat/static/y-bot.js
+++ b/src/programy/clients/webchat/static/y-bot.js
@@ -4,6 +4,31 @@ $(document).ready(function(){
$("#chatbox").append ("
Bot:Hello, my name is Y-Bot, how can I help you today?
" );
$("#chatbox").append ("
" );
+ $(".question").click(function() {
+
+ var question = $(this).text()
+
+ var xhttp = new XMLHttpRequest();
+ xhttp.onload = function () {
+ if (this.status == 200 && this.responseText != null) {
+ var response = JSON.parse(this.responseText);
+
+ $("#chatbox").append ("
You: "+response.response.question+"
" );
+ $("#chatbox").append ("
Bot: "+response.response.answer+"
" );
+ $("#chatbox").append ("
" );
+
+ $("#chatbox")[0].scrollTop = $("#chatbox")[0].scrollHeight;
+
+ }
+ }
+
+ xhttp.open("GET", "/api/v1.0/ask?question="+question+"&clientid=webchat");
+ xhttp.setRequestHeader("Content-type", "application/json");
+ xhttp.send();
+
+ return false;
+ });
+
$("#submitmsg").click(function(){
var question = $("#usermsg").val();
diff --git a/src/programy/extensions/admin/rdf.py b/src/programy/extensions/admin/rdf.py
index ee727a39e..ff82eff10 100644
--- a/src/programy/extensions/admin/rdf.py
+++ b/src/programy/extensions/admin/rdf.py
@@ -31,10 +31,13 @@ def execute(self, bot, clientid, data):
segments = data.split()
if segments[0] == 'SUBJECTS':
subjects = bot.brain.rdf.subjects()
- rdf += "
"
- for subject in subjects:
- rdf += "- %s
"%subject
- rdf += "
"
+ if segments[1] == 'LIST':
+ rdf += "
"
+ for subject in subjects:
+ rdf += "- %s
"%subject
+ rdf += "
"
+ else:
+ return str(len(subjects))
elif segments[0] == "PREDICATES":
subject = segments[1]
diff --git a/src/programy/extensions/weather/weather.py b/src/programy/extensions/weather/weather.py
index 2313d757c..c8ede09ef 100644
--- a/src/programy/extensions/weather/weather.py
+++ b/src/programy/extensions/weather/weather.py
@@ -23,34 +23,86 @@
class WeatherExtension(Extension):
+ # WEATHER [OBSERVATION|FORECAST3|FORECAST24] LOCATION * WHEN *
+
# execute() is the interface that is called from the
tag in the AIML
def execute(self, bot, clientid, data):
splits = data.split()
- if len(splits) < 4:
+ if len(splits) != 5:
+ if logging.getLogger().isEnabledFor(logging.DEBUG):
+ logging.debug("Weather - Not enough paramters passed, [%d] expected 5"%len(splits))
+ return None
+
+ type = splits[0]
+ if type not in ['OBSERVATION', 'FORECAST3', 'FORECAST24']:
+ if logging.getLogger().isEnabledFor(logging.DEBUG):
+ logging.debug("Weather - Type not understood [%s]"%type)
return None
- if splits[0] == 'LOCATION':
- postcode = splits[1]
+ if splits[1] == 'LOCATION':
+ postcode = splits[2]
else:
+ if logging.getLogger().isEnabledFor(logging.DEBUG):
+ logging.debug("Weather - LOCATION missing")
return None
- if splits[2] == 'WHEN':
- when = splits[3]
+ if splits[3] == 'WHEN':
+ when = splits[4]
+ else:
+ if logging.getLogger().isEnabledFor(logging.DEBUG):
+ logging.debug("Weather - WHEN missing")
+ return None
+
+ if type == 'OBSERVATION':
+ return self.get_observation(bot, clientid, postcode, when)
+ elif type == 'FORECAST3':
+ return self.get_forecast3(bot, clientid, postcode, when)
+ elif type == 'FORECAST24':
+ return self.get_forecast24(bot, clientid, postcode, when)
+
+ def get_observation(self, bot, clientid, postcode, when):
+ if logging.getLogger().isEnabledFor(logging.DEBUG):
+ logging.debug("Getting weather observation for [%s] at time [%s]"%(postcode, when))
+
+ googlemaps = GoogleMaps(bot.license_keys)
+ latlng = googlemaps.get_latlong_for_location(postcode)
+
+ met_office = MetOffice(bot.license_keys)
+
+ observation = met_office.current_observation(latlng.latitude, latlng.longitude)
+ if observation is not None:
+ return observation.get_latest().to_program_y_text()
else:
return None
+ def get_forecast3(self, bot, clientid, postcode, when):
if logging.getLogger().isEnabledFor(logging.DEBUG):
- logging.debug("Getting weather for %s at time %s", postcode, when)
+ logging.debug("Getting 3 hourly weather forecast for [%s] at time [%s]"%(postcode, when))
googlemaps = GoogleMaps(bot.license_keys)
latlng = googlemaps.get_latlong_for_location(postcode)
+ met_office = MetOffice(bot.license_keys)
+
+ forecast = met_office.three_hourly_forecast(latlng.latitude, latlng.longitude)
+ if forecast is not None:
+ return forecast.get_latest().to_program_y_text()
+ else:
+ return None
+
+ def get_forecast24(self, bot, clientid, postcode, when):
if logging.getLogger().isEnabledFor(logging.DEBUG):
- logging.debug("Weather - Calling external weather service for with extra data [%s]", data)
+ logging.debug("Getting 24 hour weather forecast for [%s] at time [%s]"%(postcode, when))
+
+ googlemaps = GoogleMaps(bot.license_keys)
+ latlng = googlemaps.get_latlong_for_location(postcode)
met_office = MetOffice(bot.license_keys)
- observation = met_office.current_observation(latlng.latitude, latlng.longitude)
+ forecast = met_office.daily_forecast(latlng.latitude, latlng.longitude)
+ if forecast is not None:
+ return forecast.get_latest().to_program_y_text()
+ else:
+ return None
- return observation.get_latest().to_program_y_text()
diff --git a/src/programy/utils/weather/metoffice.py b/src/programy/utils/weather/metoffice.py
index 91cb6b1ec..ebdaefdd2 100644
--- a/src/programy/utils/weather/metoffice.py
+++ b/src/programy/utils/weather/metoffice.py
@@ -41,6 +41,7 @@
PRESSURE_TENDANCY = {'F': "Falling",
'R': 'Rising'}
+
class DataPoint(object):
def extract_attribute(self, json_data, name, data_type, time_period=None):
@@ -64,6 +65,7 @@ def direction_to_full_text(self, direction):
return DIRECTIONS[direction]
return "Unknown"
+
class DailyForecastDayDataPoint(DataPoint):
def __init__(self):
@@ -87,7 +89,18 @@ def __init__(self):
#
#
def to_program_y_text(self):
- return "WEATHER %s"%(
+ return "WEATHER TYPE %s WINDDIR %s WINDSPEED %s WINDGUST %s TEMP %s FEELS %s HUMID %d RAINPROB %s UVINDEX %s UVGUIDE %s VIS %s WEATHER %s"%(
+ self._type,
+ self._wind_direction,
+ self._wind_speed,
+ self._wind_gust_noon,
+ self._temp_max,
+ self._temperature_feels_like_max,
+ self._screen_relative_humidity_noon,
+ self._precipitation_probability,
+ self._uv_index_max,
+ self._uv_guidance,
+ self._visibility_text,
self._weather_type_text
)
@@ -110,6 +123,7 @@ def parse_json(self, json_data, data_type, time_period):
if self._weather_type_code is not None:
self._weather_type_text = metoffer.WEATHER_CODES[int(self._weather_type_code)]
+
class DailyForecastNightDataPoint(DataPoint):
def __init__(self):
@@ -131,7 +145,16 @@ def __init__(self):
#
#
def to_program_y_text(self):
- return "WEATHER %s"%(
+ return "WEATHER TYPE %s WINDDIR %s WINDGUST %s WINDSPEED %s TEMP %s FEELS %s HUMID %s RAINPROB %s VISTEXT %s WEATHER %s"%(
+ self._weather_type_text,
+ self._wind_direction,
+ self._wind_gust_midnight,
+ self._wind_speed,
+ self._temp_min,
+ self._temperature_feels_like_min,
+ self._screen_relative_humidity_midnight,
+ self._precipitation_probability,
+ self._visibility_text,
self._weather_type_text
)
@@ -151,6 +174,7 @@ def parse_json(self, json_data, data_type, time_period):
if self._weather_type_code is not None:
self._weather_type_text = metoffer.WEATHER_CODES[int(self._weather_type_code)]
+
class ThreeHourlyForecastDataPoint(DataPoint):
def __init__(self):
@@ -205,16 +229,21 @@ def parse_json(self, json_data, data_type, time_period):
#
#
def to_program_y_text(self):
- return "WEATHER %s TEMP %s TF %s WIND D %s F %s S %s VISIBILITY %s UV I %s G %s RAIN %s HUMIDITY %s"%(
+ return "WEATHER %s TEMP %s FEELS %s WINDDIR %s WINDDIRFULL %s WINDSPEED %s VIS %s UVINDEX %s UVGUIDE %s RAINPROB %s HUMIDITY %s"%(
self._weather_type_text,
- self._temperature, self._temperature_feels_like,
- self._wind_direction, self._wind_direction_full, self._wind_speed,
+ self._temperature,
+ self._temperature_feels_like,
+ self._wind_direction,
+ self._wind_direction_full,
+ self._wind_speed,
self._visibility_text,
- self._uv_index_max, self._uv_guidance,
+ self._uv_index_max,
+ self._uv_guidance,
self._precipitation_probability,
self._screen_relative_humidity
)
+
class ObservationDataPoint(DataPoint):
def __init__(self):
@@ -290,6 +319,7 @@ def parse_pressure_tendancy(self, tendancy):
return PRESSURE_TENDANCY[tendancy]
return "Unknown"
+
class Report(object):
def __init__(self, data_type, time_period):
@@ -434,6 +464,7 @@ def parse_json(self, json_data):
else:
raise ValueError("name missing from Location data")
+
class DV(object):
def __init__(self, data_type, time_period):
@@ -461,6 +492,7 @@ def parse_json(self, json_data):
else:
raise ValueError("type missing from DV data")
+
class SiteReport(object):
def __init__(self, data_type, time_period):
diff --git a/test/programytest/extensions/weather/test_weather.py b/test/programytest/extensions/weather/test_weather.py
index 75a2ac62e..b1a2a9df9 100644
--- a/test/programytest/extensions/weather/test_weather.py
+++ b/test/programytest/extensions/weather/test_weather.py
@@ -29,15 +29,34 @@ def test_observation(self):
weather = WeatherExtension()
self.assertIsNotNone(weather)
- result = weather.execute(self.test_client.bot, self.clientid, "LOCATION KY39UR WHEN NOW")
+ result = weather.execute(self.test_client.bot, self.clientid, "OBSERVATION LOCATION KY39UR WHEN NOW")
self.assertIsNotNone(result)
self.assertEquals("WEATHER Partly cloudy (day) TEMP 12 3 VISIBILITY V 35000 VF Very Good WIND D SW DF South West S 10 PRESSURE P 1017 PT F PTF Falling HUMIDITY 57 3", result)
- result = weather.execute(self.test_client.bot, self.clientid, "OTHER KY39UR WHEN NOW")
+ result = weather.execute(self.test_client.bot, self.clientid, "OBSERVATION OTHER KY39UR WHEN NOW")
self.assertIsNone(result)
- result = weather.execute(self.test_client.bot, self.clientid, "LOCATION KY39UR OTHER NOW")
+ result = weather.execute(self.test_client.bot, self.clientid, "OBSERVATION LOCATION KY39UR OTHER NOW")
self.assertIsNone(result)
result = weather.execute(self.test_client.bot, self.clientid, "")
self.assertIsNone(result)
+
+ def test_forecast3(self):
+
+ weather = WeatherExtension()
+ self.assertIsNotNone(weather)
+
+ result = weather.execute(self.test_client.bot, self.clientid, "FORECAST3 LOCATION KY39UR WHEN NOW")
+ self.assertIsNotNone(result)
+ print(result)
+ self.assertEquals("WEATHER Overcast TEMP 10 FEELS 10 WINDDIR NW WINDDIRFULL North West WINDSPEED 4 VIS Very good - Between 20-40 km UVINDEX 0 UVGUIDE None RAINPROB 8 HUMIDITY 73", result)
+
+ def test_forecast24(self):
+
+ weather = WeatherExtension()
+ self.assertIsNotNone(weather)
+
+ result = weather.execute(self.test_client.bot, self.clientid, "FORECAST24 LOCATION KY39UR WHEN NOW")
+ self.assertIsNotNone(result)
+ self.assertEquals("WEATHER TYPE Cloudy WINDDIR NW WINDGUST 7 WINDSPEED 4 TEMP 8 FEELS 8 HUMID 76 RAINPROB 8 VISTEXT Very good - Between 20-40 km WEATHER Cloudy", result)