Compare commits

..

No commits in common. "master" and "954eec754c68e20213480a745ace23f99980e0fa" have entirely different histories.

117 changed files with 3387 additions and 4385 deletions

View file

@ -1,174 +0,0 @@
cmake_minimum_required(VERSION 4.0)
project(SHinterface VERSION 1.0 LANGUAGES CXX)
# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Enable all warnings
add_compile_options(-Wall)
# Find Qt packages
find_package(Qt6 COMPONENTS Core Gui Widgets Network Multimedia SerialPort Mqtt REQUIRED)
# Find dependencies using pkg-config
find_package(PkgConfig REQUIRED)
pkg_check_modules(PIPEWIRE REQUIRED libpipewire-0.3)
pkg_check_modules(LIBNL3 REQUIRED libnl-3.0 libnl-genl-3.0)
# Enable automatic moc and uic processing
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
# Add src to include path for relative includes
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src)
# Create executable
add_executable(SHinterface
src/sensors/mqttsensorsource.h src/sensors/mqttsensorsource.cpp)
# Add sources to executable
target_sources(SHinterface
PRIVATE
src/main.cpp
src/mainobject.h
src/mainobject.cpp
src/apgetconnected.h
src/apgetconnected.cpp
src/microcontroller.h
src/microcontroller.cpp
src/sun.h
src/sun.cpp
src/programmode.h
src/programmode.cpp
src/pipewire.h
src/pipewire.cpp
src/service/service.h
src/service/service.cpp
src/service/tcpclient.h
src/service/tcpclient.cpp
src/service/tcpserver.h
src/service/tcpserver.cpp
src/actors/actor.h
src/actors/actor.cpp
src/actors/factoractor.h
src/actors/factoractor.cpp
src/actors/polynomalactor.h
src/actors/polynomalactor.cpp
src/actors/sensoractor.h
src/actors/sensoractor.cpp
src/actors/alarmtime.h
src/actors/alarmtime.cpp
src/actors/regulator.h
src/actors/regulator.cpp
src/actors/timeractor.h
src/actors/timeractor.cpp
src/sensors/sensor.h
src/sensors/sensor.cpp
src/sensors/sunsensor.h
src/sensors/sunsensor.cpp
src/items/item.h
src/items/item.cpp
src/items/relay.h
src/items/relay.cpp
src/items/poweritem.h
src/items/poweritem.cpp
src/items/messageitem.h
src/items/messageitem.cpp
src/items/systemitem.h
src/items/systemitem.cpp
src/items/auxitem.h
src/items/auxitem.cpp
src/items/rgbitem.h
src/items/rgbitem.cpp
src/items/itemsource.h
src/items/itemsource.cpp
src/items/itemloadersource.h
src/items/itemloadersource.cpp
src/items/fixeditemsource.h
src/items/fixeditemsource.cpp
src/items/itemstore.h
src/items/itemstore.cpp
src/ui/mainwindow.h
src/ui/mainwindow.cpp
src/ui/itemwidget.h
src/ui/itemwidget.cpp
src/ui/itemscrollbox.h
src/ui/itemscrollbox.cpp
src/ui/sensorlistwidget.h
src/ui/sensorlistwidget.cpp
src/ui/itemcreationdialog.h
src/ui/itemcreationdialog.cpp
src/ui/itemsettingsdialog.h
src/ui/itemsettingsdialog.cpp
src/ui/actorsettingsdialog.h
src/ui/actorsettingsdialog.cpp
src/ui/actorwidgets/factoractorwidget.h
src/ui/actorwidgets/factoractorwidget.cpp
src/ui/actorwidgets/polynomalactorwidget.h
src/ui/actorwidgets/polynomalactorwidget.cpp
src/ui/actorwidgets/sensoractorwidget.h
src/ui/actorwidgets/sensoractorwidget.cpp
src/ui/actorwidgets/timeractorwidget.h
src/ui/actorwidgets/timeractorwidget.cpp
src/ui/actorwidgets/alarmwidget.h
src/ui/actorwidgets/alarmwidget.cpp
src/ui/actorwidgets/regulatorwdiget.h
src/ui/actorwidgets/regulatorwdiget.cpp
src/ui/itemsettingswidgets/messageitemsettingswidget.h
src/ui/itemsettingswidgets/messageitemsettingswidget.cpp
src/ui/itemsettingswidgets/relayitemsettingswidget.h
src/ui/itemsettingswidgets/relayitemsettingswidget.cpp
src/ui/itemsettingswidgets/systemitemsettingswidget.h
src/ui/itemsettingswidgets/systemitemsettingswidget.cpp
)
# Add UI files
target_sources(SHinterface
PRIVATE
src/ui/mainwindow.ui
src/ui/itemwidget.ui
src/ui/relayscrollbox.ui
src/ui/itemcreationdialog.ui
src/ui/itemsettingsdialog.ui
src/ui/actorsettingsdialog.ui
src/ui/actorwidgets/factoractorwidget.ui
src/ui/actorwidgets/polynomalactorwidget.ui
src/ui/actorwidgets/sensoractorwidget.ui
src/ui/actorwidgets/timeractorwidget.ui
src/ui/actorwidgets/alarmwidget.ui
src/ui/actorwidgets/regulatorwdiget.ui
src/ui/itemsettingswidgets/messageitemsettingswidget.ui
src/ui/itemsettingswidgets/relayitemsettingswidget.ui
src/ui/itemsettingswidgets/systemitemsettingswidget.ui
)
# Add resource file
target_sources(SHinterface
PRIVATE
resources.qrc
)
# Link libraries
target_link_libraries(SHinterface
Qt6::Core
Qt6::Gui
Qt6::Widgets
Qt6::Network
Qt6::Multimedia
Qt6::SerialPort
Qt6::Mqtt
${PIPEWIRE_LIBRARIES}
${LIBNL3_LIBRARIES}
)
# Add include paths
include_directories(${PIPEWIRE_INCLUDE_DIRS} ${LIBNL3_INCLUDE_DIRS})

156
SHinterface.pro Normal file
View file

@ -0,0 +1,156 @@
#-------------------------------------------------
#
# Project created by QtCreator 2017-06-01T22:31:38
#
#-------------------------------------------------
QT += core gui widgets network multimedia
QT += serialport
TARGET = SHinterface
TEMPLATE = app
INCLUDEPATH += /usr/include/libnl3/
LIBS += -lnl-3 -lnl-genl-3
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
QMAKE_CXXFLAGS += -std=c++17 -O2
SOURCES += \
src/actors/factoractor.cpp \
src/actors/polynomalactor.cpp \
src/broadcast.cpp \
src/iomuliplexer.cpp \
src/items/messageitem.cpp \
src/items/systemitem.cpp \
src/ui/actorwidgets/factoractorwidget.cpp \
src/ui/itemcreationdialog.cpp \
src/ui/itemsettingswidgets/messageitemsettingswidget.cpp \
src/mainobject.cpp \
src/apgetconnected.cpp \
src/ui/actorwidgets/polynomalactorwidget.cpp \
src/ui/actorwidgets/sensoractorwidget.cpp \
src/ui/actorwidgets/alarmwidget.cpp \
src/ui/actorwidgets/timeractorwidget.cpp \
src/ui/itemsettingswidgets/relayitemsettingswidget.cpp \
src/ui/itemsettingswidgets/systemitemsettingswidget.cpp \
src/ui/itemwidget.cpp \
src/ui/itemsettingsdialog.cpp \
src/ui/itemscrollbox.cpp \
src/items/poweritem.cpp \
src/ui/actorwidgets/regulatorwdiget.cpp
SOURCES += \
src/ui/actorsettingsdialog.cpp \
src/ui/mainwindow.cpp \
src/ui/sensorlistwidget.cpp
SOURCES += \
src/actors/actor.cpp \
src/actors/sensoractor.cpp \
src/actors/alarmtime.cpp \
src/actors/regulator.cpp \
src/actors/timeractor.cpp
SOURCES += \
src/sensors/sensor.cpp \
src/sensors/speakersensor.cpp \
src/sensors/sunsensor.cpp \
src/sensors/ocupancysensor.cpp
SOURCES += \
src/items/relay.cpp \
src/items/item.cpp \
src/items/itemstore.cpp \
src/items/auxitem.cpp \
src/items/rgbitem.cpp
SOURCES += \
src/alarmactions.cpp \
src/main.cpp \
src/microcontroller.cpp \
src/sun.cpp
HEADERS += \
src/actors/factoractor.h \
src/actors/polynomalactor.h \
src/broadcast.h \
src/iomuliplexer.h \
src/items/messageitem.h \
src/items/systemitem.h \
src/ui/actorwidgets/factoractorwidget.h \
src/ui/itemcreationdialog.h \
src/ui/itemsettingswidgets/messageitemsettingswidget.h \
src/mainobject.h \
src/apgetconnected.h \
src/ui/actorwidgets/alarmwidget.h \
src/ui/actorwidgets/polynomalactorwidget.h \
src/ui/actorwidgets/sensoractorwidget.h \
src/ui/actorwidgets/timeractorwidget.h \
src/ui/itemsettingswidgets/relayitemsettingswidget.h \
src/ui/itemsettingswidgets/systemitemsettingswidget.h \
src/ui/itemwidget.h \
src/ui/itemsettingsdialog.h \
src/ui/itemscrollbox.h \
src/items/poweritem.h \
src/ui/actorwidgets/regulatorwdiget.h
HEADERS += \
src/ui/actorsettingsdialog.h \
src/ui/mainwindow.h \
src/ui/sensorlistwidget.h
HEADERS += \
src/actors/actor.h \
src/actors/alarmtime.h \
src/actors/sensoractor.h \
src/actors/regulator.h \
src/actors/timeractor.h
HEADERS += \
src/sensors/sensor.h \
src/sensors/speakersensor.h \
src/sensors/sunsensor.h \
src/sensors/ocupancysensor.h
HEADERS += \
src/items/relay.h \
src/items/item.h \
src/items/itemstore.h \
src/items/auxitem.h \
src/items/rgbitem.h
HEADERS += \
src/alarmactions.h \
src/microcontroller.h \
src/sun.h
FORMS += \
src/ui/actorwidgets/factoractorwidget.ui \
src/ui/itemcreationdialog.ui \
src/ui/itemsettingswidgets/messageitemsettingswidget.ui \
src/ui/actorsettingsdialog.ui \
src/ui/actorwidgets/polynomalactorwidget.ui \
src/ui/itemsettingswidgets/relayitemsettingswidget.ui \
src/ui/itemsettingswidgets/systemitemsettingswidget.ui \
src/ui/mainwindow.ui \
src/ui/relayscrollbox.ui \
src/ui/actorwidgets/sensoractorwidget.ui \
src/ui/actorwidgets/alarmwidget.ui \
src/ui/actorwidgets/timeractorwidget.ui \
src/ui/itemsettingsdialog.ui \
src/ui/itemwidget.ui \
src/ui/actorwidgets/regulatorwdiget.ui
android:FORMS += src/ui/mainwindow-android.ui
RESOURCES += \
resources.qrc

100
src/actor.cpp.autosave Normal file
View file

@ -0,0 +1,100 @@
#include "actor.h"
#include<QDebug>
Actor::Actor(QObject *parent): QObject(parent)
{
buildName();
}
Actor::~Actor()
{
}
void Actor::performAction()
{
if(active)
{
trigger();
if(action_ == ACTION_OFF) off();
else if(action_ == ACTION_ON) on();
else if(action_ != ACTION_TOGGLE) toggle();
else if(action_ != ACTION_VALUE) sigValue(value_);
}
}
void Actor::makeActive()
{
active = true;
}
void Actor::makeInactive()
{
active = false;
}
void Actor::buildName()
{
name = "Actor";
appendActionToName();
}
void Actor::appendActionToName()
{
if(action_ == ACTION_OFF || action_ == ACTION_DEFAULT ) name.append("off");
else if(action_ == ACTION_ON ) name.append("on");
else if(action_ == ACTION_TOGGLE ) name.append("toggle");
else if(action_ == ACTION_VALUE ) name.append("value to " + QString::number(value_));
}
void Actor::setActive(int state)
{
state ? makeActive() : makeInactive();
buildName();
}
bool Actor::isActive()
{
return active;
}
bool Actor::isExausted()
{
return exausted;
}
void Actor::saveSettings(QString subsecton, QSettings* settings)
{
settings->setValue(subsecton + "Active", active);
settings->setValue(subsecton + "Exausted", exausted);
settings->setValue(subsecton + "Name", name);
settings->setValue(subsecton + "Action", action_);
}
void Actor::loadSettings(QString subsecton, QSettings* settings)
{
active = settings->value(subsecton + "Active").toBool();
exausted = settings->value(subsecton + "Exausted").toBool();
name = settings->value(subsecton + "Name").toString();
action_ = settings->value(subsecton + "Action").toUInt();
}
void Actor::setAction(uint8_t action)
{
action_ = action;
qDebug()<<"setting action to "<<action;
buildName();
}
void Actor::setValue(uint8_t value)
{
value_=value;
buildName();
}
void Actor::onStateChanged(bool state)
{
}

View file

@ -88,7 +88,7 @@ uint8_t Actor::getTriggerValue()
void Actor::onValueChanged(uint8_t value) void Actor::onValueChanged(uint8_t value)
{ {
(void)value;
} }
std::shared_ptr<Actor> Actor::createActor(const QString& type) std::shared_ptr<Actor> Actor::createActor(const QString& type)

View file

@ -5,7 +5,7 @@
#include <QString> #include <QString>
#include <QJsonObject> #include <QJsonObject>
#include "items/item.h" #include "../items/item.h"
class Actor : public Item class Actor : public Item
{ {

View file

@ -4,17 +4,17 @@ AlarmTime::AlarmTime(const QDateTime time, QObject *parent) : Actor(parent), tim
{ {
connect(&timer, SIGNAL(timeout()), this, SLOT(doTick())); connect(&timer, SIGNAL(timeout()), this, SLOT(doTick()));
timer.setInterval(1000); timer.setInterval(1000);
AlarmTime::run(); run();
} }
AlarmTime::~AlarmTime() AlarmTime::~AlarmTime()
{ {
AlarmTime::makeInactive(); makeInactive();
} }
void AlarmTime::run() void AlarmTime::run()
{ {
AlarmTime::makeInactive(); makeInactive();
active = true; active = true;
timer.start(); timer.start();
@ -61,7 +61,7 @@ QString AlarmTime::getName() const
void AlarmTime::setRepeat(const uint8_t repeat) void AlarmTime::setRepeat(const uint8_t repeat)
{ {
repeat_ = repeat; repeat_=repeat;
exausted = false; exausted = false;
} }

View file

@ -26,9 +26,8 @@ void MultiFactorActor::setValue(uint8_t value)
{ {
performAction(); performAction();
} }
exausted = true; bool exausted = true;
for(size_t i = 0; i < getActors().size(); ++i) if(!getActors()[i]->isExausted()) for(size_t i = 0; i < getActors().size(); ++i) if(!getActors()[i]->isExausted()) exausted = false;
exausted = false;
} }
} }

View file

@ -29,28 +29,13 @@ public:
virtual QString getName() const; virtual QString getName() const;
void setFactorActor(std::shared_ptr<Actor> factorActor); void setFactorActor(std::shared_ptr<Actor> factorActor);
std::shared_ptr<Actor> getFactorActor() std::shared_ptr<Actor> getFactorActor(){return factorActor_;}
{ void setFactorDirection(const bool direction){factorDirection = direction;}
return factorActor_; bool getFactorDirection(){return factorDirection;}
} uint getPreCancleTime(){return preCancleMin_;}
void setFactorDirection(const bool direction) void setPreCancleTime(uint minutes){preCancleMin_ = minutes;}
{
factorDirection = direction;
}
bool getFactorDirection()
{
return factorDirection;
}
uint getPreCancleTime()
{
return preCancleMin_;
}
void setPreCancleTime(uint minutes)
{
preCancleMin_ = minutes;
}
virtual ~MultiFactorActor() {} virtual ~MultiFactorActor(){}
virtual void store(QJsonObject& json); virtual void store(QJsonObject& json);
virtual void load(const QJsonObject& json, bool preserve); virtual void load(const QJsonObject& json, bool preserve);

View file

