/* * Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: ZHAI Kang-ning **/ #include "weathermanager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include const QString weatherServerAddr = "http://service.ubuntukylin.com:8001/weather/api/3.0/heweather_data_s6/"; const QString defaultCityId = "101030100"; //"101030100" 默认天津 const int weatherReqInterval = 1000 * 60 * 20; //定时更新天气,和麒麟天气保持一致 const QByteArray schemaWeather = "org.china-weather-data.settings"; static const QMap weatherMap { {"晴", "100"},{"多云", "101"},{"少云", "102"},{"晴间多云", "103"},{"阴", "104"}, {"有风", "200"},{"平静", "201"},{"微风", "202"},{"和风", "203"},{"清风", "204"},{"强风劲风", "205"},{"疾风", "206"},{"大风", "207"},{"烈风", "208"},{"风暴", "209"}, {"狂暴风", "210"},{"飓风", "211"},{"龙卷风", "212"},{"热带风暴", "213"}, {"阵雨", "300"},{"强阵雨", "301"},{"雷阵雨", "302"},{"强雷阵雨", "303"},{"雷阵雨伴有冰雹", "304"},{"小雨", "305"},{"中雨", "306"},{"大雨", "307"},{"极端降雨", "308"},{"毛毛雨细雨", "309"}, {"暴雨", "310"},{"大暴雨", "311"},{"特大暴雨", "312"},{"冻雨", "313"},{"小到中雨", "314"},{"中到大雨", "315"},{"大到暴雨", "316"},{"暴雨到大暴雨", "317"},{"大暴雨到特大暴雨", "318"}, {"雨", "399"}, {"小雪", "400"},{"中雪", "401"},{"大雪", "402"},{"暴雪", "403"},{"雨夹雪", "404"},{"雨雪天气", "405"},{"阵雨夹雪", "406"},{"阵雪", "407"},{"小到中雪", "408"},{"中到大雪", "409"}, {"大到暴雪", "410"},{"雪", "499"}, {"薄雾", "500"},{"雾", "501"},{"霾", "502"},{"扬沙", "503"},{"浮尘", "504"},{"沙尘暴", "507"},{"强沙尘暴", "508"},{"大雾", "509"}, {"强浓雾", "510"},{"中度霾", "511"},{"重度霾", "512"},{"严重霾", "513"},{"大雾", "514"},{"特强浓雾", "515"}, {"热", "900"},{"冷", "901"}, {"未知", "999"} }; WeatherManager::WeatherManager(QObject *parent) : QObject(parent) { //初始化m_net_manager请求天气 m_net_manager = new QNetworkAccessManager(this); QObject::connect(m_net_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*))); m_timer = new QTimer(this); m_timer->setInterval(weatherReqInterval); m_local_weather_info = new LocalWeatherInfo(this); connect(m_timer, &QTimer::timeout, this, &WeatherManager::weatherRequest); m_networkWatcher = new NetWorkWatcher(this); connect(m_networkWatcher, &NetWorkWatcher::NetworkStateChanged, this, &WeatherManager::onNetworkStateChanged); m_networkWatcher->checkOnline(); } void WeatherManager::onNetworkStateChanged(uint state) { qDebug() << state; if (NM_STATE_CONNECTED_GLOBAL != state) emit onWeatherUpdate("天气不可用", NULL, NULL); else getWeather(); } void WeatherManager::getWeather() { weatherRequest(); if (m_timer != NULL) { m_timer->start(); } return; } void WeatherManager::weatherRequest() { if (updateLocation()) return; QNetworkRequest request(QUrl(weatherServerAddr + m_city_id + "/")); m_net_manager->get(request); } bool WeatherManager::updateLocation() { //更新城市信息 未实现 麒麟天气提供gsettings,完成后对接 if (QGSettings::isSchemaInstalled(schemaWeather)) { m_settings = new QGSettings(schemaWeather,"",this); //org/ukui/indicator-china-weather path if(getLogcalWeather()) { emit onWeatherUpdate(m_local_weather_info->getCityName(), m_local_weather_info->getCondText(), m_local_weather_info->getTemperature()); m_networkWatcher->checkOnline(); return true; } m_city_id = getLogcalCityId(); } if (m_city_id.isEmpty()) m_city_id = defaultCityId; return false; } bool WeatherManager::getLogcalWeather() { if (m_settings != nullptr) { //"1920-08-27 10:17:42,101310204,澄迈,小雨,95%,25℃,北风,1级," 时间,城市编码,城市名称,天气,湿度,温度,风向,风力 QString weather = m_settings->get("weather").toString(); QStringList weatherInfoList = weather.split(","); if (weatherInfoList.size() < 9) return false; m_local_weather_info->setTime(weatherInfoList.at(0)); if(!m_local_weather_info->isTimeValid()) return false; m_local_weather_info->setCityId(weatherInfoList.at(1)); m_local_weather_info->setCityName(weatherInfoList.at(2)); m_local_weather_info->setCondText(weatherInfoList.at(3)); m_local_weather_info->setAirHumidity(weatherInfoList.at(4)); m_local_weather_info->setTemperature(weatherInfoList.at(5)); m_local_weather_info->setWindDirection(weatherInfoList.at(6)); m_local_weather_info->setWindForce(weatherInfoList.at(7)); return true; } return false; } QString WeatherManager::getLogcalCityId() { if (m_settings != nullptr) { QString citys = m_settings->get("citylist").toString();//"101010100," if (citys.isEmpty()) return ""; QStringList cityList = citys.split(","); if (cityList.size() >= 1) { QString s = cityList.at(0); qDebug() << "local city id = " << s; return s; } } return ""; } void WeatherManager::replyFinished(QNetworkReply *reply) { if(reply != nullptr && reply->error() != QNetworkReply::NoError) { qWarning() << "[WeatherManager][replyFinished] get weather error:(" << reply->error() << ")" << reply->errorString(); if (m_networkTryNum < 15) { m_networkTryNum++; QTimer::singleShot(1000, this, [=]{ weatherRequest(); }); } else { m_networkTryNum = 0; } emit onWeatherUpdate("天气不可用", "", ""); return; } //注:天气信息只解析了锁屏需要展示的部分 QByteArray BA; QJsonDocument JD; QJsonParseError JPE; BA = reply->readAll(); // QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // QString all = codec->toUnicode(BA); // qDebug() << "reply is:" << all; JD = QJsonDocument::fromJson(BA, &JPE); if (JPE.error == QJsonParseError::NoError) { if (JD.isObject()) { QJsonObject kylinWeatherObj = JD.object().value("KylinWeather").toObject(); QString nowWeather = kylinWeatherObj.value("weather").toObject().value("now").toString(); m_city_name = kylinWeatherObj.value("weather").toObject().value("location").toString(); QStringList nowList = nowWeather.split(","); for(QString now : nowList) { if(now.contains("cond_txt")) { m_cond_txt = now.mid(9); } if (now.contains("tmp")){ m_temperature = now.mid(4) + "°C"; } } emit onWeatherUpdate(m_city_name, m_cond_txt, m_temperature); } } else { qWarning() << "get weather info error : " << JPE.errorString(); emit onWeatherUpdate("天气不可用", "", ""); } reply->deleteLater(); } QPixmap WeatherManager::getWeatherIcon() { return getWeatherIcon(m_cond_txt); } QPixmap WeatherManager::getWeatherIcon(QString cond) { if (cond.isEmpty()) { qWarning() << "cond info is unknown"; return QPixmap(":/weather/assets/weather-icon/999.svg").scaled(32,32); } //根据m_cond_txt QString numStr = weatherMap.value(cond); if (!numStr.isEmpty()) { qDebug() << "----------------numStr=" + numStr; return QPixmap(":/weather/assets/weather-icon/" + numStr +".svg").scaled(32,32); } qWarning() << "天气为|" << cond << "|"; return QPixmap(":/weather/assets/weather-icon/999.svg").scaled(32,32); } QString WeatherManager::getCityName() { return ""; } QString WeatherManager::getCond() { return ""; } QString WeatherManager::getTemperature() { return ""; } LocalWeatherInfo::LocalWeatherInfo(QObject *parent) { } bool LocalWeatherInfo::isTimeValid() { if (m_update_time != nullptr && !m_update_time.isEmpty()) { QString strBuffer; QDateTime time = QDateTime::fromString(m_update_time, "yyyy-MM-dd hh:mm:ss"); QDateTime currentTime = QDateTime::currentDateTime(); if (!time.isValid()) return false; uint timeInterval = currentTime.toTime_t() - time.toTime_t(); if((timeInterval <= 21 * 60) && (timeInterval > 0)) { //麒麟天气更新时间为20分钟,加入1分钟容错机制 return true; } } return false; } void LocalWeatherInfo::setTime(QString time) { m_update_time = time; } QString LocalWeatherInfo::getTime() { return m_update_time; } void LocalWeatherInfo::setCityId(QString cityId) { m_city_id = cityId; } QString LocalWeatherInfo::getCityId() { return m_city_id; } void LocalWeatherInfo::setCityName(QString cityName) { m_city_name = cityName; } QString LocalWeatherInfo::getCityName() { return m_city_name; } void LocalWeatherInfo::setCondText(QString condText) { m_cond_text = condText; } QString LocalWeatherInfo::getCondText() { return m_cond_text; } void LocalWeatherInfo::setAirHumidity(QString airHumidity) { m_air_humidity = airHumidity; } QString LocalWeatherInfo::getAirHumidity() { return m_air_humidity; } void LocalWeatherInfo::setTemperature(QString temperature) { m_temperature = temperature; } QString LocalWeatherInfo::getTemperature() { return m_temperature; } void LocalWeatherInfo::setWindDirection(QString windDirection) { m_wind_direction = windDirection; } QString LocalWeatherInfo::getWindDirection() { return m_wind_direction; } void LocalWeatherInfo::setWindForce(QString windForce) { m_wind_force = windForce; } QString LocalWeatherInfo::getWindForce() { return m_wind_force; }