Skip to content

Commit

Permalink
Add a new GUI screen for a single day of weather.
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisveilleux committed May 12, 2021
1 parent 4c62179 commit 42924ca
Show file tree
Hide file tree
Showing 2 changed files with 217 additions and 21 deletions.
73 changes: 52 additions & 21 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,19 @@ def handle_sunset(self, message: Message):
dialog.build_sunset_dialog()
self._speak_weather(dialog)

def _display_sunrise_sunset_mark_ii(
self, forecast: DailyWeather, intent_data: WeatherIntent
):
"""Display the sunrise and sunset.
:param forecast: daily forecasts to display
"""
self.gui.clear()
self.gui["sunrise"] = forecast.sunrise
self.gui["sunset"] = forecast.sunset
self.gui["ampm"] = True
self.gui.show_page("sunrise_sunset_mark_ii.qml")

def _report_current_weather(self, message: Message):
"""Handles all requests for current weather conditions.
Expand All @@ -561,6 +574,7 @@ def _report_current_weather(self, message: Message):
self._speak_weather(dialog)
if self.gui.connected and self.platform != MARK_II:
self._display_more_current_conditions(weather)
dialog = CurrentDialog(intent_data, self.weather_config, weather.current)
dialog.build_high_low_temperature_dialog()
self._speak_weather(dialog)
if self.gui.connected:
Expand All @@ -570,7 +584,7 @@ def _report_current_weather(self, message: Message):
self._display_hourly_forecast(weather)
else:
four_day_forecast = weather.daily[1:5]
self._display_forecast(four_day_forecast)
self._display_multi_day_forecast(four_day_forecast)

def _display_current_conditions(
self, weather: WeatherReport, intent_data: WeatherIntent
Expand Down Expand Up @@ -690,35 +704,52 @@ def _display_hourly_forecast(self, weather: WeatherReport):
self.gui["hourlyForecast"] = dict(hours=hourly_forecast)
self.gui.show_page("hourly_mark_ii.qml")

def _report_multi_day_forecast(self, message: Message, days: int):
"""Handles all requests for multiple day forecasts.
def _report_one_day_forecast(self, message: Message):
"""Handles all requests for a single day forecast.
:param message: Message Bus event information from the intent parser
"""
intent_data = WeatherIntent(message, self.lang)
weather = self._get_weather(intent_data)
if weather is not None:
try:
forecast = weather.get_forecast_for_multiple_days(days)
except IndexError:
self.speak_dialog("seven.days.available")
forecast = weather.get_forecast_for_multiple_days(7)
dialogs = self._build_forecast_dialogs(forecast, intent_data)
self._display_forecast(forecast)
forecast = weather.get_forecast_for_date(intent_data)
dialogs = self._build_forecast_dialogs([forecast], intent_data)
if self.platform == MARK_II:
self._display_one_day_mark_ii(forecast, intent_data)
for dialog in dialogs:
self._speak_weather(dialog)

def _report_one_day_forecast(self, message: Message):
"""Handles all requests for a single day forecast.
def _display_one_day_mark_ii(
self, forecast: DailyWeather, intent_data: WeatherIntent
):
"""Display the forecast for a single day on a Mark II.
:param forecast: daily forecasts to display
"""
self.gui.clear()
self.gui["weatherLocation"] = self._build_display_location(intent_data)
self.gui["weatherCode"] = self.image_codes[forecast.condition.icon]
self.gui["weatherDate"] = forecast.date_time.strftime("%A %x")
self.gui["highTemperature"] = forecast.temperature.high
self.gui["lowTemperature"] = forecast.temperature.low
self.gui["chanceOfPrecipitation"] = str(forecast.chance_of_precipitation)
self.gui.show_page("single_day_mark_ii.qml")

def _report_multi_day_forecast(self, message: Message, days: int):
"""Handles all requests for multiple day forecasts.
:param message: Message Bus event information from the intent parser
"""
intent_data = WeatherIntent(message, self.lang)
weather = self._get_weather(intent_data)
if weather is not None:
forecast = [weather.get_forecast_for_date(intent_data)]
try:
forecast = weather.get_forecast_for_multiple_days(days)
except IndexError:
self.speak_dialog("seven.days.available")
forecast = weather.get_forecast_for_multiple_days(7)
dialogs = self._build_forecast_dialogs(forecast, intent_data)
self._display_forecast(forecast)
self._display_multi_day_forecast(forecast)
for dialog in dialogs:
self._speak_weather(dialog)

Expand All @@ -732,7 +763,7 @@ def _report_weekend_forecast(self, message: Message):
if weather is not None:
forecast = weather.get_weekend_forecast()
dialogs = self._build_forecast_dialogs(forecast, intent_data)
self._display_forecast(forecast)
self._display_multi_day_forecast(forecast)
for dialog in dialogs:
self._speak_weather(dialog)

Expand Down Expand Up @@ -768,7 +799,7 @@ def _report_week_summary(self, message: Message):
forecast = weather.get_forecast_for_multiple_days(7)
dialogs = self._build_weekly_condition_dialogs(forecast, intent_data)
dialogs.append(self._build_weekly_temperature_dialog(forecast, intent_data))
self._display_forecast(forecast)
self._display_multi_day_forecast(forecast)
for dialog in dialogs:
self._speak_weather(dialog)

Expand Down Expand Up @@ -808,17 +839,17 @@ def _build_weekly_temperature_dialog(

return dialog

def _display_forecast(self, forecast: List[DailyWeather]):
def _display_multi_day_forecast(self, forecast: List[DailyWeather]):
"""Display daily forecast data on devices that support the GUI.
:param forecast: daily forecasts to display
"""
if self.platform == MARK_II:
self._display_forecast_mark_ii(forecast)
self._display_multi_day_mark_ii(forecast)
else:
self._display_forecast_scalable(forecast)
self._display_multi_day_scalable(forecast)

def _display_forecast_mark_ii(self, forecast: List[DailyWeather]):
def _display_multi_day_mark_ii(self, forecast: List[DailyWeather]):
"""Display daily forecast data on a Mark II.
The Mark II supports displaying four days of a forecast at a time.
Expand All @@ -845,7 +876,7 @@ def _display_forecast_mark_ii(self, forecast: List[DailyWeather]):
self.gui["dailyForecast"] = dict(days=daily_forecast[4:])
self.gui.show_page(page_name)