@ -35,8 +35,7 @@ void PolynomalActor::sensorEvent(Sensor sensor)
{ {
if(active && sensor == sensor_) if(active && sensor == sensor_)
{ {
double result = pow3_*(sensor.field*sensor.field*sensor.field)+pow2_*(sensor.field*sensor.field)+pow1_*sensor.field double result = pow3_*(sensor.field*sensor.field*sensor.field)+pow2_*(sensor.field*sensor.field)+pow1_*sensor.field+pow0_;
+pow0_;
if(result < 0) result = 0; if(result < 0) result = 0;
else if(result > 254) result = 255; else if(result > 254) result = 255;
if(result != prevValue)sigValue(static_cast<uint8_t>(result)); if(result != prevValue)sigValue(static_cast<uint8_t>(result));
@ -77,8 +76,7 @@ QString PolynomalActor::getName() const
else else
{ {
QString string; QString string;
string = QString::number(pow3_) + "x^3 + " + QString::number(pow2_) + "x^2 + " + QString::number( string = QString::number(pow3_) + "x^3 + " + QString::number(pow2_) + "x^2 + " + QString::number(pow1_) + "x + " + QString::number(pow0_) + " (x: " + sensor_.name + ")";
pow1_) + "x + " + QString::number(pow0_) + " (x: " + sensor_.name + ")";
return string; return string;
} }
} }

View file

@ -1,7 +1,7 @@
#ifndef POLYNOMALACTOR_H #ifndef POLYNOMALACTOR_H
#define POLYNOMALACTOR_H #define POLYNOMALACTOR_H
#include "actor.h" #include "actor.h"
#include "sensors/sensor.h" #include "../sensors/sensor.h"
class PolynomalActor: public Actor class PolynomalActor: public Actor
{ {
@ -28,12 +28,9 @@ public:
PolynomalActor(const Sensor sensor, QObject* parent = nullptr); PolynomalActor(const Sensor sensor, QObject* parent = nullptr);
PolynomalActor(QObject* parent = nullptr); PolynomalActor(QObject* parent = nullptr);
void setSensor(const Sensor sensor); void setSensor(const Sensor sensor);
Sensor getSensor() Sensor getSensor(){return sensor_;}
{
return sensor_;
}
virtual QString getName() const; virtual QString getName() const;
virtual ~PolynomalActor() {} virtual ~PolynomalActor(){}
virtual void store(QJsonObject& json); virtual void store(QJsonObject& json);
virtual void load(const QJsonObject& json, bool preserve); virtual void load(const QJsonObject& json, bool preserve);

View file

@ -4,16 +4,12 @@
Regulator::Regulator(const Sensor sensor, QObject* parent): Actor(parent), sensor_(sensor) Regulator::Regulator(const Sensor sensor, QObject* parent): Actor(parent), sensor_(sensor)
{ {
timer.setSingleShot(true);
timer.start(timeout_*1000);
connect(&timer, &QTimer::timeout, this, &Regulator::timeout);
} }
Regulator::Regulator(QObject* parent): Actor(parent) Regulator::Regulator(QObject* parent): Actor(parent)
{ {
timer.setSingleShot(true);
timer.start(timeout_*1000);
connect(&timer, &QTimer::timeout, this, &Regulator::timeout);
} }
void Regulator::setSensor(const Sensor sensor) void Regulator::setSensor(const Sensor sensor)
@ -25,7 +21,6 @@ void Regulator::sensorEvent(Sensor sensor)
{ {
if(active && sensor == sensor_) if(active && sensor == sensor_)
{ {
timer.start(timeout_*1000);
if( sensor.field < setPoint_-band_ && (sensor.field < sensor_.field || sensor_.field > setPoint_-band_ || first) ) if( sensor.field < setPoint_-band_ && (sensor.field < sensor_.field || sensor_.field > setPoint_-band_ || first) )
{ {
sigValue(triggerValue); sigValue(triggerValue);
@ -39,20 +34,6 @@ void Regulator::sensorEvent(Sensor sensor)
} }
} }
void Regulator::makeInactive()
{
first = true;
if(active)
sigValue(!triggerValue);
timer.stop();
Actor::makeInactive();
}
void Regulator::timeout()
{
sigValue(safeValue_);
}
void Regulator::setPoint(float setPoint) void Regulator::setPoint(float setPoint)
{ {
setPoint_ = setPoint; setPoint_ = setPoint;
@ -68,25 +49,12 @@ void Regulator::setInvert( bool invert )
invert_ = invert; invert_ = invert;
} }
void Regulator::setSafeValue(int value)
{
safeValue_ = value;
}
void Regulator::setTimeout(int value)
{
timeout_ = value;
timer.start(timeout_*1000);
}
void Regulator::store(QJsonObject& json) void Regulator::store(QJsonObject& json)
{ {
json["Type"] = "Regulator"; json["Type"] = "Regulator";
Actor::store(json); Actor::store(json);
json["Band"] = band_; json["Band"] = band_;
json["SetPoint"] = setPoint_; json["SetPoint"] = setPoint_;
json["SafeValue"] = safeValue_;
json["Timeout"] = timeout_;
json["SensorType"] = static_cast<int>(sensor_.type); json["SensorType"] = static_cast<int>(sensor_.type);
json["SensorId"] = static_cast<int>(sensor_.id); json["SensorId"] = static_cast<int>(sensor_.id);
json["SensorField"] = sensor_.field; json["SensorField"] = sensor_.field;
@ -98,21 +66,15 @@ void Regulator::load(const QJsonObject& json, bool preserve)
Actor::load(json, preserve); Actor::load(json, preserve);
band_ = json["Band"].toDouble(1); band_ = json["Band"].toDouble(1);
setPoint_ = json["SetPoint"].toDouble(22); setPoint_ = json["SetPoint"].toDouble(22);
safeValue_ = json["SafeValue"].toDouble(0);
timeout_ = json["Timeout"].toDouble(1800);
sensor_.type = json["SensorType"].toInt(0); sensor_.type = json["SensorType"].toInt(0);
sensor_.id = json["SensorId"].toInt(0); sensor_.id = json["SensorId"].toInt(0);
sensor_.field = json["SensorField"].toInt(0); sensor_.field = json["SensorField"].toInt(0);
sensor_.name = json["SensorName"].toString("Sensor"); sensor_.name = json["SensorName"].toString("Sensor");
timer.start(timeout_*1000);
} }
QString Regulator::getName() const QString Regulator::getName() const
{ {
if(name_.size() > 0) if(name_.size() > 0) return name_;
{
return name_;
}
else else
{ {
QString string; QString string;

View file

@ -1,9 +1,6 @@
#pragma once #pragma once
#include <QTimer>
#include "actor.h" #include "actor.h"
#include "sensors/sensor.h" #include "../sensors/sensor.h"
class Regulator : public Actor class Regulator : public Actor
{ {
@ -14,54 +11,27 @@ private:
float setPoint_ = 0; float setPoint_ = 0;
float band_ = 1; float band_ = 1;
bool invert_ = false; bool invert_ = false;
int timeout_ = 1800;
int safeValue_ = 0;
QTimer timer;
bool first = true; bool first = true;
private slots:
void timeout();
public slots: public slots:
void sensorEvent(Sensor sensor); void sensorEvent(Sensor sensor);
void setSensor(const Sensor sensor); void setSensor(const Sensor sensor);
void setPoint(float setPoint ); void setPoint( float setPoint );
void setBand (float band ); void setBand ( float band );
void setInvert(bool invert ); void setInvert( bool invert );
void setSafeValue(int value);
void setTimeout(int value);
virtual void makeInactive() override;
public: public:
float getBand() float getBand() {return band_;}
{ float getSetPoint() {return setPoint_;}
return band_;
}
float getSetPoint()
{
return setPoint_;
}
int getSafeValue()
{
return safeValue_;
}
int getTimeout()
{
return timeout_;
}
Regulator(const Sensor sensor, QObject* parent = nullptr); Regulator(const Sensor sensor, QObject* parent = nullptr);
Regulator(QObject* parent = nullptr); Regulator(QObject* parent = nullptr);
Sensor getSensor() Sensor getSensor(){return sensor_;}
{
return sensor_;
}
virtual QString getName() const; virtual QString getName() const;
virtual ~Regulator() {} virtual ~Regulator(){}
virtual void store(QJsonObject& json); virtual void store(QJsonObject& json);
virtual void load(const QJsonObject& json, bool preserve); virtual void load(const QJsonObject& json, bool preserve);

View file

@ -21,10 +21,8 @@ void SensorActor::sensorEvent(Sensor sensor)
{ {
if(sensor == sensor_) if(sensor == sensor_)
{ {
if((sloap_ == SLOPE_UP || sloap_ == SLOPE_BOTH) && sensor_.field < threshold_ if((sloap_ == SLOPE_UP || sloap_ == SLOPE_BOTH) && sensor_.field < threshold_ && sensor.field >= threshold_ ) performAction();
&& sensor.field >= threshold_ ) performAction(); else if((sloap_ == SLOPE_DOWN || sloap_ == SLOPE_BOTH) && sensor_.field > threshold_ && sensor.field <= threshold_) performAction();
else if((sloap_ == SLOPE_DOWN || sloap_ == SLOPE_BOTH) && sensor_.field > threshold_
&& sensor.field <= threshold_) performAction();
sensor_ = sensor; sensor_ = sensor;
} }
} }

View file

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "actor.h" #include "actor.h"
#include "sensors/sensor.h" #include "../sensors/sensor.h"
class SensorActor : public Actor class SensorActor : public Actor
{ {
@ -28,12 +28,9 @@ public:
SensorActor(const Sensor sensor, QObject* parent = nullptr); SensorActor(const Sensor sensor, QObject* parent = nullptr);
SensorActor(QObject* parent = nullptr); SensorActor(QObject* parent = nullptr);
Sensor getSensor() Sensor getSensor(){return sensor_;}
{
return sensor_;
}
virtual QString getName() const; virtual QString getName() const;
virtual ~SensorActor() {} virtual ~SensorActor(){}
float getThreshold(); float getThreshold();
uint8_t getSloap(); uint8_t getSloap();

14
src/alarmactions.cpp Normal file
View file

@ -0,0 +1,14 @@
#include "alarmactions.h"
#include <QProcess>
AlarmActions::AlarmActions(QApplication* a, Microcontroller* micro, QObject *parent) : QObject(parent), _micro(micro), a_(a)
{
}
void AlarmActions::syncoff()
{
qDebug()<<"syncoff";
QProcess::execute ( "syncoff" );
a_->exit(0);
}

25
src/alarmactions.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef POWER_H
#define POWER_H
#include <QApplication>
#include "microcontroller.h"
class AlarmActions : public QObject
{
private:
Q_OBJECT
Microcontroller* _micro;
QApplication* a_;
public:
explicit AlarmActions(QApplication* a, Microcontroller* micro, QObject *parent = nullptr);
signals:
public slots:
void syncoff();
};
#endif // POWER_H

View file

@ -53,8 +53,6 @@ static int nl80211Init(struct nl_sock* nl_sock, int* nl80211_id)
static int errorHandler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) static int errorHandler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
{ {
(void)nla;
(void)err;
printf("netlink error\n"); printf("netlink error\n");
*reinterpret_cast<int*>(arg) = 0; *reinterpret_cast<int*>(arg) = 0;
return NL_STOP; return NL_STOP;
@ -62,14 +60,12 @@ static int errorHandler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg
static int finishHandler(struct nl_msg *msg, void *arg) static int finishHandler(struct nl_msg *msg, void *arg)
{ {
(void)msg;
*reinterpret_cast<int*>(arg) = 0; *reinterpret_cast<int*>(arg) = 0;
return NL_SKIP; return NL_SKIP;
} }
static int ackHandler(struct nl_msg *msg, void *arg) static int ackHandler(struct nl_msg *msg, void *arg)
{ {
(void)msg;
*reinterpret_cast<int*>(arg) = 0; *reinterpret_cast<int*>(arg) = 0;
return NL_STOP; return NL_STOP;
} }
@ -154,7 +150,7 @@ std::vector<uint64_t> connectedDevices(const std::string& ifDevice, int& error)
} }
} }
nla_put_failure: nla_put_failure:
nl_cb_put(cb); nl_cb_put(cb);
nl_cb_put(s_cb); nl_cb_put(s_cb);
nlmsg_free(msg); nlmsg_free(msg);

View file

@ -6,14 +6,14 @@
namespace ap namespace ap
{ {
enum ERRORS enum ERRORS
{ {
SUCESS, SUCESS,
ERR_INIT, ERR_INIT,
ERR_NO_DEV, ERR_NO_DEV,
ERR_ALLOC, ERR_ALLOC,
ERR_GENERAL ERR_GENERAL
}; };
std::vector<uint64_t> connectedDevices(const std::string& ifDevice, int& error); std::vector<uint64_t> connectedDevices(const std::string& ifDevice, int& error);
std::string macAddrToString(uint64_t macAddr); std::string macAddrToString(uint64_t macAddr);
} }

134
src/broadcast.cpp Normal file
View file

@ -0,0 +1,134 @@
#include "broadcast.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
BroadCast::BroadCast(QIODevice* const iodevice, bool master ): master_(master), iodevice_(iodevice)
{
if(iodevice_ != nullptr) connect(iodevice_, &QIODevice::readyRead, this, &BroadCast::readyRead);
}
void BroadCast::write(const char * const buffer, const size_t length)
{
QByteArray mBuffer("bcst: ");
for (size_t i = 0; i < length; ++i)
{
if(buffer[i] != '\n' && buffer[i] != '\0') mBuffer.push_back(buffer[i]);
else
{
mBuffer.push_back('\\');
if(buffer[i] == '\n')mBuffer.push_back('n');
else mBuffer.push_back('0');
}
}
mBuffer.push_back('\n');
if(iodevice_)iodevice_->write(mBuffer);
}
void BroadCast::write(const QByteArray& buffer)
{
write(buffer.data(), buffer.size());
}
void BroadCast::sendJson(const QJsonObject& json)
{
QJsonDocument jsonDocument(json);
QByteArray buffer("JSON: ");
buffer.append(jsonDocument.toJson());
write(buffer);
}
void BroadCast::sendSensors()
{
if(iodevice_)for(auto& sensor: *globalSensors.getSensors())
{
iodevice_->write("bcst: "+sensor.toString().toLatin1()+'\n');
}
}
void BroadCast::requestSensors()
{
if(iodevice_)iodevice_->write("bcst: GETSENSORS\n");
}
void BroadCast::requestJson()
{
if(iodevice_)iodevice_->write("bcst: GETJSN\n");
}
void BroadCast::decodeMaster(const QByteArray& buffer)
{
if(buffer.startsWith("GETJSN"))
{
qDebug()<<"json requested";
jsonRequested();
}
else if(buffer.startsWith("GETSENSORS") )
{
qDebug()<<"sensors requested";
sendSensors();
}
}
void BroadCast::decode(QByteArray buffer)
{
qDebug()<<"decodeing: "<<buffer;
if(buffer.size() >= 6 && buffer[0] == 'J' && buffer[1] == 'S' && buffer[2] == 'O' && buffer[3] == 'N' && buffer[4] == ':')
{
qDebug()<<"got json";
buffer.remove(0,6);
for(int i = 0; i < buffer.size()-1; ++i)
{
if( buffer[i] == '\\' && buffer[i+1] == 'n' )
{
buffer[i] = '\n';
buffer.remove(i+1,1);
}
else if( buffer[i] == '\\' && buffer[i+1] == '0' )
{
buffer[i] = '\0';
buffer.remove(i+1,1);
}
}
QJsonParseError error;
QJsonDocument document = QJsonDocument::fromJson(buffer, &error);
qDebug()<<"JSON:";
qDebug()<<document.toJson().data();
QJsonObject jsonObject = document.object();
if(error.error == QJsonParseError::NoError && !document.isEmpty() && !jsonObject.isEmpty()) gotJson(jsonObject);
else
{
qDebug()<<error.errorString();
}
}
else if(buffer.size() >= 6 && buffer[0] == 'S' && buffer[1] == 'E' && buffer[2] == 'N' && buffer[3] == 'S' && buffer[4] == 'O' && buffer[5] == 'R')
{
Sensor sensor = Sensor::sensorFromString(buffer);
if(sensor.type != Sensor::TYPE_DUMMY) gotSensorState(sensor);
}
}
void BroadCast::sendMessage(const QString &title, const QString &body)
{
write(QByteArray("MESG ") + title.toLatin1() + " BODY " + body.toLatin1());
}
void BroadCast::readyRead()
{
buffer_.append(iodevice_->readAll());
int newlineIndex = buffer_.indexOf('\n');
while( newlineIndex != -1 )
{
if(buffer_.startsWith("bcst: "))
{
QByteArray tmp = buffer_.mid(6,newlineIndex-6);
decode(tmp);
if(master_)decodeMaster(tmp);
}
buffer_.remove(0, newlineIndex+1);
newlineIndex = buffer_.indexOf('\n');
}
}

55
src/broadcast.h Normal file
View file

@ -0,0 +1,55 @@
#ifndef BROADCAST_H
#define BROADCAST_H
#include <QIODevice>
#include <QObject>
#include <QString>
#include <QJsonObject>
#include "sensors/sensor.h"
class BroadCast: public QObject
{
Q_OBJECT
private:
bool master_;
static constexpr uint8_t MODE_PREPACKET = 0;
static constexpr uint8_t MODE_PACKET = 1;
QByteArray buffer_;
QIODevice* const iodevice_;
void write(const char * const buffer, const size_t length);
void write(const QByteArray& buffer);
void decode(QByteArray buffer);
void decodeMaster(const QByteArray& buffer);
private slots:
void readyRead();
public slots:
void requestJson();
void requestSensors();
signals:
void jsonRequested();
void gotJson(QJsonObject json);
void gotSensorState(Sensor sensor);
public:
BroadCast(QIODevice* const iodevice = nullptr, bool master = true);
void sendJson(const QJsonObject& json);
void sendSensors();
void sendMessage(const QString& title, const QString& body);
};
#endif // BROADCAST_H

76
src/iomuliplexer.cpp Normal file
View file

@ -0,0 +1,76 @@
#include "iomuliplexer.h"
#include<QDebug>
VirutalIODevice::VirutalIODevice(QObject* parent): QBuffer(parent)
{
}
qint64 VirutalIODevice::writeData(const char *data, qint64 len)
{
blockSignals(true);
qint64 ret = QBuffer::writeData(data, len);
blockSignals(false);
masterReadyRead();
return ret;
}
qint64 VirutalIODevice::masterWrite(const QByteArray &byteArray)
{
return masterWrite(byteArray.data(), byteArray.length());
}
qint64 VirutalIODevice::masterWrite(const char *data, qint64 maxSize)
{
blockSignals(true);
qint64 ret = QBuffer::writeData(data, maxSize);
blockSignals(false);
readyRead();
return ret;
}
IoMuliplexer::IoMuliplexer(QIODevice* mainDevice, QObject* Parent): IoMuliplexer(Parent)
{
setIoDevice(mainDevice);
}
IoMuliplexer::IoMuliplexer(QObject* Parent): QObject(Parent)
{
}
IoMuliplexer::~IoMuliplexer()
{
for(size_t i = 0; i < ioDevices_.size(); ++i) delete ioDevices_[i];
ioDevices_.clear();
}
void IoMuliplexer::setIoDevice(QIODevice* mainDevice)
{
mainDevice_ = mainDevice;
connect(mainDevice_, &QIODevice::readyRead, this, &IoMuliplexer::mainIsReadyRead);
}
QIODevice* IoMuliplexer::getIoDevice()
{
ioDevices_.push_back(new VirutalIODevice);
ioDevices_.back()->open(QIODevice::ReadWrite);
connect(ioDevices_.back(), &VirutalIODevice::masterReadyRead, this, &IoMuliplexer::clientIsReadyRead);
return ioDevices_.back();
}
void IoMuliplexer::clientIsReadyRead()
{
VirutalIODevice* device = dynamic_cast<VirutalIODevice*>(sender());
if(device)
{
QByteArray array = device->readAll();
mainDevice_->write(array);
}
}
void IoMuliplexer::mainIsReadyRead()
{
QByteArray array = mainDevice_->readAll();
for(size_t i = 0; i < ioDevices_.size(); ++i) ioDevices_[i]->masterWrite(array);
}

54
src/iomuliplexer.h Normal file
View file

@ -0,0 +1,54 @@
#ifndef IOMULIPLEXER_H
#define IOMULIPLEXER_H
#include <QObject>
#include <vector>
#include <QIODevice>
#include <QBuffer>
class VirutalIODevice: public QBuffer
{
Q_OBJECT
public:
VirutalIODevice(QObject* parent = nullptr);
virtual ~VirutalIODevice() override {}
virtual qint64 writeData(const char *data, qint64 len) override;
qint64 masterWrite(const QByteArray &byteArray);
qint64 masterWrite(const char *data, qint64 maxSize);
signals:
void masterReadyRead();
};
class IoMuliplexer: public QObject
{
Q_OBJECT
private:
QIODevice* mainDevice_;
std::vector< VirutalIODevice* > ioDevices_;
public:
explicit IoMuliplexer(QIODevice* mainDevice, QObject* Parent = nullptr);
explicit IoMuliplexer(QObject* Parent = nullptr);
~IoMuliplexer();
void setIoDevice(QIODevice* mainDevice);
QIODevice* getIoDevice();
private slots:
void mainIsReadyRead();
void clientIsReadyRead();
};
#endif // IOMULIPLEXER_H

View file

@ -1,14 +1,13 @@
#include "auxitem.h" #include "auxitem.h"
AuxItem::AuxItem(Microcontroller* micro, uint32_t itemIdIn, QString name, uint8_t value, AuxItem::AuxItem(Microcontroller* micro, uint32_t itemIdIn, QString name, uint8_t value, QObject* parent): Item(itemIdIn, name, value, parent), micro_(micro)
QObject* parent): Item(itemIdIn, name, value, parent), micro_(micro)
{ {
type_ = ITEM_VALUE_UINT;
} }
void AuxItem::enactValue(uint8_t value) void AuxItem::setValue(uint8_t value)
{ {
assert(micro_); Item::setValue(value);
micro_->setAuxPwm(value); micro_->setAuxPwm(value);
} }

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "item.h" #include "item.h"
#include "microcontroller.h" #include "../microcontroller.h"
class AuxItem: public Item class AuxItem: public Item
{ {
@ -9,12 +9,12 @@ class AuxItem: public Item
private: private:
Microcontroller* micro_; Microcontroller* micro_;
protected: public slots:
virtual void enactValue(uint8_t value) override;
virtual void setValue(uint8_t value);
public: public:
AuxItem(Microcontroller* micro = nullptr, uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "", AuxItem(Microcontroller* micro, uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "", uint8_t value = 0, QObject* parent = nullptr);
uint8_t value = 0, QObject* parent = nullptr);
virtual void store(QJsonObject& json) override; virtual void store(QJsonObject& json);
}; };

View file

@ -1,14 +0,0 @@
#include "fixeditemsource.h"
FixedItemSource::FixedItemSource(Microcontroller* micro, QObject *parent):
ItemSource{parent},
powerItem(new PowerItem(5487423)),
rgbItem(new RgbItem(micro, 5487422, "Rgb Lights")),
auxItem(new AuxItem(micro, 5487421, "Desk Light"))
{
}
void FixedItemSource::refresh()
{
gotItems({powerItem, rgbItem, auxItem});
}

View file

@ -1,22 +0,0 @@
#ifndef FIXEDITEMSOURCE_H
#define FIXEDITEMSOURCE_H
#include "itemsource.h"
#include "poweritem.h"
#include "rgbitem.h"
#include "auxitem.h"
#include "microcontroller.h"
class FixedItemSource : public ItemSource
{
Q_OBJECT
std::shared_ptr<PowerItem> powerItem;
std::shared_ptr<RgbItem> rgbItem;
std::shared_ptr<AuxItem> auxItem;
public:
explicit FixedItemSource(Microcontroller* micro, QObject *parent = nullptr);
virtual void refresh() override;
};
#endif // FIXEDITEMSOURCE_H

View file

@ -1,20 +1,14 @@
#include "item.h" #include "item.h"
#include "actors/sensoractor.h"
#include "actors/regulator.h"
#include "actors/polynomalactor.h"
#include "programmode.h"
#include "relay.h" #include "relay.h"
#include "messageitem.h" #include "../microcontroller.h"
#include "systemitem.h" #include "../actors/sensoractor.h"
#include "auxitem.h" #include "../actors/regulator.h"
#include "poweritem.h" #include "../actors/polynomalactor.h"
#include "rgbitem.h"
#include <QJsonArray> #include <QJsonArray>
ItemData::ItemData(uint32_t itemIdIn, QString name, uint8_t value, bool loaded, bool hidden, item_value_type_t type): ItemData::ItemData(uint32_t itemIdIn, QString name, uint8_t value): name_(name), value_(value), itemId_(itemIdIn)
name_(name), value_(value), itemId_(itemIdIn), loaded_(loaded), hidden_(hidden), type_(type)
{ {
} }
@ -39,65 +33,12 @@ uint32_t ItemData::id() const
return itemId_; return itemId_;
} }
void ItemData::store(QJsonObject &json)
{
json["Name"] = name_;
json["ItemId"] = static_cast<double>(itemId_);
json["Value"] = static_cast<double>(value_);
}
void ItemData::load(const QJsonObject &json, const bool preserve)
{
if(!preserve)
{
name_ = json["Name"].toString(name_);
itemId_ = static_cast<uint32_t>(json["ItemId"].toDouble(0));
value_ = json["Value"].toInt();
}
}
bool ItemData::getLoaded() const
{
return loaded_;
}
void ItemData::setLoaded(bool loaded)
{
loaded_ = loaded;
}
bool ItemData::hasChanged(const ItemData& other)
{
if(other != *this)
return false;
if(other.getName() != getName())
return true;
if(other.getValue() != getValue())
return true;
if(other.getLoaded() != getLoaded())
return true;
return false;
}
bool ItemData::isHidden()
{
return hidden_;
}
void ItemData::setHidden(bool hidden)
{
hidden_ = hidden;
}
item_value_type_t ItemData::getValueType()
{
return type_;
}
//item //item
Item::Item(uint32_t itemIdIn, QString name, uint8_t value, QObject *parent): QObject(parent), ItemData (itemIdIn, name, bool Item::secondaryFlag = false;
value)
Item::Item(uint32_t itemIdIn, QString name, uint8_t value, QObject *parent): QObject(parent), ItemData (itemIdIn, name, value)
{ {
} }
@ -113,7 +54,8 @@ Item::~Item()
void Item::store(QJsonObject &json) void Item::store(QJsonObject &json)
{ {
ItemData::store(json); json["Name"] = name_;
json["ItemId"] = static_cast<double>(itemId_);
json["override"] = override_; json["override"] = override_;
QJsonArray actorsArray; QJsonArray actorsArray;
for(size_t i = 0; i < actors_.size(); ++i) for(size_t i = 0; i < actors_.size(); ++i)
@ -130,7 +72,11 @@ void Item::store(QJsonObject &json)
void Item::load(const QJsonObject &json, const bool preserve) void Item::load(const QJsonObject &json, const bool preserve)
{ {
ItemData::load(json, preserve); if(!preserve)
{
name_ = json["Name"].toString(name_);
itemId_ = static_cast<uint32_t>(json["ItemId"].toDouble(0));
}
override_ = json["override"].toBool(false); override_ = json["override"].toBool(false);
const QJsonArray actorsArray(json["Actors"].toArray(QJsonArray())); const QJsonArray actorsArray(json["Actors"].toArray(QJsonArray()));
for(int i = 0; i < actorsArray.size(); ++i) for(int i = 0; i < actorsArray.size(); ++i)
@ -138,60 +84,45 @@ void Item::load(const QJsonObject &json, const bool preserve)
if(actorsArray[i].isObject()) if(actorsArray[i].isObject())
{ {
std::shared_ptr<Actor> actor = Actor::loadActor(actorsArray[i].toObject()); std::shared_ptr<Actor> actor = Actor::loadActor(actorsArray[i].toObject());
if(actor != nullptr) if(actor != nullptr) addActor(actor);
addActor(actor);
} }
} }
} }
void Item::actorSetValue(uint8_t value) void Item::actorSetValue(uint8_t value)
{ {
if(!override_ && (programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY)) if(!override_) setValue(value);
setValue(value);
} }
void Item::setValue(uint8_t value) void Item::setValue(uint8_t value)
{ {
qDebug()<<__func__; value_ = value;
informValue(value); valueChanged(value_);
if(programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY)
enactValue(value);
} }
void Item::informValue(uint8_t value) void Item::informValue(uint8_t value)
{ {
if(value_ != value) Item::setValue(value);
{
value_ = value;
valueChanged(value_);
updated(*this);
}
}
void Item::enactValue(uint8_t value)
{
(void)value;
} }
void Item::addActor(std::shared_ptr<Actor> actor) void Item::addActor(std::shared_ptr<Actor> actor)
{ {
actor->setParent(this); actor->setParent(this);
actors_.push_back(actor); actors_.push_back(actor);
if(programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY) if(!secondaryFlag)
{
connect(actor.get(), &Actor::sigValue, this, &Item::actorSetValue); connect(actor.get(), &Actor::sigValue, this, &Item::actorSetValue);
}
connect(this, &Item::valueChanged, actor.get(), &Actor::onValueChanged); connect(this, &Item::valueChanged, actor.get(), &Actor::onValueChanged);
std::shared_ptr<SensorActor> sensorActor = std::dynamic_pointer_cast<SensorActor>(actor); std::shared_ptr<SensorActor> sensorActor = std::dynamic_pointer_cast<SensorActor>(actor);
if(sensorActor) if(sensorActor)connect(&globalSensors, &SensorStore::sensorChangedState, sensorActor.get(), &SensorActor::sensorEvent);
connect(&globalSensors, &SensorStore::sensorChangedState, sensorActor.get(), &SensorActor::sensorEvent);
std::shared_ptr<Regulator> regulator = std::dynamic_pointer_cast<Regulator>(actor); std::shared_ptr<Regulator> regulator = std::dynamic_pointer_cast<Regulator>(actor);
if(regulator) if(regulator)connect(&globalSensors, &SensorStore::sensorChangedState, regulator.get(), &Regulator::sensorEvent);
connect(&globalSensors, &SensorStore::sensorChangedState, regulator.get(), &Regulator::sensorEvent);
std::shared_ptr<PolynomalActor> polynomalActor = std::dynamic_pointer_cast<PolynomalActor>(actor); std::shared_ptr<PolynomalActor> polynomalActor = std::dynamic_pointer_cast<PolynomalActor>(actor);
if(polynomalActor != nullptr ) if(polynomalActor != nullptr )connect(&globalSensors, &SensorStore::sensorChangedState, polynomalActor.get(), &PolynomalActor::sensorEvent);
connect(&globalSensors, &SensorStore::sensorChangedState, polynomalActor.get(), &PolynomalActor::sensorEvent);
} }
bool Item::removeActor(std::shared_ptr<Actor> actor) bool Item::removeActor(std::shared_ptr<Actor> actor)
@ -234,50 +165,5 @@ bool Item::hasActors()
void Item::setActorsActive(bool in) void Item::setActorsActive(bool in)
{ {
for(unsigned i = 0; i < actors_.size(); i++) for(unsigned i = 0; i < actors_.size(); i++) in ? actors_[i]->makeActive() : actors_[i]->makeInactive();
in ? actors_[i]->makeActive() : actors_[i]->makeInactive();
} }
void Item::mergeLoaded(Item& item)
{
name_ = item.name_;
actors_.clear();
for(std::shared_ptr<Actor> actor : item.actors_)
addActor(actor);
}
std::shared_ptr<Item> Item::loadItem(const QJsonObject& json)
{
std::shared_ptr<Item> newItem = nullptr;
if(json["Type"].toString("") == "Relay")
{
newItem = std::shared_ptr<Relay>(new Relay);
}
else if(json["Type"].toString("") == "Message")
{
newItem = std::shared_ptr<MessageItem>(new MessageItem);
}
else if(json["Type"].toString("") == "System")
{
newItem = std::shared_ptr<SystemItem>(new SystemItem);
}
else if(json["Type"].toString("") == "Aux")
{
newItem = std::shared_ptr<AuxItem>(new AuxItem);
}
else if(json["Type"].toString("") == "Power")
{
newItem = std::shared_ptr<PowerItem>(new PowerItem);
}
else if(json["Type"].toString("") == "Rgb")
{
newItem = std::shared_ptr<RgbItem>(new RgbItem);
}
if(newItem)
{
newItem->load(json);
newItem->setLoaded(true);
}
return newItem;
}

View file

@ -8,52 +8,25 @@
class Actor; class Actor;
typedef enum {
ITEM_VALUE_BOOL = 0,
ITEM_VALUE_UINT,
ITEM_VALUE_NO_VALUE
} item_value_type_t;
class ItemData class ItemData
{ {
protected: protected:
QString name_; QString name_;
uint8_t value_; uint8_t value_;
uint32_t itemId_; uint32_t itemId_;
bool loaded_;
bool hidden_;
item_value_type_t type_;
public: public:
ItemData(uint32_t itemIdIn = QRandomGenerator::global()->generate(),
QString name = "Item",
uint8_t value = 0,
bool loaded = false,
bool hidden = false,
item_value_type_t type = ITEM_VALUE_BOOL);
inline bool operator==(const ItemData& in) const ItemData(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Item", uint8_t value = 0);
{
return itemId_ == in.itemId_; inline bool operator==(const ItemData& in) const{ return itemId_==in.itemId_; }
} inline bool operator!=(const ItemData& in) const{ return itemId_!=in.itemId_; }
inline bool operator!=(const ItemData& in) const
{
return itemId_ != in.itemId_;
}
uint32_t id() const; uint32_t id() const;
bool hasChanged(const ItemData& other);
void setName(QString name); void setName(QString name);
uint8_t getValue() const; uint8_t getValue() const;
bool getLoaded() const;
void setLoaded(bool loaded);
bool isHidden();
void setHidden(bool hidden);
item_value_type_t getValueType();
virtual QString getName() const; virtual QString getName() const;
virtual void store(QJsonObject& json);
virtual void load(const QJsonObject& json, const bool preserve = false);
}; };
@ -65,20 +38,24 @@ private:
bool override_ = false; bool override_ = false;
public:
static bool secondaryFlag;
signals: signals:
void valueChanged(uint8_t value); void valueChanged(uint8_t value);
void updated(ItemData data);
private slots: private slots:
virtual void actorSetValue(uint8_t value); virtual void actorSetValue(uint8_t value);
public slots: public slots:
void setValue(uint8_t value);
virtual void setValue(uint8_t value);
public: public:
Item(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Item", uint8_t value = 0, Item(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Item", uint8_t value = 0, QObject *parent = nullptr);
QObject *parent = nullptr);
Item(const ItemData& itemData, QObject *parent = nullptr); Item(const ItemData& itemData, QObject *parent = nullptr);
virtual ~Item(); virtual ~Item();
@ -92,15 +69,9 @@ public:
void setOverride(const bool in); void setOverride(const bool in);
bool getOverride(); bool getOverride();
void informValue(uint8_t value); void informValue(uint8_t value);
void mergeLoaded(Item& item);
virtual void store(QJsonObject& json); virtual void store(QJsonObject& json);
virtual void load(const QJsonObject& json, const bool preserve = false); virtual void load(const QJsonObject& json, const bool preserve = false);
static std::shared_ptr<Item> loadItem(const QJsonObject& json);
protected:
virtual void enactValue(uint8_t value);
}; };

View file

@ -1,38 +0,0 @@
#include "itemloadersource.h"
#include <QJsonArray>
ItemLoaderSource::ItemLoaderSource(const QJsonObject& json, QObject *parent):
ItemSource{parent},
json(json)
{
}
void ItemLoaderSource::refresh()
{
std::vector<std::shared_ptr<Item>> items;
const QJsonArray itemsArray(json["Items"].toArray());
for(int i = 0; i < itemsArray.size(); ++i)
{
if(!itemsArray[i].isObject())
continue;
const QJsonObject itemObject = itemsArray[i].toObject();
std::shared_ptr<Item> newItem = Item::loadItem(itemObject);
if(newItem)
{
items.push_back(newItem);
qDebug()<<"Loaded item"<<newItem->getName();
}
}
gotItems(items);
}
void ItemLoaderSource::updateJson(const QJsonObject& json)
{
this->json = json;
}
ItemLoaderSource::~ItemLoaderSource()
{}

View file

@ -1,21 +0,0 @@
#ifndef ITEMLOADERSOURCE_H
#define ITEMLOADERSOURCE_H
#include <QJsonObject>
#include "itemsource.h"
class ItemLoaderSource : public ItemSource
{
Q_OBJECT
QJsonObject json;
public:
explicit ItemLoaderSource(const QJsonObject& json = QJsonObject(), QObject *parent = nullptr);
~ItemLoaderSource();
void updateJson(const QJsonObject& json);
virtual void refresh() override;
};
#endif // ITEMLOADERSOURCE_H

View file

@ -1,5 +0,0 @@
#include "itemsource.h"
ItemSource::ItemSource(QObject *parent)
: QObject{parent}
{}

View file

@ -1,25 +0,0 @@
#ifndef ITEMSOURCE_H
#define ITEMSOURCE_H
#include <QObject>
#include <vector>
#include <memory>
#include "item.h"
class ItemSource : public QObject
{
Q_OBJECT
public:
explicit ItemSource(QObject *parent = nullptr);
public slots:
virtual void refresh() = 0;
signals:
void gotItems(std::vector<std::shared_ptr<Item>> items, bool inform = true);
void requestReplaceItems(std::vector<std::shared_ptr<Item>> items);
void updateItems(std::vector<ItemData> items, bool inform = true);
};
#endif // ITEMSOURCE_H

View file

@ -1,42 +1,52 @@
#include "itemstore.h" #include "itemstore.h"
#include "relay.h"
#include "messageitem.h"
#include "systemitem.h"
#include <QJsonArray> #include <QJsonArray>
#include <typeinfo>
ItemStore::ItemStore(QObject *parent): QObject(parent) ItemStore::ItemStore(QObject *parent): QObject(parent)
{ {
} }
void ItemStore::addItem(std::shared_ptr<Item> item, bool inform) void ItemStore::addItem(std::shared_ptr<Item> item)
{ {
std::shared_ptr<Item> matched = nullptr; bool mached = false;
for(unsigned i = 0; i < items_.size(); i++ ) for(unsigned i = 0; i < items_.size(); i++ ) if(*items_[i] == *item) mached = true;
{ if(!mached)
if(*items_[i] == *item)
{
matched = items_[i];
break;
}
}
if(!matched)
{ {
items_.push_back(std::shared_ptr<Item>(item)); items_.push_back(std::shared_ptr<Item>(item));
connect(item.get(), &Item::updated, this, &ItemStore::itemUpdateSlot);
qDebug()<<"Item"<<item->getName()<<"added"<<(item->getLoaded() ? "from loaded" : "");
itemAdded(std::weak_ptr<Item>(items_.back())); itemAdded(std::weak_ptr<Item>(items_.back()));
} }
else
{
if(item->getLoaded())
matched->mergeLoaded(*item);
else if(item->getValue() != matched->getValue())
updateItem(*item, inform);
}
} }
void ItemStore::addItems(const std::vector<std::shared_ptr<Item>>& itemIn, bool inform) void ItemStore::addItems(const std::vector<std::shared_ptr<Item>>& itemIn)
{ {
for(unsigned j = 0; j < itemIn.size(); j++) for(unsigned i = 0; i < items_.size(); i++ )
addItem(itemIn[j], inform); {
if(Relay* relay = dynamic_cast<Relay*>(items_[i].get()))
{
bool mached = false;
for(unsigned j = 0; j < itemIn.size(); j++) if(*(items_[i]) == *(itemIn[j]))
{
mached = true;
if(itemIn[j]->getValue() != items_[i]->getValue()) items_[i]->informValue(itemIn[j]->getValue());
Relay* relayIn = dynamic_cast<Relay*>(itemIn[j].get());
if(relayIn)
{
if(relay->getId() != relayIn->getId()) relay->setId(relayIn->getId());
}
}
if(!mached)
{
itemDeleted(*items_[i].get());
items_.erase(items_.begin()+i);
}
}
}
for(unsigned j = 0; j < itemIn.size(); j++)addItem(itemIn[j]);
} }
void ItemStore::removeItem(const ItemData& item) void ItemStore::removeItem(const ItemData& item)
@ -45,26 +55,12 @@ void ItemStore::removeItem(const ItemData& item)
{ {
if(item == *items_[j]) if(item == *items_[j])
{ {
qDebug()<<"Item"<<item.getName()<<"deleted";
itemDeleted(*items_[j]);
items_.erase(items_.begin()+j); items_.erase(items_.begin()+j);
--j; --j;
} }
} }
} }
void ItemStore::replaceItems(const std::vector<std::shared_ptr<Item>>& items)
{
addItems(items, true);
std::vector<ItemData> deletedItems;
for(std::shared_ptr<Item> item : items_)
{
if(std::find_if(items.begin(), items.end(), [item](const std::shared_ptr<Item> other){return *item == *other;}) == items.end())
deletedItems.push_back(*item);
}
for(const ItemData& item : deletedItems)
removeItem(item);
}
void ItemStore::clear() void ItemStore::clear()
{ {
@ -73,33 +69,19 @@ void ItemStore::clear()
} }
void ItemStore::updateItems(std::vector<ItemData> items, bool inform) void ItemStore::itemStateChanged(const ItemData& item)
{ {
for(const ItemData& item : items)
updateItem(item, inform);
}
void ItemStore::updateItem(const ItemData& item, bool inform)
{
for(unsigned i = 0; i < items_.size(); i++ ) for(unsigned i = 0; i < items_.size(); i++ )
{ {
if(items_[i]->operator==(item)) if(items_[i]->operator==(item))
{ {
if(items_[i]->hasChanged(item))
{ if(items_[i]->getValue() != item.getValue())items_[i]->informValue(item.getValue());
if(items_[i]->getValue() != item.getValue())
{
items_[i]->setLoaded(false);
if(inform)
items_[i]->informValue(item.getValue());
else
items_[i]->setValue(item.getValue());
}
qDebug()<<"Item"<<items_[i]->getName()<<"updated";
itemUpdated(items_[i]);
}
} }
} }
} }
void ItemStore::store(QJsonObject& json) void ItemStore::store(QJsonObject& json)
@ -114,41 +96,35 @@ void ItemStore::store(QJsonObject& json)
json["Items"] = itemsArray; json["Items"] = itemsArray;
} }
void ItemStore::itemUpdateSlot(ItemData data) void ItemStore::load(const QJsonObject& json)
{ {
for(std::shared_ptr<Item>& item: items_) const QJsonArray itemsArray(json["Items"].toArray(QJsonArray()));
for(int i = 0; i < itemsArray.size(); ++i)
{ {
if(*item == data) if(itemsArray[i].isObject())
itemUpdated(std::weak_ptr<Item>(item)); {
const QJsonObject itemObject = itemsArray[i].toObject();
std::shared_ptr<Item> newItem;
if(itemObject["Type"].toString("") == "Relay")
{
newItem = std::shared_ptr<Relay>(new Relay());
}
else if(itemObject["Type"].toString("") == "Message")
{
newItem = std::shared_ptr<MessageItem>(new MessageItem);
}
else if(itemObject["Type"].toString("") == "System")
{
newItem = std::shared_ptr<SystemItem>(new SystemItem());
}
else if(itemObject["Type"].toString("") == "Aux")
{
}
if(newItem)
{
newItem->load(itemObject);
addItem(newItem);
}
}
} }
} }
std::shared_ptr<Item> ItemStore::getItem(uint32_t id)
{
for(std::shared_ptr<Item>& item : items_)
{
if(item->id() == id)
return item;
}
return nullptr;
}
void ItemStore::registerItemSource(ItemSource* source)
{
qDebug()<<__func__<<typeid(*source).name();
connect(source, &ItemSource::gotItems, this, &ItemStore::addItems);
connect(source, &ItemSource::updateItems, this, &ItemStore::updateItems);
connect(source, &ItemSource::requestReplaceItems, this, &ItemStore::replaceItems);
connect(this, &ItemStore::sigRefresh, source, &ItemSource::refresh);
}
void ItemStore::refresh()
{
for(std::shared_ptr<Item>& item : items_)
itemDeleted(*item);
items_.clear();
sigRefresh();
}
ItemStore globalItems;

View file

@ -2,7 +2,7 @@
#include <vector> #include <vector>
#include <memory> #include <memory>
#include "item.h" #include "item.h"
#include "itemsource.h" #include "../sensors/sensor.h"
#include <QJsonObject> #include <QJsonObject>
@ -10,22 +10,17 @@ class ItemStore: public QObject
{ {
Q_OBJECT Q_OBJECT
private: private:
std::vector<std::shared_ptr<Item> > items_; std::vector< std::shared_ptr<Item> > items_;
public: public:
ItemStore(QObject *parent = nullptr); ItemStore(QObject *parent = nullptr);
virtual ~ItemStore() {} virtual ~ItemStore(){}
inline std::vector< std::shared_ptr<Item> >* getItems() inline std::vector< std::shared_ptr<Item> >* getItems(){ return &items_; }
{
return &items_;
}
std::shared_ptr<Item> getItem(uint32_t id);
void registerItemSource(ItemSource* source);
void store(QJsonObject &json); void store(QJsonObject &json);
void load(const QJsonObject &json);
void clear(); void clear();
@ -33,21 +28,11 @@ signals:
void itemDeleted(ItemData item); void itemDeleted(ItemData item);
void itemAdded(std::weak_ptr<Item> Item); void itemAdded(std::weak_ptr<Item> Item);
void itemUpdated(std::weak_ptr<Item> Item);
void sigRefresh();
public slots: public slots:
void removeItem(const ItemData& item); void removeItem(const ItemData& item);
void addItem(std::shared_ptr<Item> item, bool inform = true); void addItem(std::shared_ptr<Item> item);
void addItems(const std::vector<std::shared_ptr<Item>>& itemsIn, bool inform = true); void addItems(const std::vector<std::shared_ptr<Item>>& itemsIn);
void replaceItems(const std::vector<std::shared_ptr<Item>>& items); void itemStateChanged(const ItemData& item);
void updateItems(std::vector<ItemData> items, bool inform = true);
void updateItem(const ItemData& item, bool inform = true);
void refresh();
private slots:
void itemUpdateSlot(ItemData data);
}; };
extern ItemStore globalItems;

View file

@ -1,19 +1,20 @@
#include "messageitem.h" #include "messageitem.h"
#include <QTimer> #include <QTimer>
#include <QSoundEffect> #include <QSound>
BroadCast* MessageItem::broadCast = nullptr;
MessageItem::MessageItem(uint32_t itemIdIn, QString name, uint8_t value, QObject *parent): MessageItem::MessageItem(uint32_t itemIdIn, QString name, uint8_t value, QObject *parent):
Item(itemIdIn, name, value, parent) Item(itemIdIn, name, value, parent)
{ {
alertSound.setVolume(1.0);
type_ = ITEM_VALUE_NO_VALUE;
} }
MessageItem::MessageItem(const ItemData& itemData, QObject *parent): MessageItem::MessageItem(const ItemData& itemData, QObject *parent):
Item(itemData, parent) Item(itemData, parent)
{ {
alertSound.setVolume(1.0);
} }
MessageItem::~MessageItem() MessageItem::~MessageItem()
@ -21,12 +22,13 @@ MessageItem::~MessageItem()
closeMessageBox(); closeMessageBox();
} }
void MessageItem::enactValue(uint8_t value) void MessageItem::setValue(uint8_t value)
{ {
Item::setValue(value);
if(value && !messageBox_) if(value && !messageBox_)
{ {
if(!alertSoundFileName.isEmpty()) if(broadCast) broadCast->sendMessage(name_, message_);
alertSound.play(); if(!alertSoundFileName.isEmpty()) QSound::play(alertSoundFileName);
messageBox_ = new QMessageBox(QMessageBox::NoIcon, name_, message_); messageBox_ = new QMessageBox(QMessageBox::NoIcon, name_, message_);
messageBox_->setModal(false); messageBox_->setModal(false);
connect(messageBox_, &QMessageBox::finished, this, &MessageItem::closeMessageBox); connect(messageBox_, &QMessageBox::finished, this, &MessageItem::closeMessageBox);
@ -58,7 +60,6 @@ QString MessageItem::getAlert()
void MessageItem::setAlert(const QString &in) void MessageItem::setAlert(const QString &in)
{ {
alertSoundFileName = in; alertSoundFileName = in;
alertSound.setSource(QUrl::fromLocalFile(alertSoundFileName));
} }
void MessageItem::setMessage(const QString& in) void MessageItem::setMessage(const QString& in)
@ -76,8 +77,7 @@ void MessageItem::store(QJsonObject &json)
json["Type"] = "Message"; json["Type"] = "Message";
Item::store(json); Item::store(json);
json["Message"] = message_; json["Message"] = message_;
if(!alertSoundFileName.isEmpty()) if(!alertSoundFileName.isEmpty()) json["Alert"] = alertSoundFileName;
json["Alert"] = alertSoundFileName;
} }
void MessageItem::load(const QJsonObject &json, const bool preserve) void MessageItem::load(const QJsonObject &json, const bool preserve)
@ -85,6 +85,4 @@ void MessageItem::load(const QJsonObject &json, const bool preserve)
Item::load(json,preserve); Item::load(json,preserve);
message_ = json["Message"].toString("Invalid Message"); message_ = json["Message"].toString("Invalid Message");
alertSoundFileName = json["Alert"].toString(""); alertSoundFileName = json["Alert"].toString("");
if(!alertSoundFileName.isEmpty())
alertSound.setSource(QUrl::fromLocalFile(alertSoundFileName));
} }

View file

@ -2,30 +2,33 @@
#define MESSAGEITEM_H #define MESSAGEITEM_H
#include <QMessageBox> #include <QMessageBox>
#include <QSoundEffect>
#include "item.h" #include "item.h"
#include "../broadcast.h"
class MessageItem : public Item class MessageItem : public Item
{ {
Q_OBJECT Q_OBJECT
private: private:
QString message_; QString message_;
QMessageBox* messageBox_ = nullptr; QMessageBox* messageBox_ = nullptr;
QString alertSoundFileName = ""; QString alertSoundFileName = "";
QSoundEffect alertSound;
public:
static BroadCast* broadCast;
private slots: private slots:
void closeMessageBox();
protected: void closeMessageBox();
virtual void enactValue(uint8_t value) override;
public: public:
MessageItem(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Item", uint8_t value = 0, virtual void setValue(uint8_t value);
QObject *parent = nullptr);
public:
MessageItem(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Item", uint8_t value = 0, QObject *parent = nullptr);
MessageItem(const ItemData& itemData, QObject *parent = nullptr); MessageItem(const ItemData& itemData, QObject *parent = nullptr);
~MessageItem(); ~MessageItem();
@ -34,8 +37,8 @@ public:
void setAlert(const QString& in); void setAlert(const QString& in);
QString getAlert(); QString getAlert();
virtual void store(QJsonObject& json) override; virtual void store(QJsonObject& json);
virtual void load(const QJsonObject& json, const bool preserve = false) override; virtual void load(const QJsonObject& json, const bool preserve = false);
}; };
#endif // MESSAGEITEM_H #endif // MESSAGEITEM_H

View file

@ -3,20 +3,18 @@
#include <QApplication> #include <QApplication>
#include <QDebug> #include <QDebug>
PowerItem::PowerItem(uint32_t itemIdIn, QString name, uint8_t value, QObject* parent): PowerItem::PowerItem(uint32_t itemIdIn, QString name, uint8_t value, QObject* parent): Item(itemIdIn, name, value, parent)
Item(itemIdIn, name, value, parent)
{ {
stateChanged(Sensor(Sensor::TYPE_SHUTDOWN_IMMINENT, 0, 0, "Shutdown Imminent", true)); stateChanged(Sensor(Sensor::TYPE_SHUTDOWN_IMMINENT, 0, 0, "Shutdown Imminent", true));
PowerItem::setValue(true); setValue(true);
hidden_ = true;
type_ = ITEM_VALUE_NO_VALUE;
} }
void PowerItem::enactValue(uint8_t value) void PowerItem::setValue(uint8_t value)
{ {
qDebug()<<"shutdown";
Item::setValue(value);
if(!value) if(!value)
{ {
qDebug()<<"shutdown";
QTimer::singleShot(5000, this, &PowerItem::timeout); QTimer::singleShot(5000, this, &PowerItem::timeout);
stateChanged(Sensor(Sensor::TYPE_SHUTDOWN_IMMINENT, 0, 1, "Shutdown Imminent", true)); stateChanged(Sensor(Sensor::TYPE_SHUTDOWN_IMMINENT, 0, 1, "Shutdown Imminent", true));
} }
@ -25,7 +23,7 @@ void PowerItem::enactValue(uint8_t value)
void PowerItem::timeout() void PowerItem::timeout()
{ {
qDebug()<<"shutdown timeout"; qDebug()<<"shutdown timeout";
QProcess::startDetached("syncoff", QStringList()); QProcess::startDetached("syncoff");
} }
void PowerItem::store(QJsonObject& json) void PowerItem::store(QJsonObject& json)

View file

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "item.h" #include "item.h"
#include "sensors/sensor.h" #include "../sensors/sensor.h"
#include "microcontroller.h" #include "../microcontroller.h"
#include <QTimer> #include <QTimer>
@ -16,17 +16,15 @@ signals:
void stateChanged(Sensor sensor); void stateChanged(Sensor sensor);
private slots: private slots:
void timeout(); void timeout();
protected: public slots:
virtual void enactValue(uint8_t value) override;
virtual void setValue(uint8_t value);
public: public:
PowerItem(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Power", uint8_t value = 0, PowerItem(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "", uint8_t value = 0, QObject* parent = nullptr);
QObject* parent = nullptr); void emmitSensor(){stateChanged(Sensor(Sensor::TYPE_SHUTDOWN_IMMINENT, 0, 0, "Shutdown Imminent", true));}
void emmitSensor() virtual void store(QJsonObject& json);
{
stateChanged(Sensor(Sensor::TYPE_SHUTDOWN_IMMINENT, 0, 0, "Shutdown Imminent", true));
}
virtual void store(QJsonObject& json) override;
}; };

View file

@ -5,21 +5,19 @@
Microcontroller* Relay::micro_ = nullptr; Microcontroller* Relay::micro_ = nullptr;
Relay::Relay(uint8_t id, QString name, uint16_t address, bool state, QObject* parent): Item(0, name, state, parent), Relay::Relay(uint8_t id, QString name, uint16_t address, bool state, QObject* parent): Item(0, name, state, parent), id_(id), address_(address)
id_(id), address_(address)
{ {
itemId_ = address | ((uint32_t)id << 16); itemId_ = address | ((uint32_t)id << 16);
qDebug()<<"Relay "<<id_<<"Name "<<name<<" id "<<itemId_<<" state "<<state<<" addr: "<<address;
} }
void Relay::enactValue(uint8_t value) void Relay::setValue(uint8_t value)
{ {
qDebug()<<"Relay"<<__func__<<micro_; Item::setValue(value);
if(micro_) if(micro_)
{ {
if(value) if(value)micro_->relayOn(id_);
micro_->relayOn(id_); else micro_->relayOff(id_);
else
micro_->relayOff(id_);
} }
} }

View file

@ -4,7 +4,7 @@
#include<stdint.h> #include<stdint.h>
#include<QObject> #include<QObject>
#include "sensors/sensor.h" #include "../sensors/sensor.h"
#include "item.h" #include "item.h"
class Microcontroller; class Microcontroller;
@ -18,10 +18,9 @@ private:
uint8_t id_; uint8_t id_;
uint16_t address_; uint16_t address_;
protected:
virtual void enactValue(uint8_t value) override;
public slots: public slots:
virtual void setValue(uint8_t value);
void on(); void on();
void off(); void off();
void toggle(); void toggle();
@ -33,12 +32,9 @@ public:
uint8_t getId() const; uint8_t getId() const;
void setId(uint8_t id); void setId(uint8_t id);
inline static void setMicrocontroller(Microcontroller* micro) inline static void setMicrocontroller(Microcontroller* micro){ micro_ = micro; }
{
micro_ = micro;
}
virtual void store(QJsonObject& json) override; virtual void store(QJsonObject& json);
virtual void load(const QJsonObject& json, const bool preserve = false) override; virtual void load(const QJsonObject& json, const bool preserve = false);
}; };
#endif // RELAY_H #endif // RELAY_H

