first version of alarm

This commit is contained in:
Simon Stürz 2015-06-27 19:46:12 +02:00 committed by Michael Zanetti
parent 41126d016e
commit 9ee5eb20a9
8 changed files with 941 additions and 72 deletions

View 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();
}

View 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

View File

@ -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

View File

@ -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 &paramName, 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()));
}
}

View File

@ -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 &paramName, const QVariant &value);
void validateTimeTypes(const QDateTime &dateTime);
};

View File

@ -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"
}
]
}

View File

@ -126,7 +126,7 @@
"idName": "sunset",
"name": "sunset",
"unit": "UnixTime",
"type": "uint",
"type": "int",
"defaultValue": 0
},
{

View File

@ -353,7 +353,6 @@ void TestJSONRPC::ruleAddedRemovedNotifications()
QVariantMap stateEvaluator;
stateEvaluator.insert("stateDescriptor", stateDescriptor);
// RuleAction
QVariantMap actionNoParams;
actionNoParams.insert("actionTypeId", mockActionIdNoParams);