File indexing completed on 2024-05-12 07:36:28
0001 /* Ekos Observatory Module 0002 SPDX-FileCopyrightText: Wolfgang Reissenberger <sterne-jaeger@t-online.de> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "observatoryweathermodel.h" 0008 #include "Options.h" 0009 #include <KLocalizedString> 0010 0011 namespace Ekos 0012 { 0013 0014 void ObservatoryWeatherModel::initModel(Weather *weather) 0015 { 0016 weatherInterface = weather; 0017 0018 // ensure that we start the timers if required 0019 weatherChanged(status()); 0020 0021 connect(weatherInterface, &Weather::ready, this, [&]() 0022 { 0023 initialized = true; 0024 emit updateWeatherStatus(); 0025 }); 0026 connect(weatherInterface, &Weather::newStatus, this, &ObservatoryWeatherModel::weatherChanged); 0027 connect(weatherInterface, &Weather::newWeatherData, this, &ObservatoryWeatherModel::updateWeatherData); 0028 connect(weatherInterface, &Weather::newWeatherData, this, &ObservatoryWeatherModel::newWeatherData); 0029 connect(weatherInterface, &Weather::disconnected, this, [&]() 0030 { 0031 emit disconnected(); 0032 initialized = false; 0033 }); 0034 0035 // read the default values 0036 warningActionsActive = Options::warningActionsActive(); 0037 warningActions.parkDome = Options::weatherWarningCloseDome(); 0038 warningActions.closeShutter = Options::weatherWarningCloseShutter(); 0039 warningActions.delay = Options::weatherWarningDelay(); 0040 alertActionsActive = Options::alertActionsActive(); 0041 alertActions.parkDome = Options::weatherAlertCloseDome(); 0042 alertActions.closeShutter = Options::weatherAlertCloseShutter(); 0043 alertActions.delay = Options::weatherAlertDelay(); 0044 m_autoScaleValues = Options::weatherAutoScaleValues(); 0045 0046 // not implemented yet 0047 warningActions.stopScheduler = false; 0048 alertActions.stopScheduler = false; 0049 0050 warningTimer.setInterval(static_cast<int>(warningActions.delay * 1000)); 0051 warningTimer.setSingleShot(true); 0052 alertTimer.setInterval(static_cast<int>(alertActions.delay * 1000)); 0053 alertTimer.setSingleShot(true); 0054 0055 connect(&warningTimer, &QTimer::timeout, [this]() 0056 { 0057 execute(warningActions); 0058 }); 0059 connect(&alertTimer, &QTimer::timeout, [this]() 0060 { 0061 execute(alertActions); 0062 }); 0063 0064 if (weatherInterface->status() != ISD::Weather::WEATHER_IDLE) 0065 emit ready(); 0066 0067 initialized = true; 0068 } 0069 0070 ISD::Weather::Status ObservatoryWeatherModel::status() 0071 { 0072 if (weatherInterface == nullptr) 0073 return ISD::Weather::WEATHER_IDLE; 0074 0075 return weatherInterface->status(); 0076 } 0077 0078 bool ObservatoryWeatherModel::refresh() 0079 { 0080 return weatherInterface->refresh(); 0081 } 0082 0083 void ObservatoryWeatherModel::setWarningActionsActive(bool active) 0084 { 0085 warningActionsActive = active; 0086 Options::setWarningActionsActive(active); 0087 0088 // stop warning actions if deactivated 0089 if (!active && warningTimer.isActive()) 0090 warningTimer.stop(); 0091 // start warning timer if activated 0092 else if (weatherInterface->status() == ISD::Weather::WEATHER_WARNING) 0093 startWarningTimer(); 0094 } 0095 0096 void ObservatoryWeatherModel::startWarningTimer() 0097 { 0098 if (warningActionsActive && (warningActions.parkDome || warningActions.closeShutter || warningActions.stopScheduler)) 0099 { 0100 if (!warningTimer.isActive()) 0101 warningTimer.start(); 0102 } 0103 else if (warningTimer.isActive()) 0104 warningTimer.stop(); 0105 } 0106 0107 void ObservatoryWeatherModel::setAlertActionsActive(bool active) 0108 { 0109 alertActionsActive = active; 0110 Options::setAlertActionsActive(active); 0111 0112 // stop alert actions if deactivated 0113 if (!active && alertTimer.isActive()) 0114 alertTimer.stop(); 0115 // start alert timer if activated 0116 else if (weatherInterface->status() == ISD::Weather::WEATHER_ALERT) 0117 startAlertTimer(); 0118 } 0119 0120 void ObservatoryWeatherModel::setAutoScaleValues(bool value) 0121 { 0122 m_autoScaleValues = value; 0123 Options::setWeatherAutoScaleValues(value); 0124 } 0125 0126 void ObservatoryWeatherModel::startAlertTimer() 0127 { 0128 if (alertActionsActive && (alertActions.parkDome || alertActions.closeShutter || alertActions.stopScheduler)) 0129 { 0130 if (!alertTimer.isActive()) 0131 alertTimer.start(); 0132 } 0133 else if (alertTimer.isActive()) 0134 alertTimer.stop(); 0135 } 0136 0137 void ObservatoryWeatherModel::setWarningActions(WeatherActions actions) 0138 { 0139 warningActions = actions; 0140 Options::setWeatherWarningCloseDome(actions.parkDome); 0141 Options::setWeatherWarningCloseShutter(actions.closeShutter); 0142 Options::setWeatherWarningDelay(actions.delay); 0143 if (!warningTimer.isActive()) 0144 warningTimer.setInterval(static_cast<int>(actions.delay * 1000)); 0145 0146 if (weatherInterface->status() == ISD::Weather::WEATHER_WARNING) 0147 startWarningTimer(); 0148 } 0149 0150 0151 QString ObservatoryWeatherModel::getWarningActionsStatus() 0152 { 0153 if (warningTimer.isActive()) 0154 { 0155 int remaining = warningTimer.remainingTime() / 1000; 0156 return i18np("%1 second remaining", "%1 seconds remaining", remaining); 0157 } 0158 0159 return i18n("Status: inactive"); 0160 } 0161 0162 void ObservatoryWeatherModel::setAlertActions(WeatherActions actions) 0163 { 0164 alertActions = actions; 0165 Options::setWeatherAlertCloseDome(actions.parkDome); 0166 Options::setWeatherAlertCloseShutter(actions.closeShutter); 0167 Options::setWeatherAlertDelay(actions.delay); 0168 if (!alertTimer.isActive()) 0169 alertTimer.setInterval(static_cast<int>(actions.delay * 1000)); 0170 0171 if (weatherInterface->status() == ISD::Weather::WEATHER_ALERT) 0172 startAlertTimer(); 0173 } 0174 0175 QString ObservatoryWeatherModel::getAlertActionsStatus() 0176 { 0177 if (alertTimer.isActive()) 0178 { 0179 int remaining = alertTimer.remainingTime() / 1000; 0180 return i18np("%1 second remaining", "%1 seconds remaining", remaining); 0181 } 0182 0183 return i18n("Status: inactive"); 0184 } 0185 0186 void ObservatoryWeatherModel::updateWeatherStatus() 0187 { 0188 weatherChanged(status()); 0189 emit ready(); 0190 } 0191 0192 0193 void ObservatoryWeatherModel::weatherChanged(ISD::Weather::Status status) 0194 { 0195 switch (status) 0196 { 0197 case ISD::Weather::WEATHER_OK: 0198 warningTimer.stop(); 0199 alertTimer.stop(); 0200 break; 0201 case ISD::Weather::WEATHER_WARNING: 0202 alertTimer.stop(); 0203 startWarningTimer(); 0204 break; 0205 case ISD::Weather::WEATHER_ALERT: 0206 warningTimer.stop(); 0207 startAlertTimer(); 0208 break; 0209 default: 0210 break; 0211 } 0212 emit newStatus(status); 0213 } 0214 0215 void ObservatoryWeatherModel::updateWeatherData(const std::vector<ISD::Weather::WeatherData> &data) 0216 { 0217 // add or update all received values 0218 for (auto &oneEntry : data) 0219 { 0220 // update if already existing 0221 unsigned long pos = findWeatherData(oneEntry.name); 0222 if (pos < m_WeatherData.size()) 0223 m_WeatherData[pos].value = oneEntry.value; 0224 // new weather sensor? 0225 else if (oneEntry.name.startsWith("WEATHER_")) 0226 m_WeatherData.push_back({QString(oneEntry.name), QString(oneEntry.label), oneEntry.value}); 0227 } 0228 // update UI 0229 emit newStatus(status()); 0230 } 0231 0232 unsigned long ObservatoryWeatherModel::findWeatherData(const QString name) 0233 { 0234 unsigned long i; 0235 for (i = 0; i < m_WeatherData.size(); i++) 0236 { 0237 if (m_WeatherData[i].name.compare(name) == 0) 0238 return i; 0239 } 0240 // none found 0241 return i; 0242 } 0243 } // Ekos