View file

@ -1,14 +1,13 @@
#include "rgbitem.h" #include "rgbitem.h"
RgbItem::RgbItem(Microcontroller* micro, uint32_t itemIdIn, QString name, uint8_t value, RgbItem::RgbItem(Microcontroller* micro, uint32_t itemIdIn, QString name, uint8_t value, QObject* parent): Item(itemIdIn, name, value, parent), micro_(micro)
QObject* parent): Item(itemIdIn, name, value, parent), micro_(micro)
{ {
} }
void RgbItem::enactValue(uint8_t value) void RgbItem::setValue(uint8_t value)
{ {
assert(micro_); Item::setValue(value);
value ? micro_->rgbOn() : micro_->rgbOff(); value ? micro_->rgbOn() : micro_->rgbOff();
} }

View file

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "microcontroller.h" #include "../microcontroller.h"
#include "item.h" #include "item.h"
class RgbItem: public Item class RgbItem: public Item
@ -9,12 +9,12 @@ class RgbItem: public Item
private: private:
Microcontroller* micro_; Microcontroller* micro_;
protected: public slots:
virtual void enactValue(uint8_t value) override;
virtual void setValue(uint8_t value);
public: public:
RgbItem(Microcontroller* micro = nullptr, uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "", RgbItem(Microcontroller* micro, uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "", uint8_t value = 0, QObject* parent = nullptr);
uint8_t value = 0, QObject* parent = nullptr);
virtual void store(QJsonObject& json) override; virtual void store(QJsonObject& json);
}; };

