// SPDX-License-Identifier: GPL-3.0-or-later
|
|
/*
|
|
* Qt mutizone MQTT thermostat
|
|
*
|
|
* Copyright (C) 2019 Richard Genoud
|
|
*
|
|
*/
|
|
|
|
#include <QTranslator>
|
|
#include <QSettings>
|
|
#include <QString>
|
|
#include <QDebug>
|
|
|
|
#include "settings.h"
|
|
|
|
const char default_room_names[MAX_NB_ZONES][42] = {
|
|
"Bedroom",
|
|
"Living Room",
|
|
"Workspace",
|
|
"Bathroom"
|
|
};
|
|
|
|
const char default_sensors_topics[MAX_NB_ZONES][64] = {
|
|
"sensors/bedroom/xiaomi",
|
|
"sensors/living_room/xiaomi",
|
|
"sensors/workspace/xiaomi",
|
|
"sensors/bathroom/xiaomi"
|
|
};
|
|
|
|
const char default_availability_topics[MAX_NB_ZONES][64] = {
|
|
"sensors/bedroom/availability",
|
|
"sensors/living_room/availability",
|
|
"sensors/workspace/availability",
|
|
"sensors/bathroom/availability"
|
|
};
|
|
|
|
const char default_control_topics[MAX_NB_ZONES][64] = {
|
|
"heaters/bedroom",
|
|
"heaters/living_room",
|
|
"heaters/workspace",
|
|
"heaters/bathroom"
|
|
};
|
|
|
|
Settings *Settings::_singleton = NULL;
|
|
|
|
Settings::Settings(QObject *parent) : QSettings(parent)
|
|
{
|
|
struct Room room;
|
|
struct Heater heater;
|
|
struct Program program;
|
|
int nb_rooms;
|
|
|
|
m_state = OFF;
|
|
|
|
QString st = this->value("state", "off").toString();
|
|
if (st.compare(QString("on"), Qt::CaseInsensitive) == 0) {
|
|
m_state = ON;
|
|
}
|
|
if (st.compare(QString("auto"), Qt::CaseInsensitive) == 0) {
|
|
m_state = AUTO;
|
|
}
|
|
|
|
m_end_holiday = QDateTime::fromString(this->value("end_holiday",
|
|
"2020-01-01T00:00:00Z").toString(),
|
|
Qt::ISODate);
|
|
if (!m_end_holiday.isValid()) {
|
|
m_end_holiday = QDateTime::currentDateTime();
|
|
}
|
|
|
|
nb_rooms = this->beginReadArray("rooms");
|
|
if (nb_rooms == 0) {
|
|
this->endArray();
|
|
set_rooms_default_config();
|
|
nb_rooms = this->beginReadArray("rooms");
|
|
}
|
|
|
|
if (nb_rooms > MAX_NB_ZONES) {
|
|
// TODO;
|
|
nb_rooms = MAX_NB_ZONES;
|
|
}
|
|
|
|
// TODO: handle unset values in a better way
|
|
for (int i = 0; i < nb_rooms; ++i) {
|
|
this->setArrayIndex(i);
|
|
room.name = this->value("name", default_room_names[i]).toString();
|
|
room.sensor_topic = this->value("sensor_topic", default_sensors_topics[i]).toString();
|
|
room.availability_topic = this->value("availability_topic",
|
|
default_availability_topics[i]).toString();
|
|
int size = this->beginReadArray("heaters");
|
|
for (int j = 0; j < size; ++j) {
|
|
this->setArrayIndex(j);
|
|
heater.ctrl_topic = this->value("control_topic", "").toString();
|
|
room.heaters << heater;
|
|
}
|
|
this->endArray();
|
|
room.default_temperature = this->value("default_temperature", 20).toDouble();
|
|
size = this->beginReadArray("temperature_schedule");
|
|
for (int j = 0; j < size; ++j) {
|
|
/* TODO: check for overlapping schedules ? */
|
|
this->setArrayIndex(j);
|
|
program.temperature = this->value("temperature", 20).toDouble();
|
|
program.DoW = this->value("days_of_week", 127).toInt();
|
|
program.start_time = QTime::fromString(this->value("start_time", "").toString(), "H:m");
|
|
program.end_time = QTime::fromString(this->value("end_time", "").toString(), "H:m");
|
|
if (program.start_time.isValid() && program.end_time.isValid() &&
|
|
(program.DoW > 0) && (program.DoW < 128)) {
|
|
room.progs << program;
|
|
}
|
|
}
|
|
this->endArray();
|
|
m_rooms << room;
|
|
room.progs.clear();
|
|
room.heaters.clear();
|
|
}
|
|
this->endArray();
|
|
m_broker.address = this->value("broker/address", "localhost").toString();
|
|
m_broker.port = this->value("broker/port", 1883).toInt();
|
|
}
|
|
|
|
void Settings::setRoomDefaultTemperature(int idx, double temperature)
|
|
{
|
|
if ((idx < 0) || (idx >= MAX_NB_ZONES)) {
|
|
// ERROR
|
|
return;
|
|
}
|
|
|
|
this->beginWriteArray("rooms");
|
|
this->setArrayIndex(idx);
|
|
this->setValue("default_temperature", temperature);
|
|
this->endArray();
|
|
this->sync();
|
|
}
|
|
|
|
void Settings::setRoomPrograms(int idx, QVector<struct Program> &progs)
|
|
{
|
|
if ((idx < 0) || (idx >= MAX_NB_ZONES)) {
|
|
// ERROR
|
|
return;
|
|
}
|
|
|
|
this->beginWriteArray("rooms");
|
|
|
|
this->setArrayIndex(idx);
|
|
this->remove("temperature_schedule");
|
|
this->beginWriteArray("temperature_schedule");
|
|
for (int i = 0; i < progs.count(); i++) {
|
|
this->setArrayIndex(i);
|
|
this->setValue("temperature", progs.at(i).temperature);
|
|
this->setValue("days_of_week", progs.at(i).DoW);
|
|
this->setValue("start_time", progs.at(i).start_time.toString("H:m"));
|
|
this->setValue("end_time", progs.at(i).end_time.toString("H:m"));
|
|
}
|
|
this->endArray();
|
|
this->endArray();
|
|
this->sync();
|
|
}
|
|
|
|
void Settings::setPowerState(enum power_states state)
|
|
{
|
|
switch (state) {
|
|
case OFF:
|
|
m_state = OFF;
|
|
this->setValue("state", "off");
|
|
break;
|
|
case ON:
|
|
m_state = ON;
|
|
this->setValue("state", "on");
|
|
break;
|
|
case AUTO:
|
|
m_state = AUTO;
|
|
this->setValue("state", "auto");
|
|
break;
|
|
default:
|
|
/* TODO: error */
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Settings::setEndHoliday(const QDateTime &endDate)
|
|
{
|
|
if (endDate.isValid()) {
|
|
m_end_holiday = endDate;
|
|
this->setValue("end_holiday", m_end_holiday.toString(Qt::ISODate));
|
|
}
|
|
/* else TODO: error */
|
|
}
|
|
|
|
void Settings::set_rooms_default_config(void)
|
|
{
|
|
this->setValue("state", "auto");
|
|
this->beginWriteArray("rooms");
|
|
|
|
for (int i = 0; i < MAX_NB_ZONES; i++) {
|
|
this->setArrayIndex(i);
|
|
this->setValue("name", tr(default_room_names[i]));
|
|
this->setValue("sensor_topic", default_sensors_topics[i]);
|
|
this->setValue("availability_topic", default_availability_topics[i]);
|
|
this->setValue("default_temperature", 20);
|
|
this->beginWriteArray("heaters");
|
|
this->setArrayIndex(0);
|
|
this->setValue("control_topic", default_control_topics[i]);
|
|
this->endArray();
|
|
}
|
|
|
|
this->setArrayIndex(0);
|
|
this->beginWriteArray("temperature_schedule");
|
|
this->setArrayIndex(0);
|
|
this->setValue("temperature", 18);
|
|
this->setValue("days_of_week", 127);
|
|
this->setValue("start_time", QTime(22,0).toString("H:m"));
|
|
this->setValue("end_time", QTime(7,0).toString("H:m"));
|
|
this->endArray();
|
|
|
|
|
|
this->setArrayIndex(3);
|
|
this->beginWriteArray("temperature_schedule");
|
|
this->setArrayIndex(0);
|
|
this->setValue("temperature", FORCE_ON);
|
|
this->setValue("days_of_week", 31);
|
|
this->setValue("start_time", QTime(6,30).toString("H:m"));
|
|
this->setValue("end_time", QTime(7,0).toString("H:m"));
|
|
this->setArrayIndex(1);
|
|
this->setValue("temperature", FORCE_ON);
|
|
this->setValue("days_of_week", 96);
|
|
this->setValue("start_time", QTime(7,30).toString("H:m"));
|
|
this->setValue("end_time", QTime(8,0).toString("H:m"));
|
|
this->endArray();
|
|
|
|
this->endArray();
|
|
this->sync();
|
|
}
|
|
|
|
int Settings::nbZones(void)
|
|
{
|
|
return m_rooms.size();
|
|
}
|
|
|
|
Settings::~Settings(void)
|
|
{
|
|
}
|
|
|
|
Settings *Settings::getInstance(void)
|
|
{
|
|
if (!_singleton) {
|
|
_singleton = new Settings();
|
|
}
|
|
|
|
return _singleton;
|
|
}
|
|
|
|
/* vim: set tabstop=8 shiftwidth=8 softtabstop=0 noexpandtab: */
|
|
|
|
|