Skip to content

Commit

Permalink
First work on a weather plugin. See #5
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-gromeyer committed May 22, 2023
1 parent 272b002 commit 35519c1
Show file tree
Hide file tree
Showing 9 changed files with 602 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "3rdparty/11Zip"]
path = 3rdparty/11Zip
url = https://github.com/Sygmei/11Zip
[submodule "plugins/weather/icons"]
path = plugins/weather/icons
url = https://github.com/Makin-Things/weather-icons
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ endif()
if(BUILD_TEST_PLUGIN)
message(STATUS "Building a test plugin")
add_subdirectory(plugins/testPlugin)
add_subdirectory(plugins/weather)
endif()

target_include_directories(voiceassistant PRIVATE src)
Expand Down
43 changes: 43 additions & 0 deletions plugins/weather/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
cmake_minimum_required(VERSION 3.14)

project(weatherPlugin LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(Dirs)
include(Plugins)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets OPTIONAL_COMPONENTS Positioning)

if (NOT Qt${QT_VERSION_MAJOR}Positioning_FOUND)
message(WARNING "Qt Positioning not found. The weather plugin will not be build")
return()
endif()

add_plugin(weatherPlugin CLASS_NAME WeatherPlugin)
target_sources(weatherPlugin PUBLIC
../base.h
../bridge.h
../utils.h
weatherdata.cpp
weatherdata.h
weatherplugin.cpp
weatherplugin.h
)
target_link_libraries(weatherPlugin PUBLIC
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Positioning
)

add_custom_command(TARGET weatherPlugin POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:weatherPlugin> ${PLUGINS_DIR}
COMMAND_EXPAND_LISTS
)

set(PLUGINS ${PLUGINS} weatherPlugin PARENT_SCOPE)
1 change: 1 addition & 0 deletions plugins/weather/icons
Submodule icons added at 3793c6
1 change: 1 addition & 0 deletions plugins/weather/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
201 changes: 201 additions & 0 deletions plugins/weather/weatherdata.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
#include "weatherdata.h"

#include <QDebug>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>

std::string getIconPath(WeatherData::WeatherCode code, bool isDay)
{
std::string path = "icons/";
switch (code) {
case WeatherData::ClearSky:
case WeatherData::MainlyClear:
path += isDay ? "animated/clear-day.svg" : "animated/clear-night.svg";
break;
case WeatherData::PartlyCloudy:
path += isDay ? "animated/cloudy-3-day.svg" : "animated/cloudy-3-night.svg";
break;
case WeatherData::Overcast:
path += "animated/cloudy.svg";
break;
case WeatherData::Fog:
case WeatherData::DepositingRimeFog:
path += isDay ? "animated/fog-day.svg" : "animated/fog-night.svg";
break;
case WeatherData::DrizzleLight:
case WeatherData::DrizzleModerate:
case WeatherData::DrizzleDense:
case WeatherData::FreezingDrizzleLight:
case WeatherData::FreezingDrizzleDense:
path += isDay ? "bom/app/08_light_rain.svg" : "bom/app/08_light_rain_night.svg";
break;
case WeatherData::RainSlight:
case WeatherData::RainModerate:
case WeatherData::RainHeavy:
case WeatherData::FreezingRainLight:
case WeatherData::FreezingRainHeavy:
path += isDay ? "bom/app/12_rain.svg" : "bom/app/12_rain_night.svg";
break;
case WeatherData::SnowFallSlight:
case WeatherData::SnowFallModerate:
case WeatherData::SnowFallHeavy:
case WeatherData::SnowGrains:
path += isDay ? "bom/app/15_snow.svg" : "bom/app/15_snow_night.svg";
break;
case WeatherData::RainShowersSlight:
case WeatherData::RainShowersModerate:
case WeatherData::RainShowersViolent:
path += isDay ? "bom/app/17_light_showers.svg" : "bom/app/17_light_showers_night.svg";
break;
case WeatherData::SnowShowersSlight:
case WeatherData::SnowShowersHeavy:
path += isDay ? "bom/app/18_heavy_showers.svg" : "bom/app/18_heavy_showers_night.svg";
break;
case WeatherData::ThunderstormSlight:
case WeatherData::ThunderstormSlightHail:
case WeatherData::ThunderstormHeavyHail:
path += isDay ? "animated/thunderstorms.svg" : "animated/scattered-thunderstorms-night.svg";
break;
default:
path += isDay ? "bom/app/00_missing_data.svg" : "bom/app/00_missing_night.svg";
path += "animated/weather.svg";
break;
}
return path;
}

WeatherData::WeatherData(QObject *parent)
: QObject(parent)
{}

// Parse JSON data into struct
void WeatherData::parseWeatherData(const QByteArray &jsonData)
{
hourlyWeatherList.clear();

QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData);
QJsonObject jsonObject = jsonDoc.object();

// Daily object
QJsonObject dailyObject = jsonObject[QStringLiteral("daily")].toObject();
QJsonArray dailyTimesArray = dailyObject[QStringLiteral("times")].toArray();
QJsonArray dailyTempMin = dailyObject[QStringLiteral("temperature_2m_min")].toArray();
QJsonArray dailyTempMax = dailyObject[QStringLiteral("temperature_2m_max")].toArray();
QJsonArray dailySunrise = dailyObject[QStringLiteral("sunrise")].toArray();
QJsonArray dailySunset = dailyObject[QStringLiteral("sunset")].toArray();
QJsonArray dailyUVIndex = dailyObject[QStringLiteral("uv_index_max")].toArray();