View file

@ -1,19 +1,19 @@
#include "systemitem.h" #include "systemitem.h"
#include <QProcess> #include <QProcess>
void SystemItem::enactValue(uint8_t value) void SystemItem::setValue(uint8_t value)
{ {
QProcess::execute(value ? onCommand_ : offCommand_); QProcess::execute(value ? onCommand_ : offCommand_);
} }
SystemItem::SystemItem(uint32_t itemIdIn, QString name, uint8_t value, QObject *parent): SystemItem::SystemItem(uint32_t itemIdIn, QString name, uint8_t value, QObject *parent):
Item(itemIdIn, name, value, parent) Item(itemIdIn, name, value, parent)
{ {
} }
SystemItem::SystemItem(const ItemData& itemData, QObject *parent): SystemItem::SystemItem(const ItemData& itemData, QObject *parent):
Item(itemData, parent) Item(itemData, parent)
{ {
} }

View file

@ -1,37 +1,34 @@
#ifndef SYSTEMITEM_H #ifndef SYSTEMITEM_H
#define SYSTEMITEM_H #define SYSTEMITEM_H
#include "item.h" #include "item.h"
class SystemItem : public Item class SystemItem : public Item
{ {
Q_OBJECT Q_OBJECT
private: private:
QString onCommand_; QString onCommand_;
QString offCommand_; QString offCommand_;
protected: public:
virtual void enactValue(uint8_t value) override;
virtual void setValue(uint8_t value);
public: public:
SystemItem(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Item", uint8_t value = 0,
QObject *parent = nullptr); SystemItem(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Item", uint8_t value = 0, QObject *parent = nullptr);
SystemItem(const ItemData& itemData, QObject *parent = nullptr); SystemItem(const ItemData& itemData, QObject *parent = nullptr);
~SystemItem() = default; ~SystemItem() = default;
void setOnCommand(const QString& in); void setOnCommand(const QString& in);
void setOffCommand(const QString& in); void setOffCommand(const QString& in);
QString getOnCommand() QString getOnCommand(){return onCommand_;}
{ QString getOffCommand(){return offCommand_;}
return onCommand_;
}
QString getOffCommand()
{
return offCommand_;
}
virtual void store(QJsonObject& json) override; virtual void store(QJsonObject& json);
virtual void load(const QJsonObject& json, const bool preserve = false) override; virtual void load(const QJsonObject& json, const bool preserve = false);
}; };
#endif // SYSTEMITEM_H #endif // SYSTEMITEM_H

View file

@ -1,23 +1,37 @@
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
#include <stdio.h>
#include <QDebug> #include <QDebug>
#include <QTcpSocket> #include <QTcpSocket>
#include <QMessageBox> #include <QMessageBox>
#include <QSettings>
#ifndef Q_OS_ANDROID
#include <QtSerialPort/QtSerialPort> #include <QtSerialPort/QtSerialPort>
#include <QtSerialPort/QSerialPortInfo> #include <QtSerialPort/QSerialPortInfo>
#include <QCommandLineParser> #include <QCommandLineParser>
#endif
#include "actors/alarmtime.h"
#include "microcontroller.h"
#include "ui/mainwindow.h" #include "ui/mainwindow.h"
#include "sensors/speakersensor.h"
#include "sensors/sunsensor.h"
#include "sensors/ocupancysensor.h"
#include "alarmactions.h"
#include "sensors/sensor.h"
#include "items/itemstore.h" #include "items/itemstore.h"
#include "items/auxitem.h"
#include "items/rgbitem.h"
#include "items/poweritem.h"
#include "mainobject.h" #include "mainobject.h"
#include "programmode.h"
#define BAUD QSerialPort::Baud38400
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication a(argc, argv); QApplication a(argc, argv);
//pw_init(&argc, &argv);
//set info //set info
QCoreApplication::setOrganizationName("UVOS"); QCoreApplication::setOrganizationName("UVOS");
QCoreApplication::setOrganizationDomain("uvos.xyz"); QCoreApplication::setOrganizationDomain("uvos.xyz");
@ -27,113 +41,93 @@ int main(int argc, char *argv[])
QDir::setCurrent(a.applicationDirPath()); QDir::setCurrent(a.applicationDirPath());
//parse comand line //parse comand line
#ifndef Q_OS_ANDROID
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription("Smart Home Interface"); parser.setApplicationDescription("Smart Home Interface");
parser.addHelpOption(); parser.addHelpOption();
parser.addVersionOption(); parser.addVersionOption();
QCommandLineOption masterOption(QStringList() << "m" << "master", QCoreApplication::translate("main", "Use in master mode")); QCommandLineOption tcpOption(QStringList() << "t" << "tcp", QCoreApplication::translate("main", "Use Tcp connection"));
parser.addOption(masterOption); parser.addOption(tcpOption);
QCommandLineOption hostOption(QStringList() << "H" << "host", QCoreApplication::translate("main", "Set server host ip addres"), "address", "0.0.0.0"); QCommandLineOption hostOption(QStringList() << "H" << "host", QCoreApplication::translate("main", "Set server host ip addres"), "adress");
parser.addOption(hostOption); parser.addOption(hostOption);
QCommandLineOption portOption(QStringList() << "p" << "port", QCoreApplication::translate("main", "Set server Port"), "port", "104476"); QCommandLineOption portOption(QStringList() << "p" << "port", QCoreApplication::translate("main", "Set server Port in TCP mode or Serial port in serial mode"), "port");
parser.addOption(portOption); parser.addOption(portOption);
QCommandLineOption settingsPathOption(QStringList()<<"c"<<"config", QCoreApplication::translate("main", "Set config file"), "configFilePath", QCommandLineOption serialOption(QStringList() << "s" << "serial", QCoreApplication::translate("main", "Use serial connection"));
QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/shinterface.json"); parser.addOption(serialOption);
QCommandLineOption baudOption(QStringList() << "b" << "baud", QCoreApplication::translate("main", "Set Baud Rate"));
parser.addOption(baudOption);
QCommandLineOption settingsPathOption(QStringList() << "c" << "config", QCoreApplication::translate("main", "Set config file"), "configFilePath");
parser.addOption(settingsPathOption); parser.addOption(settingsPathOption);
QCommandLineOption headlessOption(QStringList()<<"e"<<"headless", QCoreApplication::translate("main", "Dont start the gui")); QCommandLineOption secondaryOption(QStringList() << "e" << "secondary", QCoreApplication::translate("main", "Set if instance is not main instance"));
parser.addOption(headlessOption); parser.addOption(secondaryOption);
parser.process(a); parser.process(a);
#endif
int retVal; QIODevice* masterIODevice = nullptr;
programMode = PROGRAM_MODE_UI_ONLY; #ifndef Q_OS_ANDROID
if(parser.isSet(masterOption)) if(parser.isSet(tcpOption))
{ {
programMode = PROGRAM_MODE_PRIMARY;
if(parser.isSet(headlessOption))
programMode = PROGRAM_MODE_HEADLESS_PRIMARY;
}
if(programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY)
{
QString settingsPath = parser.value(settingsPathOption);
QJsonObject json = MainObject::getJsonObjectFromDisk(settingsPath);
bool tcpMicro = json["MicroTcp"].toBool(true);
json["MicroTcp"] = tcpMicro;
QIODevice* microDevice = nullptr;
if(tcpMicro)
{
int port = json["MicroTcpPort"].toInt(6856);
json["MicroTcpPort"] = port;
QString host = json["MicroTcpHost"].toString("127.0.0.1");
json["MicroTcpHost"] = host;
QTcpSocket* microSocket = new QTcpSocket; QTcpSocket* microSocket = new QTcpSocket;
qInfo()<<"connecting to "<<host<<':'<<port<<" for tcp micro"; int port = 6856;
microSocket->connectToHost(host, port, QIODevice::ReadWrite); if(parser.isSet(portOption)) port = parser.value(portOption).toInt();
QString host("127.0.0.1");
if(parser.isSet(hostOption)) host = parser.value(hostOption);
std::cout<<"connecting to "<<host.toStdString()<<':'<<port<<'\n';
microSocket->connectToHost(host, port, QIODevice::ReadWrite);
if(!microSocket->waitForConnected(1000)) if(!microSocket->waitForConnected(1000))
{ {
qCritical()<<"Can not connect to tcp micro"; std::cout<<"Can not connect to to Server.\n";
MainObject::storeJsonObjectToDisk(settingsPath, json); QMessageBox::critical(nullptr, "Error", "Can not connect to to Server");
if(programMode == PROGRAM_MODE_PRIMARY)
QMessageBox::critical(nullptr, "Error", "Can not connect to tcp micro");
return 1; return 1;
} }
microDevice = microSocket; masterIODevice = microSocket;
} }
else else
{ {
QString port = json["MicroSerialPort"].toString("ttyUSB0"); QSerialPort* microPort = new QSerialPort;
json["MicroSerialPort"] = port; if(parser.isSet(portOption)) microPort->setPortName(parser.value(portOption));
int baud = json["MicroSerialBaud"].toInt(38400); else microPort->setPortName("ttyUSB0");
json["MicroSerialBaud"] = baud;
QSerialPort *microPort = new QSerialPort; if(parser.isSet(portOption)) microPort->setBaudRate(parser.value(baudOption).toInt());
microPort->setPortName(port); else microPort->setBaudRate(BAUD);
microPort->setBaudRate(baud);
microPort->open(QIODevice::ReadWrite);
if(!microPort->isOpen()) if(!microPort->open(QIODevice::ReadWrite)) std::cout<<"Can not open serial port "<<microPort->portName().toStdString()<<". Continueing in demo mode"<<'\n';
masterIODevice = microPort;
}
MainObject mainObject(masterIODevice, parser.isSet(settingsPathOption) ? parser.value(settingsPathOption) : "", !parser.isSet(secondaryOption));
#else
QTcpSocket* microSocket = new QTcpSocket;
microSocket->connectToHost("10.0.0.1", 6856, QIODevice::ReadWrite);
if(!microSocket->waitForConnected(1000))
{ {
qCritical()<<"Can not open serial port"<<port; std::cout<<"Can not connect to to Server.\n";
MainObject::storeJsonObjectToDisk(settingsPath, json);
if(programMode == PROGRAM_MODE_PRIMARY)
QMessageBox::critical(nullptr, "Error", "Can not open serial port " + port);
return 1; return 1;
} }
microDevice = microPort; masterIODevice = microSocket;
}
PrimaryMainObject mainObject(microDevice, settingsPath, parser.value(hostOption), parser.value(portOption).toInt());
QObject::connect(mainObject.tcpServer, &TcpServer::sigRequestSave, &mainObject, [&mainObject, settingsPath](){mainObject.storeToDisk(settingsPath);});
MainWindow* w = nullptr;
if(programMode != PROGRAM_MODE_HEADLESS_PRIMARY)
{
w = new MainWindow(&mainObject);
QObject::connect(&mainObject.micro, SIGNAL(textRecived(QString)), w, SLOT(changeHeaderLableText(QString)));
QObject::connect(&mainObject.micro, SIGNAL(textRecived(QString)), w, SLOT(changeHeaderLableText(QString)));
QObject::connect(w, &MainWindow::sigSetRgb, &mainObject.micro, &Microcontroller::changeRgbColor);
QObject::connect(w, &MainWindow::sigSave, &mainObject, [&mainObject, settingsPath](){mainObject.storeToDisk(settingsPath);});
QObject::connect(w, &MainWindow::createdItem, &globalItems, [](std::shared_ptr<Item> item){globalItems.addItem(item, false);});
w->show();
}
retVal = a.exec();
delete w; MainObject mainObject(masterIODevice, parser.isSet(settingsPathOption) ? parser.value(settingsPathOption) : "", !parser.isSet(secondaryOption));
delete microDevice; #endif
}
else
{ //mainwindow
SecondaryMainObject mainObject(parser.value(hostOption), parser.value(portOption).toInt());
MainWindow w(&mainObject); MainWindow w(&mainObject);
QObject::connect(&w, &MainWindow::createdItem, &globalItems, [](std::shared_ptr<Item> item){globalItems.addItem(item, false);}); QObject::connect(&mainObject.micro, SIGNAL(textRecived(QString)), &w, SLOT(changeHeaderLableText(QString)));
QObject::connect(&w, &MainWindow::sigSave, mainObject.tcpClient, &TcpClient::sendItems); QObject::connect(&w, &MainWindow::sigBrodcast, &mainObject, &MainObject::sendJson);
QObject::connect(&w, &MainWindow::sigSave, &mainObject, &MainObject::storeToDisk);
QObject::connect(&w, &MainWindow::createdItem, &mainObject.items, &ItemStore::addItem);
if(!mainObject.micro.connected()) w.changeHeaderLableText("No io debug only!");
w.show(); w.show();
retVal = a.exec(); int retVal = a.exec();
}
if(masterIODevice)
delete masterIODevice;
return retVal; return retVal;
} }

View file

