|
|
@ -9,6 +9,8 @@ |
|
|
|
#include <QtWidgets>
|
|
|
|
#include <QPushButton>
|
|
|
|
#include <QTime>
|
|
|
|
#include <QDate>
|
|
|
|
#include <QtMath>
|
|
|
|
#include <QLocale>
|
|
|
|
#include <QVector>
|
|
|
|
|
|
|
@ -26,6 +28,7 @@ MainWindow::MainWindow(QWidget *parent) : |
|
|
|
|
|
|
|
for (int i = 0; i < s->nbZones(); i++) { |
|
|
|
zone = new ZoneItem(s->m_rooms.at(i).name, this); |
|
|
|
zone->m_target_temperature = get_target_temperature(i); |
|
|
|
m_zones << zone; |
|
|
|
} |
|
|
|
|
|
|
@ -36,7 +39,7 @@ MainWindow::MainWindow(QWidget *parent) : |
|
|
|
|
|
|
|
m_state_btn.setText(tr("Auto")); |
|
|
|
|
|
|
|
if (s->nbZones() < 4) { |
|
|
|
if (s->nbZones() < MAX_NB_ZONES) { |
|
|
|
// TODO
|
|
|
|
qDebug() << "bad configuration" ; |
|
|
|
} else { |
|
|
@ -47,8 +50,7 @@ MainWindow::MainWindow(QWidget *parent) : |
|
|
|
mainLayout->addWidget(m_zones.at(3), 1, 1); |
|
|
|
mainLayout->addWidget(&m_state_btn, 1, 2); |
|
|
|
} |
|
|
|
m_pwr_state = OFF; |
|
|
|
update_state_btn(m_pwr_state); |
|
|
|
update_state_btn(s->m_state); |
|
|
|
|
|
|
|
QWidget *mainWidget = new QWidget; |
|
|
|
mainWidget->setLayout(mainLayout); |
|
|
@ -75,6 +77,7 @@ MainWindow::MainWindow(QWidget *parent) : |
|
|
|
this, SLOT(availability_slot(int, bool))); |
|
|
|
|
|
|
|
connect(this, SIGNAL(setAllHeatersOn(bool)), m_mqtt, SLOT(allHeatersOn(bool))); |
|
|
|
connect(m_mqtt, SIGNAL(connected(void)), this, SLOT(apply_order_to_heaters(void))); |
|
|
|
|
|
|
|
connect(&m_state_btn, SIGNAL(clicked()), this, SLOT(change_state())); |
|
|
|
|
|
|
@ -83,7 +86,7 @@ MainWindow::MainWindow(QWidget *parent) : |
|
|
|
*/ |
|
|
|
m_timer = new QTimer(this); |
|
|
|
connect(m_timer, SIGNAL(timeout()), this, SLOT(apply_order_to_heaters())); |
|
|
|
m_timer->start(600000); |
|
|
|
m_timer->start(60000); |
|
|
|
} |
|
|
|
|
|
|
|
MainWindow::~MainWindow() |
|
|
@ -108,39 +111,150 @@ void MainWindow::update_state_btn(enum power_states st) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
double MainWindow::get_target_temperature(int room_idx) |
|
|
|
{ |
|
|
|
Settings *s = Settings::getInstance(); |
|
|
|
const struct Room *r = NULL; |
|
|
|
const struct Program *p = NULL; |
|
|
|
double target = FORCE_OFF; |
|
|
|
QTime now = QTime::currentTime(); |
|
|
|
uint8_t dow = QDate::currentDate().dayOfWeek(); |
|
|
|
|
|
|
|
if ((room_idx < 0) || (room_idx >= MAX_NB_ZONES)) { |
|
|
|
goto out; |
|
|
|
} |
|
|
|
|
|
|
|
r = &(s->m_rooms.at(room_idx)); |
|
|
|
target = r->default_temperature; |
|
|
|
if (!dow) { |
|
|
|
goto out; |
|
|
|
} |
|
|
|
|
|
|
|
dow <<= 1; |
|
|
|
for (int i = 0; i < r->progs.count(); i++) { |
|
|
|
p = &(r->progs.at(i)); |
|
|
|
if (dow & p->DoW) { |
|
|
|
if (p->start_time == p->end_time) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
* Ex: from 10h to 18h |
|
|
|
*/ |
|
|
|
if (p->start_time < p->end_time) { |
|
|
|
if ((now >= p->start_time) && (now < p->end_time)) { |
|
|
|
target = p->temperature; |
|
|
|
} |
|
|
|
} else { |
|
|
|
/*
|
|
|
|
* Ex: from 22h to 6h |
|
|
|
*/ |
|
|
|
if (now >= p->start_time) { |
|
|
|
target = p->temperature; |
|
|
|
} else { |
|
|
|
if (now < p->end_time) { |
|
|
|
target = p->temperature; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
out: |
|
|
|
return target; |
|
|
|
} |
|
|
|
|
|
|
|
bool MainWindow::get_heater_order(int room_idx) |
|
|
|
{ |
|
|
|
bool should_heat = false; |
|
|
|
|
|
|
|
if ((room_idx < 0) || (room_idx >= MAX_NB_ZONES)) { |
|
|
|
goto out; |
|
|
|
} |
|
|
|
|
|
|
|
if (m_zones.at(room_idx)->m_temperature_value == FORCE_OFF) { |
|
|
|
goto out; |
|
|
|
} |
|
|
|
|
|
|
|
/* TODO: make it smarter */ |
|
|
|
if (qFabs(get_target_temperature(room_idx) |
|
|
|
- m_zones.at(room_idx)->m_temperature_value) < 0.3) { |
|
|
|
/*
|
|
|
|
* Stay like before |
|
|
|
*/ |
|
|
|
should_heat = m_zones.at(room_idx)->m_heating_on; |
|
|
|
} else { |
|
|
|
|
|
|
|
if (get_target_temperature(room_idx) > |
|
|
|
m_zones.at(room_idx)->m_temperature_value) { |
|
|
|
should_heat = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
out: |
|
|
|
return should_heat; |
|
|
|
} |
|
|
|
|
|
|
|
void MainWindow::apply_automatic_state(void) |
|
|
|
{ |
|
|
|
Settings *s = Settings::getInstance(); |
|
|
|
int i; |
|
|
|
|
|
|
|
qDebug() << "apply auto state"; |
|
|
|
for (i = 0; i < s->m_rooms.count(); i++) { |
|
|
|
const struct Room *r = &(s->m_rooms.at(i)); |
|
|
|
bool should_heat = get_heater_order(i); |
|
|
|
qDebug() << "room " << r->name; |
|
|
|
for (int j = 0; j < r->heaters.count(); j++) { |
|
|
|
const struct Heater *h = &(r->heaters.at(j)); |
|
|
|
qDebug() << "heater " << h->ctrl_topic; |
|
|
|
/* TODO: check if connected */ |
|
|
|
m_mqtt->publish_msg(h->ctrl_topic, |
|
|
|
should_heat ? "on" : "off"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void MainWindow::change_state(void) |
|
|
|
{ |
|
|
|
switch (m_pwr_state) { |
|
|
|
Settings *s = Settings::getInstance(); |
|
|
|
|
|
|
|
switch (s->m_state) { |
|
|
|
case OFF: |
|
|
|
m_pwr_state = ON; |
|
|
|
s->m_state = ON; |
|
|
|
break; |
|
|
|
case ON: |
|
|
|
m_pwr_state = AUTO; |
|
|
|
s->m_state = AUTO; |
|
|
|
break; |
|
|
|
case AUTO: |
|
|
|
/* fall through */ |
|
|
|
default: |
|
|
|
m_pwr_state = OFF; |
|
|
|
s->m_state = OFF; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
update_state_btn(m_pwr_state); |
|
|
|
update_state_btn(s->m_state); |
|
|
|
|
|
|
|
apply_order_to_heaters(); |
|
|
|
} |
|
|
|
|
|
|
|
void MainWindow::apply_order_to_heaters(void) |
|
|
|
{ |
|
|
|
switch (m_pwr_state) { |
|
|
|
Settings *s = Settings::getInstance(); |
|
|
|
|
|
|
|
switch (s->m_state) { |
|
|
|
case ON: |
|
|
|
qDebug() << "emit ALL_ON order"; |
|
|
|
emit setAllHeatersOn(true); |
|
|
|
break; |
|
|
|
case AUTO: |
|
|
|
/* TODO */ |
|
|
|
qDebug() << "apply AUTO state"; |
|
|
|
apply_automatic_state(); |
|
|
|
break; |
|
|
|
case OFF: |
|
|
|
/* fall */ |
|
|
|
default: |
|
|
|
qDebug() << "emit ALL_OFF order"; |
|
|
|
emit setAllHeatersOn(false); |
|
|
|
break; |
|
|
|
} |
|
|
@ -152,7 +266,8 @@ void MainWindow::temperature_slot(int idx, double val) |
|
|
|
|
|
|
|
qDebug() << "temperature idx:" << idx << " val: " << val << endl; |
|
|
|
if (idx < s->nbZones()) { |
|
|
|
m_zones.at(idx)->set_temperature_value(val); |
|
|
|
m_zones.at(idx)->m_temperature_value = val; |
|
|
|
m_zones.at(idx)->refresh(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -162,16 +277,19 @@ void MainWindow::hygro_slot(int idx, double val) |
|
|
|
|
|
|
|
qDebug() << "hygro idx:" << idx << " val: " << val << endl; |
|
|
|
if (idx < s->nbZones()) { |
|
|
|
m_zones.at(idx)->set_hygro_value(val); |
|
|
|
m_zones.at(idx)-> m_hygro_value = val; |
|
|
|
m_zones.at(idx)->refresh(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void MainWindow::availability_slot(int idx, bool ok) |
|
|
|
{ |
|
|
|
Settings *s = Settings::getInstance(); |
|
|
|
|
|
|
|
if ((idx < s->nbZones()) && !ok) { |
|
|
|
m_zones.at(idx)->set_hygro_value(0); |
|
|
|
m_zones.at(idx)->set_temperature_value(0); |
|
|
|
m_zones.at(idx)->m_hygro_value = 0; |
|
|
|
m_zones.at(idx)->m_temperature_value = 0; |
|
|
|
m_zones.at(idx)->refresh(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|