def _display_forecast_scalable(self, forecast: List[DailyWeather]):
def _display_multi_day_scalable(self, forecast: List[DailyWeather]):
"""Display daily forecast data on GUI devices other than the Mark II.
The generic layout supports displaying two days of a forecast at a time.
Expand Down
165 changes: 165 additions & 0 deletions ui/single_day_mark_ii.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Copyright 2021, Mycroft AI Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*
One of many screns that show when the user asks for the current weather.
Shows an image representing current conditions, the current temperature, and
the high/low temperature for today.
This code is specific to the Mark II device. It uses a grid of 32x32 pixel
squares for alignment of items.
*/
import QtQuick.Layouts 1.4
import QtQuick 2.4
import QtQuick.Controls 2.0

WeatherDelegateMarkII {
id: root

Item {
// Bounding box for the content of the screen.
id: card
height: parent.height
width: parent.width

WeatherLabel {
// The date of the weather forecast being displayed
id: weatherDate
heightUnits: 4
fontSize: 48
fontStyle: "Medium"
text: sessionData.weatherDate
}

WeatherLabel {
// City/state if in same country as device. City/country if in a different country
id: weatherLocation
anchors.top: weatherDate.bottom
heightUnits: 4
fontSize: 48
fontStyle: "Medium"
text: sessionData.weatherLocation
}

GridLayout {
id: weather
anchors.left: parent.left
anchors.leftMargin: gridUnit * 2
anchors.top: weatherLocation.bottom
anchors.topMargin: gridUnit * 2
columns: 2
columnSpacing: gridUnit * 2
width: gridUnit * 20

Item {
// First column in grid
id: weatherConditions
height: gridUnit * 14
width: parent.width

WeatherImage {
id: forecastCondition
heightUnits: 6
imageSource: Qt.resolvedUrl(getWeatherImagery(sessionData.weatherCode))
}

WeatherLabel {
id: precipitation
anchors.top: forecastCondition.bottom
anchors.topMargin: gridUnit * 2
heightUnits: 6
fontSize: 118
fontStyle: "Regular"
text: sessionData.chanceOfPrecipitation + "%"
}

Label {
// Chance of precipitation for the day.
id: currentTemperature
anchors.baseline: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
font.family: "Noto Sans Display"
font.pixelSize: 118
font.styleName: "Light"
text: sessionData.chanceOfPrecipitation + "%"
}
}

Column {
// Second column in grid
id: highLowTemperature
height: gridUnit * 14
spacing: gridUnit * 2
width: parent.width

Item {
// High temperature for today
id: highTemperature
height: gridUnit * 6
width: parent.width

Image {
id: highTemperatureIcon
anchors.bottom: parent.bottom
anchors.left: highTemperature.left
anchors.leftMargin: gridUnit * 2
fillMode: Image.PreserveAspectFit
height: gridUnit * 4
source: Qt.resolvedUrl("images/high_temperature.svg")
}

Label {
id: highTemperatureValue
anchors.baseline: parent.bottom
anchors.left: highTemperatureIcon.right
anchors.leftMargin: gridUnit * 2
font.family: "Noto Sans Display"
font.pixelSize: 118
font.styleName: "SemiBold"
text: sessionData.highTemperature + "°"
}
}

Item {
// Low temperature for today
id: lowTemperature
height: gridUnit * 6
width: parent.width

Image {
id: lowTemperatureIcon
anchors.bottom: parent.bottom
anchors.left: lowTemperature.left
anchors.leftMargin: gridUnit * 2
fillMode: Image.PreserveAspectFit
height: gridUnit * 4
source: Qt.resolvedUrl("images/low_temperature.svg")
}

Label {
id: lowTemperatureValue
anchors.baseline: parent.bottom
anchors.left: lowTemperatureIcon.right
anchors.leftMargin: gridUnit * 2
font.family: "Noto Sans Display"
font.pixelSize: 118
font.styleName: "Light"
text: sessionData.lowTemperature + "°"
}
}
}
}
}
}

0 comments on commit 42924ca

Please sign in to comment.