@ -1,35 +1,135 @@
#include "mainobject.h" #include "mainobject.h"
#include "items/messageitem.h"
#include<QJsonObject> MainObject::MainObject(QIODevice* ioDevice, const QString& settingsPathIn, const bool masterIn, QObject *parent) :
#include<QJsonArray> QObject(parent),
#include<QMessageBox> master(masterIn),
masterIODevice(ioDevice),
ioMultiplexer(masterIODevice),
micro(ioMultiplexer.getIoDevice()),
broadCast(ioMultiplexer.getIoDevice(), masterIn),
settingsPath(settingsPathIn),
sunSensorSource(49.884450, 8.650536),
powerItem(new PowerItem),
rgbItem(new RgbItem(&micro, 5487422, "Rgb Lights")),
auxItem(new AuxItem(&micro, 5487421, "Desk Light"))
#include "items/itemstore.h"
MainObject::MainObject(QObject *parent) :
QObject(parent)
{ {
qDebug()<<"Is master:"<<master;
//connect sensors subsystem
QObject::connect(&micro, &Microcontroller::gotSensorState, &globalSensors, &SensorStore::sensorGotState);
QObject::connect(&sunSensorSource, &SunSensorSource::stateChanged, &globalSensors, &SensorStore::sensorGotState);
QObject::connect(&globalSensors, &SensorStore::sensorChangedState, &ocupancySensor, &OcupancySensorSource::sensorEvent);
QObject::connect(&ocupancySensor, &OcupancySensorSource::stateChanged, &globalSensors, &SensorStore::sensorGotState);
sunSensorSource.run();
//connect item store
QObject::connect(&micro, &Microcontroller::gotRelayList, &items, &ItemStore::addItems);
QObject::connect(&micro, &Microcontroller::itemChanged, &items, &ItemStore::itemStateChanged);
//special items
QObject::connect(powerItem.get(), &PowerItem::stateChanged, &globalSensors, &SensorStore::sensorGotState);
powerItem->emmitSensor();
items.addItem(rgbItem);
items.addItem(auxItem);
MessageItem::broadCast = &broadCast;
Relay::setMicrocontroller(&micro);
connect(&broadCast, &BroadCast::gotJson, this, &MainObject::recivedJson);
QObject::connect(&broadCast, &BroadCast::gotSensorState, &globalSensors, &SensorStore::sensorGotState);
if(master)connect(&broadCast, &BroadCast::jsonRequested, this, &MainObject::sendJson);
if(master) load(getJsonObjectFromDisk(settingsPath, &noSave));
else
{
broadCast.requestJson();
broadCast.requestSensors();
}
#ifndef Q_OS_ANDROID
Item::secondaryFlag = !master;
#endif
} }
MainObject::~MainObject() MainObject::~MainObject()
{ {
} }
void MainObject::refresh() void MainObject::store(QJsonObject &json)
{ {
globalItems.refresh(); items.store(json);
QJsonObject powerObject;
powerItem->store(powerObject);
json.insert("Power", powerObject);
QJsonDocument pwrDoc(powerObject);
QJsonObject ocupancyObject;
ocupancySensor.store(ocupancyObject);
json.insert("Ocupancy", ocupancyObject);
} }
QJsonObject MainObject::getJsonObjectFromDisk(const QString& filename, bool* error) void MainObject::load(const QJsonObject& json)
{
items.clear();
rgbItem->removeAllActors();
auxItem->removeAllActors();
powerItem->removeAllActors();
items.addItem(rgbItem);
items.addItem(auxItem);
items.load(json);
powerItem->load(json["Power"].toObject());
ocupancySensor.load(json["Ocupancy"].toObject());
qDebug()<<"aray size: "<<json.isEmpty();
if(json["Items"].toArray().size() >= 2)
{
rgbItem->load(json["Items"].toArray()[0].toObject());
auxItem->load(json["Items"].toArray()[1].toObject());
}
micro.requestState();
}
void MainObject::storeToDisk()
{
if(master && !noSave)
{
QJsonObject json;
store(json);
storeJsonObjectToDisk(json, settingsPath);
}
}
void MainObject::recivedJson(const QJsonObject json)
{
if(master && !noSave)
storeJsonObjectToDisk(json, settingsPath);
load(json);
}
void MainObject::sendJson()
{
QJsonObject json;
store(json);
broadCast.sendJson(json);
}
QJsonObject MainObject::getJsonObjectFromDisk(const QString& filePath, bool* error)
{ {
QFile file; QFile file;
file.setFileName(filename);
bool ret = file.open(QIODevice::ReadOnly); #ifndef Q_OS_ANDROID
if(!file.isOpen() || !ret) if(filePath.size() > 0) file.setFileName(filePath);
else
#endif
{ {
std::cerr<<"Can not open config file: "<<filename.toLatin1().data()<<std::endl; file.setFileName(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/shinterface.json");
} }
file.open(QIODevice::ReadOnly);
if(!file.isOpen()) std::cerr<<"Can not open config file: "<<filePath.toLatin1().data()<<std::endl;
else else
{ {
QJsonParseError qerror; QJsonParseError qerror;
@ -37,24 +137,29 @@ QJsonObject MainObject::getJsonObjectFromDisk(const QString& filename, bool* err
file.close(); file.close();
if(qerror.error != QJsonParseError::NoError) if(qerror.error != QJsonParseError::NoError)
{ {
qDebug()<<filename<<" "<<qerror.errorString(); qDebug()<<filePath<<" "<<qerror.errorString();
if(error) if(error) (*error) = true;
(*error) = true;
} }
return document.object(); return document.object();
} }
return QJsonObject(); return QJsonObject();
} }
bool MainObject::storeJsonObjectToDisk(const QString& filename, const QJsonObject& json) bool MainObject::storeJsonObjectToDisk(const QJsonObject& json, QString filePath)
{ {
QFile file(filename + ".out"); #ifndef Q_OS_ANDROID
if(filePath.size() == 0)
qDebug()<<"config file: "<<filename; #endif
bool ret = file.open(QIODevice::WriteOnly);
if(!file.isOpen() || !ret)
{ {
std::cerr<<"Can not open config file: "<<filename.toLatin1().data()<<std::endl; filePath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/shinterface.json";
}
QFile file(filePath + ".out");
qDebug()<<"config file: "<<filePath;
file.open(QIODevice::WriteOnly);
if(!file.isOpen())
{
std::cerr<<"Can not open config file: "<<filePath.toLatin1().data()<<std::endl;
return false; return false;
} }
else else
@ -62,101 +167,9 @@ bool MainObject::storeJsonObjectToDisk(const QString& filename, const QJsonObjec
QJsonDocument document(json); QJsonDocument document(json);
file.write(document.toJson()); file.write(document.toJson());
file.close(); file.close();
QFile::remove(filename); QFile::remove(filePath);
file.rename(filename); file.rename(filePath);
return true; return true;
} }
} }
PrimaryMainObject::PrimaryMainObject(QIODevice* microDevice, const QString& settingsPath, const QString& host, int port, QObject *parent) :
MainObject(parent),
settingsPath(settingsPath),
micro(microDevice),
tcpServer(new TcpServer),
sunSensorSource(49.824972, 8.702194),
fixedItems(&micro)
{
//connect sensors subsystem
connect(&globalSensors, &SensorStore::sensorChangedState, tcpServer, &TcpServer::sensorEvent);
connect(tcpServer, &TcpServer::gotSensor, &globalSensors, &SensorStore::sensorGotState);
connect(&sunSensorSource, &SunSensorSource::stateChanged, &globalSensors, &SensorStore::sensorGotState);
connect(&micro, &Microcontroller::gotSensorState, &globalSensors, &SensorStore::sensorGotState);
connect(&mqttSensorSource, &MqttSensorSource::stateChanged, &globalSensors, &SensorStore::sensorGotState);
sunSensorSource.run();
globalItems.registerItemSource(&fixedItems);
globalItems.registerItemSource(tcpServer);
globalItems.registerItemSource(&micro);
globalItems.registerItemSource(&itemLoader);
Relay::setMicrocontroller(&micro);
loadFromDisk(settingsPath);
QJsonObject mqttJson = settings["Mqtt"].toObject();
mqttSensorSource.start(mqttJson);
tcpServer->launch(QHostAddress(host), port);
connect(&globalItems, &ItemStore::itemUpdated, tcpServer, &TcpServer::itemUpdated);
}
PrimaryMainObject::~PrimaryMainObject()
{
storeToDisk(settingsPath);
}
void PrimaryMainObject::store(QJsonObject &json)
{
globalItems.store(json);
QJsonObject mqttJson = json["Mqtt"].toObject();
mqttSensorSource.store(mqttJson);
json["Mqtt"] = mqttJson;
}
void PrimaryMainObject::load(const QJsonObject& json)
{
settings = json;
itemLoader.updateJson(json);
globalItems.clear();
globalItems.refresh();
}
bool PrimaryMainObject::storeToDisk(const QString& filename)
{
store(settings);
itemLoader.updateJson(settings);
return storeJsonObjectToDisk(filename, settings);
}
bool PrimaryMainObject::loadFromDisk(const QString& filename)
{
bool error = false;
QJsonObject json = getJsonObjectFromDisk(filename, &error);
if(!error)
load(json);
return error;
}
SecondaryMainObject::SecondaryMainObject(QString host, int port, QObject *parent) :
MainObject(parent),
tcpClient(new TcpClient)
{
connect(tcpClient, &TcpClient::gotSensor, &globalSensors, &SensorStore::sensorGotState);
globalItems.registerItemSource(tcpClient);
if(!tcpClient->launch(QHostAddress(host), port))
{
QMessageBox::critical(nullptr, "Error", "Could not connect to "+host+":"+QString::number(port));
QMetaObject::invokeMethod(this, [](){exit(1);}, Qt::QueuedConnection);
}
connect(&globalItems, &ItemStore::itemUpdated, tcpClient, &TcpClient::itemUpdated);
globalItems.refresh();
}
SecondaryMainObject::~SecondaryMainObject()
{
}

View file

@ -2,6 +2,7 @@
#define MAINOBJECT_H #define MAINOBJECT_H
#include <QObject> #include <QObject>
#include <stdio.h>
#include <QDir> #include <QDir>
#include <QDebug> #include <QDebug>
#include <QString> #include <QString>
@ -11,66 +12,76 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <memory> #include <memory>
#ifndef Q_OS_ANDROID
#include <QtSerialPort/QtSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QCommandLineParser>
#endif
#include "actors/alarmtime.h"
#include "microcontroller.h" #include "microcontroller.h"
#include "ui/mainwindow.h" #include "ui/mainwindow.h"
#include "sensors/speakersensor.h"
#include "sensors/sunsensor.h" #include "sensors/sunsensor.h"
#include "sensors/mqttsensorsource.h" #include "sensors/ocupancysensor.h"
#include "items/fixeditemsource.h" #include "sensors/sensor.h"
#include "items/itemloadersource.h" #include "items/itemstore.h"
#include "service/tcpclient.h" #include "items/auxitem.h"
#include "service/tcpserver.h" #include "items/rgbitem.h"
#include "items/poweritem.h"
#include "iomuliplexer.h"
#include "broadcast.h"
class MainObject : public QObject class MainObject : public QObject
{
Q_OBJECT
public:
explicit MainObject(QObject *parent = nullptr);
~MainObject();
static QJsonObject getJsonObjectFromDisk(const QString& filename, bool* error = nullptr);
static bool storeJsonObjectToDisk(const QString& filename, const QJsonObject& json);
public slots:
void refresh();
};
class PrimaryMainObject : public MainObject
{ {
Q_OBJECT Q_OBJECT
public: public:
QString settingsPath; //io
QJsonObject settings; const bool master;
bool noSave = false;
QIODevice * const masterIODevice = nullptr;
IoMuliplexer ioMultiplexer;
Microcontroller micro; Microcontroller micro;
TcpServer* tcpServer; BroadCast broadCast;
const QString settingsPath;
//sensors //sensors
SunSensorSource sunSensorSource; SunSensorSource sunSensorSource;
MqttSensorSource mqttSensorSource; OcupancySensorSource ocupancySensor;
//item sources //items
FixedItemSource fixedItems; ItemStore items;
ItemLoaderSource itemLoader;
std::shared_ptr<PowerItem> powerItem;
std::shared_ptr<RgbItem> rgbItem;
std::shared_ptr<AuxItem> auxItem;
private:
static QJsonObject getJsonObjectFromDisk(const QString& filePath = "", bool* error = nullptr);
static bool storeJsonObjectToDisk(const QJsonObject& json, QString filePath = "");
public: public:
explicit PrimaryMainObject(QIODevice* microDevice, const QString& settingsPath, const QString& host, int port, QObject *parent = nullptr); explicit MainObject(QIODevice* ioDevice, const QString& settingsPathIn, const bool masterIn, QObject *parent = nullptr);
~PrimaryMainObject(); ~MainObject();
void store(QJsonObject& json); void store(QJsonObject& json);
void load(const QJsonObject& json); void load(const QJsonObject& json);
bool storeToDisk(const QString& filename);
bool loadFromDisk(const QString& filename);
};
class SecondaryMainObject : public MainObject signals:
{
Q_OBJECT
public:
TcpClient* tcpClient;
public: public slots:
explicit SecondaryMainObject(QString host, int port, QObject *parent = nullptr);
~SecondaryMainObject(); void storeToDisk();
void sendJson();
void recivedJson(const QJsonObject json);
}; };

View file

@ -3,6 +3,8 @@
#include <chrono> #include <chrono>
#include <thread> #include <thread>
static constexpr bool debug = true;
void Microcontroller::relayToggle(int state, int relay) void Microcontroller::relayToggle(int state, int relay)
{ {
char buffer[8]; char buffer[8];
@ -38,10 +40,11 @@ void Microcontroller::changeRgbColor(const QColor color)
char buffer[64]; char buffer[64];
int length = sprintf(buffer, "rgb set %03d %03d %03d\n", color.red(), color.green(), color.blue()); int length = sprintf(buffer, "rgb set %03d %03d %03d\n", color.red(), color.green(), color.blue());
write(buffer, length); write(buffer, length);
} std::cout<<buffer;
}
void Microcontroller::setAuxPwm(int duty) void Microcontroller::setAuxPwm(int duty)
{ {
char buffer[64]; char buffer[64];
int length = sprintf(buffer, "aux set %03d\n", duty ); int length = sprintf(buffer, "aux set %03d\n", duty );
write(buffer, length); write(buffer, length);
@ -49,6 +52,9 @@ void Microcontroller::setAuxPwm(int duty)
void Microcontroller::write(const QByteArray& buffer) void Microcontroller::write(const QByteArray& buffer)
{ {
#ifndef Q_OS_ANDROID
if constexpr(debug) std::cerr<<buffer.data();
#endif
if(_port != nullptr) if(_port != nullptr)
{ {
_port->write(buffer); _port->write(buffer);
@ -59,6 +65,9 @@ void Microcontroller::write(const QByteArray& buffer)
void Microcontroller::write(char* buffer, const size_t length) void Microcontroller::write(char* buffer, const size_t length)
{ {
#ifndef Q_OS_ANDROID
if constexpr(debug) std::cerr<<buffer;
#endif
if(_port != nullptr) if(_port != nullptr)
{ {
_port->write(buffer, length); _port->write(buffer, length);
@ -86,7 +95,7 @@ bool Microcontroller::connected()
else return false; else return false;
} }
void Microcontroller::refresh() void Microcontroller::requestState()
{ {
write("state\n"); write("state\n");
} }
@ -118,16 +127,10 @@ std::shared_ptr<Relay> Microcontroller::processRelayLine(const QString& buffer)
if(bufferList.size() >= 9 && buffer.startsWith("ITEM NUMBER:")) if(bufferList.size() >= 9 && buffer.startsWith("ITEM NUMBER:"))
{ {
QString name; QString name;
for(int i = 10; i < bufferList.size(); i++) for(int i = 10; i < bufferList.size(); i++) name.append(bufferList[i] + ' ');
name.append(bufferList[i] + ' '); if(name.size() > 1)name.remove(name.size()-1, 1);
if(name.size() > 1) else name = "Relay " + QString::number(bufferList[1].toInt(nullptr, 2));
name.remove(name.size()-1, 1); return std::shared_ptr<Relay>( new Relay(bufferList[2].toInt(), name, bufferList[4].toInt(nullptr, 2), bufferList[8].toInt()));
else
name = "Relay " + QString::number(bufferList[1].toInt(nullptr, 2));
return std::shared_ptr<Relay>(new Relay(bufferList[2].toInt(),
name,
bufferList[6].toInt(nullptr, 2),
bufferList[8].toInt()));
} }
return nullptr; return nullptr;
} }
@ -142,7 +145,8 @@ void Microcontroller::processList(const QString& buffer)
else if(buffer.contains("EOL")) else if(buffer.contains("EOL"))
{ {
listMode = false; listMode = false;
gotItems(relayList); qDebug()<<"got relay list " << relayList.size();
gotRelayList(relayList);
relayList.clear(); relayList.clear();
} }
else listMode = false; else listMode = false;
@ -150,23 +154,19 @@ void Microcontroller::processList(const QString& buffer)
void Microcontroller::processRelayState(const QString& buffer) void Microcontroller::processRelayState(const QString& buffer)
{ {
updateItems({static_cast<ItemData>(*processRelayLine(buffer))}); itemChanged(static_cast<ItemData>(*processRelayLine(buffer)));
} }
void Microcontroller::processSensorState(const QString& buffer) void Microcontroller::processSensorState(const QString& buffer)
{ {
Sensor sensor = Sensor::sensorFromString(buffer); Sensor sensor = Sensor::sensorFromString(buffer);
if(sensor.type != Sensor::TYPE_DUMMY) if(sensor.type != Sensor::TYPE_DUMMY) gotSensorState(sensor);
gotSensorState(sensor);
} }
void Microcontroller::processMicroReturn() void Microcontroller::processMicroReturn()
{ {
if(listMode) if(listMode) processList(_buffer);
{
processList(_buffer);
}
else else
{ {
if(_buffer.startsWith("Items:")) if(_buffer.startsWith("Items:"))
@ -174,14 +174,8 @@ void Microcontroller::processMicroReturn()
listMode = true; listMode = true;
relayList.clear(); relayList.clear();
} }
else if(_buffer.startsWith("ITEM NUMBER:")) else if(_buffer.startsWith("ITEM NUMBER:"))processRelayState(_buffer);
{ else if(_buffer.startsWith("SENSOR")) processSensorState(_buffer);
processRelayState(_buffer);
}
else if(_buffer.startsWith("SENSOR"))
{
processSensorState(_buffer);
}
} }
} }
@ -192,7 +186,7 @@ void Microcontroller::isReadyRead()
while(_port->getChar(&charBuf)) while(_port->getChar(&charBuf))
{ {
_buffer.push_back(charBuf); _buffer.push_back(charBuf);
if(_buffer.endsWith('\n') ) if( _buffer.endsWith('\n') )
{ {
_buffer.remove('\n'); _buffer.remove('\n');
processMicroReturn(); processMicroReturn();

View file

@ -1,6 +1,8 @@
#ifndef MICROCONTROLLER_H #ifndef MICROCONTROLLER_H
#define MICROCONTROLLER_H #define MICROCONTROLLER_H
#include <iostream>
#include <QObject> #include <QObject>
#include <QColor> #include <QColor>
#include <QIODevice> #include <QIODevice>
@ -15,9 +17,8 @@
#include "items/item.h" #include "items/item.h"
#include "items/relay.h" #include "items/relay.h"
#include "sensors/sensor.h" #include "sensors/sensor.h"
#include "items/itemsource.h"
class Microcontroller : public ItemSource class Microcontroller : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -64,7 +65,7 @@ public slots:
void setPattern(int pattern); void setPattern(int pattern);
void startSunrise(); void startSunrise();
void refresh() override; void requestState();
void setAuxPwm(int duty); void setAuxPwm(int duty);
@ -78,6 +79,10 @@ private slots:
signals: signals:
void textRecived(const QString string); void textRecived(const QString string);
void itemChanged(ItemData relay);
void auxStateChanged(int value);
void gotRelayList(std::vector< std::shared_ptr<Item> >&);
void gotSensorState(Sensor sensor); void gotSensorState(Sensor sensor);
}; };

View file

@ -1,72 +0,0 @@
#include "pipewire.h"
#include <stdexcept>
#include <QDebug>
static const struct pw_registry_events registry_events = {
.version = PW_VERSION_REGISTRY_EVENTS,
.global = &PipeWireHandler::registryEventHandler,
.global_remove = nullptr
};
PipeWireHandler::PipeWireHandler()
{
loop = pw_thread_loop_new("SHinterface", nullptr);
if(!loop)
throw std::runtime_error("Could not create pipewire main loop");
context = pw_context_new(pw_thread_loop_get_loop(loop), nullptr, 0);
if(!context)
throw std::runtime_error("Could not create pipewire context");
core = pw_context_connect(context, NULL, 0);
if(!core)
throw std::runtime_error("Could not connect to pipewire");
registry = pw_core_get_registry(core, PW_VERSION_REGISTRY, 0);
if(!registry)
throw std::runtime_error("Could not get pipewire registry");
spa_zero(registryListener);
pw_registry_add_listener(registry, &registryListener, &registry_events, this);
}
bool PipeWireHandler::startLoop()
{
if(!loop || !context || !core || !registry)
return false;
int ret = pw_thread_loop_start(loop);
return ret == 0;
}
struct pw_registry* PipeWireHandler::getRegistry()
{
return registry;
}
void PipeWireHandler::registryEventHandler(void *data, uint32_t id,
uint32_t permissions, const char *type, uint32_t version,
const struct spa_dict *props)
{
(void)permissions;
(void)version;
PipeWireHandler* handler = static_cast<PipeWireHandler*>(data);
if(std::string(type) == PW_TYPE_INTERFACE_Node)
{
const struct spa_dict_item *item = spa_dict_lookup_item(props, "node.name");
if(item)
{
qDebug()<<"got new pipewire node:"<<id<<"name:"<<item->value;
handler->nodeAdded({id, item->value});
}
}
}
PipeWireHandler::~PipeWireHandler()
{
pw_core_disconnect(core);
pw_context_destroy(context);
pw_thread_loop_stop(loop);
}

View file

@ -1,56 +0,0 @@
#pragma once
#include <pipewire/context.h>
#include <pipewire/core.h>
#include <pipewire/pipewire.h>
#include <QObject>
#include <string>
#include <cstdint>
class PipeWireHandler: public QObject
{
Q_OBJECT
public:
struct PwNode
{
uint32_t id;
std::string name;
};
private:
struct pw_thread_loop* loop;
struct pw_context* context;
struct pw_core* core;
struct pw_registry* registry;
struct spa_hook registryListener;
void write(const char * const buffer, const size_t length);
void write(const QByteArray& buffer);
void decode(QByteArray buffer);
void decodeMaster(const QByteArray& buffer);
public:
static void registryEventHandler(void *data, uint32_t id,
uint32_t permissions, const char *type, uint32_t version,
const struct spa_dict *props);
signals:
void nodeAdded(PwNode node);
void nodeRemoved(PwNode node);
public:
PipeWireHandler();
PipeWireHandler(const PipeWireHandler&) = delete;
PipeWireHandler operator=(const PipeWireHandler&) = delete;
bool startLoop();
struct pw_registry* getRegistry();
~PipeWireHandler();
};

View file

@ -1,3 +0,0 @@
#include "programmode.h"
program_mode_t programMode = PROGRAM_MODE_PRIMARY;

View file

@ -1,13 +0,0 @@
#ifndef PROGRAMMODE_H
#define PROGRAMMODE_H
typedef enum
{
PROGRAM_MODE_PRIMARY = 0,
PROGRAM_MODE_HEADLESS_PRIMARY,
PROGRAM_MODE_UI_ONLY
} program_mode_t;
extern program_mode_t programMode;
#endif // PROGRAMMODE_H

View file

@ -1,187 +0,0 @@
#include "mqttsensorsource.h"
#include<QJsonArray>
MqttSensorSource::MqttSensorSource(QObject *parent)
: QObject{parent}
{
}
void MqttSensorSource::start(const QJsonObject& settings)
{
baseTopicName = settings["BaseTopic"].toString("zigbee2mqtt");
connect(&client, &QMqttClient::stateChanged, this, &MqttSensorSource::onClientStateChanged);
connect(&client, &QMqttClient::errorChanged, this, &MqttSensorSource::onClientError);
client.setHostname(settings["Host"].toString("127.0.0.1"));
client.setPort(settings["Port"].toInt(1883));
if(settings.contains("User"))
client.setUsername(settings["User"].toString());
if(settings.contains("Password"))
client.setPassword(settings["Password"].toString());
client.setProtocolVersion(QMqttClient::MQTT_5_0);
client.connectToHost();
QJsonArray sensorsArray = settings["Sensors"].toArray();
for(QJsonValueRef sensorRef : sensorsArray)
{
QJsonObject sensorObject = sensorRef.toObject();
if(!sensorObject.contains("Topic"))
continue;
SensorSubscription sensor;
sensor.topic = sensorObject["Topic"].toString();
if(!sensorObject.contains("Name"))
sensor.name = sensor.topic;
else
sensor.name = sensorObject["Name"].toString();
sensor.id = qHash(baseTopicName + "/" + sensor.topic);
sensors.push_back(sensor);
}
}
void MqttSensorSource::onClientError(QMqttClient::ClientError error)
{
qWarning()<<"MQTT Client error:"<<error;
}
MqttSensorSource::SensorSubscription& MqttSensorSource::findSubscription(const QString& topic)
{
for(SensorSubscription& sensor : sensors)
{
if(baseTopicName + "/" + sensor.topic == topic)
return sensor;
}
assert(false);
}
void MqttSensorSource::onClientStateChanged(QMqttClient::ClientState state)
{
if(state == QMqttClient::ClientState::Connected)
{
qInfo()<<"Connected to MQTT broker at "<<client.hostname()<<client.port();
for(SensorSubscription& sensor : sensors)
{
qDebug()<<"MQTT subscribeing to"<<baseTopicName + "/" + sensor.topic;
sensor.subscription = client.subscribe(baseTopicName + "/" + sensor.topic);
connect(sensor.subscription, &QMqttSubscription::messageReceived, this, &MqttSensorSource::onMessageReceived);
}
}
else if (state == QMqttClient::ClientState::Disconnected)
{
qWarning()<<"Lost connection to MQTT broker";
for(SensorSubscription& sensor : sensors)
{
if(sensor.subscription)
{
client.unsubscribe(sensor.topic);
sensor.subscription = nullptr;
}
}
}
else if(state == QMqttClient::ClientState::Connecting)
{
qInfo()<<"Connecting to MQTT broker at "<<client.hostname()<<client.port();
}
}
void MqttSensorSource::onMessageReceived(const QMqttMessage& message)
{
Sensor sensor;
SensorSubscription& sensorSub = findSubscription(message.topic().name());
QString baseName = sensorSub.name;
sensor.id = sensorSub.id;
sensor.updateSeen();
QJsonDocument doc = QJsonDocument::fromJson(message.payload());
if(doc.isObject())
{
QJsonObject obj = doc.object();
if(obj.contains("temperature"))
{
sensor.name = baseName + " Temperature";
sensor.type = Sensor::TYPE_TEMPERATURE;
sensor.field = obj["temperature"].toDouble(0);
stateChanged(sensor);
}
if(obj.contains("humidity"))
{
sensor.name = baseName + " Humidity";
sensor.type = Sensor::TYPE_HUMIDITY;
sensor.field = obj["humidity"].toDouble(0);
stateChanged(sensor);
}
if(obj.contains("illuminance"))
{
sensor.name = baseName + " Illuminance";
sensor.type = Sensor::TYPE_BRIGHTNESS;
sensor.field = obj["illuminance"].toDouble(0);
stateChanged(sensor);
}
if(obj.contains("presence"))
{
sensor.name = baseName + " Presence";
sensor.type = Sensor::TYPE_OCUPANCY;
sensor.field = obj["presence"].toBool() ? 1 : 0;
stateChanged(sensor);
}
if(obj.contains("co2"))
{
sensor.name = baseName + " co2";
sensor.type = Sensor::TYPE_CO2;
sensor.field = obj["co2"].toDouble(0);
stateChanged(sensor);
}
if(obj.contains("formaldehyd"))
{
sensor.name = baseName + " Formaldehyd";
sensor.type = Sensor::TYPE_FORMALDEHYD;
sensor.field = obj["formaldehyd"].toDouble(0);
stateChanged(sensor);
}
if(obj.contains("pm25"))
{
sensor.name = baseName + " pm25";
sensor.type = Sensor::TYPE_PM25;
sensor.field = obj["pm25"].toDouble(0);
stateChanged(sensor);
}
if(obj.contains("voc"))
{
sensor.name = baseName + " VOC";
sensor.type = Sensor::TYPE_TOTAL_VOC;
sensor.field = obj["voc"].toDouble(0);
stateChanged(sensor);
}
}
}
void MqttSensorSource::store(QJsonObject& json)
{
json["Host"] = client.hostname();
json["Port"] = client.port();
json["BaseTopic"] = baseTopicName;
if(client.username() != "")
json["User"] = client.username();
if(client.password() != "")
json["Password"] = client.password();
QJsonArray sensorsArray;
for(const SensorSubscription& sensor : sensors)
{
QJsonObject sensorObject;
sensorObject["Name"] = sensor.name;
sensorObject["Topic"] = sensor.topic;
sensorsArray.append(sensorObject);
}
json["Sensors"] = sensorsArray;
}

View file

@ -1,44 +0,0 @@
#ifndef MQTTSENSORSOURCE_H
#define MQTTSENSORSOURCE_H
#include <QObject>
#include <QJsonObject>
#include <QtMqtt/QMqttClient>
#include <vector>
#include "sensor.h"
class MqttSensorSource : public QObject
{
Q_OBJECT
struct SensorSubscription
{
uint64_t id;
QString topic;
QString name;
QMqttSubscription* subscription = nullptr;
};
QString baseTopicName;
std::vector<SensorSubscription> sensors;
QMqttClient client;
private:
SensorSubscription& findSubscription(const QString& topic);
private slots:
void onClientStateChanged(QMqttClient::ClientState state);
void onMessageReceived(const QMqttMessage& message);
void onClientError(QMqttClient::ClientError error);
public:
explicit MqttSensorSource(QObject *parent = nullptr);
void start(const QJsonObject& settings);
void store(QJsonObject& json);
signals:
void stateChanged(Sensor sensor);
};
#endif // MQTTSENSORSOURCE_H

View file

@ -0,0 +1,61 @@
#include "ocupancysensor.h"
#include <QTimer>
#include <QDebug>
#include "../apgetconnected.h"
OcupancySensorSource::OcupancySensorSource(QObject *parent, const QString& device, const QString& deviceMac): QObject (parent), deviceMac_(deviceMac), device_(device)
{
QTimer::singleShot(timeoutMs, this, &OcupancySensorSource::Timeout);
}
void OcupancySensorSource::sensorEvent(Sensor sensor)
{
if(sensor.type == Sensor::TYPE_DOOR && sensor.id == 1 && sensor.field != 0.0f)
{
if(occupied == false) stateChanged(Sensor(Sensor::TYPE_OCUPANCY, 0, 1, "Occupancy"));
QTimer::singleShot(timeoutMs, this, &OcupancySensorSource::Timeout);
}
}
void OcupancySensorSource::Timeout()
{
int error = 0;
qDebug()<<"testing for occupancy";
std::vector<uint64_t> devices = ap::connectedDevices(device_.toLatin1().toStdString(), error);
if(error == 0)
{
bool found = false;
for(size_t i = 0; i < devices.size(); ++i)
{
std::string mac = ap::macAddrToString(devices[i]);
if(mac.find(deviceMac_.toLatin1().toStdString()) != std::string::npos)
{
found = true;
qDebug()<<"occupied";
break;
}
}
stateChanged(Sensor(Sensor::TYPE_OCUPANCY, 0, found, "Occupancy"));
occupied = found;
}
else
{
stateChanged(Sensor(Sensor::TYPE_OCUPANCY, 0, true, "Occupancy"));
qDebug()<<"occupancy sensor error "<<error;
}
}
void OcupancySensorSource::store(QJsonObject &json)
{
json["Device"] = device_;
json["MacAddres"] = deviceMac_;
}
void OcupancySensorSource::load(const QJsonObject &json)
{
device_ = json["Device"].toString("wlan0");
deviceMac_ = json["MacAddres"].toString("60:BE:B5:25:8C:E0");
}

View file

@ -0,0 +1,32 @@
#pragma once
#include <QObject>
#include <QJsonObject>
#include "sensor.h"
class OcupancySensorSource : public QObject
{
Q_OBJECT
private:
QString deviceMac_;
QString device_;
bool occupied = true;
static constexpr unsigned timeoutMs = (15 * 60) * 1000;
public:
explicit OcupancySensorSource(QObject *parent = nullptr, const QString& device = "wlan0", const QString& deviceMac = "60:BE:B5:25:8C:E0");
void store(QJsonObject& json);
void load(const QJsonObject& json);
public slots:
void sensorEvent(Sensor sensor);
private slots:
void Timeout();
signals:
void stateChanged(Sensor sensor);
};

View file

@ -4,7 +4,6 @@
#include<QDateTime> #include<QDateTime>
#include<QObject> #include<QObject>
#include<vector> #include<vector>
#include<QJsonObject>
class Sensor class Sensor
{ {
@ -17,10 +16,6 @@ public:
static constexpr uint8_t TYPE_BRIGHTNESS = 4; static constexpr uint8_t TYPE_BRIGHTNESS = 4;
static constexpr uint8_t TYPE_BUTTON = 5; static constexpr uint8_t TYPE_BUTTON = 5;
static constexpr uint8_t TYPE_ADC = 6; static constexpr uint8_t TYPE_ADC = 6;
static constexpr uint8_t TYPE_CO2 = 7;
static constexpr uint8_t TYPE_FORMALDEHYD= 8;
static constexpr uint8_t TYPE_PM25 = 9;
static constexpr uint8_t TYPE_TOTAL_VOC = 10;
static constexpr uint8_t TYPE_LOWBATTERY = 128; static constexpr uint8_t TYPE_LOWBATTERY = 128;
static constexpr uint8_t TYPE_SHUTDOWN_IMMINENT = 251; static constexpr uint8_t TYPE_SHUTDOWN_IMMINENT = 251;
static constexpr uint8_t TYPE_OCUPANCY = 252; static constexpr uint8_t TYPE_OCUPANCY = 252;
@ -29,94 +24,49 @@ public:
static constexpr uint8_t TYPE_DUMMY = 255; static constexpr uint8_t TYPE_DUMMY = 255;
uint8_t type; uint8_t type;
uint64_t id; uint8_t id;
float field; float field;
QString name; QString name;
QDateTime lastSeen; QDateTime lastSeen;
bool hidden; bool hidden;
Sensor(uint64_t typeIn, uint8_t idIn, float fieldIn = 0, QString nameIn = "", bool hiddenIn = false): type(typeIn), Sensor(uint8_t typeIn, uint8_t idIn, float fieldIn = 0, QString nameIn = "", bool hiddenIn = false): type(typeIn), id(idIn), field(fieldIn), name(nameIn), hidden(hiddenIn)
id(idIn), field(fieldIn), name(nameIn), hidden(hiddenIn)
{ {
lastSeen = QDateTime::currentDateTime(); lastSeen = QDateTime::currentDateTime();
if(nameIn == "") if(nameIn == "") generateName();
generateName();
} }
Sensor(QString nameIn = "dummy"): type(TYPE_DUMMY), id(0), field(0), name(nameIn), hidden(false) Sensor(QString nameIn = "dummy"): type(TYPE_DUMMY), id(0), field(0), name(nameIn), hidden(false)
{ {
lastSeen = QDateTime::currentDateTime(); lastSeen = QDateTime::currentDateTime();
} }
Sensor(const QJsonObject& json) inline bool operator==(const Sensor& in) const{ return type==in.type && id == in.id; }
{ inline bool operator!=(const Sensor& in) const{ return !(*this==in); }
type = json["SensorType"].toInt(0); inline void updateSeen(){lastSeen = QDateTime::currentDateTime();}
id = json["Id"].toInt(0);
field = json["Field"].toDouble(0);
name = json["Name"].toString("Sensor");
lastSeen = QDateTime::fromString(json["LastSeen"].toString(""));
hidden = json["Hidden"].toBool(false);
}
inline bool operator==(const Sensor& in) const
{
return type==in.type && id == in.id;
}
inline bool operator!=(const Sensor& in) const
{
return !(*this==in);
}
inline void updateSeen()
{
lastSeen = QDateTime::currentDateTime();
}
static Sensor sensorFromString(const QString& str) static Sensor sensorFromString(const QString& str)
{ {
QStringList bufferList = str.split(' '); QStringList bufferList = str.split(' ');
if(bufferList.size() >= 7) if(bufferList.size() >= 7)
{ {
Sensor sensor(bufferList[2].toUInt(), bufferList[4].toUInt(), bufferList[6].toUInt()); Sensor sensor(bufferList[2].toUInt(), bufferList[4].toUInt(), bufferList[6].toUInt());
if(sensor.type == Sensor::TYPE_HUMIDITY || sensor.type == Sensor::TYPE_TEMPERATURE) if(sensor.type == Sensor::TYPE_HUMIDITY || sensor.type == Sensor::TYPE_TEMPERATURE) sensor.field = sensor.field/10;
sensor.field = sensor.field/10;
if(bufferList.size() >= 9)
sensor.lastSeen = QDateTime::fromSecsSinceEpoch(bufferList[8].toLongLong());
return sensor; return sensor;
} }
else else return Sensor(TYPE_DUMMY, 0, 0, "", true);
{
return Sensor(TYPE_DUMMY, 0, 0, "", true);
}
} }
QString toString() QString toString()
{ {
return QString("SENSOR TYPE: ")+QString::number(type)+" ID: "+QString::number(id)+" FIELD: "+ return QString("SENSOR TYPE: ")+QString::number(type)+" ID: "+QString::number(id)+" FIELD: "+
QString::number((type == Sensor::TYPE_HUMIDITY || type == Sensor::TYPE_TEMPERATURE) ? field*10 : field) + QString::number((type == Sensor::TYPE_HUMIDITY || type == Sensor::TYPE_TEMPERATURE) ? field*10 : field);
" TIME: " + QString::number(lastSeen.toSecsSinceEpoch());
}
inline void store(QJsonObject& json)
{
json["Type"] = "Sensor";
json["SensorType"] = static_cast<int>(type);
json["Id"] = static_cast<int>(id);
json["Field"] = field;
json["Name"] = name;
json["LastSeen"] = lastSeen.toString();
json["Hidden"] = hidden;
} }
inline void generateName() inline void generateName()
{ {
if(type == TYPE_TEMPERATURE) if(type == TYPE_TEMPERATURE) name = "Temperature " + QString::number(id);
name = "Temperature " + QString::number(id); else if(type == TYPE_DOOR) name = "Door " + QString::number(id);
else if(type == TYPE_DOOR) else if(type == TYPE_BUTTON) name = "Button " + QString::number(id);
name = "Door " + QString::number(id); else if(type == TYPE_AUDIO_OUTPUT) name = "Speakers " + QString::number(id);
else if(type == TYPE_BUTTON) else if(type == TYPE_HUMIDITY) name = "Humidity " + QString::number(id);
name = "Button " + QString::number(id); else if(type == TYPE_SUN_ALTITUDE) name = "Solar Altitude";
else if(type == TYPE_AUDIO_OUTPUT) else if(type == TYPE_SHUTDOWN_IMMINENT) name = "Shutdown Imminent";
name = "Speakers " + QString::number(id);
else if(type == TYPE_HUMIDITY)
name = "Humidity " + QString::number(id);
else if(type == TYPE_SUN_ALTITUDE)
name = "Solar Altitude";
else if(type == TYPE_SHUTDOWN_IMMINENT)
name = "Shutdown Imminent";
else name = "Sensor Type " + QString::number(type) + " Id " + QString::number(id); else name = "Sensor Type " + QString::number(type) + " Id " + QString::number(id);
} }
}; };
@ -130,12 +80,9 @@ private:
public: public:
SensorStore(QObject *parent = nullptr); SensorStore(QObject *parent = nullptr);
virtual ~SensorStore() {} virtual ~SensorStore(){}
inline std::vector<Sensor>* getSensors() inline std::vector<Sensor>* getSensors(){ return &sensors_; }
{
return &sensors_;
}
public slots: public slots:

View file

@ -0,0 +1,59 @@
#include "speakersensor.h"
#include <QDebug>
SpeakerSensorSource::SpeakerSensorSource(QString name, QObject *parent) : QObject(parent), name_(name)
{
silenceCount = 0;
}
SpeakerSensorSource::~SpeakerSensorSource()
{
abort();
}
void SpeakerSensorSource::run()
{
abort();
arecord.start( "arecord --disable-softvol -r 8000 -D front -" );
connect(&timer, SIGNAL(timeout()), this, SLOT(doTick()));
timer.setInterval(500);
timer.start();
stateChanged(Sensor(Sensor::TYPE_AUDIO_OUTPUT, 0, 1, name_));
}
void SpeakerSensorSource::abort()
{
if(arecord.state() == QProcess::Running)arecord.close();
if(timer.isActive())timer.stop();
}
void SpeakerSensorSource::doTick()
{
if(arecord.state() == QProcess::Running)
{
QByteArray buffer = arecord.readAllStandardOutput();
//qDebug()<<(int16_t)buffer[0];
for(long i = 0; i < buffer.size(); i++)
{
if((int16_t)buffer.at(i) != -128)
{
silenceCount = 0;
}
}
if(silenceCount > 40 && state)
{
stateChanged(Sensor(Sensor::TYPE_AUDIO_OUTPUT, 0, 0, name_));
state = false;
}
else if(silenceCount == 0 && !state)
{
stateChanged(Sensor(Sensor::TYPE_AUDIO_OUTPUT, 0, 1, name_));
state = true;
}
silenceCount++;
}
}

View file

@ -0,0 +1,45 @@
#ifndef AMPMANAGER_H
#define AMPMANAGER_H
#include <iostream>
#include <QObject>
#include <QRunnable>
#include <QScopedPointer>
#include <QEventLoop>
#include <QTimer>
#include <QProcess>
#include <QByteArray>
#include "sensor.h"
class SpeakerSensorSource : public QObject
{
Q_OBJECT
private:
QString name_;
bool state = true;
QTimer timer;
public:
explicit SpeakerSensorSource(QString name = "", QObject *parent = nullptr);
~SpeakerSensorSource();
public slots:
void run();
void abort();
signals:
void stateChanged(Sensor sensor);
private slots:
void doTick();
private:
long silenceCount = 0;
QProcess arecord;
};
#endif // AMPMANAGER_H

View file

@ -2,7 +2,7 @@
#include <QTimer> #include <QTimer>
#include "sun.h" #include "../sun.h"
#include "sensor.h" #include "sensor.h"

View file

@ -1,104 +0,0 @@
#include <QTcpSocket>
#include <QJsonDocument>
#include <QJsonArray>
#include <iostream>
#include "items/item.h"
#include "items/itemstore.h"
#include "service.h"
Service::Service(QObject* parent):
ItemSource(parent)
{}
QJsonObject Service::createMessage(const QString& type, const QJsonArray& data)
{
QJsonObject json;
json["MessageType"] = type;
json["Data"] = data;
return json;
}
void Service::sensorEvent(Sensor sensor)
{
QJsonArray sensors;
QJsonObject sensorjson;
sensor.store(sensorjson);
sensors.append(sensorjson);
QJsonObject json = createMessage("SensorUpdate", sensors);
sendJson(json);
}
void Service::itemUpdated(std::weak_ptr<Item> item)
{
qDebug()<<__func__;
QJsonArray items;
QJsonObject itemjson;
item.lock()->store(itemjson);
items.append(itemjson);
QJsonObject json = createMessage("ItemUpdate", items);
json["FullList"] = false;
sendJson(json);
}
void Service::refresh()
{
sendJson(createMessage("GetSensors", QJsonArray()));
sendJson(createMessage("GetItems", QJsonArray()));
}
void Service::sendSensors()
{
QJsonArray sensors;
for(auto& sensor: *globalSensors.getSensors())
{
QJsonObject sensorjson;
sensor.store(sensorjson);
sensors.append(sensorjson);
}
sendJson(createMessage("SensorUpdate", sensors));
}
void Service::sendItems()
{
QJsonArray items;
for(auto& item: *globalItems.getItems())
{
QJsonObject itemjson;
item->store(itemjson);
items.append(itemjson);
}
QJsonObject json = createMessage("ItemUpdate", items);
json["FullList"] = true;
sendJson(json);
}
void Service::processIncomeingJson(const QByteArray& jsonbytes)
{
QJsonDocument doc = QJsonDocument::fromJson(jsonbytes);
qDebug()<<"Got Json:"<<QString::fromLatin1(doc.toJson(QJsonDocument::JsonFormat::Indented));
QJsonObject json = doc.object();
QString type = json["MessageType"].toString();
if(type == "GetSensors")
{
qDebug()<<"Sending sensors";
sendSensors();
}
else if(type == "GetItems")
{
qDebug()<<"Sending Items";
sendItems();
}
else if(type == "SensorUpdate")
{
QJsonArray data = json["Data"].toArray();
for(QJsonValueRef sensorjson : data)
{
QJsonObject jsonobject = sensorjson.toObject();
Sensor sensor(jsonobject);
gotSensor(sensor);
}
}
}

View file

@ -1,42 +0,0 @@
#ifndef TCPSERVER_BASE_H
#define TCPSERVER_BASE_H
#include <QTcpServer>
#include <vector>
#include "sensors/sensor.h"
#include "items/item.h"
#include "items/itemsource.h"
class Service : public ItemSource
{
Q_OBJECT
protected:
typedef enum
{
STATE_IDLE,
STATE_RECV_JSON,
} client_state_t;
signals:
void gotSensor(Sensor sensor);
public slots:
void sensorEvent(Sensor sensor);
void itemUpdated(std::weak_ptr<Item> item);
virtual void refresh() override;
public:
Service(QObject* parent = nullptr);
void sendSensors();
void sendItems();
virtual void sendJson(const QJsonObject& json) = 0;
virtual bool launch(const QHostAddress &address = QHostAddress::Any, quint16 port = 0) = 0;
protected:
static QJsonObject createMessage(const QString& type, const QJsonArray& data);
virtual void processIncomeingJson(const QByteArray& jsonbytes);
};
#endif // TCPSERVER_BASE_H

View file

@ -1,100 +0,0 @@
#include <QTcpSocket>
#include <QJsonDocument>
#include <QJsonArray>
#include <iostream>
#include "items/item.h"
#include "service.h"
#include "tcpclient.h"
TcpClient::TcpClient(QObject* parent):
Service(parent),
socket(new QTcpSocket(this))
{
connect(socket, &QTcpSocket::readyRead, this, &TcpClient::socketReadyRead);
}
void TcpClient::sendJson(const QJsonObject& json)
{
QByteArray jsonData = QJsonDocument(json).toJson();
socket->write(QString("MSG JSON LEN " + QString::number(jsonData.size()) + "\n").toLatin1() + jsonData);
}
bool TcpClient::launch(const QHostAddress &address, quint16 port)
{
socket->connectToHost(address, port);
return socket->waitForConnected(2000);
}
void TcpClient::processIncomeingJson(const QByteArray& jsonbytes)
{
QJsonDocument doc = QJsonDocument::fromJson(jsonbytes);
QJsonObject json = doc.object();
QString type = json["MessageType"].toString();
if(type == "ItemUpdate")
{
std::cout<<"Got item json:\n"<<QString::fromLatin1(jsonbytes).toStdString();
QJsonArray data = json["Data"].toArray();
std::vector<std::shared_ptr<Item>> items;
for(QJsonValueRef itemjson : data)
{
QJsonObject jsonobject = itemjson.toObject();
std::shared_ptr<Item> item = Item::loadItem(jsonobject);
if(item)
{
item->setLoaded(false);
items.push_back(item);
}
}
if(!items.empty())
gotItems(items, true);
}
else
{
Service::processIncomeingJson(jsonbytes);
}
}
void TcpClient::processComand(const QByteArray& command)
{
if(command.startsWith("MSG JSON LEN "))
{
state = STATE_RECV_JSON;
recievebytes = command.mid(13).toLongLong();
}
}
void TcpClient::socketReadyRead()
{
buffer += socket->readAll();
bool remianing = true;
while(remianing)
{
remianing = false;
while(state == STATE_IDLE && buffer.contains('\n'))
{
size_t newlineIndex = buffer.indexOf('\n');
QByteArray command = buffer.left(newlineIndex);
buffer.remove(0, newlineIndex+1);
processComand(command);
remianing = true;
}
if(state == STATE_RECV_JSON)
{
if(recievebytes <= buffer.size())
{
QByteArray json = buffer.left(recievebytes);
buffer.remove(0, recievebytes);
recievebytes = 0;
state = STATE_IDLE;
processIncomeingJson(json);
remianing = true;
}
}
}
}
TcpClient::~TcpClient()
{
delete socket;
}

View file

@ -1,33 +0,0 @@
#ifndef TCPSERVER_CLIENT_H
#define TCPSERVER_CLIENT_H
#include <QTcpSocket>
#include <QJsonDocument>
#include <QJsonArray>
#include "service.h"
class TcpClient : public Service
{
Q_OBJECT
QTcpSocket* socket;
client_state_t state = STATE_IDLE;
long long recievebytes = 0;
QByteArray buffer;
public:
TcpClient(QObject* parent = nullptr);
~TcpClient();
virtual bool launch(const QHostAddress &address = QHostAddress::Any, quint16 port = 0) override;
virtual void sendJson(const QJsonObject& json) override;
protected:
virtual void processIncomeingJson(const QByteArray& jsonbytes) override;
private slots:
void socketReadyRead();
void processComand(const QByteArray& command);
};
#endif // TCPSERVER_CLIENT_H

View file

@ -1,153 +0,0 @@
#include <QTcpServer>
#include <vector>
#include <QTcpSocket>
#include <QJsonArray>
#include "items/item.h"
#include "service.h"
#include "tcpserver.h"
TcpServer::TcpServer(QObject* parent):
Service(parent),
server(this)
{
connect(&server, &QTcpServer::newConnection, this, &TcpServer::incomingConnection);
}
void TcpServer::sendJson(const QJsonObject& json)
{
for(auto client: clients)
{
QByteArray jsonData = QJsonDocument(json).toJson();
client.socket->write(QString("MSG JSON LEN " + QString::number(jsonData.size()) + "\n").toLatin1() + jsonData);
}
}
void TcpServer::processIncomeingJson(const QByteArray& jsonbytes)
{
QJsonDocument doc = QJsonDocument::fromJson(jsonbytes);
QJsonObject json = doc.object();
QString type = json["MessageType"].toString();
if(type == "ItemUpdate")
{
qDebug()<<"Got Items";
QJsonArray data = json["Data"].toArray();
bool FullList = json["FullList"].toBool(false);
std::vector<std::shared_ptr<Item>> items;
for(QJsonValueRef itemjson : data)
{
QJsonObject jsonobject = itemjson.toObject();
std::shared_ptr<Item> item = Item::loadItem(jsonobject);
item->setLoaded(FullList);
if(item)
items.push_back(item);
}
if(FullList && !items.empty())
{
requestReplaceItems(items);
sigRequestSave();
}
else if(!items.empty())
{
gotItems(items, false);
}
}
else
{
Service::processIncomeingJson(jsonbytes);
}
}
bool TcpServer::launch(const QHostAddress &address, quint16 port)
{
return server.listen(address, port);
}
void TcpServer::incomingConnection()
{
while(server.hasPendingConnections())
{
QTcpSocket* client = server.nextPendingConnection();
qDebug()<<"Got new client from"<<client->peerAddress().toString();
if(client)
{
clients.push_back({client});
connect(client, &QTcpSocket::errorOccurred, this, &TcpServer::socketError);
connect(client, &QTcpSocket::disconnected, this, &TcpServer::socketDisconnect);
connect(client, &QTcpSocket::readyRead, this, &TcpServer::socketReadyRead);
}
}
}
void TcpServer::socketError(QAbstractSocket::SocketError socketError)
{
(void)socketError;
for(size_t i = 0; i < clients.size(); i++)
{
if(clients[i].socket == TcpServer::sender())
{
clients.erase(clients.begin()+i);
--i;
}
}
}
void TcpServer::socketDisconnect()
{
for(size_t i = 0; i < clients.size(); i++)
{
if(clients[i].socket == TcpServer::sender())
{
clients.erase(clients.begin()+i);
--i;
}
}
}
void TcpServer::processComand(const QByteArray& command, Client& client)
{
if(command.startsWith("MSG JSON LEN "))
{
client.state = STATE_RECV_JSON;
client.recievebytes = command.mid(13).toLongLong();
qDebug()<<"Got command:"<<QString::fromLatin1(command);
}
}
void TcpServer::socketReadyRead()
{
for(size_t i = 0; i < clients.size(); i++)
{
if(clients[i].socket == sender())
{
QByteArray newChars = clients[i].socket->readAll();
clients[i].buffer += newChars;
bool remianing = true;
while(remianing)
{
qDebug()<<clients[i].buffer;
remianing = false;
while(clients[i].state == STATE_IDLE && clients[i].buffer.contains('\n'))
{
size_t newlineIndex = clients[i].buffer.indexOf('\n');
QByteArray command = clients[i].buffer.left(newlineIndex);
clients[i].buffer.remove(0, newlineIndex+1);
processComand(command, clients[i]);
remianing = true;
}
if(clients[i].state == STATE_RECV_JSON)
{
if(clients[i].recievebytes <= clients[i].buffer.size())
{
QByteArray json = clients[i].buffer.left(clients[i].recievebytes);
clients[i].buffer.remove(0, clients[i].recievebytes);
clients[i].recievebytes = 0;
clients[i].state = STATE_IDLE;
processIncomeingJson(json);
remianing = true;
}
}
}
}
}
}

View file

@ -1,45 +0,0 @@
#ifndef TCPSERVER_SERVER_H
#define TCPSERVER_SERVER_H
#include <QTcpServer>
#include <vector>
#include "service.h"
class TcpServer : public Service
{
Q_OBJECT
struct Client
{
QTcpSocket* socket;
QByteArray buffer;
client_state_t state = STATE_IDLE;
long long recievebytes = 0;
};
std::vector<Client> clients;
QTcpServer server;
public:
TcpServer(QObject* parent = nullptr);
virtual bool launch(const QHostAddress &address = QHostAddress::Any, quint16 port = 0) override;
virtual void sendJson(const QJsonObject& json) override;
signals:
void sigRequestSave();
private slots:
void incomingConnection();
void socketError(QAbstractSocket::SocketError socketError);
void socketDisconnect();
void socketReadyRead();
protected:
virtual void processIncomeingJson(const QByteArray& jsonbytes) override;
private:
void processComand(const QByteArray& command, Client& client);
};
#endif // TCPSERVER_SERVER_H

View file

@ -63,8 +63,7 @@ std::time_t Sun::JdTime::toStdTime()
return millenniumTime; return millenniumTime;
} }
Sun::Sun(double latitude, double longitude, double altitude): latitude_(latitude), longetude_(longitude), Sun::Sun(double latitude, double longitude, double altitude): latitude_(latitude), longetude_(longitude), altitude_(altitude)
altitude_(altitude)
{} {}
double Sun::nextMeanSolarNoonJD(const JdTime& time) double Sun::nextMeanSolarNoonJD(const JdTime& time)
@ -79,8 +78,7 @@ double Sun::meanSolarAnomaly(double meanSolarNoon)
double Sun::eqOfCenter(double meanSolarAnomaly) double Sun::eqOfCenter(double meanSolarAnomaly)
{ {
return 1.9148*sin(meanSolarAnomaly*TO_RADS) + 0.0200*sin(2*meanSolarAnomaly*TO_RADS) + 0.0003*sin( return 1.9148*sin(meanSolarAnomaly*TO_RADS) + 0.0200*sin(2*meanSolarAnomaly*TO_RADS) + 0.0003*sin(3*meanSolarAnomaly*TO_RADS);
3*meanSolarAnomaly*TO_RADS);
} }
double Sun::eclipticLongitude(double eqOfCenter, double meanSolarAnomaly) double Sun::eclipticLongitude(double eqOfCenter, double meanSolarAnomaly)
@ -110,8 +108,7 @@ double Sun::hourAngle(double localSolarTime)
double Sun::hourAngleAtSunset(double solarDeclination) double Sun::hourAngleAtSunset(double solarDeclination)
{ {
return TO_DEGS*acos((sin((-0.83-(2.076*sqrt(altitude_)/60.0))*TO_RADS) - sin(solarDeclination*TO_RADS)*sin( return TO_DEGS*acos((sin((-0.83-(2.076*sqrt(altitude_)/60.0))*TO_RADS) - sin(solarDeclination*TO_RADS)*sin(latitude_*TO_RADS))/(cos(latitude_*TO_RADS)*cos(solarDeclination*TO_RADS)));
latitude_*TO_RADS))/(cos(latitude_*TO_RADS)*cos(solarDeclination*TO_RADS)));
} }
double Sun::altitude() double Sun::altitude()
@ -123,8 +120,7 @@ double Sun::altitude()
double localSolarTimeValue = localSolarTime(time, equationOfTime(meanSolarAnomalyValue, eclipticLongitudeValue)); double localSolarTimeValue = localSolarTime(time, equationOfTime(meanSolarAnomalyValue, eclipticLongitudeValue));
double declinationValue = solarDeclination(eclipticLongitudeValue); double declinationValue = solarDeclination(eclipticLongitudeValue);
double cosZenithAngle = sin(latitude_*TO_RADS)*sin(declinationValue*TO_RADS)+cos(latitude_*TO_RADS)*cos( double cosZenithAngle = sin(latitude_*TO_RADS)*sin(declinationValue*TO_RADS)+cos(latitude_*TO_RADS)*cos(declinationValue*TO_RADS)*cos(hourAngle(localSolarTimeValue)*TO_RADS);
declinationValue*TO_RADS)*cos(hourAngle(localSolarTimeValue)*TO_RADS);
return TO_DEGS*asin(cosZenithAngle); return TO_DEGS*asin(cosZenithAngle);
} }
@ -137,8 +133,7 @@ double Sun::maximumAltitude()
double eclipticLongitudeValue = eclipticLongitude(eqOfCenter(meanSolarAnomalyValue), meanSolarAnomalyValue); double eclipticLongitudeValue = eclipticLongitude(eqOfCenter(meanSolarAnomalyValue), meanSolarAnomalyValue);
double declinationValue = solarDeclination(eclipticLongitudeValue); double declinationValue = solarDeclination(eclipticLongitudeValue);
double cosZenithAngle = sin(latitude_*TO_RADS)*sin(declinationValue*TO_RADS)+cos(latitude_*TO_RADS)*cos( double cosZenithAngle = sin(latitude_*TO_RADS)*sin(declinationValue*TO_RADS)+cos(latitude_*TO_RADS)*cos(declinationValue*TO_RADS);
declinationValue*TO_RADS);
return TO_DEGS*asin(cosZenithAngle); return TO_DEGS*asin(cosZenithAngle);
} }
@ -148,6 +143,7 @@ double Sun::azimuth()
return 0; return 0;
} }
std::time_t Sun::riseTime() std::time_t Sun::riseTime()
{ {
JdTime time; JdTime time;
@ -157,12 +153,10 @@ std::time_t Sun::riseTime()
double declinationValue = solarDeclination(eclipticLongitudeValue); double declinationValue = solarDeclination(eclipticLongitudeValue);
double hourAngleValue = hourAngleAtSunset(declinationValue); double hourAngleValue = hourAngleAtSunset(declinationValue);
time.julianDate = meanSolarNoonValue + equationOfTime(meanSolarAnomalyValue, time.julianDate = meanSolarNoonValue + equationOfTime(meanSolarAnomalyValue, eclipticLongitudeValue) - hourAngleValue/360.0;
eclipticLongitudeValue) - hourAngleValue/360.0;
return time.toStdTime(); return time.toStdTime();
} }
std::time_t Sun::setTime() std::time_t Sun::setTime()
{ {
JdTime time; JdTime time;
@ -172,12 +166,12 @@ std::time_t Sun::setTime()
double declinationValue = solarDeclination(eclipticLongitudeValue); double declinationValue = solarDeclination(eclipticLongitudeValue);
double hourAngleValue = hourAngleAtSunset(declinationValue); double hourAngleValue = hourAngleAtSunset(declinationValue);
time.julianDate = meanSolarNoonValue + equationOfTime(meanSolarAnomalyValue, time.julianDate = meanSolarNoonValue + equationOfTime(meanSolarAnomalyValue, eclipticLongitudeValue) + hourAngleValue/360.0;
eclipticLongitudeValue) + hourAngleValue/360.0;
return time.toStdTime(); return time.toStdTime();
} }
double Sun::declination() double Sun::declination()
{ {
JdTime time; JdTime time;

View file

@ -16,9 +16,9 @@ ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<AlarmTime> alarm, QWidg
} }
ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<SensorActor> actor, QWidget *parent) : ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<SensorActor> actor, QWidget *parent) :
QDialog(parent), QDialog(parent),
actor_(actor), actor_(actor),
ui(new Ui::ActorSettingsDialog) ui(new Ui::ActorSettingsDialog)
{ {
init(); init();
@ -38,9 +38,9 @@ ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<Regulator> actor, QWidg
} }
ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<TimerActor> actor, QWidget *parent) : ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<TimerActor> actor, QWidget *parent) :
QDialog(parent), QDialog(parent),
actor_(actor), actor_(actor),
ui(new Ui::ActorSettingsDialog) ui(new Ui::ActorSettingsDialog)
{ {
init(); init();
@ -49,9 +49,9 @@ ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<TimerActor> actor, QWid
} }
ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<PolynomalActor> actor, QWidget *parent) : ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<PolynomalActor> actor, QWidget *parent) :
QDialog(parent), QDialog(parent),
actor_(actor), actor_(actor),
ui(new Ui::ActorSettingsDialog) ui(new Ui::ActorSettingsDialog)
{ {
init(); init();
@ -60,9 +60,9 @@ ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<PolynomalActor> actor,
} }
ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<MultiFactorActor> actor, QWidget *parent) : ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<MultiFactorActor> actor, QWidget *parent) :
QDialog(parent), QDialog(parent),
actor_(actor), actor_(actor),
ui(new Ui::ActorSettingsDialog) ui(new Ui::ActorSettingsDialog)
{ {
init(); init();
widget = new FactorActorWidget(actor, this); widget = new FactorActorWidget(actor, this);
@ -70,9 +70,9 @@ ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<MultiFactorActor> actor
} }
ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<Actor> actor, QWidget *parent) : ActorSettingsDialog::ActorSettingsDialog(std::shared_ptr<Actor> actor, QWidget *parent) :
QDialog(parent), QDialog(parent),
actor_(actor), actor_(actor),
ui(new Ui::ActorSettingsDialog) ui(new Ui::ActorSettingsDialog)
{ {
init(); init();
} }
@ -83,20 +83,14 @@ void ActorSettingsDialog::init()
connect(ui->comboBox_action, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAction(int))); connect(ui->comboBox_action, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAction(int)));
connect(ui->spinBox, SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int))); connect(ui->spinBox, SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int)));
connect(ui->pushButton_editItem, &QPushButton::clicked, this, &ActorSettingsDialog::editAsItem); connect(ui->pushButton_editItem, &QPushButton::clicked, this, &ActorSettingsDialog::editAsItem);
connect(ui->pushButton_enable, &QPushButton::clicked, this, &ActorSettingsDialog::setEnabled);
ui->spinBox->hide(); ui->spinBox->hide();
ui->spinBox->setValue(actor_->getTriggerValue()); ui->spinBox->setValue(actor_->getTriggerValue());
if(actor_->getTriggerValue() == 0) if(actor_->getTriggerValue() == 0) ui->comboBox_action->setCurrentIndex(0);
ui->comboBox_action->setCurrentIndex(0); else if(actor_->getTriggerValue() == 1) ui->comboBox_action->setCurrentIndex(1);
else if(actor_->getTriggerValue() == 1) else ui->comboBox_action->setCurrentIndex(2);
ui->comboBox_action->setCurrentIndex(1);
else
ui->comboBox_action->setCurrentIndex(2);
ui->label_Exausted->setText(actor_->isExausted() ? "True" : "False"); ui->label_Exausted->setText(actor_->isExausted() ? "True" : "False");
ui->label_Enabled->setText(actor_->isActive() ? "True" : "False");
ui->pushButton_enable->setText(actor_->isActive() ? "Disable" : "Enable");
} }
ActorSettingsDialog::~ActorSettingsDialog() ActorSettingsDialog::~ActorSettingsDialog()
@ -110,13 +104,6 @@ void ActorSettingsDialog::editAsItem()
itemSettingsDiag.exec(); itemSettingsDiag.exec();
} }
void ActorSettingsDialog::setEnabled()
{
actor_->setActive(!actor_->isActive());
ui->label_Enabled->setText(actor_->isActive() ? "True" : "False");
ui->pushButton_enable->setText(actor_->isActive() ? "Disable" : "Enable");
}
void ActorSettingsDialog::valueChanged(int value) void ActorSettingsDialog::valueChanged(int value)
{ {
actor_->setTriggerValue(value); actor_->setTriggerValue(value);

View file

@ -10,8 +10,7 @@
#include "actorwidgets/polynomalactorwidget.h" #include "actorwidgets/polynomalactorwidget.h"
#include "actorwidgets/factoractorwidget.h" #include "actorwidgets/factoractorwidget.h"
namespace Ui namespace Ui {
{
class ActorSettingsDialog; class ActorSettingsDialog;
} }
@ -41,7 +40,6 @@ private slots:
void changeAction(int index); void changeAction(int index);
void valueChanged(int value); void valueChanged(int value);
void editAsItem(); void editAsItem();
void setEnabled();
private: private:

View file

@ -85,63 +85,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Enabled:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_Enabled">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>True</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton_enable">
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>

View file

@ -7,6 +7,11 @@ AlarmWidget::AlarmWidget(std::shared_ptr<AlarmTime> alarm, QWidget *parent) :
ui(new Ui::AlarmWidget) ui(new Ui::AlarmWidget)
{ {
ui->setupUi(this); ui->setupUi(this);
connect(ui->checkBox, &QCheckBox::stateChanged, this, &AlarmWidget::toggleRepeating);
connect(ui->radioButton, &QRadioButton::clicked, this, &AlarmWidget::setRepeatingType);
connect(ui->radioButton_2, &QRadioButton::clicked, this, &AlarmWidget::setRepeatingType);
connect(ui->radioButton_3, &QRadioButton::clicked, this, &AlarmWidget::setRepeatingType);
connect(ui->radioButton_4, &QRadioButton::clicked, this, &AlarmWidget::setRepeatingType);
ui->dateTimeEdit->setDateTime(alarm->getDateTime()); ui->dateTimeEdit->setDateTime(alarm->getDateTime());
@ -26,20 +31,11 @@ AlarmWidget::AlarmWidget(std::shared_ptr<AlarmTime> alarm, QWidget *parent) :
ui->radioButton_4->setEnabled(true); ui->radioButton_4->setEnabled(true);
} }
if(alarm_->getRepeat() == AlarmTime::REPEAT_DAILY) if(alarm_->getRepeat() == AlarmTime::REPEAT_DAILY) ui->radioButton->setChecked(true);
ui->radioButton->setChecked(true); else if(alarm_->getRepeat() == AlarmTime::REPEAT_WEEKLY) ui->radioButton_2->setChecked(true);
else if(alarm_->getRepeat() == AlarmTime::REPEAT_WEEKLY) else if(alarm_->getRepeat() == AlarmTime::REPEAT_MONTHLY)ui->radioButton_3->setChecked(true);
ui->radioButton_2->setChecked(true); else if(alarm_->getRepeat() == AlarmTime::REPEAT_YEARLY) ui->radioButton_4->setChecked(true);
else if(alarm_->getRepeat() == AlarmTime::REPEAT_MONTHLY)
ui->radioButton_3->setChecked(true);
else if(alarm_->getRepeat() == AlarmTime::REPEAT_YEARLY)
ui->radioButton_4->setChecked(true);
connect(ui->checkBox, &QCheckBox::stateChanged, this, &AlarmWidget::toggleRepeating);
connect(ui->radioButton, &QRadioButton::clicked, this, &AlarmWidget::setRepeatingType);
connect(ui->radioButton_2, &QRadioButton::clicked, this, &AlarmWidget::setRepeatingType);
connect(ui->radioButton_3, &QRadioButton::clicked, this, &AlarmWidget::setRepeatingType);
connect(ui->radioButton_4, &QRadioButton::clicked, this, &AlarmWidget::setRepeatingType);
connect(ui->dateTimeEdit, &QDateTimeEdit::dateTimeChanged, alarm.get(), &AlarmTime::changeTime); connect(ui->dateTimeEdit, &QDateTimeEdit::dateTimeChanged, alarm.get(), &AlarmTime::changeTime);
} }
@ -50,14 +46,10 @@ AlarmWidget::~AlarmWidget()
void AlarmWidget::setRepeatingType() void AlarmWidget::setRepeatingType()
{ {
if(ui->radioButton->isChecked()) if(ui->radioButton->isChecked())alarm_->setRepeat(AlarmTime::REPEAT_DAILY);
alarm_->setRepeat(AlarmTime::REPEAT_DAILY); if(ui->radioButton_2->isChecked())alarm_->setRepeat(AlarmTime::REPEAT_WEEKLY);
if(ui->radioButton_2->isChecked()) if(ui->radioButton_3->isChecked())alarm_->setRepeat(AlarmTime::REPEAT_MONTHLY);
alarm_->setRepeat(AlarmTime::REPEAT_WEEKLY); if(ui->radioButton_4->isChecked())alarm_->setRepeat(AlarmTime::REPEAT_YEARLY);
if(ui->radioButton_3->isChecked())
alarm_->setRepeat(AlarmTime::REPEAT_MONTHLY);
if(ui->radioButton_4->isChecked())
alarm_->setRepeat(AlarmTime::REPEAT_YEARLY);
} }
void AlarmWidget::toggleRepeating(int state) void AlarmWidget::toggleRepeating(int state)