for (int i = 0; i < dailyTimesArray.size(); ++i) {
QString dateString = dailyTimesArray[i].toString();
double tempMin = dailyTempMin[i].toDouble();
double tempMax = dailyTempMax[i].toDouble();
QString sunriseString = dailySunrise[i].toString();
QString sunsetString = dailySunrise[i].toString();
double uvIndex = dailyUVIndex[i].toDouble();

QDate date = QDate::fromString(dateString, Qt::ISODate);
QDateTime sunrise = QDateTime::fromString(sunriseString, Qt::ISODate);
QDateTime sunset = QDateTime::fromString(sunsetString, Qt::ISODate);

DailyWeather dailyWeather;
dailyWeather.day = date;
dailyWeather.sunrise = sunrise;
dailyWeather.sunset = sunset;
dailyWeather.tempMin = tempMin;
dailyWeather.tempMax = tempMax;
dailyWeather.uvIndex = uvIndex;

dailyWeatherList.append(dailyWeather);
}

// Hourly object
QJsonObject hourlyObject = jsonObject[QStringLiteral("hourly")].toObject();
QJsonArray timeArray = hourlyObject[QStringLiteral("time")].toArray();
QJsonArray temperatureArray = hourlyObject[QStringLiteral("temperature_2m")].toArray();
QJsonArray apparentTempArray = hourlyObject[QStringLiteral("apparent_temperature")].toArray();
QJsonArray windspeedArray = hourlyObject[QStringLiteral("windspeed_10m")].toArray();
QJsonArray winddirectionArray = hourlyObject[QStringLiteral("winddirection_10m")].toArray();
QJsonArray weatherCodeArray = hourlyObject[QStringLiteral("weathercode")].toArray();
QJsonArray relativehumidityArray = hourlyObject[QStringLiteral("relativehumidity_2m")].toArray();
QJsonArray visibilityArray = hourlyObject[QStringLiteral("visibility")].toArray();
QJsonArray isDayArray = hourlyObject[QStringLiteral("is_day")].toArray();

for (int i = 0; i < timeArray.size(); ++i) {
QString timeString = timeArray[i].toString();
double temperature = temperatureArray[i].toDouble();
double apparentTemp = apparentTempArray[i].toDouble();
double windspeed = windspeedArray[i].toDouble();
double winddirection = winddirectionArray[i].toDouble();
int weatherCode = weatherCodeArray[i].toInt();
int relativehumidity = relativehumidityArray[i].toInt();
double visibility = visibilityArray[i].toDouble();
bool isDay = isDayArray[i].toInt();

QDateTime time = QDateTime::fromString(timeString, Qt::ISODate);

HourlyWeather hourlyWeather;
hourlyWeather.time = time;
hourlyWeather.temperature = temperature;
hourlyWeather.apparentTemp = apparentTemp;
hourlyWeather.windspeed = windspeed;
hourlyWeather.winddirection = winddirection;
hourlyWeather.weathercode = convertToWeatherCode(weatherCode);
hourlyWeather.relativehumidity = relativehumidity;
hourlyWeather.visibility = convertVisibilityToRange(visibility);
hourlyWeather.is_day = isDay;

hourlyWeatherList.append(hourlyWeather);

for (DailyWeather &dailyWeather : dailyWeatherList) {
if (dailyWeather.day == time.date())
dailyWeather.hours.append(hourlyWeather);
}
}

// Convert the list with the hourly weather to a list with daily weather
for (const HourlyWeather &hourlyWeather : qAsConst(hourlyWeatherList)) {
bool foundDay = false;
for (DailyWeather &dailyWeather : dailyWeatherList) {
if (dailyWeather.day == hourlyWeather.time.date()) {
// Add the hourly weather data to the existing day
dailyWeather.hours.append(hourlyWeather);
foundDay = true;
break;
}
}

// If the day doesn't exist, create a new DailyWeather entry
if (!foundDay) {
DailyWeather newDay;
newDay.day = hourlyWeather.time.date();
newDay.hours.append(hourlyWeather);
newDay.sunrise = QDateTime();
newDay.sunset = QDateTime();
newDay.uvIndex = 0;
newDay.tempMin = 0;
newDay.tempMax = 0;
dailyWeatherList.append(newDay);
}
}

// Print the parsed data
for (const HourlyWeather &weather : qAsConst(hourlyWeatherList)) {
qDebug() << "Time:" << weather.time.toString(QStringLiteral("yyyy-MM-dd hh:mm"));
qDebug() << "Temperature:" << weather.temperature;
qDebug() << "Apparent temperature:" << weather.apparentTemp;
qDebug() << "Relative humidity:" << weather.relativehumidity;
qDebug() << "Windspeed:" << weather.windspeed;
qDebug() << "Winddirection:" << weather.winddirection;
qDebug() << "Weather Code:" << weather.weathercode;
qDebug() << "Visibility:" << weather.visibility;
qDebug() << "Is Day:" << weather.is_day;
qDebug() << "-----------------------------------";
}
}

QDebug operator<<(QDebug debug, const WeatherData &data)
{
// TODO: Implement
return debug;
}

0 comments on commit 35519c1

Please sign in to comment.