diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 5c24e80..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,169 +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/tcpserver.h - src/tcpserver.cpp - src/pipewire.h - src/pipewire.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}) diff --git a/SHinterface.pro b/SHinterface.pro new file mode 100644 index 0000000..c7ff09f --- /dev/null +++ b/SHinterface.pro @@ -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 diff --git a/src/actor.cpp.autosave b/src/actor.cpp.autosave new file mode 100644 index 0000000..72a0dd4 --- /dev/null +++ b/src/actor.cpp.autosave @@ -0,0 +1,100 @@ +#include "actor.h" +#include + +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 "< #include -#include "items/item.h" +#include "../items/item.h" class Actor : public Item { diff --git a/src/actors/alarmtime.cpp b/src/actors/alarmtime.cpp index 0f38f27..ff26813 100644 --- a/src/actors/alarmtime.cpp +++ b/src/actors/alarmtime.cpp @@ -4,17 +4,17 @@ AlarmTime::AlarmTime(const QDateTime time, QObject *parent) : Actor(parent), tim { connect(&timer, SIGNAL(timeout()), this, SLOT(doTick())); timer.setInterval(1000); - AlarmTime::run(); + run(); } AlarmTime::~AlarmTime() { - AlarmTime::makeInactive(); + makeInactive(); } void AlarmTime::run() { - AlarmTime::makeInactive(); + makeInactive(); active = true; timer.start(); diff --git a/src/actors/polynomalactor.h b/src/actors/polynomalactor.h index 1ff3675..d91f2ba 100644 --- a/src/actors/polynomalactor.h +++ b/src/actors/polynomalactor.h @@ -1,7 +1,7 @@ #ifndef POLYNOMALACTOR_H #define POLYNOMALACTOR_H #include "actor.h" -#include "sensors/sensor.h" +#include "../sensors/sensor.h" class PolynomalActor: public Actor { diff --git a/src/actors/regulator.h b/src/actors/regulator.h index 339b2ca..733d643 100644 --- a/src/actors/regulator.h +++ b/src/actors/regulator.h @@ -3,7 +3,7 @@ #include #include "actor.h" -#include "sensors/sensor.h" +#include "../sensors/sensor.h" class Regulator : public Actor { diff --git a/src/actors/sensoractor.h b/src/actors/sensoractor.h index 27a9355..720146e 100644 --- a/src/actors/sensoractor.h +++ b/src/actors/sensoractor.h @@ -1,6 +1,6 @@ #pragma once #include "actor.h" -#include "sensors/sensor.h" +#include "../sensors/sensor.h" class SensorActor : public Actor { diff --git a/src/alarmactions.cpp b/src/alarmactions.cpp new file mode 100644 index 0000000..20853ce --- /dev/null +++ b/src/alarmactions.cpp @@ -0,0 +1,15 @@ +#include "alarmactions.h" +#include + +AlarmActions::AlarmActions(QApplication* a, Microcontroller* micro, QObject *parent) : QObject(parent), _micro(micro), + a_(a) +{ + +} + +void AlarmActions::syncoff() +{ + qDebug()<<"syncoff"; + QProcess::execute ("syncoff", QStringList()); + a_->exit(0); +} diff --git a/src/alarmactions.h b/src/alarmactions.h new file mode 100644 index 0000000..2922e9d --- /dev/null +++ b/src/alarmactions.h @@ -0,0 +1,25 @@ +#ifndef POWER_H +#define POWER_H + +#include +#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 diff --git a/src/broadcast.cpp b/src/broadcast.cpp new file mode 100644 index 0000000..ed42f16 --- /dev/null +++ b/src/broadcast.cpp @@ -0,0 +1,139 @@ +#include "broadcast.h" +#include +#include +#include +#include + +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: "<= 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()<= 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'); + } +} diff --git a/src/broadcast.h b/src/broadcast.h new file mode 100644 index 0000000..ae7e802 --- /dev/null +++ b/src/broadcast.h @@ -0,0 +1,55 @@ +#ifndef BROADCAST_H +#define BROADCAST_H +#include +#include +#include +#include +#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 + diff --git a/src/iomuliplexer.cpp b/src/iomuliplexer.cpp new file mode 100644 index 0000000..84b3b1a --- /dev/null +++ b/src/iomuliplexer.cpp @@ -0,0 +1,76 @@ +#include "iomuliplexer.h" +#include + +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(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); +} diff --git a/src/iomuliplexer.h b/src/iomuliplexer.h new file mode 100644 index 0000000..68ad624 --- /dev/null +++ b/src/iomuliplexer.h @@ -0,0 +1,54 @@ +#ifndef IOMULIPLEXER_H +#define IOMULIPLEXER_H + +#include +#include +#include +#include + +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 diff --git a/src/items/auxitem.cpp b/src/items/auxitem.cpp index 5bee87e..860a121 100644 --- a/src/items/auxitem.cpp +++ b/src/items/auxitem.cpp @@ -3,12 +3,12 @@ AuxItem::AuxItem(Microcontroller* micro, uint32_t itemIdIn, QString name, uint8_t value, 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); } diff --git a/src/items/auxitem.h b/src/items/auxitem.h index 774d44e..512144f 100644 --- a/src/items/auxitem.h +++ b/src/items/auxitem.h @@ -1,7 +1,7 @@ #pragma once #include "item.h" -#include "microcontroller.h" +#include "../microcontroller.h" class AuxItem: public Item { @@ -9,12 +9,13 @@ class AuxItem: public Item private: Microcontroller* micro_; -protected: - virtual void enactValue(uint8_t value) override; +public slots: + + virtual void setValue(uint8_t value); 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); - virtual void store(QJsonObject& json) override; + virtual void store(QJsonObject& json); }; diff --git a/src/items/fixeditemsource.cpp b/src/items/fixeditemsource.cpp deleted file mode 100644 index d1abc21..0000000 --- a/src/items/fixeditemsource.cpp +++ /dev/null @@ -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}); -} diff --git a/src/items/fixeditemsource.h b/src/items/fixeditemsource.h deleted file mode 100644 index e535842..0000000 --- a/src/items/fixeditemsource.h +++ /dev/null @@ -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; - std::shared_ptr rgbItem; - std::shared_ptr auxItem; - -public: - explicit FixedItemSource(Microcontroller* micro, QObject *parent = nullptr); - virtual void refresh() override; -}; - -#endif // FIXEDITEMSOURCE_H diff --git a/src/items/item.cpp b/src/items/item.cpp index e297094..862834c 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -1,20 +1,14 @@ #include "item.h" -#include "actors/sensoractor.h" -#include "actors/regulator.h" -#include "actors/polynomalactor.h" -#include "programmode.h" #include "relay.h" -#include "messageitem.h" -#include "systemitem.h" -#include "auxitem.h" -#include "poweritem.h" -#include "rgbitem.h" +#include "../microcontroller.h" +#include "../actors/sensoractor.h" +#include "../actors/regulator.h" +#include "../actors/polynomalactor.h" #include -ItemData::ItemData(uint32_t itemIdIn, QString name, uint8_t value, bool loaded, bool hidden, item_value_type_t type): - name_(name), value_(value), itemId_(itemIdIn), loaded_(loaded), hidden_(hidden), type_(type) +ItemData::ItemData(uint32_t itemIdIn, QString name, uint8_t value): name_(name), value_(value), itemId_(itemIdIn) { } @@ -39,63 +33,11 @@ uint32_t ItemData::id() const return itemId_; } -void ItemData::store(QJsonObject &json) -{ - json["Name"] = name_; - json["ItemId"] = static_cast(itemId_); - json["Value"] = static_cast(value_); -} - -void ItemData::load(const QJsonObject &json, const bool preserve) -{ - if(!preserve) - { - name_ = json["Name"].toString(name_); - itemId_ = static_cast(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 +bool Item::secondaryFlag = false; + Item::Item(uint32_t itemIdIn, QString name, uint8_t value, QObject *parent): QObject(parent), ItemData (itemIdIn, name, value) { @@ -113,7 +55,8 @@ Item::~Item() void Item::store(QJsonObject &json) { - ItemData::store(json); + json["Name"] = name_; + json["ItemId"] = static_cast(itemId_); json["override"] = override_; QJsonArray actorsArray; for(size_t i = 0; i < actors_.size(); ++i) @@ -130,7 +73,11 @@ void Item::store(QJsonObject &json) void Item::load(const QJsonObject &json, const bool preserve) { - ItemData::load(json, preserve); + if(!preserve) + { + name_ = json["Name"].toString(name_); + itemId_ = static_cast(json["ItemId"].toDouble(0)); + } override_ = json["override"].toBool(false); const QJsonArray actorsArray(json["Actors"].toArray(QJsonArray())); for(int i = 0; i < actorsArray.size(); ++i) @@ -138,60 +85,46 @@ void Item::load(const QJsonObject &json, const bool preserve) if(actorsArray[i].isObject()) { std::shared_ptr actor = Actor::loadActor(actorsArray[i].toObject()); - if(actor != nullptr) - addActor(actor); + if(actor != nullptr) addActor(actor); } } } void Item::actorSetValue(uint8_t value) { - if(!override_ && (programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY)) - setValue(value); + if(!override_) setValue(value); } void Item::setValue(uint8_t value) { - qDebug()<<__func__; - informValue(value); - if(programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY) - enactValue(value); + value_ = value; + valueChanged(value_); } void Item::informValue(uint8_t value) { - if(value_ != value) - { - value_ = value; - valueChanged(value_); - updated(*this); - } -} - -void Item::enactValue(uint8_t value) -{ - (void)value; + Item::setValue(value); } void Item::addActor(std::shared_ptr actor) { actor->setParent(this); 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(this, &Item::valueChanged, actor.get(), &Actor::onValueChanged); std::shared_ptr sensorActor = std::dynamic_pointer_cast(actor); - if(sensorActor) - connect(&globalSensors, &SensorStore::sensorChangedState, sensorActor.get(), &SensorActor::sensorEvent); + if(sensorActor)connect(&globalSensors, &SensorStore::sensorChangedState, sensorActor.get(), &SensorActor::sensorEvent); std::shared_ptr regulator = std::dynamic_pointer_cast(actor); - if(regulator) - connect(&globalSensors, &SensorStore::sensorChangedState, regulator.get(), &Regulator::sensorEvent); + if(regulator)connect(&globalSensors, &SensorStore::sensorChangedState, regulator.get(), &Regulator::sensorEvent); std::shared_ptr polynomalActor = std::dynamic_pointer_cast(actor); - if(polynomalActor != nullptr ) - connect(&globalSensors, &SensorStore::sensorChangedState, polynomalActor.get(), &PolynomalActor::sensorEvent); + if(polynomalActor != nullptr )connect(&globalSensors, &SensorStore::sensorChangedState, polynomalActor.get(), + &PolynomalActor::sensorEvent); } bool Item::removeActor(std::shared_ptr actor) @@ -234,50 +167,5 @@ bool Item::hasActors() void Item::setActorsActive(bool in) { - for(unsigned i = 0; i < actors_.size(); i++) - in ? actors_[i]->makeActive() : actors_[i]->makeInactive(); + for(unsigned i = 0; i < actors_.size(); i++) in ? actors_[i]->makeActive() : actors_[i]->makeInactive(); } - -void Item::mergeLoaded(Item& item) -{ - name_ = item.name_; - actors_.clear(); - for(std::shared_ptr actor : item.actors_) - addActor(actor); -} - -std::shared_ptr Item::loadItem(const QJsonObject& json) -{ - std::shared_ptr newItem = nullptr; - if(json["Type"].toString("") == "Relay") - { - newItem = std::shared_ptr(new Relay); - } - else if(json["Type"].toString("") == "Message") - { - newItem = std::shared_ptr(new MessageItem); - } - else if(json["Type"].toString("") == "System") - { - newItem = std::shared_ptr(new SystemItem); - } - else if(json["Type"].toString("") == "Aux") - { - newItem = std::shared_ptr(new AuxItem); - } - else if(json["Type"].toString("") == "Power") - { - newItem = std::shared_ptr(new PowerItem); - } - else if(json["Type"].toString("") == "Rgb") - { - newItem = std::shared_ptr(new RgbItem); - } - if(newItem) - { - newItem->load(json); - newItem->setLoaded(true); - } - return newItem; -} - diff --git a/src/items/item.h b/src/items/item.h index 1aaa090..18aa0cc 100644 --- a/src/items/item.h +++ b/src/items/item.h @@ -8,52 +8,31 @@ class Actor; -typedef enum { - ITEM_VALUE_BOOL = 0, - ITEM_VALUE_UINT, - ITEM_VALUE_NO_VALUE -} item_value_type_t; - class ItemData { protected: QString name_; uint8_t value_; uint32_t itemId_; - bool loaded_; - bool hidden_; - item_value_type_t type_; 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); + + ItemData(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Item", uint8_t value = 0); inline bool operator==(const ItemData& in) const { - return itemId_ == in.itemId_; + return itemId_==in.itemId_; } inline bool operator!=(const ItemData& in) const { - return itemId_ != in.itemId_; + return itemId_!=in.itemId_; } uint32_t id() const; - bool hasChanged(const ItemData& other); void setName(QString name); 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 void store(QJsonObject& json); - virtual void load(const QJsonObject& json, const bool preserve = false); }; @@ -65,15 +44,20 @@ private: bool override_ = false; +public: + + static bool secondaryFlag; + signals: + void valueChanged(uint8_t value); - void updated(ItemData data); private slots: virtual void actorSetValue(uint8_t value); public slots: - void setValue(uint8_t value); + + virtual void setValue(uint8_t value); public: @@ -92,15 +76,9 @@ public: void setOverride(const bool in); bool getOverride(); void informValue(uint8_t value); - void mergeLoaded(Item& item); virtual void store(QJsonObject& json); virtual void load(const QJsonObject& json, const bool preserve = false); - static std::shared_ptr loadItem(const QJsonObject& json); - -protected: - virtual void enactValue(uint8_t value); - }; diff --git a/src/items/itemloadersource.cpp b/src/items/itemloadersource.cpp deleted file mode 100644 index d5e6afa..0000000 --- a/src/items/itemloadersource.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "itemloadersource.h" - -#include - -ItemLoaderSource::ItemLoaderSource(const QJsonObject& json, QObject *parent): - ItemSource{parent}, - json(json) -{ -} - -void ItemLoaderSource::refresh() -{ - std::vector> 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 newItem = Item::loadItem(itemObject); - if(newItem) - { - items.push_back(newItem); - qDebug()<<"Loaded item"<getName(); - } - } - gotItems(items); -} - -void ItemLoaderSource::updateJson(const QJsonObject& json) -{ - this->json = json; -} - -ItemLoaderSource::~ItemLoaderSource() -{} - diff --git a/src/items/itemloadersource.h b/src/items/itemloadersource.h deleted file mode 100644 index c31c7fd..0000000 --- a/src/items/itemloadersource.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef ITEMLOADERSOURCE_H -#define ITEMLOADERSOURCE_H - -#include - -#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 diff --git a/src/items/itemsource.cpp b/src/items/itemsource.cpp deleted file mode 100644 index 1a223dc..0000000 --- a/src/items/itemsource.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "itemsource.h" - -ItemSource::ItemSource(QObject *parent) - : QObject{parent} -{} diff --git a/src/items/itemsource.h b/src/items/itemsource.h deleted file mode 100644 index 9fee9c1..0000000 --- a/src/items/itemsource.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef ITEMSOURCE_H -#define ITEMSOURCE_H - -#include -#include -#include - -#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> items, bool inform = true); - void requestReplaceItems(std::vector> items); - void updateItems(std::vector items, bool inform = true); -}; - -#endif // ITEMSOURCE_H diff --git a/src/items/itemstore.cpp b/src/items/itemstore.cpp index 1242afc..f3e4ab1 100644 --- a/src/items/itemstore.cpp +++ b/src/items/itemstore.cpp @@ -1,42 +1,52 @@ #include "itemstore.h" +#include "relay.h" +#include "messageitem.h" +#include "systemitem.h" #include -#include ItemStore::ItemStore(QObject *parent): QObject(parent) { } -void ItemStore::addItem(std::shared_ptr item, bool inform) +void ItemStore::addItem(std::shared_ptr item) { - std::shared_ptr matched = nullptr; - for(unsigned i = 0; i < items_.size(); i++ ) - { - if(*items_[i] == *item) - { - matched = items_[i]; - break; - } - } - if(!matched) + bool mached = false; + for(unsigned i = 0; i < items_.size(); i++ ) if(*items_[i] == *item) mached = true; + if(!mached) { items_.push_back(std::shared_ptr(item)); - connect(item.get(), &Item::updated, this, &ItemStore::itemUpdateSlot); - qDebug()<<"Item"<getName()<<"added"<<(item->getLoaded() ? "from loaded" : ""); itemAdded(std::weak_ptr(items_.back())); } - else - { - if(item->getLoaded()) - matched->mergeLoaded(*item); - else if(item->getValue() != matched->getValue()) - updateItem(*item, inform); - } } -void ItemStore::addItems(const std::vector>& itemIn, bool inform) +void ItemStore::addItems(const std::vector>& itemIn) { - for(unsigned j = 0; j < itemIn.size(); j++) - addItem(itemIn[j], inform); + for(unsigned i = 0; i < items_.size(); i++ ) + { + if(Relay* relay = dynamic_cast(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(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) @@ -45,26 +55,12 @@ void ItemStore::removeItem(const ItemData& item) { if(item == *items_[j]) { - qDebug()<<"Item"<>& items) -{ - addItems(items, true); - std::vector deletedItems; - for(std::shared_ptr item : items_) - { - if(std::find_if(items.begin(), items.end(), [item](const std::shared_ptr other){return *item == *other;}) == items.end()) - deletedItems.push_back(*item); - } - for(const ItemData& item : deletedItems) - removeItem(item); -} void ItemStore::clear() { @@ -73,33 +69,19 @@ void ItemStore::clear() } -void ItemStore::updateItems(std::vector 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++ ) { if(items_[i]->operator==(item)) { - if(items_[i]->hasChanged(item)) - { - 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"<getName()<<"updated"; - itemUpdated(items_[i]); - } + + if(items_[i]->getValue() != item.getValue())items_[i]->informValue(item.getValue()); } + } + } void ItemStore::store(QJsonObject& json) @@ -114,41 +96,35 @@ void ItemStore::store(QJsonObject& json) json["Items"] = itemsArray; } -void ItemStore::itemUpdateSlot(ItemData data) +void ItemStore::load(const QJsonObject& json) { - for(std::shared_ptr& item: items_) + const QJsonArray itemsArray(json["Items"].toArray(QJsonArray())); + for(int i = 0; i < itemsArray.size(); ++i) { - if(*item == data) - itemUpdated(std::weak_ptr(item)); + if(itemsArray[i].isObject()) + { + const QJsonObject itemObject = itemsArray[i].toObject(); + std::shared_ptr newItem; + if(itemObject["Type"].toString("") == "Relay") + { + newItem = std::shared_ptr(new Relay()); + } + else if(itemObject["Type"].toString("") == "Message") + { + newItem = std::shared_ptr(new MessageItem); + } + else if(itemObject["Type"].toString("") == "System") + { + newItem = std::shared_ptr(new SystemItem()); + } + else if(itemObject["Type"].toString("") == "Aux") + { + } + if(newItem) + { + newItem->load(itemObject); + addItem(newItem); + } + } } } - -std::shared_ptr ItemStore::getItem(uint32_t id) -{ - for(std::shared_ptr& item : items_) - { - if(item->id() == id) - return item; - } - return nullptr; -} - -void ItemStore::registerItemSource(ItemSource* source) -{ - qDebug()<<__func__<& item : items_) - itemDeleted(*item); - items_.clear(); - sigRefresh(); -} - -ItemStore globalItems; - diff --git a/src/items/itemstore.h b/src/items/itemstore.h index 830cc40..44d8fd6 100644 --- a/src/items/itemstore.h +++ b/src/items/itemstore.h @@ -2,7 +2,7 @@ #include #include #include "item.h" -#include "itemsource.h" +#include "../sensors/sensor.h" #include @@ -10,7 +10,7 @@ class ItemStore: public QObject { Q_OBJECT private: - std::vector > items_; + std::vector< std::shared_ptr > items_; public: @@ -22,10 +22,8 @@ public: return &items_; } - std::shared_ptr getItem(uint32_t id); - - void registerItemSource(ItemSource* source); void store(QJsonObject &json); + void load(const QJsonObject &json); void clear(); @@ -33,21 +31,11 @@ signals: void itemDeleted(ItemData item); void itemAdded(std::weak_ptr Item); - void itemUpdated(std::weak_ptr Item); - void sigRefresh(); public slots: void removeItem(const ItemData& item); - void addItem(std::shared_ptr item, bool inform = true); - void addItems(const std::vector>& itemsIn, bool inform = true); - void replaceItems(const std::vector>& items); - void updateItems(std::vector items, bool inform = true); - void updateItem(const ItemData& item, bool inform = true); - void refresh(); - -private slots: - void itemUpdateSlot(ItemData data); + void addItem(std::shared_ptr item); + void addItems(const std::vector>& itemsIn); + void itemStateChanged(const ItemData& item); }; - -extern ItemStore globalItems; diff --git a/src/items/messageitem.cpp b/src/items/messageitem.cpp index 151b934..0174586 100644 --- a/src/items/messageitem.cpp +++ b/src/items/messageitem.cpp @@ -1,19 +1,20 @@ #include "messageitem.h" #include -#include +#include + +BroadCast* MessageItem::broadCast = nullptr; MessageItem::MessageItem(uint32_t itemIdIn, QString name, uint8_t value, QObject *parent): Item(itemIdIn, name, value, parent) { - alertSound.setVolume(1.0); - type_ = ITEM_VALUE_NO_VALUE; + } MessageItem::MessageItem(const ItemData& itemData, QObject *parent): Item(itemData, parent) { - alertSound.setVolume(1.0); + } MessageItem::~MessageItem() @@ -21,12 +22,13 @@ MessageItem::~MessageItem() closeMessageBox(); } -void MessageItem::enactValue(uint8_t value) +void MessageItem::setValue(uint8_t value) { + Item::setValue(value); if(value && !messageBox_) { - if(!alertSoundFileName.isEmpty()) - alertSound.play(); + if(broadCast) broadCast->sendMessage(name_, message_); + if(!alertSoundFileName.isEmpty()) QSound::play(alertSoundFileName); messageBox_ = new QMessageBox(QMessageBox::NoIcon, name_, message_); messageBox_->setModal(false); connect(messageBox_, &QMessageBox::finished, this, &MessageItem::closeMessageBox); @@ -58,7 +60,6 @@ QString MessageItem::getAlert() void MessageItem::setAlert(const QString &in) { alertSoundFileName = in; - alertSound.setSource(QUrl::fromLocalFile(alertSoundFileName)); } void MessageItem::setMessage(const QString& in) @@ -76,8 +77,7 @@ void MessageItem::store(QJsonObject &json) json["Type"] = "Message"; Item::store(json); json["Message"] = message_; - if(!alertSoundFileName.isEmpty()) - json["Alert"] = alertSoundFileName; + if(!alertSoundFileName.isEmpty()) json["Alert"] = alertSoundFileName; } 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); message_ = json["Message"].toString("Invalid Message"); alertSoundFileName = json["Alert"].toString(""); - if(!alertSoundFileName.isEmpty()) - alertSound.setSource(QUrl::fromLocalFile(alertSoundFileName)); } diff --git a/src/items/messageitem.h b/src/items/messageitem.h index d23fb11..fadeda6 100644 --- a/src/items/messageitem.h +++ b/src/items/messageitem.h @@ -2,9 +2,9 @@ #define MESSAGEITEM_H #include -#include #include "item.h" +#include "../broadcast.h" class MessageItem : public Item { @@ -14,13 +14,17 @@ private: QString message_; QMessageBox* messageBox_ = nullptr; QString alertSoundFileName = ""; - QSoundEffect alertSound; + +public: + static BroadCast* broadCast; private slots: + void closeMessageBox(); -protected: - virtual void enactValue(uint8_t value) override; +public: + + virtual void setValue(uint8_t value); public: @@ -34,8 +38,8 @@ public: void setAlert(const QString& in); QString getAlert(); - virtual void store(QJsonObject& json) override; - virtual void load(const QJsonObject& json, const bool preserve = false) override; + virtual void store(QJsonObject& json); + virtual void load(const QJsonObject& json, const bool preserve = false); }; #endif // MESSAGEITEM_H diff --git a/src/items/poweritem.cpp b/src/items/poweritem.cpp index 2b2e4e1..998e6d2 100644 --- a/src/items/poweritem.cpp +++ b/src/items/poweritem.cpp @@ -3,20 +3,19 @@ #include #include -PowerItem::PowerItem(uint32_t itemIdIn, QString name, uint8_t value, QObject* parent): - Item(itemIdIn, name, value, parent) +PowerItem::PowerItem(uint32_t itemIdIn, QString name, uint8_t value, QObject* parent): Item(itemIdIn, name, value, + parent) { stateChanged(Sensor(Sensor::TYPE_SHUTDOWN_IMMINENT, 0, 0, "Shutdown Imminent", true)); - PowerItem::setValue(true); - hidden_ = true; - type_ = ITEM_VALUE_NO_VALUE; + setValue(true); } -void PowerItem::enactValue(uint8_t value) +void PowerItem::setValue(uint8_t value) { + qDebug()<<"shutdown"; + Item::setValue(value); if(!value) { - qDebug()<<"shutdown"; QTimer::singleShot(5000, this, &PowerItem::timeout); stateChanged(Sensor(Sensor::TYPE_SHUTDOWN_IMMINENT, 0, 1, "Shutdown Imminent", true)); } diff --git a/src/items/poweritem.h b/src/items/poweritem.h index d6a610f..dd13629 100644 --- a/src/items/poweritem.h +++ b/src/items/poweritem.h @@ -1,8 +1,8 @@ #pragma once #include "item.h" -#include "sensors/sensor.h" -#include "microcontroller.h" +#include "../sensors/sensor.h" +#include "../microcontroller.h" #include @@ -16,17 +16,19 @@ signals: void stateChanged(Sensor sensor); private slots: + void timeout(); -protected: - virtual void enactValue(uint8_t value) override; +public slots: + + virtual void setValue(uint8_t value); 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); void emmitSensor() { stateChanged(Sensor(Sensor::TYPE_SHUTDOWN_IMMINENT, 0, 0, "Shutdown Imminent", true)); } - virtual void store(QJsonObject& json) override; + virtual void store(QJsonObject& json); }; diff --git a/src/items/relay.cpp b/src/items/relay.cpp index f801e1b..67197e0 100644 --- a/src/items/relay.cpp +++ b/src/items/relay.cpp @@ -9,17 +9,16 @@ Relay::Relay(uint8_t id, QString name, uint16_t address, bool state, QObject* pa id_(id), address_(address) { itemId_ = address | ((uint32_t)id << 16); + qDebug()<<"Relay "<relayOn(id_); - else - micro_->relayOff(id_); + if(value)micro_->relayOn(id_); + else micro_->relayOff(id_); } } diff --git a/src/items/relay.h b/src/items/relay.h index 3c3c4b4..0ba4849 100644 --- a/src/items/relay.h +++ b/src/items/relay.h @@ -4,7 +4,7 @@ #include #include -#include "sensors/sensor.h" +#include "../sensors/sensor.h" #include "item.h" class Microcontroller; @@ -18,10 +18,9 @@ private: uint8_t id_; uint16_t address_; -protected: - virtual void enactValue(uint8_t value) override; - public slots: + + virtual void setValue(uint8_t value); void on(); void off(); void toggle(); @@ -38,7 +37,7 @@ public: micro_ = micro; } - virtual void store(QJsonObject& json) override; - virtual void load(const QJsonObject& json, const bool preserve = false) override; + virtual void store(QJsonObject& json); + virtual void load(const QJsonObject& json, const bool preserve = false); }; #endif // RELAY_H diff --git a/src/items/rgbitem.cpp b/src/items/rgbitem.cpp index 6df7c33..46bc80d 100644 --- a/src/items/rgbitem.cpp +++ b/src/items/rgbitem.cpp @@ -6,9 +6,9 @@ RgbItem::RgbItem(Microcontroller* micro, uint32_t itemIdIn, QString name, uint8 } -void RgbItem::enactValue(uint8_t value) +void RgbItem::setValue(uint8_t value) { - assert(micro_); + Item::setValue(value); value ? micro_->rgbOn() : micro_->rgbOff(); } diff --git a/src/items/rgbitem.h b/src/items/rgbitem.h index db721b9..9aff188 100644 --- a/src/items/rgbitem.h +++ b/src/items/rgbitem.h @@ -1,6 +1,6 @@ #pragma once -#include "microcontroller.h" +#include "../microcontroller.h" #include "item.h" class RgbItem: public Item @@ -9,12 +9,13 @@ class RgbItem: public Item private: Microcontroller* micro_; -protected: - virtual void enactValue(uint8_t value) override; +public slots: + + virtual void setValue(uint8_t value); 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); - virtual void store(QJsonObject& json) override; + virtual void store(QJsonObject& json); }; diff --git a/src/items/systemitem.cpp b/src/items/systemitem.cpp index 7887ce5..c11ee29 100644 --- a/src/items/systemitem.cpp +++ b/src/items/systemitem.cpp @@ -1,7 +1,7 @@ #include "systemitem.h" #include -void SystemItem::enactValue(uint8_t value) +void SystemItem::setValue(uint8_t value) { QProcess::execute(value ? onCommand_ : offCommand_); } diff --git a/src/items/systemitem.h b/src/items/systemitem.h index 392e914..9fe7a11 100644 --- a/src/items/systemitem.h +++ b/src/items/systemitem.h @@ -1,19 +1,23 @@ #ifndef SYSTEMITEM_H #define SYSTEMITEM_H + #include "item.h" class SystemItem : public Item { Q_OBJECT private: + QString onCommand_; QString offCommand_; -protected: - virtual void enactValue(uint8_t value) override; +public: + + virtual void setValue(uint8_t value); public: + SystemItem(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Item", uint8_t value = 0, QObject *parent = nullptr); SystemItem(const ItemData& itemData, QObject *parent = nullptr); @@ -30,8 +34,8 @@ public: return offCommand_; } - virtual void store(QJsonObject& json) override; - virtual void load(const QJsonObject& json, const bool preserve = false) override; + virtual void store(QJsonObject& json); + virtual void load(const QJsonObject& json, const bool preserve = false); }; #endif // SYSTEMITEM_H diff --git a/src/main.cpp b/src/main.cpp index 8e5ca4c..529202d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,16 +1,26 @@ #include +#include #include #include #include -#include + +//Currently pipewire support is disabled +//#include + + +#ifndef Q_OS_ANDROID #include #include #include +#endif +#include "microcontroller.h" #include "ui/mainwindow.h" #include "items/itemstore.h" #include "mainobject.h" -#include "programmode.h" + + +#define BAUD QSerialPort::Baud38400 int main(int argc, char *argv[]) { @@ -27,113 +37,102 @@ int main(int argc, char *argv[]) QDir::setCurrent(a.applicationDirPath()); //parse comand line +#ifndef Q_OS_ANDROID QCommandLineParser parser; parser.setApplicationDescription("Smart Home Interface"); parser.addHelpOption(); parser.addVersionOption(); - QCommandLineOption masterOption(QStringList() << "m" << "master", QCoreApplication::translate("main", "Use in master mode")); - parser.addOption(masterOption); - QCommandLineOption hostOption(QStringList() << "H" << "host", QCoreApplication::translate("main", "Set server host ip addres"), "address", "0.0.0.0"); + QCommandLineOption tcpOption(QStringList() << "t" << "tcp", QCoreApplication::translate("main", "Use Tcp connection")); + parser.addOption(tcpOption); + QCommandLineOption hostOption(QStringList() << "H" << "host", QCoreApplication::translate("main", + "Set server host ip addres"), "adress"); 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); - QCommandLineOption settingsPathOption(QStringList()<<"c"<<"config", QCoreApplication::translate("main", "Set config file"), "configFilePath", - QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/shinterface.json"); + QCommandLineOption serialOption(QStringList() << "s" << "serial", QCoreApplication::translate("main", + "Use serial connection")); + 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); - QCommandLineOption headlessOption(QStringList()<<"e"<<"headless", QCoreApplication::translate("main", "Dont start the gui")); - parser.addOption(headlessOption); + QCommandLineOption secondaryOption(QStringList() << "e" << "secondary", QCoreApplication::translate("main", + "Set if instance is not main instance")); + parser.addOption(secondaryOption); parser.process(a); +#endif - int retVal; + QIODevice* masterIODevice = nullptr; - programMode = PROGRAM_MODE_UI_ONLY; - if(parser.isSet(masterOption)) +#ifndef Q_OS_ANDROID + 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; + QTcpSocket* microSocket = new QTcpSocket; - QIODevice* microDevice = nullptr; - if(tcpMicro) + int port = 6856; + 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 "<connectToHost(host, port, QIODevice::ReadWrite); + if(!microSocket->waitForConnected(1000)) { - 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; - - qInfo()<<"connecting to "<connectToHost(host, port, QIODevice::ReadWrite); - - if(!microSocket->waitForConnected(1000)) - { - qCritical()<<"Can not connect to tcp micro"; - MainObject::storeJsonObjectToDisk(settingsPath, json); - if(programMode == PROGRAM_MODE_PRIMARY) - QMessageBox::critical(nullptr, "Error", "Can not connect to tcp micro"); - return 1; - } - microDevice = microSocket; + std::cout<<"Can not connect to to Server.\n"; + QMessageBox::critical(nullptr, "Error", "Can not connect to to Server"); + return 1; } - else - { - QString port = json["MicroSerialPort"].toString("ttyUSB0"); - json["MicroSerialPort"] = port; - int baud = json["MicroSerialBaud"].toInt(38400); - json["MicroSerialBaud"] = baud; - - QSerialPort *microPort = new QSerialPort; - microPort->setPortName(port); - microPort->setBaudRate(baud); - microPort->open(QIODevice::ReadWrite); - - if(!microPort->isOpen()) - { - qCritical()<<"Can not open serial port"< item){globalItems.addItem(item, false);}); - w->show(); - } - retVal = a.exec(); - - delete w; - delete microDevice; + masterIODevice = microSocket; } else { - SecondaryMainObject mainObject(parser.value(hostOption), parser.value(portOption).toInt()); - MainWindow w(&mainObject); - QObject::connect(&w, &MainWindow::createdItem, &globalItems, [](std::shared_ptr item){globalItems.addItem(item, false);}); - QObject::connect(&w, &MainWindow::sigSave, mainObject.tcpClient, &TcpClient::sendItems); - w.show(); + QSerialPort* microPort = new QSerialPort; + if(parser.isSet(portOption)) microPort->setPortName(parser.value(portOption)); + else microPort->setPortName("ttyUSB0"); - retVal = a.exec(); + if(parser.isSet(portOption)) microPort->setBaudRate(parser.value(baudOption).toInt()); + else microPort->setBaudRate(BAUD); + + if(!microPort->open(QIODevice::ReadWrite)) std::cout<<"Can not open serial port "<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)) + { + std::cout<<"Can not connect to to Server.\n"; + return 1; + } + masterIODevice = microSocket; + + MainObject mainObject(masterIODevice, parser.isSet(settingsPathOption) ? parser.value(settingsPathOption) : "", + !parser.isSet(secondaryOption)); +#endif + + + //mainwindow + MainWindow w(&mainObject); + QObject::connect(&mainObject.micro, SIGNAL(textRecived(QString)), &w, SLOT(changeHeaderLableText(QString))); + 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(); + + int retVal = a.exec(); + + if(masterIODevice) + delete masterIODevice; return retVal; } diff --git a/src/mainobject.cpp b/src/mainobject.cpp index 0f41d19..d474d87 100644 --- a/src/mainobject.cpp +++ b/src/mainobject.cpp @@ -1,35 +1,139 @@ #include "mainobject.h" +#include "items/messageitem.h" -#include -#include -#include +MainObject::MainObject(QIODevice* ioDevice, const QString& settingsPathIn, const bool masterIn, QObject *parent) : + QObject(parent), + 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(µ, 5487422, "Rgb Lights")), + auxItem(new AuxItem(µ, 5487421, "Desk Light")) -#include "items/itemstore.h" - -MainObject::MainObject(QObject *parent) : - QObject(parent) { + qDebug()<<"Is master:"<emmitSensor(); + items.addItem(rgbItem); + items.addItem(auxItem); + MessageItem::broadCast = &broadCast; + + Relay::setMicrocontroller(µ); + + 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() { } -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: "<= 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; - file.setFileName(filename); - bool ret = file.open(QIODevice::ReadOnly); - if(!file.isOpen() || !ret) +#ifndef Q_OS_ANDROID + if(filePath.size() > 0) file.setFileName(filePath); + else +#endif { - std::cerr<<"Can not open config file: "<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() -{ -} - diff --git a/src/mainobject.h b/src/mainobject.h index 79f5ed2..cfa5fff 100644 --- a/src/mainobject.h +++ b/src/mainobject.h @@ -2,6 +2,7 @@ #define MAINOBJECT_H #include +#include #include #include #include @@ -11,65 +12,80 @@ #include #include + +#ifndef Q_OS_ANDROID +#include +#include +#include +#endif + +#include "actors/alarmtime.h" #include "microcontroller.h" #include "ui/mainwindow.h" +#include "sensors/speakersensor.h" #include "sensors/sunsensor.h" -#include "sensors/mqttsensorsource.h" -#include "items/fixeditemsource.h" -#include "items/itemloadersource.h" -#include "tcpserver.h" +#include "sensors/ocupancysensor.h" +#include "sensors/sensor.h" +#include "items/itemstore.h" +#include "items/auxitem.h" +#include "items/rgbitem.h" +#include "items/poweritem.h" +#include "iomuliplexer.h" +#include "broadcast.h" +//#include "pipewire.h" 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 public: - QString settingsPath; - QJsonObject settings; + //io + const bool master; + + bool noSave = false; + + QIODevice * const masterIODevice = nullptr; + IoMuliplexer ioMultiplexer; Microcontroller micro; - TcpServer* tcpServer; + BroadCast broadCast; + + + const QString settingsPath; //sensors - SunSensorSource sunSensorSource; - MqttSensorSource mqttSensorSource; + SunSensorSource sunSensorSource; + OcupancySensorSource ocupancySensor; - //item sources - FixedItemSource fixedItems; - ItemLoaderSource itemLoader; + //items + ItemStore items; + + std::shared_ptr powerItem; + std::shared_ptr rgbItem; + std::shared_ptr auxItem; + + //PipeWireHandler pwHandler; + +private: + + static QJsonObject getJsonObjectFromDisk(const QString& filePath = "", bool* error = nullptr); + static bool storeJsonObjectToDisk(const QJsonObject& json, QString filePath = ""); public: - explicit PrimaryMainObject(QIODevice* microDevice, const QString& settingsPath, const QString& host, int port, QObject *parent = nullptr); - ~PrimaryMainObject(); + explicit MainObject(QIODevice* ioDevice, const QString& settingsPathIn, const bool masterIn, QObject *parent = nullptr); + ~MainObject(); + void store(QJsonObject& json); + void load(const QJsonObject& json); - bool storeToDisk(const QString& filename); - bool loadFromDisk(const QString& filename); -}; -class SecondaryMainObject : public MainObject -{ - Q_OBJECT -public: - TcpClient* tcpClient; +signals: -public: - explicit SecondaryMainObject(QString host, int port, QObject *parent = nullptr); - ~SecondaryMainObject(); +public slots: + + void storeToDisk(); + void sendJson(); + void recivedJson(const QJsonObject json); }; diff --git a/src/microcontroller.cpp b/src/microcontroller.cpp index 4833461..ba5f54b 100644 --- a/src/microcontroller.cpp +++ b/src/microcontroller.cpp @@ -3,6 +3,8 @@ #include #include +static constexpr bool debug = true; + void Microcontroller::relayToggle(int state, int relay) { char buffer[8]; @@ -38,6 +40,7 @@ void Microcontroller::changeRgbColor(const QColor color) char buffer[64]; int length = sprintf(buffer, "rgb set %03d %03d %03d\n", color.red(), color.green(), color.blue()); write(buffer, length); + std::cout<write(buffer); @@ -59,6 +65,9 @@ void Microcontroller::write(const QByteArray& buffer) void Microcontroller::write(char* buffer, const size_t length) { +#ifndef Q_OS_ANDROID + if constexpr(debug) std::cerr<write(buffer, length); @@ -86,7 +95,7 @@ bool Microcontroller::connected() else return false; } -void Microcontroller::refresh() +void Microcontroller::requestState() { write("state\n"); } @@ -142,7 +151,8 @@ void Microcontroller::processList(const QString& buffer) else if(buffer.contains("EOL")) { listMode = false; - gotItems(relayList); + qDebug()<<"got relay list " << relayList.size(); + gotRelayList(relayList); relayList.clear(); } else listMode = false; @@ -150,23 +160,19 @@ void Microcontroller::processList(const QString& buffer) void Microcontroller::processRelayState(const QString& buffer) { - updateItems({static_cast(*processRelayLine(buffer))}); + itemChanged(static_cast(*processRelayLine(buffer))); } void Microcontroller::processSensorState(const QString& buffer) { Sensor sensor = Sensor::sensorFromString(buffer); - if(sensor.type != Sensor::TYPE_DUMMY) - gotSensorState(sensor); + if(sensor.type != Sensor::TYPE_DUMMY) gotSensorState(sensor); } void Microcontroller::processMicroReturn() { - if(listMode) - { - processList(_buffer); - } + if(listMode) processList(_buffer); else { if(_buffer.startsWith("Items:")) @@ -174,14 +180,8 @@ void Microcontroller::processMicroReturn() listMode = true; relayList.clear(); } - else if(_buffer.startsWith("ITEM NUMBER:")) - { - processRelayState(_buffer); - } - else if(_buffer.startsWith("SENSOR")) - { - processSensorState(_buffer); - } + else if(_buffer.startsWith("ITEM NUMBER:"))processRelayState(_buffer); + else if(_buffer.startsWith("SENSOR")) processSensorState(_buffer); } } @@ -192,7 +192,7 @@ void Microcontroller::isReadyRead() while(_port->getChar(&charBuf)) { _buffer.push_back(charBuf); - if(_buffer.endsWith('\n') ) + if( _buffer.endsWith('\n') ) { _buffer.remove('\n'); processMicroReturn(); diff --git a/src/microcontroller.h b/src/microcontroller.h index 1845dc0..8392491 100644 --- a/src/microcontroller.h +++ b/src/microcontroller.h @@ -1,6 +1,8 @@ #ifndef MICROCONTROLLER_H #define MICROCONTROLLER_H +#include + #include #include #include @@ -15,9 +17,8 @@ #include "items/item.h" #include "items/relay.h" #include "sensors/sensor.h" -#include "items/itemsource.h" -class Microcontroller : public ItemSource +class Microcontroller : public QObject { Q_OBJECT @@ -64,7 +65,7 @@ public slots: void setPattern(int pattern); void startSunrise(); - void refresh() override; + void requestState(); void setAuxPwm(int duty); @@ -78,6 +79,10 @@ private slots: signals: void textRecived(const QString string); + void itemChanged(ItemData relay); + void auxStateChanged(int value); + void gotRelayList(std::vector< std::shared_ptr >&); + void gotSensorState(Sensor sensor); }; diff --git a/src/programmode.cpp b/src/programmode.cpp deleted file mode 100644 index d37ba81..0000000 --- a/src/programmode.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "programmode.h" - -program_mode_t programMode = PROGRAM_MODE_PRIMARY; diff --git a/src/programmode.h b/src/programmode.h deleted file mode 100644 index ccbb900..0000000 --- a/src/programmode.h +++ /dev/null @@ -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 diff --git a/src/sensors/mqttsensorsource.cpp b/src/sensors/mqttsensorsource.cpp deleted file mode 100644 index 4202ab8..0000000 --- a/src/sensors/mqttsensorsource.cpp +++ /dev/null @@ -1,187 +0,0 @@ -#include "mqttsensorsource.h" - -#include - -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:"< -#include -#include -#include - -#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 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 diff --git a/src/sensors/ocupancysensor.cpp b/src/sensors/ocupancysensor.cpp new file mode 100644 index 0000000..3bf7b7c --- /dev/null +++ b/src/sensors/ocupancysensor.cpp @@ -0,0 +1,62 @@ +#include "ocupancysensor.h" +#include +#include + +#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 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 "< +#include +#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); +}; diff --git a/src/sensors/pipewiresensor.cpp b/src/sensors/pipewiresensor.cpp new file mode 100644 index 0000000..89ee7e4 --- /dev/null +++ b/src/sensors/pipewiresensor.cpp @@ -0,0 +1,74 @@ +#include "pipewiresensor.h" +#include + +static const struct pw_node_events node_events = { + .version = PW_VERSION_NODE_EVENTS, + .info = &PipeWireSensorSource::nodeEventHandler, + .param = nullptr +}; + +PipeWireSensorSource::PipeWireSensorSource(PipeWireHandler* handler, const std::string& nodeName, uint8_t id, QObject *parent) + : QObject{parent}, handler_(handler), nodeName_(nodeName), id_(id) +{ + connect(handler_, &PipeWireHandler::nodeAdded, this, &PipeWireSensorSource::nodeAdded); + connect(&timer, &QTimer::timeout, this, &PipeWireSensorSource::offTimeout); + timer.setSingleShot(true); +} + +void PipeWireSensorSource::offTimeout() +{ + if(state == false) + return; + state = false; + stateChanged(Sensor(Sensor::TYPE_AUDIO_OUTPUT, id_, state)); +} + +void PipeWireSensorSource::nodeEventHandler(void* data, const struct pw_node_info *info) +{ + PipeWireSensorSource* source = static_cast(data); + + if(info->state == source->prevState) + return; + + source->prevState = info->state; + + switch (info->state) + { + case PW_NODE_STATE_ERROR: + case PW_NODE_STATE_CREATING: + source->state = false; + source->stateChanged(Sensor(Sensor::TYPE_AUDIO_OUTPUT, source->id_, 0)); + break; + case PW_NODE_STATE_SUSPENDED: + case PW_NODE_STATE_IDLE: + if(source->state == true) + source->timer.start(10000); + break; + case PW_NODE_STATE_RUNNING: + if(source->state == false) + { + source->state = true; + source->stateChanged(Sensor(Sensor::TYPE_AUDIO_OUTPUT, source->id_, source->state)); + } + break; + default: + break; + } +} + +void PipeWireSensorSource::nodeAdded(PipeWireHandler::PwNode node) +{ + if(node.name == nodeName_) + { + + sinkNode = static_cast(pw_registry_bind(handler_->getRegistry(), node.id, PW_TYPE_INTERFACE_Node, PW_VERSION_CLIENT, 0)); + if(sinkNode) + { + qDebug()<<"Failed to register to required pipewire node"< +#include +#include +#include +#include + +#include "sensor.h" +#include "../pipewire.h" + +class PipeWireSensorSource : public QObject +{ + Q_OBJECT + + PipeWireHandler* handler_; + std::string nodeName_; + struct pw_node* sinkNode = nullptr; + struct spa_hook sinkListener; + pw_node_state prevState = PW_NODE_STATE_SUSPENDED; + QTimer timer; + uint8_t id_; + bool state = false; + +private slots: + void offTimeout(); + +public: + explicit PipeWireSensorSource(PipeWireHandler* handler, const std::string& nodeName, uint8_t id, QObject *parent = nullptr); + static void nodeEventHandler(void* data, const struct pw_node_info *info); + +signals: + void stateChanged(Sensor sensor); + +private slots: + void nodeAdded(PipeWireHandler::PwNode node); +}; + +#endif // PIPEWIRESENSOR_H diff --git a/src/sensors/sensor.h b/src/sensors/sensor.h index bc5e748..e64498e 100644 --- a/src/sensors/sensor.h +++ b/src/sensors/sensor.h @@ -4,7 +4,6 @@ #include #include #include -#include class Sensor { @@ -17,10 +16,6 @@ public: static constexpr uint8_t TYPE_BRIGHTNESS = 4; static constexpr uint8_t TYPE_BUTTON = 5; 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_SHUTDOWN_IMMINENT = 251; static constexpr uint8_t TYPE_OCUPANCY = 252; @@ -29,13 +24,13 @@ public: static constexpr uint8_t TYPE_DUMMY = 255; uint8_t type; - uint64_t id; + uint8_t id; float field; QString name; QDateTime lastSeen; 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) { lastSeen = QDateTime::currentDateTime(); @@ -46,15 +41,6 @@ public: { lastSeen = QDateTime::currentDateTime(); } - Sensor(const QJsonObject& json) - { - type = json["SensorType"].toInt(0); - 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; @@ -91,32 +77,15 @@ public: 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(type); - json["Id"] = static_cast(id); - json["Field"] = field; - json["Name"] = name; - json["LastSeen"] = lastSeen.toString(); - json["Hidden"] = hidden; - } inline void generateName() { - if(type == TYPE_TEMPERATURE) - name = "Temperature " + QString::number(id); - else if(type == TYPE_DOOR) - name = "Door " + QString::number(id); - else if(type == TYPE_BUTTON) - name = "Button " + QString::number(id); - else if(type == TYPE_AUDIO_OUTPUT) - 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"; + if(type == TYPE_TEMPERATURE) name = "Temperature " + QString::number(id); + else if(type == TYPE_DOOR) name = "Door " + QString::number(id); + else if(type == TYPE_BUTTON) name = "Button " + QString::number(id); + else if(type == TYPE_AUDIO_OUTPUT) 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); } }; diff --git a/src/sensors/speakersensor.cpp b/src/sensors/speakersensor.cpp new file mode 100644 index 0000000..e2a4171 --- /dev/null +++ b/src/sensors/speakersensor.cpp @@ -0,0 +1,59 @@ +#include "speakersensor.h" + +#include + +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++; + } +} diff --git a/src/sensors/speakersensor.h b/src/sensors/speakersensor.h new file mode 100644 index 0000000..8479ff2 --- /dev/null +++ b/src/sensors/speakersensor.h @@ -0,0 +1,45 @@ +#ifndef AMPMANAGER_H +#define AMPMANAGER_H + +#include + +#include +#include +#include +#include +#include +#include +#include + +#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 diff --git a/src/sensors/sunsensor.h b/src/sensors/sunsensor.h index 65d84c3..bfbce04 100644 --- a/src/sensors/sunsensor.h +++ b/src/sensors/sunsensor.h @@ -2,7 +2,7 @@ #include -#include "sun.h" +#include "../sun.h" #include "sensor.h" diff --git a/src/tcpserver.cpp b/src/tcpserver.cpp deleted file mode 100644 index f49150f..0000000 --- a/src/tcpserver.cpp +++ /dev/null @@ -1,342 +0,0 @@ -#include -#include -#include -#include - -#include "items/item.h" -#include "items/itemstore.h" -#include "tcpserver.h" - - -TcpService::TcpService(QObject* parent): - ItemSource(parent) -{} - -QJsonObject TcpService::createMessage(const QString& type, const QJsonArray& data) -{ - QJsonObject json; - json["MessageType"] = type; - json["Data"] = data; - return json; -} - -void TcpService::sensorEvent(Sensor sensor) -{ - QJsonArray sensors; - QJsonObject sensorjson; - sensor.store(sensorjson); - sensors.append(sensorjson); - QJsonObject json = createMessage("SensorUpdate", sensors); - sendJson(json); -} - -void TcpService::itemUpdated(std::weak_ptr 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 TcpService::refresh() -{ - sendJson(createMessage("GetSensors", QJsonArray())); - sendJson(createMessage("GetItems", QJsonArray())); -} - -void TcpService::sendSensors() -{ - QJsonArray sensors; - for(auto& sensor: *globalSensors.getSensors()) - { - QJsonObject sensorjson; - sensor.store(sensorjson); - sensors.append(sensorjson); - } - sendJson(createMessage("SensorUpdate", sensors)); -} - -void TcpService::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 TcpService::processIncomeingJson(const QByteArray& jsonbytes) -{ - QJsonDocument doc = QJsonDocument::fromJson(jsonbytes); - qDebug()<<"Got Json:"<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"<> items; - for(QJsonValueRef itemjson : data) - { - QJsonObject jsonobject = itemjson.toObject(); - std::shared_ptr item = Item::loadItem(jsonobject); - if(item) - { - item->setLoaded(false); - items.push_back(item); - } - } - if(!items.empty()) - gotItems(items, true); - } - else - { - TcpService::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; -} - -TcpServer::TcpServer(QObject* parent): - TcpService(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> items; - for(QJsonValueRef itemjson : data) - { - QJsonObject jsonobject = itemjson.toObject(); - std::shared_ptr 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 - { - TcpService::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"<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:"<readAll(); - clients[i].buffer += newChars; - - bool remianing = true; - while(remianing) - { - qDebug()< -#include - -#include "sensors/sensor.h" -#include "items/item.h" -#include "items/itemsource.h" - -class TcpService : 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); - virtual void refresh() override; - -public: - TcpService(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); -}; - -class TcpClient : public TcpService -{ - 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); -}; - -class TcpServer : public TcpService -{ - Q_OBJECT - - struct Client - { - QTcpSocket* socket; - QByteArray buffer; - client_state_t state = STATE_IDLE; - long long recievebytes = 0; - }; - - std::vector 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_H diff --git a/src/ui/actorwidgets/alarmwidget.ui b/src/ui/actorwidgets/alarmwidget.ui index 3b99187..1b29275 100644 --- a/src/ui/actorwidgets/alarmwidget.ui +++ b/src/ui/actorwidgets/alarmwidget.ui @@ -24,16 +24,16 @@ - QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow + QFormLayout::AllNonFixedFieldsGrow - QFormLayout::RowWrapPolicy::DontWrapRows + QFormLayout::DontWrapRows - Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 50 @@ -57,7 +57,7 @@ false - QDateTimeEdit::Section::DaySection + QDateTimeEdit::DaySection dd.MM.yyyy hh:mm diff --git a/src/ui/actorwidgets/polynomalactorwidget.ui b/src/ui/actorwidgets/polynomalactorwidget.ui index 39bf709..e1733df 100644 --- a/src/ui/actorwidgets/polynomalactorwidget.ui +++ b/src/ui/actorwidgets/polynomalactorwidget.ui @@ -132,7 +132,7 @@ SensorListWidget QListView -
ui/sensorlistwidget.h
+
../src/ui/sensorlistwidget.h
diff --git a/src/ui/actorwidgets/regulatorwdiget.ui b/src/ui/actorwidgets/regulatorwdiget.ui index ee79da6..a6784a3 100644 --- a/src/ui/actorwidgets/regulatorwdiget.ui +++ b/src/ui/actorwidgets/regulatorwdiget.ui @@ -110,7 +110,7 @@ SensorListWidget QListView -
ui/sensorlistwidget.h
+
../src/ui/sensorlistwidget.h
diff --git a/src/ui/actorwidgets/sensoractorwidget.ui b/src/ui/actorwidgets/sensoractorwidget.ui index 5f49c96..8e9d967 100644 --- a/src/ui/actorwidgets/sensoractorwidget.ui +++ b/src/ui/actorwidgets/sensoractorwidget.ui @@ -89,7 +89,7 @@ SensorListWidget QListView -
ui/sensorlistwidget.h
+
../src/ui/sensorlistwidget.h
diff --git a/src/ui/itemscrollbox.cpp b/src/ui/itemscrollbox.cpp index 170a557..6a7e6b4 100644 --- a/src/ui/itemscrollbox.cpp +++ b/src/ui/itemscrollbox.cpp @@ -21,9 +21,18 @@ void ItemScrollBox::addItem(std::weak_ptr item) { if(auto workItem = item.lock()) { - if(workItem->isHidden()) - return; - widgets_.push_back(new ItemWidget(item)); + if(dynamic_cast(workItem.get())) + { + widgets_.push_back(new ItemWidget(item, true)); + } + else if(dynamic_cast(workItem.get())) + { + widgets_.push_back(new ItemWidget(item, false, true)); + } + else + { + widgets_.push_back(new ItemWidget(item)); + } ui->relayWidgetVbox->addWidget(widgets_.back()); connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest); connect(widgets_.back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::removeItem); diff --git a/src/ui/itemsettingsdialog.cpp b/src/ui/itemsettingsdialog.cpp index 08417d3..1bf371c 100644 --- a/src/ui/itemsettingsdialog.cpp +++ b/src/ui/itemsettingsdialog.cpp @@ -8,9 +8,9 @@ #include "../actors/factoractor.h" #include "../items/messageitem.h" #include "../items/systemitem.h" -#include "itemsettingswidgets/messageitemsettingswidget.h" -#include "itemsettingswidgets/systemitemsettingswidget.h" -#include "itemsettingswidgets/relayitemsettingswidget.h" +#include "./itemsettingswidgets/messageitemsettingswidget.h" +#include "./itemsettingswidgets/systemitemsettingswidget.h" +#include "./itemsettingswidgets/relayitemsettingswidget.h" #include ItemSettingsDialog::ItemSettingsDialog(std::shared_ptr item, QWidget *parent) : @@ -177,7 +177,7 @@ void ItemSettingsDialog::editActor() dialog->show(); dialog->exec(); - for(int i = 0; i < ui->tableWidget->rowCount() && i < static_cast(item_->getActors().size()); ++i) + for(int i = 0; i < ui->tableWidget->rowCount() && i < static_cast(item_->getActors().size()); ++i) { ui->tableWidget->item(i, 0)->setText(item_->getActors()[i]->getName()); ui->tableWidget->item(i, 1)->setText(item_->getActors()[i]->actionName()); diff --git a/src/ui/itemwidget.cpp b/src/ui/itemwidget.cpp index d073e50..c1f681d 100644 --- a/src/ui/itemwidget.cpp +++ b/src/ui/itemwidget.cpp @@ -5,47 +5,39 @@ #include #include -ItemWidget::ItemWidget(std::weak_ptr item, QWidget *parent) : +ItemWidget::ItemWidget(std::weak_ptr item, bool analog, bool nameOnly, QWidget *parent) : QWidget(parent), item_(item), ui(new Ui::ItemWidget) { ui->setupUi(this); - if(auto workingItem = item_.lock()) + if(analog) { - if(workingItem->getValueType() == ITEM_VALUE_UINT) - { - ui->horizontalSpacer->changeSize(0,0); - ui->checkBox->hide(); - } - else if(workingItem->getValueType() == ITEM_VALUE_NO_VALUE) - { - ui->checkBox->hide(); - ui->slider->hide(); - } - else - { - ui->slider->hide(); - } + ui->horizontalSpacer->changeSize(0,0); + ui->checkBox->hide(); + } + else if(nameOnly) + { + ui->checkBox->hide(); + ui->slider->hide(); + } + else ui->slider->hide(); - ui->checkBox->setChecked(workingItem->getValue()); + if(auto workingRelay = item_.lock()) + { + ui->checkBox->setChecked(workingRelay->getValue()); - ui->label->setText(workingItem->getName()); + ui->label->setText(workingRelay->getName()); - if(workingItem->getValueType() == ITEM_VALUE_UINT) - connect(ui->slider, &QSlider::valueChanged, this, &ItemWidget::moveToValue); - else - connect(ui->checkBox, &QCheckBox::toggled, this, &ItemWidget::moveToState); + if(analog)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(workingItem.get(), &Relay::valueChanged, this, &ItemWidget::stateChanged); + connect(workingRelay.get(), &Relay::valueChanged, this, &ItemWidget::stateChanged); connect(ui->pushButton_Remove, &QPushButton::clicked, this, &ItemWidget::deleteItem); } - else - { - disable(); - } + else disable(); } void ItemWidget::deleteItem() @@ -58,18 +50,14 @@ void ItemWidget::deleteItem() void ItemWidget::moveToValue(int value) { - if(auto workingItem = item_.lock()) - workingItem->setValue(value); - else - disable(); + if(auto workingItem = item_.lock()) workingItem->setValue(value); + else disable(); } void ItemWidget::moveToState(bool state) { - if(auto workingItem = item_.lock()) - workingItem->setValue(state); - else - disable(); + if(auto workingItem = item_.lock()) workingItem->setValue(state); + else disable(); } void ItemWidget::disable() @@ -82,9 +70,9 @@ void ItemWidget::disable() 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; } return true; @@ -92,9 +80,9 @@ bool ItemWidget::controles(const ItemData& relay) void ItemWidget::showSettingsDialog() { - if(auto workingItem = item_.lock()) + if(auto workingRelay = item_.lock()) { - ItemSettingsDialog dialog(workingItem, this); + ItemSettingsDialog dialog(workingRelay, this); dialog.exec(); } else disable(); @@ -107,6 +95,7 @@ std::weak_ptr ItemWidget::getItem() void ItemWidget::stateChanged(int state) { + qDebug()<<"widget got state "<slider->blockSignals(true); ui->slider->setValue(state); ui->slider->blockSignals(false); diff --git a/src/ui/itemwidget.h b/src/ui/itemwidget.h index 18d2861..d4c93c6 100644 --- a/src/ui/itemwidget.h +++ b/src/ui/itemwidget.h @@ -30,7 +30,7 @@ private slots: void deleteItem(); public: - explicit ItemWidget(std::weak_ptr item, QWidget *parent = nullptr); + explicit ItemWidget(std::weak_ptr item, bool analog = false, bool nameOnly = false, QWidget *parent = nullptr); std::weak_ptr getItem(); bool controles(const ItemData& relay); ~ItemWidget(); diff --git a/src/ui/itemwidget.ui b/src/ui/itemwidget.ui index 91d92f5..bdbc8a6 100644 --- a/src/ui/itemwidget.ui +++ b/src/ui/itemwidget.ui @@ -30,7 +30,7 @@ - Qt::Orientation::Horizontal + Qt::Horizontal @@ -46,10 +46,10 @@ 255 - false + true - Qt::Orientation::Horizontal + Qt::Horizontal diff --git a/src/ui/mainwindow-android.ui b/src/ui/mainwindow-android.ui index e7802b3..fa90bc9 100644 --- a/src/ui/mainwindow-android.ui +++ b/src/ui/mainwindow-android.ui @@ -245,13 +245,13 @@ ItemScrollBox QWidget -
../ui/itemscrollbox.h
+
../src/ui/itemscrollbox.h
1
SensorListWidget QListView -
../ui/sensorlistwidget.h
+
../src/ui/sensorlistwidget.h
diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 79a6b3e..b3e317e 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -1,35 +1,46 @@ #include "mainwindow.h" - -#include - #include "ui_mainwindow.h" #include "itemscrollbox.h" #include "itemsettingsdialog.h" #include "itemcreationdialog.h" -#include "mainobject.h" -#include "programmode.h" -#include "items/poweritem.h" +#include "../mainobject.h" +#include MainWindow::MainWindow(MainObject * const mainObject, QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), - colorChooser(this) + colorChooser(this), + _micro(&mainObject->micro), + _powerItem(mainObject->powerItem) { ui->setupUi(this); - connect(ui->pushButton_broadcast, &QPushButton::clicked, this, &MainWindow::sigSave); - connect(ui->pushButton_broadcast, &QPushButton::clicked, this, [this](){QMessageBox::information(this, "Saved", "Settings where saved");}); + + if(!mainObject->master) + { + connect(ui->pushButton_broadcast, &QPushButton::clicked, this, &MainWindow::sigBrodcast); + } + else + { + connect(ui->pushButton_broadcast, &QPushButton::clicked, this, &MainWindow::sigSave); + connect(ui->pushButton_broadcast, &QPushButton::clicked, this, &MainWindow::saved); + } connect(ui->pushButton_power, SIGNAL(clicked()), this, SLOT(showPowerItemDialog())); - connect(ui->pushButton_refesh, &QPushButton::clicked, mainObject, &MainObject::refresh); - connect(&globalItems, &ItemStore::itemAdded, ui->relayList, &ItemScrollBox::addItem); - connect(&globalItems, &ItemStore::itemDeleted, ui->relayList, &ItemScrollBox::removeItem); + //Relays + if(mainObject->master)connect(ui->pushButton_refesh, &QPushButton::clicked, _micro, &Microcontroller::requestState); + else + { + connect(ui->pushButton_refesh, &QPushButton::clicked, &mainObject->broadCast, &BroadCast::requestJson); + connect(ui->pushButton_refesh, &QPushButton::clicked, &mainObject->broadCast, &BroadCast::requestSensors); + } + connect(&mainObject->items, &ItemStore::itemAdded, ui->relayList, &ItemScrollBox::addItem); + connect(&mainObject->items, &ItemStore::itemDeleted, ui->relayList, &ItemScrollBox::removeItem); - for(size_t i = 0; i < globalItems.getItems()->size(); ++i) - ui->relayList->addItem(globalItems.getItems()->at(i)); - - if(programMode != PROGRAM_MODE_PRIMARY) - ui->label_serialRecive->setHidden(true); + for(size_t i = 0; i < mainObject->items.getItems()->size(); ++i) + { + ui->relayList->addItem(mainObject->items.getItems()->at(i)); + } //Sensors ui->sensorListView->setShowHidden(false); @@ -37,14 +48,12 @@ MainWindow::MainWindow(MainObject * const mainObject, QWidget *parent) : connect(&globalSensors, &SensorStore::stateChenged, ui->sensorListView, &SensorListWidget::sensorsChanged); //RGB Leds - connect(&colorChooser, &QColorDialog::colorSelected, this, &MainWindow::sigSetRgb); + connect(&colorChooser, SIGNAL(colorSelected(QColor)), this, SLOT(slotChangedRgb(QColor))); connect(ui->button_quit, SIGNAL(clicked()), this, SLOT(close())); connect(ui->button_color, SIGNAL(clicked()), &colorChooser, SLOT(show())); - if(programMode != PROGRAM_MODE_PRIMARY) - ui->button_color->hide(); connect(ui->pushButton_addItem, &QPushButton::clicked, this, &MainWindow::showItemCreationDialog); - connect(ui->relayList, &ItemScrollBox::deleteRequest, &globalItems, &ItemStore::removeItem); + connect(ui->relayList, &ItemScrollBox::deleteRequest, &mainObject->items, &ItemStore::removeItem); ui->splitter->setStretchFactor(1, 1); } @@ -56,30 +65,29 @@ MainWindow::~MainWindow() void MainWindow::showPowerItemDialog() { - std::shared_ptr powerItem; - for(std::shared_ptr item : *globalItems.getItems()) - { - powerItem = std::dynamic_pointer_cast(item); - if(powerItem) - break; - } - if(powerItem) - { - ItemSettingsDialog diag(std::shared_ptr(powerItem), this); - diag.show(); - diag.exec(); - } - else - { - QMessageBox::warning(this, "Error", "No power item found, refresh first"); - } + ItemSettingsDialog diag(std::shared_ptr(_powerItem), this); + diag.show(); + diag.exec(); } + +void MainWindow::saved() +{ + QMessageBox::information(this, "Saved", "Settings where saved"); +} + +void MainWindow::slotChangedRgb(const QColor color) +{ + _micro->changeRgbColor(color); +} + void MainWindow::showItemCreationDialog() { ItemCreationDialog diag(this); diag.show(); if(diag.exec()) + { createdItem(diag.item); + } } void MainWindow::changeHeaderLableText(QString string) diff --git a/src/ui/mainwindow.h b/src/ui/mainwindow.h index 5b04b64..e15c466 100644 --- a/src/ui/mainwindow.h +++ b/src/ui/mainwindow.h @@ -5,9 +5,14 @@ #include #include #include -#include +#include +#include "../actors/alarmtime.h" +#include "../microcontroller.h" +#include "../sensors/sensor.h" +#include "../items/itemstore.h" +#include "../items/poweritem.h" +#include "../broadcast.h" -#include class MainObject; @@ -29,17 +34,23 @@ private: QColorDialog colorChooser; + Microcontroller *_micro; + + std::shared_ptr _powerItem; + signals: + void sigBrodcast(); void sigSave(); void createdItem(std::shared_ptr item); - void sigSetRgb(const QColor color); private slots: //RGB + void slotChangedRgb(const QColor color); void showPowerItemDialog(); void showItemCreationDialog(); + void saved(); public slots: diff --git a/src/ui/mainwindow.ui b/src/ui/mainwindow.ui index 0e6732c..c44b0e9 100644 --- a/src/ui/mainwindow.ui +++ b/src/ui/mainwindow.ui @@ -37,21 +37,21 @@
- Qt::LayoutDirection::LeftToRight + Qt::LeftToRight false - + - Qt::Orientation::Horizontal + Qt::Horizontal false - + @@ -62,13 +62,13 @@ - QFrame::Shape::Box + QFrame::Box SHinterface - Qt::TextFormat::AutoText + Qt::AutoText @@ -99,7 +99,7 @@ - QAbstractItemView::SelectionMode::NoSelection + QAbstractItemView::NoSelection false @@ -114,11 +114,49 @@ 0 + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 48 + + + + + 0 + 128 + + + + Color + + + + + + + Config Shutdown + + + - + @@ -156,91 +194,49 @@ 0 + + + + Refesh + + + + + + + Save + + + + + + + Add Item + + + + + + + + 0 + 0 + + + + Qt::RightToLeft + + + Quit + + +
- - - - - - Config Shutdown - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - 0 - 128 - - - - Color - - - - - - - Refesh - - - - - - - Save - - - - - - - Add Item - - - - - - - - 0 - 0 - - - - Qt::LayoutDirection::RightToLeft - - - Quit - - - - - @@ -249,12 +245,12 @@ SensorListWidget QListView -
ui/sensorlistwidget.h
+
../src/ui/sensorlistwidget.h
ItemScrollBox QWidget -
ui/itemscrollbox.h
+
../src/ui/itemscrollbox.h
1
diff --git a/src/ui/sensorlistwidget.h b/src/ui/sensorlistwidget.h index 4c84d54..c963a05 100644 --- a/src/ui/sensorlistwidget.h +++ b/src/ui/sensorlistwidget.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include "sensors/sensor.h" +#include "../sensors/sensor.h" class SensorListItem : public QTableWidgetItem {