View file

@ -5,8 +5,7 @@
#include <memory> #include <memory>
#include "../../actors/alarmtime.h" #include "../../actors/alarmtime.h"
namespace Ui namespace Ui {
{
class AlarmWidget; class AlarmWidget;
} }

View file

@ -24,16 +24,16 @@
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy"> <property name="fieldGrowthPolicy">
<enum>QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow</enum> <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property> </property>
<property name="rowWrapPolicy"> <property name="rowWrapPolicy">
<enum>QFormLayout::RowWrapPolicy::DontWrapRows</enum> <enum>QFormLayout::DontWrapRows</enum>
</property> </property>
<property name="labelAlignment"> <property name="labelAlignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property> </property>
<property name="formAlignment"> <property name="formAlignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property> </property>
<property name="horizontalSpacing"> <property name="horizontalSpacing">
<number>50</number> <number>50</number>
@ -57,7 +57,7 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="currentSection"> <property name="currentSection">
<enum>QDateTimeEdit::Section::DaySection</enum> <enum>QDateTimeEdit::DaySection</enum>
</property> </property>
<property name="displayFormat"> <property name="displayFormat">
<string>dd.MM.yyyy hh:mm</string> <string>dd.MM.yyyy hh:mm</string>

View file

@ -4,8 +4,7 @@
#include <QWidget> #include <QWidget>
#include "../../actors/factoractor.h" #include "../../actors/factoractor.h"
namespace Ui namespace Ui {
{
class FactorActorWidget; class FactorActorWidget;
} }

