first version of alarm
This commit is contained in:
parent
41126d016e
commit
9ee5eb20a9
302
plugins/deviceplugins/datetime/alarm.cpp
Normal file
302
plugins/deviceplugins/datetime/alarm.cpp
Normal file
@ -0,0 +1,302 @@
|
||||
#include "alarm.h"
|
||||
#include "loggingcategories.h"
|
||||
|
||||
Alarm::Alarm(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void Alarm::setName(const QString &name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
QString Alarm::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void Alarm::setMonday(const bool &monday)
|
||||
{
|
||||
m_monday = monday;
|
||||
}
|
||||
|
||||
bool Alarm::monday() const
|
||||
{
|
||||
return m_monday;
|
||||
}
|
||||
|
||||
void Alarm::setTuesday(const bool &tuesday)
|
||||
{
|
||||
m_tuesday = tuesday;
|
||||
}
|
||||
|
||||
bool Alarm::tuesday() const
|
||||
{
|
||||
return m_tuesday;
|
||||
}
|
||||
|
||||
void Alarm::setWednesday(const bool &wednesday)
|
||||
{
|
||||
m_wednsday = wednesday;
|
||||
}
|
||||
|
||||
bool Alarm::wednesday() const
|
||||
{
|
||||
return m_wednsday;
|
||||
}
|
||||
|
||||
void Alarm::setThursday(const bool &thursday)
|
||||
{
|
||||
m_thursday = thursday;
|
||||
}
|
||||
|
||||
bool Alarm::thursday() const
|
||||
{
|
||||
return m_thursday;
|
||||
}
|
||||
|
||||
void Alarm::setFriday(const bool &friday)
|
||||
{
|
||||
m_friday = friday;
|
||||
}
|
||||
|
||||
bool Alarm::friday() const
|
||||
{
|
||||
return m_friday;
|
||||
}
|
||||
|
||||
void Alarm::setSaturday(const bool &saturday)
|
||||
{
|
||||
m_saturday = saturday;
|
||||
}
|
||||
|
||||
bool Alarm::saturday() const
|
||||
{
|
||||
return m_saturday;
|
||||
}
|
||||
|
||||
void Alarm::setSunday(const bool &sunday)
|
||||
{
|
||||
m_sunday = sunday;
|
||||
}
|
||||
|
||||
bool Alarm::sunday() const
|
||||
{
|
||||
return m_sunday;
|
||||
}
|
||||
|
||||
void Alarm::setMinutes(const int &minutes)
|
||||
{
|
||||
m_minutes = minutes;
|
||||
}
|
||||
|
||||
int Alarm::minutes() const
|
||||
{
|
||||
return m_minutes;
|
||||
}
|
||||
|
||||
void Alarm::setHours(const int &hours)
|
||||
{
|
||||
m_hours = hours;
|
||||
}
|
||||
|
||||
int Alarm::hours() const
|
||||
{
|
||||
return m_hours;
|
||||
}
|
||||
|
||||
void Alarm::setOffset(const int &offset)
|
||||
{
|
||||
m_offset = offset;
|
||||
}
|
||||
|
||||
int Alarm::offset() const
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
void Alarm::setDusk(const QDateTime &dusk)
|
||||
{
|
||||
m_duskOffset = calculateOffsetTime(dusk);
|
||||
}
|
||||
|
||||
void Alarm::setSunrise(const QDateTime &sunrise)
|
||||
{
|
||||
m_sunriseOffset = calculateOffsetTime(sunrise);
|
||||
}
|
||||
|
||||
void Alarm::setNoon(const QDateTime &noon)
|
||||
{
|
||||
m_noonOffset = calculateOffsetTime(noon);
|
||||
}
|
||||
|
||||
void Alarm::setDawn(const QDateTime &dawn)
|
||||
{
|
||||
m_dawnOffset = calculateOffsetTime(dawn);
|
||||
}
|
||||
|
||||
void Alarm::setSunset(const QDateTime &sunset)
|
||||
{
|
||||
m_sunsetOffset = calculateOffsetTime(sunset);
|
||||
}
|
||||
|
||||
void Alarm::setTimeType(const Alarm::TimeType &timeType)
|
||||
{
|
||||
m_timeType = timeType;
|
||||
}
|
||||
|
||||
void Alarm::setTimeType(const QString &timeType)
|
||||
{
|
||||
if (timeType == "time") {
|
||||
m_timeType = TimeTypeTime;
|
||||
} else if (timeType == "dusk") {
|
||||
m_timeType = TimeTypeDusk;
|
||||
} else if (timeType == "sunrise") {
|
||||
m_timeType = TimeTypeSunrise;
|
||||
} else if (timeType == "noon") {
|
||||
m_timeType = TimeTypeNoon;
|
||||
} else if (timeType == "dawn") {
|
||||
m_timeType = TimeTypeDawn;
|
||||
} else if (timeType == "sunset") {
|
||||
m_timeType = TimeTypeSunset;
|
||||
}
|
||||
}
|
||||
|
||||
Alarm::TimeType Alarm::timeType() const
|
||||
{
|
||||
return m_timeType;
|
||||
}
|
||||
|
||||
QDateTime Alarm::calculateOffsetTime(const QDateTime &dateTime) const
|
||||
{
|
||||
QDateTime offsetTime = QDateTime(dateTime);
|
||||
offsetTime.time().addSecs(m_offset * 60);
|
||||
return offsetTime;
|
||||
}
|
||||
|
||||
bool Alarm::checkDayOfWeek(const QDateTime &dateTime)
|
||||
{
|
||||
QDateTime offsetTime = calculateOffsetTime(dateTime);
|
||||
|
||||
switch (offsetTime.date().dayOfWeek()) {
|
||||
case Qt::Monday:
|
||||
return monday();
|
||||
break;
|
||||
case Qt::Tuesday:
|
||||
return tuesday();
|
||||
break;
|
||||
case Qt::Wednesday:
|
||||
return wednesday();
|
||||
break;
|
||||
case Qt::Thursday:
|
||||
return thursday();
|
||||
break;
|
||||
case Qt::Friday:
|
||||
return friday();
|
||||
break;
|
||||
case Qt::Saturday:
|
||||
return saturday();
|
||||
break;
|
||||
case Qt::Sunday:
|
||||
return sunday();
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Alarm::checkHour(const QDateTime &dateTime)
|
||||
{
|
||||
QDateTime offsetTime = calculateOffsetTime(dateTime);
|
||||
|
||||
if (offsetTime.time().hour() != m_hours) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Alarm::checkMinute(const QDateTime &dateTime)
|
||||
{
|
||||
QDateTime offsetTime = calculateOffsetTime(dateTime);
|
||||
|
||||
if (offsetTime.time().minute() != m_minutes) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Alarm::checkTimeTypes(const QDateTime &dateTime)
|
||||
{
|
||||
bool checkOk = false;
|
||||
switch (m_timeType) {
|
||||
case TimeTypeTime:
|
||||
qCWarning(dcDateTime) << name() << "wrong time type";
|
||||
checkOk = false;
|
||||
break;
|
||||
case TimeTypeDusk:
|
||||
if (m_duskOffset == dateTime) {
|
||||
qCDebug(dcDateTime) << name() << "match dusk with offset" << m_offset;
|
||||
checkOk = true;
|
||||
}
|
||||
break;
|
||||
case TimeTypeSunrise:
|
||||
if (m_sunriseOffset == dateTime) {
|
||||
qCDebug(dcDateTime) << name() << "match sunrise with offset" << m_offset;
|
||||
checkOk = true;
|
||||
}
|
||||
break;
|
||||
case TimeTypeNoon:
|
||||
if (m_noonOffset == dateTime) {
|
||||
qCDebug(dcDateTime) << name() << "match noon with offset" << m_offset;
|
||||
checkOk = true;
|
||||
}
|
||||
break;
|
||||
case TimeTypeDawn:
|
||||
if (m_dawnOffset == dateTime) {
|
||||
qCDebug(dcDateTime) << name() << "match dawn with offset" << m_offset;
|
||||
checkOk = true;
|
||||
}
|
||||
break;
|
||||
case TimeTypeSunset:
|
||||
if (m_sunsetOffset == dateTime) {
|
||||
qCDebug(dcDateTime) << name() << "match sunset with offset" << m_offset;
|
||||
checkOk = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
checkOk = false;
|
||||
}
|
||||
return checkOk;
|
||||
}
|
||||
|
||||
void Alarm::validate(const QDateTime &dateTime)
|
||||
{
|
||||
qCDebug(dcDateTime) << name() << "validate" << dateTime.toString() << "...";
|
||||
|
||||
if (!checkDayOfWeek(dateTime))
|
||||
return;
|
||||
|
||||
// check if should use the given time
|
||||
if (m_timeType == TimeTypeTime) {
|
||||
if (!checkHour(dateTime))
|
||||
return;
|
||||
|
||||
if (!checkMinute(dateTime))
|
||||
return;
|
||||
|
||||
qCDebug(dcDateTime) << name() << "match time" << QTime(hours(), minutes()).toString("hh:mm") << "with offset" << m_offset;
|
||||
emit alarm();
|
||||
}
|
||||
}
|
||||
|
||||
void Alarm::validateTimes(const QDateTime &dateTime)
|
||||
{
|
||||
if (m_timeType == TimeTypeTime)
|
||||
return;
|
||||
|
||||
if (!checkTimeTypes(dateTime))
|
||||
return;
|
||||
|
||||
emit alarm();
|
||||
}
|
||||
103
plugins/deviceplugins/datetime/alarm.h
Normal file
103
plugins/deviceplugins/datetime/alarm.h
Normal file
@ -0,0 +1,103 @@
|
||||
#ifndef ALARM_H
|
||||
#define ALARM_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDateTime>
|
||||
|
||||
class Alarm : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum TimeType {
|
||||
TimeTypeTime,
|
||||
TimeTypeDusk,
|
||||
TimeTypeSunrise,
|
||||
TimeTypeNoon,
|
||||
TimeTypeSunset,
|
||||
TimeTypeDawn
|
||||
};
|
||||
|
||||
explicit Alarm(QObject *parent = 0);
|
||||
|
||||
void setName(const QString &name);
|
||||
QString name() const;
|
||||
|
||||
void setMonday(const bool &monday);
|
||||
bool monday() const;
|
||||
|
||||
void setTuesday(const bool &tuesday);
|
||||
bool tuesday() const;
|
||||
|
||||
void setWednesday(const bool &wednesday);
|
||||
bool wednesday() const;
|
||||
|
||||
void setThursday(const bool &thursday);
|
||||
bool thursday() const;
|
||||
|
||||
void setFriday(const bool &friday);
|
||||
bool friday() const;
|
||||
|
||||
void setSaturday(const bool &saturday);
|
||||
bool saturday() const;
|
||||
|
||||
void setSunday(const bool &sunday);
|
||||
bool sunday() const;
|
||||
|
||||
void setMinutes(const int &minutes);
|
||||
int minutes() const;
|
||||
|
||||
void setHours(const int &hours);
|
||||
int hours() const;
|
||||
|
||||
void setOffset(const int &offset);
|
||||
int offset() const;
|
||||
|
||||
void setDusk(const QDateTime &dusk);
|
||||
void setSunrise(const QDateTime &sunrise);
|
||||
void setNoon(const QDateTime &noon);
|
||||
void setDawn(const QDateTime &dawn);
|
||||
void setSunset(const QDateTime &sunset);
|
||||
|
||||
void setTimeType(const TimeType &timeType);
|
||||
void setTimeType(const QString &timeType);
|
||||
TimeType timeType() const;
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
bool m_monday;
|
||||
bool m_tuesday;
|
||||
bool m_wednsday;
|
||||
bool m_thursday;
|
||||
bool m_friday;
|
||||
bool m_saturday;
|
||||
bool m_sunday;
|
||||
|
||||
int m_minutes;
|
||||
int m_hours;
|
||||
int m_offset;
|
||||
TimeType m_timeType;
|
||||
|
||||
QDateTime m_duskOffset;
|
||||
QDateTime m_sunriseOffset;
|
||||
QDateTime m_noonOffset;
|
||||
QDateTime m_sunsetOffset;
|
||||
QDateTime m_dawnOffset;
|
||||
|
||||
QDateTime calculateOffsetTime(const QDateTime &dateTime) const;
|
||||
|
||||
bool checkDayOfWeek(const QDateTime &dateTime);
|
||||
bool checkHour(const QDateTime &dateTime);
|
||||
bool checkMinute(const QDateTime &dateTime);
|
||||
|
||||
bool checkTimeTypes(const QDateTime &dateTime);
|
||||
|
||||
signals:
|
||||
void alarm();
|
||||
|
||||
public slots:
|
||||
void validate(const QDateTime &dateTime);
|
||||
void validateTimes(const QDateTime &dateTime);
|
||||
|
||||
};
|
||||
|
||||
#endif // ALARM_H
|
||||
@ -3,8 +3,10 @@ include (../../plugins.pri)
|
||||
TARGET = $$qtLibraryTarget(guh_deviceplugindatetime)
|
||||
|
||||
SOURCES += \
|
||||
deviceplugindatetime.cpp
|
||||
deviceplugindatetime.cpp \
|
||||
alarm.cpp
|
||||
|
||||
HEADERS += \
|
||||
deviceplugindatetime.h
|
||||
deviceplugindatetime.h \
|
||||
alarm.h
|
||||
|
||||
|
||||
@ -84,106 +84,365 @@
|
||||
#include "plugininfo.h"
|
||||
#include "loggingcategories.h"
|
||||
|
||||
DevicePluginDateTime::DevicePluginDateTime()
|
||||
#include <QJsonDocument>
|
||||
#include <QUrlQuery>
|
||||
|
||||
DevicePluginDateTime::DevicePluginDateTime() :
|
||||
m_timer(0),
|
||||
m_todayDevice(0),
|
||||
m_timeZone(QTimeZone("Europe/Vienna"))
|
||||
{
|
||||
m_timer = new QTimer(this);
|
||||
m_timer->setInterval(1000);
|
||||
|
||||
qCDebug(dcDateTime) << configuration();
|
||||
|
||||
m_timeZone = QTimeZone(configValue("timezone").toByteArray());
|
||||
m_currentDateTime = QDateTime(QDate::currentDate(), QTime::currentTime(), m_timeZone);
|
||||
|
||||
connect(m_timer, &QTimer::timeout, this, &DevicePluginDateTime::timeout);
|
||||
connect(m_timer, &QTimer::timeout, this, &DevicePluginDateTime::onTimeout);
|
||||
connect(this, &DevicePluginDateTime::minuteChanged, this, &DevicePluginDateTime::onMinuteChanged);
|
||||
connect(this, &DevicePluginDateTime::hourChanged, this, &DevicePluginDateTime::onHourChanged);
|
||||
connect(this, &DevicePluginDateTime::dayChanged, this, &DevicePluginDateTime::onDayChanged);
|
||||
connect(this, &DevicePluginDateTime::timeDataChanged, this, &DevicePluginDateTime::onTimeDataUpdate);
|
||||
connect(this, &DevicePluginDateTime::configValueChanged, this, &DevicePluginDateTime::onConfigValueChanged);
|
||||
}
|
||||
|
||||
DeviceManager::HardwareResources DevicePluginDateTime::requiredHardware() const
|
||||
{
|
||||
return DeviceManager::HardwareResourceNone;
|
||||
return DeviceManager::HardwareResourceNetworkManager;
|
||||
}
|
||||
|
||||
QList<ParamType> DevicePluginDateTime::configurationDescription() const
|
||||
{
|
||||
QList<ParamType> params;
|
||||
ParamType timezoneParamType("timezone", QVariant::String, "Europe/Vienna");
|
||||
|
||||
QList<QVariant> allowedValues;
|
||||
foreach (QByteArray timeZone, QTimeZone::availableTimeZoneIds()) {
|
||||
allowedValues.append(timeZone);
|
||||
}
|
||||
timezoneParamType.setAllowedValues(allowedValues);
|
||||
|
||||
params.append(timezoneParamType);
|
||||
return params;
|
||||
}
|
||||
|
||||
DeviceManager::DeviceSetupStatus DevicePluginDateTime::setupDevice(Device *device)
|
||||
{
|
||||
// check the DeviceClassId
|
||||
|
||||
device->setName("Time (" + device->paramValue("timezone").toString() + ")");
|
||||
m_timeZone = QTimeZone(device->paramValue("timezone").toByteArray());
|
||||
|
||||
if(m_timeZone.isValid()){
|
||||
QDateTime zoneTime = QDateTime(QDate::currentDate(), QTime::currentTime(), m_timeZone).toLocalTime();
|
||||
qCDebug(dcDateTime) << zoneTime.toLocalTime().date() << zoneTime.toLocalTime().time() << QLocale::countryToString(m_timeZone.country());
|
||||
m_timer->start();
|
||||
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
// check timezone
|
||||
if(!m_timeZone.isValid()){
|
||||
qCWarning(dcDateTime) << "invalid time zone.";
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
}
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
|
||||
// date
|
||||
if (device->deviceClassId() == todayDeviceClassId) {
|
||||
if (m_todayDevice != 0) {
|
||||
qCWarning(dcDateTime) << "there is already a date device or not deleted correctly! this should never happen!!";
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
}
|
||||
m_todayDevice = device;
|
||||
qCDebug(dcDateTime) << "create today device: current time" << m_currentDateTime.currentDateTime().toString();
|
||||
}
|
||||
|
||||
// alarm
|
||||
if (device->deviceClassId() == alarmDeviceClassId) {
|
||||
Alarm *alarm = new Alarm(this);
|
||||
alarm->setName(device->paramValue("name").toString());
|
||||
alarm->setMonday(device->paramValue("monday").toBool());
|
||||
alarm->setTuesday(device->paramValue("tuesday").toBool());
|
||||
alarm->setWednesday(device->paramValue("wednesday").toBool());
|
||||
alarm->setThursday(device->paramValue("thursday").toBool());
|
||||
alarm->setFriday(device->paramValue("friday").toBool());
|
||||
alarm->setSaturday(device->paramValue("saturday").toBool());
|
||||
alarm->setSunday(device->paramValue("sunday").toBool());
|
||||
alarm->setMinutes(device->paramValue("minutes").toInt());
|
||||
alarm->setHours(device->paramValue("hours").toInt());
|
||||
alarm->setTimeType(device->paramValue("time type").toString());
|
||||
alarm->setOffset(device->paramValue("offset").toInt());
|
||||
|
||||
connect(alarm, &Alarm::alarm, this, &DevicePluginDateTime::onAlarm);
|
||||
|
||||
m_alarms.insert(device, alarm);
|
||||
}
|
||||
|
||||
m_timer->start();
|
||||
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
}
|
||||
|
||||
void DevicePluginDateTime::postSetupDevice(Device *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
qCDebug(dcDateTime) << "post setup";
|
||||
searchGeoLocation();
|
||||
}
|
||||
|
||||
void DevicePluginDateTime::deviceRemoved(Device *device)
|
||||
{
|
||||
Q_UNUSED(device);
|
||||
m_timer->stop();
|
||||
// check if we still need the timer
|
||||
if (myDevices().count() == 0) {
|
||||
m_timer->stop();
|
||||
}
|
||||
|
||||
// date
|
||||
if (device->deviceClassId() == todayDeviceClassId) {
|
||||
m_todayDevice = 0;
|
||||
}
|
||||
|
||||
// alarm
|
||||
if (device->deviceClassId() == alarmDeviceClassId) {
|
||||
Alarm *alarm = m_alarms.take(device);
|
||||
alarm->deleteLater();
|
||||
}
|
||||
startMonitoringAutoDevices();
|
||||
}
|
||||
|
||||
DeviceManager::DeviceError DevicePluginDateTime::executeAction(Device *device, const Action &action)
|
||||
void DevicePluginDateTime::networkManagerReplyReady(QNetworkReply *reply)
|
||||
{
|
||||
Q_UNUSED(device);
|
||||
Q_UNUSED(action);
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
if (m_locationReplies.contains(reply)) {
|
||||
m_locationReplies.removeAll(reply);
|
||||
if (status != 200) {
|
||||
qCWarning(dcDateTime) << "http error status for location request:" << status << reply->error();
|
||||
} else {
|
||||
processGeoLocationData(reply->readAll());
|
||||
}
|
||||
} else if (m_timeReplies.contains(reply)) {
|
||||
m_timeReplies.removeAll(reply);
|
||||
if (status != 200) {
|
||||
qCWarning(dcDateTime) << "http error status for time request:" << status << reply->error();
|
||||
} else {
|
||||
processTimesData(reply->readAll());
|
||||
}
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void DevicePluginDateTime::startMonitoringAutoDevices()
|
||||
{
|
||||
foreach (Device *device, myDevices()) {
|
||||
if (device->deviceClassId() == dateDeviceClassId) {
|
||||
return; // We already have a Auto Mock device... do nothing.
|
||||
if (device->deviceClassId() == todayDeviceClassId) {
|
||||
return; // We already have the date device... do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
DeviceDescriptor dateDescriptor(dateDeviceClassId, QString("Date"), QString(m_timeZone.id()));
|
||||
DeviceDescriptor dateDescriptor(todayDeviceClassId, QString("Date"), QString(m_timeZone.id()));
|
||||
ParamList params;
|
||||
params.append(Param("name", m_timeZone.id()));
|
||||
dateDescriptor.setParams(params);
|
||||
|
||||
emit autoDevicesAppeared(dateDeviceClassId, QList<DeviceDescriptor>() << dateDescriptor);
|
||||
emit autoDevicesAppeared(todayDeviceClassId, QList<DeviceDescriptor>() << dateDescriptor);
|
||||
}
|
||||
|
||||
void DevicePluginDateTime::timeout()
|
||||
void DevicePluginDateTime::searchGeoLocation()
|
||||
{
|
||||
if (m_todayDevice == 0)
|
||||
return;
|
||||
|
||||
QNetworkRequest request;
|
||||
request.setUrl(QUrl("http://ip-api.com/json"));
|
||||
|
||||
qCDebug(dcDateTime) << "request geo location.";
|
||||
|
||||
QNetworkReply *reply = networkManagerGet(request);
|
||||
m_locationReplies.append(reply);
|
||||
}
|
||||
|
||||
void DevicePluginDateTime::processGeoLocationData(const QByteArray &data)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
|
||||
if(error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcDateTime) << "failed to parse location JSON data:" << error.errorString() << ":" << data ;
|
||||
return;
|
||||
}
|
||||
|
||||
//qCDebug(dcDateTime) << "geo location data received:" << jsonDoc.toJson();
|
||||
QVariantMap response = jsonDoc.toVariant().toMap();
|
||||
if (response.value("status") != "success") {
|
||||
qCWarning(dcDateTime) << "failed to request geo location:" << response.value("status");
|
||||
}
|
||||
|
||||
// check timezone
|
||||
QString timeZone = response.value("timezone").toString();
|
||||
if (QString(m_timeZone.id()) != timeZone) {
|
||||
qCWarning(dcDateTime) << "error: configured timezone does not match the discovered timezone";
|
||||
qCWarning(dcDateTime) << " configured:" << m_timeZone.id();
|
||||
qCWarning(dcDateTime) << " discovered:" << timeZone;
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcDateTime) << "---------------------------------------------";
|
||||
qCDebug(dcDateTime) << "autodetected location for" << response.value("query").toString();
|
||||
qCDebug(dcDateTime) << " city :" << response.value("city").toString();
|
||||
qCDebug(dcDateTime) << " country :" << response.value("country").toString();
|
||||
qCDebug(dcDateTime) << " code :" << response.value("countryCode").toString();
|
||||
qCDebug(dcDateTime) << " zip code :" << response.value("zip").toString();
|
||||
qCDebug(dcDateTime) << " lon :" << response.value("lon").toByteArray();
|
||||
qCDebug(dcDateTime) << " lat :" << response.value("lat").toByteArray();
|
||||
qCDebug(dcDateTime) << "---------------------------------------------";
|
||||
|
||||
getTimes(response.value("lat").toString(), response.value("lon").toString());
|
||||
}
|
||||
|
||||
void DevicePluginDateTime::getTimes(const QString &latitude, const QString &longitude)
|
||||
{
|
||||
QUrlQuery urlQuery;
|
||||
urlQuery.addQueryItem("lat", latitude);
|
||||
urlQuery.addQueryItem("lng", longitude);
|
||||
urlQuery.addQueryItem("date", "today");
|
||||
|
||||
QUrl url = QUrl("http://api.sunrise-sunset.org/json");
|
||||
url.setQuery(urlQuery.toString());
|
||||
|
||||
QNetworkRequest request;
|
||||
request.setUrl(url);
|
||||
|
||||
QNetworkReply *reply = networkManagerGet(request);
|
||||
m_timeReplies.append(reply);
|
||||
}
|
||||
|
||||
void DevicePluginDateTime::processTimesData(const QByteArray &data)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
|
||||
if(error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcDateTime) << "failed to parse time JSON data:" << error.errorString() << ":" << data ;
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap response = jsonDoc.toVariant().toMap();
|
||||
if (response.value("status") != "OK") {
|
||||
qCWarning(dcDateTime) << "failed to request time data:" << response.value("status");
|
||||
return;
|
||||
}
|
||||
|
||||
// given time is always in UTC
|
||||
QVariantMap result = response.value("results").toMap();
|
||||
QString duskString = result.value("civil_twilight_begin").toString();
|
||||
QString sunriseString = result.value("sunrise").toString();
|
||||
QString noonString = result.value("solar_noon").toString();
|
||||
QString dawnString = result.value("civil_twilight_end").toString();
|
||||
QString sunsetString = result.value("sunset").toString();
|
||||
|
||||
m_dusk = QDateTime(QDate::currentDate(), QTime::fromString(duskString, "h:m:s AP"), Qt::UTC).toTimeZone(m_timeZone);
|
||||
m_sunrise = QDateTime(QDate::currentDate(), QTime::fromString(sunriseString, "h:m:s AP"), Qt::UTC).toTimeZone(m_timeZone);
|
||||
m_noon = QDateTime(QDate::currentDate(), QTime::fromString(noonString, "h:m:s AP"), Qt::UTC).toTimeZone(m_timeZone);
|
||||
m_dawn = QDateTime(QDate::currentDate(), QTime::fromString(dawnString, "h:m:s AP"), Qt::UTC).toTimeZone(m_timeZone);
|
||||
m_sunset = QDateTime(QDate::currentDate(), QTime::fromString(sunsetString, "h:m:s AP"), Qt::UTC).toTimeZone(m_timeZone);
|
||||
|
||||
emit timeDataChanged();
|
||||
}
|
||||
|
||||
|
||||
void DevicePluginDateTime::onTimeout()
|
||||
{
|
||||
QDateTime zoneTime = QDateTime::currentDateTime().toTimeZone(m_timeZone);
|
||||
//qCDebug(dcDateTime) << m_timeZone.id() << zoneTime.toString();
|
||||
|
||||
qCDebug(dcDateTime) << m_timeZone.id() << zoneTime.toString();
|
||||
if (zoneTime.date() != m_currentDateTime.date())
|
||||
emit dayChanged();
|
||||
|
||||
if(deviceManager()->findConfiguredDevices(dateDeviceClassId).count() == 1){
|
||||
Device *device = deviceManager()->findConfiguredDevices(dateDeviceClassId).first();
|
||||
device->setStateValue(dayStateTypeId, zoneTime.date().day());
|
||||
device->setStateValue(monthStateTypeId, zoneTime.date().month());
|
||||
device->setStateValue(monthNameStateTypeId, zoneTime.date().longMonthName(zoneTime.date().month()));
|
||||
device->setStateValue(monthNameShortStateTypeId, zoneTime.date().shortMonthName(zoneTime.date().month()));
|
||||
device->setStateValue(yearStateTypeId, zoneTime.date().year());
|
||||
device->setStateValue(weekdayStateTypeId, zoneTime.date().dayOfWeek());
|
||||
device->setStateValue(weekdayNameStateTypeId, zoneTime.date().longDayName(zoneTime.date().dayOfWeek()));
|
||||
device->setStateValue(weekdayNameShortStateTypeId, zoneTime.date().shortDayName(zoneTime.date().dayOfWeek()));
|
||||
if (zoneTime.time().hour() != m_currentDateTime.time().hour())
|
||||
emit hourChanged();
|
||||
|
||||
if(zoneTime.date().dayOfWeek() == 6 || zoneTime.date().dayOfWeek() == 7){
|
||||
device->setStateValue(weekendStateTypeId, true);
|
||||
}else{
|
||||
device->setStateValue(weekendStateTypeId, false);
|
||||
}
|
||||
if (zoneTime.time().minute() != m_currentDateTime.time().minute())
|
||||
emit minuteChanged();
|
||||
|
||||
foreach (Device *device, deviceManager()->findConfiguredDevices(alarmDeviceClassId)) {
|
||||
Alarm *alarm = m_alarms.value(device);
|
||||
alarm->validateTimes(zoneTime);
|
||||
}
|
||||
|
||||
validateTimeTypes(zoneTime);
|
||||
|
||||
// just store for compairing
|
||||
m_currentDateTime = zoneTime;
|
||||
}
|
||||
|
||||
void DevicePluginDateTime::onAlarm()
|
||||
{
|
||||
Alarm *alarm = static_cast<Alarm *>(sender());
|
||||
Device *device = m_alarms.key(alarm);
|
||||
|
||||
qCDebug(dcDateTime) << alarm->name() << "alarm!";
|
||||
|
||||
emit emitEvent(Event(alarmEventTypeId, device->id()));
|
||||
}
|
||||
|
||||
void DevicePluginDateTime::onTimeDataUpdate()
|
||||
{
|
||||
// calculate the times in each alarm
|
||||
qCDebug(dcDateTime) << " dusk :" << m_dusk.toString();
|
||||
qCDebug(dcDateTime) << " sunrise :" << m_sunrise.toString();
|
||||
qCDebug(dcDateTime) << " noon :" << m_noon.toString();
|
||||
qCDebug(dcDateTime) << " dawn :" << m_dawn.toString();
|
||||
qCDebug(dcDateTime) << " sunset :" << m_sunset.toString();
|
||||
qCDebug(dcDateTime) << "---------------------------------------------";
|
||||
|
||||
// alarms
|
||||
foreach (Alarm *alarm, m_alarms.values()) {
|
||||
alarm->setDusk(m_dusk);
|
||||
alarm->setSunrise(m_sunrise);
|
||||
alarm->setNoon(m_noon);
|
||||
alarm->setDawn(m_dawn);
|
||||
alarm->setSunset(m_sunset);
|
||||
}
|
||||
|
||||
// date
|
||||
if (m_todayDevice != 0)
|
||||
return;
|
||||
|
||||
m_todayDevice->setStateValue(duskStateTypeId, m_dusk.toTime_t());
|
||||
m_todayDevice->setStateValue(sunriseStateTypeId, m_sunrise.toTime_t());
|
||||
m_todayDevice->setStateValue(noonStateTypeId, m_noon.toTime_t());
|
||||
m_todayDevice->setStateValue(dawnStateTypeId, m_dawn.toTime_t());
|
||||
m_todayDevice->setStateValue(sunsetStateTypeId, m_sunset.toTime_t());
|
||||
|
||||
}
|
||||
|
||||
void DevicePluginDateTime::onMinuteChanged()
|
||||
{
|
||||
QDateTime zoneTime = QDateTime::currentDateTime().toTimeZone(m_timeZone);
|
||||
qCDebug(dcDateTime) << "minute changed" << zoneTime.toString();
|
||||
|
||||
// validate alerts
|
||||
foreach (Device *device, deviceManager()->findConfiguredDevices(alarmDeviceClassId)) {
|
||||
Alarm *alarm = m_alarms.value(device);
|
||||
alarm->validate(zoneTime);
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginDateTime::onHourChanged()
|
||||
{
|
||||
QDateTime zoneTime = QDateTime::currentDateTime().toTimeZone(m_timeZone);
|
||||
qCDebug(dcDateTime) << "hour changed" << zoneTime.toString();
|
||||
|
||||
// check every hour in case we are offline in the wrong moment
|
||||
searchGeoLocation();
|
||||
}
|
||||
|
||||
void DevicePluginDateTime::onDayChanged()
|
||||
{
|
||||
QDateTime zoneTime = QDateTime::currentDateTime().toTimeZone(m_timeZone);
|
||||
qCDebug(dcDateTime) << "day changed" << zoneTime.toString();
|
||||
|
||||
if (m_todayDevice == 0)
|
||||
return;
|
||||
|
||||
m_todayDevice->setStateValue(dayStateTypeId, zoneTime.date().day());
|
||||
m_todayDevice->setStateValue(monthStateTypeId, zoneTime.date().month());
|
||||
m_todayDevice->setStateValue(yearStateTypeId, zoneTime.date().year());
|
||||
m_todayDevice->setStateValue(weekdayStateTypeId, zoneTime.date().dayOfWeek());
|
||||
m_todayDevice->setStateValue(weekdayNameStateTypeId, zoneTime.date().longDayName(zoneTime.date().dayOfWeek()));
|
||||
m_todayDevice->setStateValue(monthNameStateTypeId, zoneTime.date().longMonthName(zoneTime.date().month()));
|
||||
if(zoneTime.date().dayOfWeek() == 6 || zoneTime.date().dayOfWeek() == 7){
|
||||
m_todayDevice->setStateValue(weekendStateTypeId, true);
|
||||
}else{
|
||||
m_todayDevice->setStateValue(weekendStateTypeId, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,12 +454,32 @@ void DevicePluginDateTime::onConfigValueChanged(const QString ¶mName, const
|
||||
if (newZone.isValid()) {
|
||||
m_timeZone = newZone;
|
||||
QDateTime zoneTime = QDateTime(QDate::currentDate(), QTime::currentTime(), m_timeZone);
|
||||
qCDebug(dcDateTime) << "set new time zone:" << value.toString();
|
||||
qCDebug(dcDateTime) << "current time" << zoneTime.currentDateTime().toString();
|
||||
qCDebug(dcDateTime) << " time zone:" << value.toString();
|
||||
qCDebug(dcDateTime) << " current time:" << zoneTime.currentDateTime().toString();
|
||||
qCDebug(dcDateTime) << "-----------------------------";
|
||||
timeout();
|
||||
} else {
|
||||
qCWarning(dcDateTime) << "could not set new timezone" << value.toString() << ". keeping old time zone:" << m_timeZone;
|
||||
}
|
||||
|
||||
// update everything with the new timezone
|
||||
onTimeout();
|
||||
}
|
||||
|
||||
void DevicePluginDateTime::validateTimeTypes(const QDateTime &dateTime)
|
||||
{
|
||||
if (m_todayDevice == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dateTime == m_dusk) {
|
||||
emit emitEvent(Event(duskEventTypeId, m_todayDevice->id()));
|
||||
} else if (dateTime == m_sunrise) {
|
||||
emit emitEvent(Event(sunriseEventTypeId, m_todayDevice->id()));
|
||||
} else if (dateTime == m_noon) {
|
||||
emit emitEvent(Event(noonEventTypeId, m_todayDevice->id()));
|
||||
} else if (dateTime == m_dawn) {
|
||||
emit emitEvent(Event(dawnEventTypeId, m_todayDevice->id()));
|
||||
} else if (dateTime == m_sunset) {
|
||||
emit emitEvent(Event(sunsetEventTypeId, m_todayDevice->id()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,8 +22,11 @@
|
||||
#define DEVICEPLUGINDATETIME_H
|
||||
|
||||
#include "plugin/deviceplugin.h"
|
||||
#include "alarm.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QTimeZone>
|
||||
#include <QTime>
|
||||
#include <QTimer>
|
||||
|
||||
class DevicePluginDateTime : public DevicePlugin
|
||||
@ -39,22 +42,58 @@ public:
|
||||
DeviceManager::HardwareResources requiredHardware() const override;
|
||||
QList<ParamType> configurationDescription() const override;
|
||||
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
|
||||
void postSetupDevice(Device *device) override;
|
||||
void deviceRemoved(Device *device) override;
|
||||
|
||||
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
|
||||
void networkManagerReplyReady(QNetworkReply *reply) override;
|
||||
|
||||
void startMonitoringAutoDevices() override;
|
||||
|
||||
|
||||
private:
|
||||
QTimer *m_timer;
|
||||
Device *m_todayDevice;
|
||||
QTimeZone m_timeZone;
|
||||
QDateTime m_currentDateTime;
|
||||
|
||||
QHash<Device *, Alarm *> m_alarms;
|
||||
|
||||
QDateTime m_dusk;
|
||||
QDateTime m_sunrise;
|
||||
QDateTime m_noon;
|
||||
QDateTime m_dawn;
|
||||
QDateTime m_sunset;
|
||||
|
||||
|
||||
QList<QNetworkReply *> m_locationReplies;
|
||||
QList<QNetworkReply *> m_timeReplies;
|
||||
|
||||
void searchGeoLocation();
|
||||
void processGeoLocationData(const QByteArray &data);
|
||||
|
||||
void getTimes(const QString &latitude, const QString &longitude);
|
||||
void processTimesData(const QByteArray &data);
|
||||
|
||||
signals:
|
||||
void dusk();
|
||||
void sunset();
|
||||
void noon();
|
||||
void sunrise();
|
||||
void dawn();
|
||||
void timeDataChanged();
|
||||
void minuteChanged();
|
||||
void hourChanged();
|
||||
void dayChanged();
|
||||
|
||||
private slots:
|
||||
void timeout();
|
||||
void onTimeout();
|
||||
void onAlarm();
|
||||
void onTimeDataUpdate();
|
||||
void onMinuteChanged();
|
||||
void onHourChanged();
|
||||
void onDayChanged();
|
||||
|
||||
void onConfigValueChanged(const QString ¶mName, const QVariant &value);
|
||||
|
||||
|
||||
void validateTimeTypes(const QDateTime &dateTime);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
"deviceClasses": [
|
||||
{
|
||||
"deviceClassId": "fbf665fb-9aca-423f-a5f2-924e50ebe6ca",
|
||||
"idName": "date",
|
||||
"name": "Date",
|
||||
"idName": "today",
|
||||
"name": "Today",
|
||||
"createMethods": ["auto"],
|
||||
"paramTypes": [
|
||||
{
|
||||
@ -40,13 +40,6 @@
|
||||
"type": "QString",
|
||||
"defaultValue": "-"
|
||||
},
|
||||
{
|
||||
"id": "4d0814f2-60a6-48c4-8b3b-031a099be8e3",
|
||||
"idName": "monthNameShort",
|
||||
"name": "month name short",
|
||||
"type": "QString",
|
||||
"defaultValue": "-"
|
||||
},
|
||||
{
|
||||
"id": "79d4ae9b-ea27-4346-8229-1d90f1ddfc9d",
|
||||
"idName": "year",
|
||||
@ -68,19 +61,171 @@
|
||||
"type": "QString",
|
||||
"defaultValue": "-"
|
||||
},
|
||||
{
|
||||
"id": "7e8e8e53-a83b-493d-850d-b0407f03463a",
|
||||
"idName": "weekdayNameShort",
|
||||
"name": "weekday name short",
|
||||
"type": "QString",
|
||||
"defaultValue": "-"
|
||||
},
|
||||
{
|
||||
"id": "4de5b57b-bb1a-4d66-9ce3-22bb280b075d",
|
||||
"idName": "weekend",
|
||||
"name": "weekend",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "44a99419-fbcd-4d8e-9441-897848b8f77c",
|
||||
"idName": "dusk",
|
||||
"name": "dusk",
|
||||
"unit": "UnixTime",
|
||||
"type": "int",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "3a08824d-285b-412e-a515-9664b491a85c",
|
||||
"idName": "sunrise",
|
||||
"name": "sunrise",
|
||||
"unit": "UnixTime",
|
||||
"type": "int",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "d92be29a-929c-4240-91a0-30153850f838",
|
||||
"idName": "noon",
|
||||
"name": "sun noon",
|
||||
"unit": "UnixTime",
|
||||
"type": "int",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "a5779b11-0499-4a6d-a7bd-8143dcc546b4",
|
||||
"idName": "dawn",
|
||||
"name": "dawn",
|
||||
"unit": "UnixTime",
|
||||
"type": "int",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "377f04a7-df58-42ad-a234-e9e23bdc2f85",
|
||||
"idName": "sunset",
|
||||
"name": "sunset",
|
||||
"unit": "UnixTime",
|
||||
"type": "int",
|
||||
"defaultValue": 0
|
||||
}
|
||||
],
|
||||
"eventTypes": [
|
||||
{
|
||||
"id": "792885f3-f505-42db-8c74-3d0460b575a1",
|
||||
"idName": "dusk",
|
||||
"name": "dusk"
|
||||
},
|
||||
{
|
||||
"id": "792885f3-f505-42db-8c74-3d0460b575a1",
|
||||
"idName": "sunrise",
|
||||
"name": "sunrise"
|
||||
},
|
||||
{
|
||||
"id": "97ae8dd8-640c-4f9b-8773-aa7abb1d32fa",
|
||||
"idName": "noon",
|
||||
"name": "noon"
|
||||
},
|
||||
{
|
||||
"id": "5e3657b0-a459-4837-a632-0b20de4b7349",
|
||||
"idName": "dawn",
|
||||
"name": "dawn"
|
||||
},
|
||||
{
|
||||
"id": "f40d6e0f-fda2-475e-a6ae-c3fee03138b9",
|
||||
"idName": "sunset",
|
||||
"name": "sunset"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"deviceClassId": "3f3c7ecc-9915-4e4e-95a1-e11f4f9d174d",
|
||||
"idName": "alarm",
|
||||
"name": "Alarm",
|
||||
"createMethods": ["user"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "QString",
|
||||
"inputType": "TextLine"
|
||||
},
|
||||
{
|
||||
"name": "monday",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"name": "tuesday",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"name": "wednesday",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"name": "thursday",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"name": "friday",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"name": "saturday",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"name": "sunday",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"name": "minutes",
|
||||
"type": "int",
|
||||
"unit": "Minutes",
|
||||
"minValue": 0,
|
||||
"maxValue": 60,
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"name": "hours",
|
||||
"type": "int",
|
||||
"minValue": 0,
|
||||
"maxValue": 24,
|
||||
"unit": "Hours",
|
||||
"defaultValue": 12
|
||||
},
|
||||
{
|
||||
"name": "time type",
|
||||
"type": "QString",
|
||||
"allowedValues": [
|
||||
"time",
|
||||
"dusk",
|
||||
"sunrise",
|
||||
"sunnoon",
|
||||
"sunset",
|
||||
"dawn"
|
||||
],
|
||||
"defaultValue": "time"
|
||||
},
|
||||
{
|
||||
"name": "offset",
|
||||
"type": "int",
|
||||
"unit": "Minutes",
|
||||
"minValue": -59,
|
||||
"maxValue": 59,
|
||||
"defaultValue": 0
|
||||
}
|
||||
],
|
||||
"eventTypes": [
|
||||
{
|
||||
"id": "5ec9a4af-d5ea-4f68-ab32-f7a3fcd75ccc",
|
||||
"idName": "alarm",
|
||||
"name": "alarm"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@
|
||||
"idName": "sunset",
|
||||
"name": "sunset",
|
||||
"unit": "UnixTime",
|
||||
"type": "uint",
|
||||
"type": "int",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
|
||||
@ -353,7 +353,6 @@ void TestJSONRPC::ruleAddedRemovedNotifications()
|
||||
QVariantMap stateEvaluator;
|
||||
stateEvaluator.insert("stateDescriptor", stateDescriptor);
|
||||
|
||||
|
||||
// RuleAction
|
||||
QVariantMap actionNoParams;
|
||||
actionNoParams.insert("actionTypeId", mockActionIdNoParams);
|
||||
|
||||
Reference in New Issue
Block a user