View file

@ -1,8 +1,7 @@
#include "polynomalactorwidget.h" #include "polynomalactorwidget.h"
#include "ui_polynomalactorwidget.h" #include "ui_polynomalactorwidget.h"
PolynomalActorWidget::PolynomalActorWidget(std::shared_ptr<PolynomalActor> actor, SensorStore* sensors, PolynomalActorWidget::PolynomalActorWidget(std::shared_ptr<PolynomalActor> actor, SensorStore* sensors, QWidget *parent):
QWidget *parent):
QWidget(parent), QWidget(parent),
sensors_(sensors), sensors_(sensors),
actor_(actor), actor_(actor),
@ -40,11 +39,10 @@ PolynomalActorWidget::~PolynomalActorWidget()
void PolynomalActorWidget::setPow() void PolynomalActorWidget::setPow()
{ {
actor_->setCoeffiancts(ui->doubleSpinBox_pow3->value(), ui->doubleSpinBox_pow2->value(), actor_->setCoeffiancts(ui->doubleSpinBox_pow3->value(), ui->doubleSpinBox_pow2->value(), ui->doubleSpinBox_pow1->value(), ui->doubleSpinBox_pow0->value());
ui->doubleSpinBox_pow1->value(), ui->doubleSpinBox_pow0->value());
} }
void PolynomalActorWidget::setSensor(const QModelIndex &index) void PolynomalActorWidget::setSensor(const QModelIndex &index)
{ {
actor_->setSensor(ui->listView->getSensorForIndex(index)); actor_->setSensor(sensors_->getSensors()->at(index.row()));
} }

View file

@ -4,8 +4,7 @@
#include <QWidget> #include <QWidget>
#include "../../actors/polynomalactor.h" #include "../../actors/polynomalactor.h"
namespace Ui namespace Ui {
{
class PolynomalActorWidget; class PolynomalActorWidget;
} }
@ -16,8 +15,7 @@ class PolynomalActorWidget : public QWidget
std::shared_ptr<PolynomalActor> actor_; std::shared_ptr<PolynomalActor> actor_;
public: public:
explicit PolynomalActorWidget(std::shared_ptr<PolynomalActor> regulator, SensorStore* sensors = nullptr, explicit PolynomalActorWidget(std::shared_ptr<PolynomalActor> regulator, SensorStore* sensors = nullptr, QWidget *parent = nullptr);
QWidget *parent = nullptr);
~PolynomalActorWidget(); ~PolynomalActorWidget();
private slots: private slots:

View file

@ -132,7 +132,7 @@
<customwidget> <customwidget>
<class>SensorListWidget</class> <class>SensorListWidget</class>
<extends>QListView</extends> <extends>QListView</extends>
<header location="local">ui/sensorlistwidget.h</header> <header location="global">../src/ui/sensorlistwidget.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>

View file

@ -24,17 +24,12 @@ RegulatorWdiget::RegulatorWdiget(std::shared_ptr<Regulator> regulator, SensorSto
} }
ui->doubleSpinBox_setPoint->setValue(regulator->getSetPoint()); ui->doubleSpinBox_setPoint->setValue(regulator->getSetPoint());
ui->doubleSpinBox_band->setValue(regulator->getBand()); ui->doubleSpinBox_band->setValue(regulator->getBand());
ui->spinBox_safe->setValue(regulator_->getSafeValue());
ui->spinBox_timeout->setValue(regulator_->getTimeout());
connect(ui->listView, &SensorListWidget::clicked, this, &RegulatorWdiget::setSensor); connect(ui->listView, &SensorListWidget::clicked, this, &RegulatorWdiget::setSensor);
connect(ui->doubleSpinBox_setPoint, SIGNAL(valueChanged(double)), this, SLOT(setPoint(double))); connect(ui->doubleSpinBox_setPoint, SIGNAL(valueChanged(double)), this, SLOT(setPoint(double)));
connect(ui->doubleSpinBox_band, SIGNAL(valueChanged(double)), this, SLOT(setBand(double))); connect(ui->doubleSpinBox_band, SIGNAL(valueChanged(double)), this, SLOT(setBand(double)));
connect(ui->spinBox_safe, SIGNAL(valueChanged(int)), regulator_.get(), SLOT(setSafeValue(int)));
connect(ui->spinBox_timeout, SIGNAL(valueChanged(int)), regulator_.get(), SLOT(setTimeout(int)));
} }
void RegulatorWdiget::setPoint(double in) void RegulatorWdiget::setPoint(double in)
{ {
regulator_->setPoint(in); regulator_->setPoint(in);
@ -47,7 +42,7 @@ void RegulatorWdiget::setBand(double band)
void RegulatorWdiget::setSensor(const QModelIndex &index) void RegulatorWdiget::setSensor(const QModelIndex &index)
{ {
regulator_->setSensor(ui->listView->getSensorForIndex(index)); regulator_->setSensor(sensors_->getSensors()->at(index.row()));
setPoint(ui->listView->getSensorForIndex(index).field); setPoint(sensors_->getSensors()->at(index.row()).field);
ui->doubleSpinBox_setPoint->setValue(ui->listView->getSensorForIndex(index).field); ui->doubleSpinBox_setPoint->setValue(sensors_->getSensors()->at(index.row()).field);
} }

View file

@ -4,8 +4,7 @@
#include <QWidget> #include <QWidget>
#include "../../actors/regulator.h" #include "../../actors/regulator.h"
namespace Ui namespace Ui {
{
class RegulatorWdiget; class RegulatorWdiget;
} }
@ -17,8 +16,7 @@ class RegulatorWdiget : public QWidget
SensorStore* sensors_; SensorStore* sensors_;
public: public:
explicit RegulatorWdiget(std::shared_ptr<Regulator> regulator, SensorStore* sensors = nullptr, explicit RegulatorWdiget(std::shared_ptr<Regulator> regulator, SensorStore* sensors = nullptr, QWidget *parent = nullptr);
QWidget *parent = nullptr);
~RegulatorWdiget(); ~RegulatorWdiget();
private slots: private slots:

View file

@ -38,8 +38,15 @@
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QGridLayout" name="gridLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item row="0" column="1"> <item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Set Point</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="doubleSpinBox_setPoint"> <widget class="QDoubleSpinBox" name="doubleSpinBox_setPoint">
<property name="minimum"> <property name="minimum">
<double>-9999.989999999999782</double> <double>-9999.989999999999782</double>
@ -49,7 +56,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="2"> <item>
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
@ -62,46 +69,9 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="2"> <item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Timeout</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Set Point</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QDoubleSpinBox" name="doubleSpinBox_band"/> <widget class="QDoubleSpinBox" name="doubleSpinBox_band"/>
</item> </item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Safety Value</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox_safe"/>
</item>
<item row="1" column="3">
<widget class="QSpinBox" name="spinBox_timeout">
<property name="suffix">
<string> s</string>
</property>
<property name="maximum">
<number>999999999</number>
</property>
<property name="value">
<number>1800</number>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>
@ -110,7 +80,7 @@
<customwidget> <customwidget>
<class>SensorListWidget</class> <class>SensorListWidget</class>
<extends>QListView</extends> <extends>QListView</extends>
<header location="local">ui/sensorlistwidget.h</header> <header location="global">../src/ui/sensorlistwidget.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>

View file

@ -17,12 +17,9 @@ SensorActorWidget::SensorActorWidget(std::shared_ptr<SensorActor> sensorActor, S
ui->label->hide(); ui->label->hide();
} }
if(sensorActor_->getSloap() == SensorActor::SLOPE_UP) if(sensorActor_->getSloap() == SensorActor::SLOPE_UP) ui->comboBox_slope->setCurrentIndex(0);
ui->comboBox_slope->setCurrentIndex(0); else if(sensorActor_->getSloap() == SensorActor::SLOPE_DOWN) ui->comboBox_slope->setCurrentIndex(1);
else if(sensorActor_->getSloap() == SensorActor::SLOPE_DOWN) else if(sensorActor_->getSloap() == SensorActor::SLOPE_BOTH) ui->comboBox_slope->setCurrentIndex(2);
ui->comboBox_slope->setCurrentIndex(1);
else if(sensorActor_->getSloap() == SensorActor::SLOPE_BOTH)
ui->comboBox_slope->setCurrentIndex(2);
ui->doubleSpinBox_threshold->setValue(sensorActor_->getThreshold()); ui->doubleSpinBox_threshold->setValue(sensorActor_->getThreshold());
@ -50,5 +47,6 @@ void SensorActorWidget::setSlope(int index)
void SensorActorWidget::setSensor(const QModelIndex &index) void SensorActorWidget::setSensor(const QModelIndex &index)
{ {
sensorActor_->setSensor(ui->listView->getSensorForIndex(index)); sensorActor_->setSensor(sensors_->getSensors()->at(index.row()));
qDebug()<<"Selected "<<sensors_->getSensors()->at(index.row()).name;
} }

View file

@ -5,8 +5,7 @@
#include <QItemSelection> #include <QItemSelection>
#include "../../actors/sensoractor.h" #include "../../actors/sensoractor.h"
namespace Ui namespace Ui {
{
class SensorActorWidget; class SensorActorWidget;
} }
@ -18,8 +17,7 @@ class SensorActorWidget : public QWidget
SensorStore* sensors_; SensorStore* sensors_;
public: public:
explicit SensorActorWidget(std::shared_ptr<SensorActor> sensorActor, SensorStore* sensors = nullptr, explicit SensorActorWidget(std::shared_ptr<SensorActor> sensorActor, SensorStore* sensors = nullptr, QWidget *parent = nullptr);
QWidget *parent = nullptr);
~SensorActorWidget(); ~SensorActorWidget();
private slots: private slots:

View file

@ -89,7 +89,7 @@
<customwidget> <customwidget>
<class>SensorListWidget</class> <class>SensorListWidget</class>
<extends>QListView</extends> <extends>QListView</extends>
<header location="local">ui/sensorlistwidget.h</header> <header location="global">../src/ui/sensorlistwidget.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>

View file

@ -4,8 +4,7 @@
#include <QWidget> #include <QWidget>
#include "../../actors/timeractor.h" #include "../../actors/timeractor.h"
namespace Ui namespace Ui {
{
class TimerActorWidget; class TimerActorWidget;
} }

View file

@ -5,8 +5,7 @@
#include <memory> #include <memory>
#include "../items/item.h" #include "../items/item.h"
namespace Ui namespace Ui {
{
class ItemCreationDialog; class ItemCreationDialog;
} }

View file

@ -21,9 +21,18 @@ void ItemScrollBox::addItem(std::weak_ptr<Item> item)
{ {
if(auto workItem = item.lock()) if(auto workItem = item.lock())
{ {
if(workItem->isHidden()) if(dynamic_cast<AuxItem*>(workItem.get()))
return; {
widgets_.push_back(new ItemWidget(item, true));
}
else if(dynamic_cast<MessageItem*>(workItem.get()))
{
widgets_.push_back(new ItemWidget(item, false, true));
}
else
{
widgets_.push_back(new ItemWidget(item)); widgets_.push_back(new ItemWidget(item));
}
ui->relayWidgetVbox->addWidget(widgets_.back()); ui->relayWidgetVbox->addWidget(widgets_.back());
connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest); connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest);
connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::removeItem); connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::removeItem);

View file

@ -11,8 +11,7 @@
#include "../items/itemstore.h" #include "../items/itemstore.h"
namespace Ui namespace Ui {
{
class RelayScrollBox; class RelayScrollBox;
} }

View file

@ -1,4 +1,4 @@
#include "itemsettingsdialog.h" #include "itemsettingsdialog.h"
#include "ui_itemsettingsdialog.h" #include "ui_itemsettingsdialog.h"
#include "actorsettingsdialog.h" #include "actorsettingsdialog.h"
#include "../actors/alarmtime.h" #include "../actors/alarmtime.h"
@ -8,9 +8,9 @@
#include "../actors/factoractor.h" #include "../actors/factoractor.h"
#include "../items/messageitem.h" #include "../items/messageitem.h"
#include "../items/systemitem.h" #include "../items/systemitem.h"
#include "itemsettingswidgets/messageitemsettingswidget.h" #include "./itemsettingswidgets/messageitemsettingswidget.h"
#include "itemsettingswidgets/systemitemsettingswidget.h" #include "./itemsettingswidgets/systemitemsettingswidget.h"
#include "itemsettingswidgets/relayitemsettingswidget.h" #include "./itemsettingswidgets/relayitemsettingswidget.h"
#include<memory> #include<memory>
ItemSettingsDialog::ItemSettingsDialog(std::shared_ptr<Item> item, QWidget *parent) : ItemSettingsDialog::ItemSettingsDialog(std::shared_ptr<Item> item, QWidget *parent) :
@ -144,7 +144,7 @@ void ItemSettingsDialog::addActor()
void ItemSettingsDialog::removeActor() void ItemSettingsDialog::removeActor()
{ {
if(item_->getActors().size() > static_cast<size_t>(ui->tableWidget->currentRow())) if(item_->getActors().size() > ui->tableWidget->currentRow())
{ {
item_->removeActor(item_->getActors().at(ui->tableWidget->currentRow())); item_->removeActor(item_->getActors().at(ui->tableWidget->currentRow()));
loadActorList(); loadActorList();
@ -153,7 +153,7 @@ void ItemSettingsDialog::removeActor()
void ItemSettingsDialog::editActor() void ItemSettingsDialog::editActor()
{ {
if(item_->getActors().size() > static_cast<size_t>(ui->tableWidget->currentRow())) if(item_->getActors().size() > ui->tableWidget->currentRow())
{ {
std::shared_ptr<Actor> actor = item_->getActors()[ui->tableWidget->currentRow()]; std::shared_ptr<Actor> actor = item_->getActors()[ui->tableWidget->currentRow()];
@ -177,7 +177,7 @@ void ItemSettingsDialog::editActor()
dialog->show(); dialog->show();
dialog->exec(); dialog->exec();
for(int i = 0; i < ui->tableWidget->rowCount() && i < static_cast<int>(item_->getActors().size()); ++i) for(int i = 0; i < ui->tableWidget->rowCount() && i < item_->getActors().size(); ++i)
{ {
ui->tableWidget->item(i, 0)->setText(item_->getActors()[i]->getName()); ui->tableWidget->item(i, 0)->setText(item_->getActors()[i]->getName());
ui->tableWidget->item(i, 1)->setText(item_->getActors()[i]->actionName()); ui->tableWidget->item(i, 1)->setText(item_->getActors()[i]->actionName());

View file

@ -6,8 +6,7 @@
#include <memory> #include <memory>
#include "../items/relay.h" #include "../items/relay.h"
namespace Ui namespace Ui {
{
class ItemSettingsDialog; class ItemSettingsDialog;
} }

View file

@ -115,7 +115,7 @@
<number>3</number> <number>3</number>
</property> </property>
<attribute name="horizontalHeaderVisible"> <attribute name="horizontalHeaderVisible">
<bool>true</bool> <bool>false</bool>
</attribute> </attribute>
<attribute name="horizontalHeaderMinimumSectionSize"> <attribute name="horizontalHeaderMinimumSectionSize">
<number>32</number> <number>32</number>

View file

@ -1,48 +0,0 @@
#include "messageitemsettingswidget.h"
#include "ui_messageitemsettingswidget.h"
#include <QFileDialog>
#include <QDebug>
MessageItemSettingsWidget::MessageItemSettingsWidget(std::weak_ptr<MessageItem> item, QWidget *parent) :
QWidget(parent),
item_(item),
ui(new Ui::MessageItemSettingsWidget)
{
ui->setupUi(this);
qDebug()<<"test";
if(auto workingItem = item_.lock())
{
ui->lineEdit->setText(workingItem->getMessage());
ui->lineEdit_alert->setText(workingItem->getAlert());
}
connect(ui->lineEdit, &QLineEdit::textChanged, this, &MessageItemSettingsWidget::setText);
connect(ui->lineEdit_alert, &QLineEdit::textChanged, this, &MessageItemSettingsWidget::setAlert);
connect(ui->pushButton, &QPushButton::pressed, [this]()
{
ui->lineEdit_alert->setText(QFileDialog::getOpenFileName(this, "Choose File"));
});
}
void MessageItemSettingsWidget::setText(const QString& text)
{
if(auto workingItem = item_.lock())
{
workingItem->setMessage(text);
}
}
void MessageItemSettingsWidget::setAlert(const QString &in)
{
if(auto workingItem = item_.lock())
{
workingItem->setAlert(in);
}
}
MessageItemSettingsWidget::~MessageItemSettingsWidget()
{
delete ui;
}

View file

@ -1,31 +0,0 @@
#ifndef MESSAGEITEMSETTINGSWIDGET_H
#define MESSAGEITEMSETTINGSWIDGET_H
#include <QWidget>
#include <memory>
#include "../../items/messageitem.h"
namespace Ui
{
class MessageItemSettingsWidget;
}
class MessageItemSettingsWidget : public QWidget
{
Q_OBJECT
std::weak_ptr<MessageItem> item_;
private slots:
void setText(const QString& text);
void setAlert(const QString &in);
public:
explicit MessageItemSettingsWidget(std::weak_ptr<MessageItem> item, QWidget *parent = nullptr);
~MessageItemSettingsWidget();
private:
Ui::MessageItemSettingsWidget *ui;
};
#endif // MESSAGEITEMSETTINGSWIDGET_H

View file

@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MessageItemSettingsWidget</class>
<widget class="QWidget" name="MessageItemSettingsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>124</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Text:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Alert:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_alert"/>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -5,8 +5,7 @@
#include <memory> #include <memory>
#include "../../items/relay.h" #include "../../items/relay.h"
namespace Ui namespace Ui {
{
class RelayItemSettingsWidget; class RelayItemSettingsWidget;
} }

View file

@ -5,8 +5,7 @@
#include <memory> #include <memory>
#include "../../items/systemitem.h" #include "../../items/systemitem.h"
namespace Ui namespace Ui {
{
class SystemItemSettingsWidget; class SystemItemSettingsWidget;
} }

View file

@ -5,47 +5,39 @@
#include <QDebug> #include <QDebug>
#include <QSlider> #include <QSlider>
ItemWidget::ItemWidget(std::weak_ptr<Item> item, QWidget *parent) : ItemWidget::ItemWidget(std::weak_ptr<Item> item, bool analog, bool nameOnly, QWidget *parent) :
QWidget(parent), QWidget(parent),
item_(item), item_(item),
ui(new Ui::ItemWidget) ui(new Ui::ItemWidget)
{ {
ui->setupUi(this); ui->setupUi(this);
if(auto workingItem = item_.lock()) if(analog)
{
if(workingItem->getValueType() == ITEM_VALUE_UINT)
{ {
ui->horizontalSpacer->changeSize(0,0); ui->horizontalSpacer->changeSize(0,0);
ui->checkBox->hide(); ui->checkBox->hide();
} }
else if(workingItem->getValueType() == ITEM_VALUE_NO_VALUE) else if(nameOnly)
{ {
ui->checkBox->hide(); ui->checkBox->hide();
ui->slider->hide(); ui->slider->hide();
} }
else else ui->slider->hide();
if(auto workingRelay = item_.lock())
{ {
ui->slider->hide(); ui->checkBox->setChecked(workingRelay->getValue());
}
ui->checkBox->setChecked(workingItem->getValue()); ui->label->setText(workingRelay->getName());
ui->label->setText(workingItem->getName()); if(analog)connect(ui->slider, &QSlider::valueChanged, this, &ItemWidget::moveToValue);
else connect(ui->checkBox, &QCheckBox::toggled, this, &ItemWidget::moveToState);
if(workingItem->getValueType() == ITEM_VALUE_UINT)
connect(ui->slider, &QSlider::valueChanged, this, &ItemWidget::moveToValue);
else
connect(ui->checkBox, &QCheckBox::toggled, this, &ItemWidget::moveToState);
connect(ui->pushButton, &QPushButton::clicked, this, &ItemWidget::showSettingsDialog); connect(ui->pushButton, &QPushButton::clicked, this, &ItemWidget::showSettingsDialog);
connect(workingItem.get(), &Relay::valueChanged, this, &ItemWidget::stateChanged); connect(workingRelay.get(), &Relay::valueChanged, this, &ItemWidget::stateChanged);
connect(ui->pushButton_Remove, &QPushButton::clicked, this, &ItemWidget::deleteItem); connect(ui->pushButton_Remove, &QPushButton::clicked, this, &ItemWidget::deleteItem);
} }
else else disable();
{
disable();
}
} }
void ItemWidget::deleteItem() void ItemWidget::deleteItem()
@ -58,18 +50,14 @@ void ItemWidget::deleteItem()
void ItemWidget::moveToValue(int value) void ItemWidget::moveToValue(int value)
{ {
if(auto workingItem = item_.lock()) if(auto workingItem = item_.lock()) workingItem->setValue(value);
workingItem->setValue(value); else disable();
else
disable();
} }
void ItemWidget::moveToState(bool state) void ItemWidget::moveToState(bool state)
{ {
if(auto workingItem = item_.lock()) if(auto workingItem = item_.lock()) workingItem->setValue(state);
workingItem->setValue(state); else disable();
else
disable();
} }
void ItemWidget::disable() void ItemWidget::disable()
@ -82,9 +70,9 @@ void ItemWidget::disable()
bool ItemWidget::controles(const ItemData& relay) bool ItemWidget::controles(const ItemData& relay)
{ {
if(auto workingItem = item_.lock()) if(auto workingRelay = item_.lock())
{ {
if(relay == *workingItem) return true; if(relay == *workingRelay) return true;
else return false; else return false;
} }
return true; return true;
@ -92,9 +80,9 @@ bool ItemWidget::controles(const ItemData& relay)
void ItemWidget::showSettingsDialog() void ItemWidget::showSettingsDialog()
{ {
if(auto workingItem = item_.lock()) if(auto workingRelay = item_.lock())
{ {
ItemSettingsDialog dialog(workingItem, this); ItemSettingsDialog dialog(workingRelay, this);
dialog.exec(); dialog.exec();
} }
else disable(); else disable();
@ -107,6 +95,7 @@ std::weak_ptr<Item> ItemWidget::getItem()
void ItemWidget::stateChanged(int state) void ItemWidget::stateChanged(int state)
{ {
qDebug()<<"widget got state "<<state;
ui->slider->blockSignals(true); ui->slider->blockSignals(true);
ui->slider->setValue(state); ui->slider->setValue(state);
ui->slider->blockSignals(false); ui->slider->blockSignals(false);

View file

@ -6,8 +6,7 @@
#include "itemsettingsdialog.h" #include "itemsettingsdialog.h"
#include "../items/item.h" #include "../items/item.h"
namespace Ui namespace Ui {
{
class ItemWidget; class ItemWidget;
} }
@ -30,7 +29,7 @@ private slots:
void deleteItem(); void deleteItem();
public: public:
explicit ItemWidget(std::weak_ptr<Item> item, QWidget *parent = nullptr); explicit ItemWidget(std::weak_ptr<Item> item, bool analog = false, bool nameOnly = false, QWidget *parent = nullptr);
std::weak_ptr<Item> getItem(); std::weak_ptr<Item> getItem();
bool controles(const ItemData& relay); bool controles(const ItemData& relay);
~ItemWidget(); ~ItemWidget();

View file

@ -30,7 +30,7 @@
<item> <item>
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Orientation::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
@ -46,10 +46,10 @@
<number>255</number> <number>255</number>
</property> </property>
<property name="tracking"> <property name="tracking">
<bool>false</bool> <bool>true</bool>
</property> </property>
<property name="orientation"> <property name="orientation">
<enum>Qt::Orientation::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>

View file

@ -245,13 +245,13 @@
<customwidget> <customwidget>
<class>ItemScrollBox</class> <class>ItemScrollBox</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header location="global">../ui/itemscrollbox.h</header> <header location="global">../src/ui/itemscrollbox.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>SensorListWidget</class> <class>SensorListWidget</class>
<extends>QListView</extends> <extends>QListView</extends>
<header location="global">../ui/sensorlistwidget.h</header> <header location="global">../src/ui/sensorlistwidget.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources> <resources>

Some files were not shown because too many files have changed in this diff Show more