Finish lerge refactor of systems

This commit is contained in:
Carl Philipp Klemm 2026-03-22 23:23:18 +01:00
parent 6d742e60db
commit 913d7df56d
36 changed files with 614 additions and 634 deletions

View file

@ -26,8 +26,8 @@ QMAKE_CXXFLAGS += -std=c++17 -O2
SOURCES += \
src/actors/factoractor.cpp \
src/actors/polynomalactor.cpp \
src/items/fixeditemsource.cpp \
src/tcpserver.cpp \
src/iomuliplexer.cpp \
src/items/messageitem.cpp \
src/items/systemitem.cpp \
src/ui/actorwidgets/factoractorwidget.cpp \
@ -69,7 +69,8 @@ SOURCES += \
src/items/itemstore.cpp \
src/items/auxitem.cpp \
src/items/rgbitem.cpp \
src/items/itemsource.cpp
src/items/itemsource.cpp\
src/items/itemloadersource.cpp
SOURCES += \
src/main.cpp \
@ -81,10 +82,10 @@ SOURCES += \
HEADERS += \
src/actors/factoractor.h \
src/actors/polynomalactor.h \
src/items/fixeditemsource.h \
src/items/itemsource.h \
src/programmode.h \
src/tcpserver.h \
src/iomuliplexer.h \
src/items/messageitem.h \
src/items/systemitem.h \
src/ui/actorwidgets/factoractorwidget.h \
@ -126,7 +127,8 @@ HEADERS += \
src/items/itemstore.h \
src/items/auxitem.h \
src/items/rgbitem.h \
src/items/itemsource.h
src/items/itemsource.h \
src/items/itemloadersource.h
HEADERS += \
src/microcontroller.h \

View file

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

View file

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

View file

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

View file

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

View file

@ -3,11 +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)
{
assert(micro_);
micro_->setAuxPwm(value);
}

View file

@ -13,7 +13,7 @@ protected:
virtual void enactValue(uint8_t value) override;
public:
AuxItem(Microcontroller* micro, uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "",
AuxItem(Microcontroller* micro = nullptr, uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "",
uint8_t value = 0, QObject* parent = nullptr);
virtual void store(QJsonObject& json) override;

View file

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

View file

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

View file

@ -7,10 +7,14 @@
#include "relay.h"
#include "messageitem.h"
#include "systemitem.h"
#include "auxitem.h"
#include "poweritem.h"
#include "rgbitem.h"
#include <QJsonArray>
ItemData::ItemData(uint32_t itemIdIn, QString name, uint8_t value): name_(name), value_(value), itemId_(itemIdIn)
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)
{
}
@ -48,9 +52,47 @@ void ItemData::load(const QJsonObject &json, const bool preserve)
{
name_ = json["Name"].toString(name_);
itemId_ = static_cast<uint32_t>(json["ItemId"].toDouble(0));
value_ = json["Value"].toInt();
}
}
bool ItemData::getLoaded() const
{
return loaded_;
}
void ItemData::setLoaded(bool loaded)
{
loaded_ = loaded;
}
bool ItemData::hasChanged(const ItemData& other)
{
if(other != *this)
return false;
if(other.getName() != getName())
return true;
if(other.getValue() != getValue())
return true;
if(other.getLoaded() != getLoaded())
return true;
return false;
}
bool ItemData::isHidden()
{
return hidden_;
}
void ItemData::setHidden(bool hidden)
{
hidden_ = hidden;
}
item_value_type_t ItemData::getValueType()
{
return type_;
}
//item
@ -96,7 +138,8 @@ void Item::load(const QJsonObject &json, const bool preserve)
if(actorsArray[i].isObject())
{
std::shared_ptr<Actor> actor = Actor::loadActor(actorsArray[i].toObject());
if(actor != nullptr) addActor(actor);
if(actor != nullptr)
addActor(actor);
}
}
}
@ -109,6 +152,7 @@ void Item::actorSetValue(uint8_t value)
void Item::setValue(uint8_t value)
{
qDebug()<<__func__;
informValue(value);
if(programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY)
enactValue(value);
@ -116,9 +160,12 @@ void Item::setValue(uint8_t value)
void Item::informValue(uint8_t value)
{
if(value_ != value)
{
value_ = value;
valueChanged(value_);
updated(*this);
}
}
void Item::enactValue(uint8_t value)
@ -135,14 +182,16 @@ void Item::addActor(std::shared_ptr<Actor> actor)
connect(this, &Item::valueChanged, actor.get(), &Actor::onValueChanged);
std::shared_ptr<SensorActor> sensorActor = std::dynamic_pointer_cast<SensorActor>(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> regulator = std::dynamic_pointer_cast<Regulator>(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> polynomalActor = std::dynamic_pointer_cast<PolynomalActor>(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> actor)
@ -189,6 +238,14 @@ void Item::setActorsActive(bool in)
in ? actors_[i]->makeActive() : actors_[i]->makeInactive();
}
void Item::mergeLoaded(Item& item)
{
name_ = item.name_;
actors_.clear();
for(std::shared_ptr<Actor> actor : item.actors_)
addActor(actor);
}
std::shared_ptr<Item> Item::loadItem(const QJsonObject& json)
{
std::shared_ptr<Item> newItem = nullptr;
@ -206,8 +263,21 @@ std::shared_ptr<Item> Item::loadItem(const QJsonObject& json)
}
else if(json["Type"].toString("") == "Aux")
{
newItem = std::shared_ptr<AuxItem>(new AuxItem);
}
else if(json["Type"].toString("") == "Power")
{
newItem = std::shared_ptr<PowerItem>(new PowerItem);
}
else if(json["Type"].toString("") == "Rgb")
{
newItem = std::shared_ptr<RgbItem>(new RgbItem);
}
if(newItem)
{
newItem->load(json);
newItem->setLoaded(true);
}
return newItem;
}

View file

@ -8,15 +8,29 @@
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);
ItemData(uint32_t itemIdIn = QRandomGenerator::global()->generate(),
QString name = "Item",
uint8_t value = 0,
bool loaded = false,
bool hidden = false,
item_value_type_t type = ITEM_VALUE_BOOL);
inline bool operator==(const ItemData& in) const
{
@ -29,8 +43,14 @@ public:
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);
@ -72,6 +92,7 @@ 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);

View file

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

View file

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

View file

@ -18,6 +18,7 @@ public slots:
signals:
void gotItems(std::vector<std::shared_ptr<Item>> items, bool inform = true);
void requestReplaceItems(std::vector<std::shared_ptr<Item>> items);
void updateItems(std::vector<ItemData> items, bool inform = true);
};

View file

@ -21,15 +21,15 @@ void ItemStore::addItem(std::shared_ptr<Item> item, bool inform)
{
items_.push_back(std::shared_ptr<Item>(item));
connect(item.get(), &Item::updated, this, &ItemStore::itemUpdateSlot);
qDebug()<<"Item"<<item->getName()<<"added";
qDebug()<<"Item"<<item->getName()<<"added"<<(item->getLoaded() ? "from loaded" : "");
itemAdded(std::weak_ptr<Item>(items_.back()));
}
else if(item->getValue() != matched->getValue())
{
if(inform)
matched->informValue(item->getValue());
else
matched->setValue(item->getValue());
{
if(item->getLoaded())
matched->mergeLoaded(*item);
else if(item->getValue() != matched->getValue())
updateItem(*item, inform);
}
}
@ -53,6 +53,19 @@ void ItemStore::removeItem(const ItemData& item)
}
}
void ItemStore::replaceItems(const std::vector<std::shared_ptr<Item>>& items)
{
addItems(items, true);
std::vector<ItemData> deletedItems;
for(std::shared_ptr<Item> item : items_)
{
if(std::find_if(items.begin(), items.end(), [item](const std::shared_ptr<Item> other){return *item == *other;}) == items.end())
deletedItems.push_back(*item);
}
for(const ItemData& item : deletedItems)
removeItem(item);
}
void ItemStore::clear()
{
for(size_t i = 0; i < items_.size(); ++i) itemDeleted(*items_[i]);
@ -66,15 +79,17 @@ void ItemStore::updateItems(std::vector<ItemData> items, bool inform)
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
@ -84,6 +99,7 @@ void ItemStore::updateItem(const ItemData& item, bool inform)
itemUpdated(items_[i]);
}
}
}
}
void ItemStore::store(QJsonObject& json)
@ -98,24 +114,8 @@ void ItemStore::store(QJsonObject& json)
json["Items"] = itemsArray;
}
void ItemStore::load(const QJsonObject& json)
{
const QJsonArray itemsArray(json["Items"].toArray(QJsonArray()));
for(int i = 0; i < itemsArray.size(); ++i)
{
if(!itemsArray[i].isObject())
continue;
const QJsonObject itemObject = itemsArray[i].toObject();
std::shared_ptr<Item> newItem = Item::loadItem(itemObject);
if(newItem)
addItem(newItem);
}
}
void ItemStore::itemUpdateSlot(ItemData data)
{
qDebug()<<__func__;
for(std::shared_ptr<Item>& item: items_)
{
if(*item == data)
@ -138,6 +138,7 @@ void ItemStore::registerItemSource(ItemSource* source)
qDebug()<<__func__<<typeid(*source).name();
connect(source, &ItemSource::gotItems, this, &ItemStore::addItems);
connect(source, &ItemSource::updateItems, this, &ItemStore::updateItems);
connect(source, &ItemSource::requestReplaceItems, this, &ItemStore::replaceItems);
connect(this, &ItemStore::sigRefresh, source, &ItemSource::refresh);
}

View file

@ -26,7 +26,6 @@ public:
void registerItemSource(ItemSource* source);
void store(QJsonObject &json);
void load(const QJsonObject &json);
void clear();
@ -42,6 +41,7 @@ public slots:
void removeItem(const ItemData& item);
void addItem(std::shared_ptr<Item> item, bool inform = true);
void addItems(const std::vector<std::shared_ptr<Item>>& itemsIn, bool inform = true);
void replaceItems(const std::vector<std::shared_ptr<Item>>& items);
void updateItems(std::vector<ItemData> items, bool inform = true);
void updateItem(const ItemData& item, bool inform = true);
void refresh();

View file

@ -7,6 +7,7 @@ MessageItem::MessageItem(uint32_t itemIdIn, QString name, uint8_t value, QObjec
Item(itemIdIn, name, value, parent)
{
alertSound.setVolume(1.0);
type_ = ITEM_VALUE_NO_VALUE;
}
MessageItem::MessageItem(const ItemData& itemData, QObject *parent):

View file

@ -3,11 +3,13 @@
#include <QApplication>
#include <QDebug>
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;
}
void PowerItem::enactValue(uint8_t value)

View file

@ -22,7 +22,7 @@ protected:
virtual void enactValue(uint8_t value) override;
public:
PowerItem(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "", uint8_t value = 0,
PowerItem(uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "Power", uint8_t value = 0,
QObject* parent = nullptr);
void emmitSensor()
{

View file

@ -9,11 +9,11 @@ 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 "<<id_<<"Name "<<name<<" id "<<itemId_<<" state "<<state<<" addr: "<<address;
}
void Relay::enactValue(uint8_t value)
{
qDebug()<<"Relay"<<__func__<<micro_;
if(micro_)
{
if(value)

View file

@ -8,6 +8,7 @@ RgbItem::RgbItem(Microcontroller* micro, uint32_t itemIdIn, QString name, uint8
void RgbItem::enactValue(uint8_t value)
{
assert(micro_);
value ? micro_->rgbOn() : micro_->rgbOff();
}

View file

@ -13,7 +13,7 @@ protected:
virtual void enactValue(uint8_t value) override;
public:
RgbItem(Microcontroller* micro, uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "",
RgbItem(Microcontroller* micro = nullptr, uint32_t itemIdIn = QRandomGenerator::global()->generate(), QString name = "",
uint8_t value = 0, QObject* parent = nullptr);
virtual void store(QJsonObject& json) override;

View file

@ -12,54 +12,6 @@
#include "mainobject.h"
#include "programmode.h"
QJsonObject getJsonObjectFromDisk(const QString& filePath, bool* error = nullptr)
{
QFile file;
file.setFileName(filePath);
bool ret = file.open(QIODevice::ReadOnly);
if(!file.isOpen() || !ret)
{
std::cerr<<"Can not open config file: "<<filePath.toLatin1().data()<<std::endl;
}
else
{
QJsonParseError qerror;
QJsonDocument document(QJsonDocument::fromJson(file.readAll(), &qerror));
file.close();
if(qerror.error != QJsonParseError::NoError)
{
qDebug()<<filePath<<" "<<qerror.errorString();
if(error) (*error) = true;
}
return document.object();
}
return QJsonObject();
}
bool storeJsonObjectToDisk(const QJsonObject& json, QString filePath)
{
QFile file(filePath + ".out");
qDebug()<<"config file: "<<filePath;
bool ret = file.open(QIODevice::WriteOnly);
if(!file.isOpen() || !ret)
{
std::cerr<<"Can not open config file: "<<filePath.toLatin1().data()<<std::endl;
return false;
}
else
{
QJsonDocument document(json);
file.write(document.toJson());
file.close();
QFile::remove(filePath);
file.rename(filePath);
return true;
}
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
@ -103,7 +55,8 @@ int main(int argc, char *argv[])
}
if(programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY)
{
QJsonObject json = getJsonObjectFromDisk(parser.value(settingsPathOption));
QString settingsPath = parser.value(settingsPathOption);
QJsonObject json = MainObject::getJsonObjectFromDisk(settingsPath);
bool tcpMicro = json["MicroTcp"].toBool(true);
json["MicroTcp"] = tcpMicro;
@ -123,7 +76,7 @@ int main(int argc, char *argv[])
if(!microSocket->waitForConnected(1000))
{
qCritical()<<"Can not connect to tcp micro";
storeJsonObjectToDisk(json, parser.value(settingsPathOption));
MainObject::storeJsonObjectToDisk(settingsPath, json);
if(programMode == PROGRAM_MODE_PRIMARY)
QMessageBox::critical(nullptr, "Error", "Can not connect to tcp micro");
return 1;
@ -145,21 +98,23 @@ int main(int argc, char *argv[])
if(!microPort->isOpen())
{
qCritical()<<"Can not open serial port"<<port;
storeJsonObjectToDisk(json, parser.value(settingsPathOption));
MainObject::storeJsonObjectToDisk(settingsPath, json);
if(programMode == PROGRAM_MODE_PRIMARY)
QMessageBox::critical(nullptr, "Error", "Can not open serial port " + port);
return 1;
}
microDevice = microPort;
}
PrimaryMainObject mainObject(microDevice, &json, parser.value(hostOption), parser.value(portOption).toInt());
PrimaryMainObject mainObject(microDevice, settingsPath, parser.value(hostOption), parser.value(portOption).toInt());
QObject::connect(mainObject.tcpServer, &TcpServer::sigRequestSave, &mainObject, [&mainObject, settingsPath](){mainObject.storeToDisk(settingsPath);});
MainWindow* w = nullptr;
if(programMode != PROGRAM_MODE_HEADLESS_PRIMARY)
{
w = new MainWindow(&mainObject);
QObject::connect(&mainObject.micro, SIGNAL(textRecived(QString)), w, SLOT(changeHeaderLableText(QString)));
QObject::connect(&mainObject.micro, SIGNAL(textRecived(QString)), w, SLOT(changeHeaderLableText(QString)));
//QObject::connect(&w, &MainWindow::sigSave, &mainObject, &MainObject::storeToDisk);
QObject::connect(w, &MainWindow::sigSetRgb, &mainObject.micro, &Microcontroller::changeRgbColor);
QObject::connect(w, &MainWindow::sigSave, &mainObject, [&mainObject, settingsPath](){mainObject.storeToDisk(settingsPath);});
QObject::connect(w, &MainWindow::createdItem, &globalItems, [](std::shared_ptr<Item> item){globalItems.addItem(item, false);});
w->show();
}
@ -167,14 +122,13 @@ int main(int argc, char *argv[])
delete w;
delete microDevice;
mainObject.store(json);
storeJsonObjectToDisk(json, parser.value(settingsPathOption));
}
else
{
SecondaryMainObject mainObject(parser.value(hostOption), parser.value(portOption).toInt());
MainWindow w(&mainObject);
//QObject::connect(&w, &MainWindow::sigSave, &mainObject, &MainObject::sendJson);
QObject::connect(&w, &MainWindow::createdItem, &globalItems, [](std::shared_ptr<Item> item){globalItems.addItem(item, false);});
QObject::connect(&w, &MainWindow::sigSave, mainObject.tcpClient, &TcpClient::sendItems);
w.show();
retVal = a.exec();

View file

@ -20,17 +20,61 @@ void MainObject::refresh()
globalItems.refresh();
}
PrimaryMainObject::PrimaryMainObject(QIODevice* microDevice, QJsonObject* settings, QString host, int port, QObject *parent) :
QJsonObject MainObject::getJsonObjectFromDisk(const QString& filename, bool* error)
{
QFile file;
file.setFileName(filename);
bool ret = file.open(QIODevice::ReadOnly);
if(!file.isOpen() || !ret)
{
std::cerr<<"Can not open config file: "<<filename.toLatin1().data()<<std::endl;
}
else
{
QJsonParseError qerror;
QJsonDocument document(QJsonDocument::fromJson(file.readAll(), &qerror));
file.close();
if(qerror.error != QJsonParseError::NoError)
{
qDebug()<<filename<<" "<<qerror.errorString();
if(error)
(*error) = true;
}
return document.object();
}
return QJsonObject();
}
bool MainObject::storeJsonObjectToDisk(const QString& filename, const QJsonObject& json)
{
QFile file(filename + ".out");
qDebug()<<"config file: "<<filename;
bool ret = file.open(QIODevice::WriteOnly);
if(!file.isOpen() || !ret)
{
std::cerr<<"Can not open config file: "<<filename.toLatin1().data()<<std::endl;
return false;
}
else
{
QJsonDocument document(json);
file.write(document.toJson());
file.close();
QFile::remove(filename);
file.rename(filename);
return true;
}
}
PrimaryMainObject::PrimaryMainObject(QIODevice* microDevice, const QString& settingsPath, const QString& host, int port, QObject *parent) :
MainObject(parent),
settings(settings),
microDevice(microDevice),
ioMultiplexer(microDevice),
settingsPath(settingsPath),
micro(microDevice),
tcpServer(new TcpServer),
sunSensorSource(49.824972, 8.702194),
powerItem(new PowerItem),
rgbItem(new RgbItem(&micro, 5487422, "Rgb Lights")),
auxItem(new AuxItem(&micro, 5487421, "Desk Light"))
fixedItems(&micro)
{
//connect sensors subsystem
connect(&globalSensors, &SensorStore::sensorChangedState, tcpServer, &TcpServer::sensorEvent);
@ -38,17 +82,24 @@ PrimaryMainObject::PrimaryMainObject(QIODevice* microDevice, QJsonObject* settin
connect(&sunSensorSource, &SunSensorSource::stateChanged, &globalSensors, &SensorStore::sensorGotState);
connect(&micro, &Microcontroller::gotSensorState, &globalSensors, &SensorStore::sensorGotState);
sunSensorSource.run();
globalItems.registerItemSource(&fixedItems);
globalItems.registerItemSource(tcpServer);
globalItems.registerItemSource(&micro);
globalItems.registerItemSource(&itemLoader);
load(*settings);
Relay::setMicrocontroller(&micro);
loadFromDisk(settingsPath);
tcpServer->launch(QHostAddress(host), port);
connect(&globalItems, &ItemStore::itemUpdated, tcpServer, &TcpServer::itemUpdated);
}
PrimaryMainObject::~PrimaryMainObject()
{
store(*settings);
storeToDisk(settingsPath);
}
void PrimaryMainObject::store(QJsonObject &json)
@ -58,22 +109,28 @@ void PrimaryMainObject::store(QJsonObject &json)
void PrimaryMainObject::load(const QJsonObject& json)
{
settings = json;
itemLoader.updateJson(json);
globalItems.clear();
rgbItem->removeAllActors();
auxItem->removeAllActors();
powerItem->removeAllActors();
globalItems.addItem(rgbItem);
globalItems.addItem(auxItem);
globalItems.addItem(powerItem);
globalItems.load(json);
if(json["Items"].toArray().size() >= 2)
{
rgbItem->load(json["Items"].toArray()[0].toObject());
auxItem->load(json["Items"].toArray()[1].toObject());
}
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)
@ -84,8 +141,12 @@ SecondaryMainObject::SecondaryMainObject(QString host, int port, QObject *parent
if(!tcpClient->launch(QHostAddress(host), port))
{
QMessageBox::critical(nullptr, "Error", "Could not connect to "+host+":"+QString::number(port));
exit(1);
QMetaObject::invokeMethod(this, [](){exit(1);}, Qt::QueuedConnection);
}
connect(&globalItems, &ItemStore::itemUpdated, tcpClient, &TcpClient::itemUpdated);
globalItems.refresh();
}
SecondaryMainObject::~SecondaryMainObject()

View file

@ -14,11 +14,8 @@
#include "microcontroller.h"
#include "ui/mainwindow.h"
#include "sensors/sunsensor.h"
#include "items/auxitem.h"
#include "items/rgbitem.h"
#include "items/poweritem.h"
#include "iomuliplexer.h"
#include "broadcast.h"
#include "items/fixeditemsource.h"
#include "items/itemloadersource.h"
#include "tcpserver.h"
class MainObject : public QObject
@ -28,6 +25,8 @@ class MainObject : public QObject
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();
@ -38,11 +37,8 @@ class PrimaryMainObject : public MainObject
Q_OBJECT
public:
QJsonObject* settings;
//io
QIODevice * const microDevice = nullptr;
IoMuliplexer ioMultiplexer;
QString settingsPath;
QJsonObject settings;
Microcontroller micro;
TcpServer* tcpServer;
@ -50,16 +46,17 @@ public:
//sensors
SunSensorSource sunSensorSource;
//items
std::shared_ptr<PowerItem> powerItem;
std::shared_ptr<RgbItem> rgbItem;
std::shared_ptr<AuxItem> auxItem;
//item sources
FixedItemSource fixedItems;
ItemLoaderSource itemLoader;
public:
explicit PrimaryMainObject(QIODevice* microDevice, QJsonObject* settings, QString host, int port, QObject *parent = nullptr);
explicit PrimaryMainObject(QIODevice* microDevice, const QString& settingsPath, const QString& host, int port, QObject *parent = nullptr);
~PrimaryMainObject();
void store(QJsonObject& json);
void load(const QJsonObject& json);
bool storeToDisk(const QString& filename);
bool loadFromDisk(const QString& filename);
};
class SecondaryMainObject : public MainObject

View file

@ -138,12 +138,10 @@ void Microcontroller::processList(const QString& buffer)
if(bufferList.size() >= 8 && buffer.startsWith("ITEM NUMBER:"))
{
relayList.push_back(processRelayLine(buffer));
qDebug()<<"Micro item recived:"<<relayList.back()->getName();
}
else if(buffer.contains("EOL"))
{
listMode = false;
qDebug()<<"got relay list " << relayList.size();
gotItems(relayList);
relayList.clear();
}
@ -158,13 +156,13 @@ void Microcontroller::processRelayState(const QString& 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()
{
qDebug()<<_buffer;
if(listMode)
{
processList(_buffer);
@ -176,8 +174,14 @@ 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);
}
}
}
@ -188,8 +192,6 @@ void Microcontroller::isReadyRead()
while(_port->getChar(&charBuf))
{
_buffer.push_back(charBuf);
qDebug()<<_buffer;
if(_buffer.endsWith('\n') )
{
_buffer.remove('\n');

View file

@ -46,7 +46,7 @@ public:
{
type = json["SensorType"].toInt(0);
id = json["Id"].toInt(0);
field = json["Field"].toInt(0);
field = json["Field"].toDouble(0);
name = json["Name"].toString("Sensor");
lastSeen = QDateTime::fromString(json["LastSeen"].toString(""));
hidden = json["Hidden"].toBool(false);

View file

@ -1,6 +1,7 @@
#include <QTcpSocket>
#include <QJsonDocument>
#include <QJsonArray>
#include <iostream>
#include "items/item.h"
#include "items/itemstore.h"
@ -14,7 +15,7 @@ TcpService::TcpService(QObject* parent):
QJsonObject TcpService::createMessage(const QString& type, const QJsonArray& data)
{
QJsonObject json;
json["MesageType"] = type;
json["MessageType"] = type;
json["Data"] = data;
return json;
}
@ -26,17 +27,18 @@ void TcpService::sensorEvent(Sensor sensor)
sensor.store(sensorjson);
sensors.append(sensorjson);
QJsonObject json = createMessage("SensorUpdate", sensors);
sendJson(json);
}
void TcpService::itemUpdated(std::weak_ptr<Item> item)
{
qDebug()<<__func__;
QJsonArray items;
QJsonObject itemjson;
item.lock()->store(itemjson);
items.append(itemjson);
QJsonObject json = createMessage("ItemUpdate", items);
json["FullList"] = false;
sendJson(json);
}
@ -67,22 +69,26 @@ void TcpService::sendItems()
item->store(itemjson);
items.append(itemjson);
}
sendJson(createMessage("ItemUpdate", items));
QJsonObject json = createMessage("ItemUpdate", items);
json["FullList"] = true;
sendJson(json);
}
void TcpService::processIncomeingJson(const QByteArray& jsonbytes)
{
qDebug()<<__func__<<jsonbytes;
QJsonDocument doc = QJsonDocument::fromJson(jsonbytes);
qDebug()<<"Got Json:"<<QString::fromLatin1(doc.toJson(QJsonDocument::JsonFormat::Indented));
QJsonObject json = doc.object();
QString type = json["MessageType"].toString();
if(type == "GetSensors")
{
qDebug()<<"Sending sensors";
sendSensors();
}
else if(type == "GetItems")
{
qDebug()<<"Sending Items";
sendItems();
}
else if(type == "SensorUpdate")
@ -101,6 +107,7 @@ TcpClient::TcpClient(QObject* parent):
TcpService(parent),
socket(new QTcpSocket(this))
{
connect(socket, &QTcpSocket::readyRead, this, &TcpClient::socketReadyRead);
}
void TcpClient::sendJson(const QJsonObject& json)
@ -122,6 +129,7 @@ void TcpClient::processIncomeingJson(const QByteArray& jsonbytes)
QString type = json["MessageType"].toString();
if(type == "ItemUpdate")
{
std::cout<<"Got item json:\n"<<QString::fromLatin1(jsonbytes).toStdString();
QJsonArray data = json["Data"].toArray();
std::vector<std::shared_ptr<Item>> items;
for(QJsonValueRef itemjson : data)
@ -129,8 +137,11 @@ void TcpClient::processIncomeingJson(const QByteArray& jsonbytes)
QJsonObject jsonobject = itemjson.toObject();
std::shared_ptr<Item> item = Item::loadItem(jsonobject);
if(item)
{
item->setLoaded(false);
items.push_back(item);
}
}
if(!items.empty())
gotItems(items, true);
}
@ -140,6 +151,45 @@ void TcpClient::processIncomeingJson(const QByteArray& 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;
@ -149,6 +199,7 @@ TcpServer::TcpServer(QObject* parent):
TcpService(parent),
server(this)
{
connect(&server, &QTcpServer::newConnection, this, &TcpServer::incomingConnection);
}
void TcpServer::sendJson(const QJsonObject& json)
@ -167,18 +218,28 @@ void TcpServer::processIncomeingJson(const QByteArray& jsonbytes)
QString type = json["MessageType"].toString();
if(type == "ItemUpdate")
{
qDebug()<<"Got Items";
QJsonArray data = json["Data"].toArray();
bool FullList = json["FullList"].toBool(false);
std::vector<std::shared_ptr<Item>> items;
for(QJsonValueRef itemjson : data)
{
QJsonObject jsonobject = itemjson.toObject();
std::shared_ptr<Item> item = Item::loadItem(jsonobject);
item->setLoaded(FullList);
if(item)
items.push_back(item);
}
if(!items.empty())
if(FullList && !items.empty())
{
requestReplaceItems(items);
sigRequestSave();
}
else if(!items.empty())
{
gotItems(items, false);
}
}
else
{
TcpService::processIncomeingJson(jsonbytes);
@ -195,6 +256,7 @@ void TcpServer::incomingConnection()
while(server.hasPendingConnections())
{
QTcpSocket* client = server.nextPendingConnection();
qDebug()<<"Got new client from"<<client->peerAddress().toString();
if(client)
{
clients.push_back({client});
@ -231,11 +293,11 @@ void TcpServer::socketDisconnect()
void TcpServer::processComand(const QByteArray& command, Client& client)
{
qDebug()<<__func__<<command;
if(command.startsWith("MSG JSON LEN "))
{
client.state = STATE_RECV_JSON;
client.recievebytes = command.mid(13).toLongLong();
qDebug()<<"Got command:"<<QString::fromLatin1(command);
}
}
@ -245,16 +307,19 @@ void TcpServer::socketReadyRead()
{
if(clients[i].socket == sender())
{
clients[i].buffer += clients[i].socket->readAll();
QByteArray newChars = clients[i].socket->readAll();
clients[i].buffer += newChars;
bool remianing = true;
while(remianing)
{
qDebug()<<clients[i].buffer;
remianing = false;
while(clients[i].state == STATE_IDLE && clients[i].buffer.contains('\n'))
{
size_t newlineIndex = clients[i].buffer.indexOf('\n');
QByteArray command = clients[i].buffer.chopped(newlineIndex);
clients[i].buffer.chop(newlineIndex);
QByteArray command = clients[i].buffer.left(newlineIndex);
clients[i].buffer.remove(0, newlineIndex+1);
processComand(command, clients[i]);
remianing = true;
}
@ -262,8 +327,8 @@ void TcpServer::socketReadyRead()
{
if(clients[i].recievebytes <= clients[i].buffer.size())
{
QByteArray json = clients[i].buffer.chopped(clients[i].recievebytes);
clients[i].buffer.chop(clients[i].recievebytes);
QByteArray json = clients[i].buffer.left(clients[i].recievebytes);
clients[i].buffer.remove(0, clients[i].recievebytes);
clients[i].recievebytes = 0;
clients[i].state = STATE_IDLE;
processIncomeingJson(json);

View file

@ -11,6 +11,14 @@
class TcpService : public ItemSource
{
Q_OBJECT
protected:
typedef enum
{
STATE_IDLE,
STATE_RECV_JSON,
} client_state_t;
signals:
void gotSensor(Sensor sensor);
@ -36,6 +44,9 @@ 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);
@ -45,18 +56,16 @@ public:
protected:
virtual void processIncomeingJson(const QByteArray& jsonbytes) override;
private slots:
void socketReadyRead();
void processComand(const QByteArray& command);
};
class TcpServer : public TcpService
{
Q_OBJECT
typedef enum
{
STATE_IDLE,
STATE_RECV_JSON,
} client_state_t;
struct Client
{
QTcpSocket* socket;
@ -73,6 +82,9 @@ public:
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);

View file

@ -21,18 +21,9 @@ void ItemScrollBox::addItem(std::weak_ptr<Item> item)
{
if(auto workItem = item.lock())
{
if(dynamic_cast<AuxItem*>(workItem.get()))
{
widgets_.push_back(new ItemWidget(item, true));
}
else if(dynamic_cast<MessageItem*>(workItem.get()))
{
widgets_.push_back(new ItemWidget(item, false, true));
}
else
{
if(workItem->isHidden())
return;
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);

View file

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

View file

@ -30,7 +30,7 @@ private slots:
void deleteItem();
public:
explicit ItemWidget(std::weak_ptr<Item> item, bool analog = false, bool nameOnly = false, QWidget *parent = nullptr);
explicit ItemWidget(std::weak_ptr<Item> item, QWidget *parent = nullptr);
std::weak_ptr<Item> getItem();
bool controles(const ItemData& relay);
~ItemWidget();

View file

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

View file

@ -1,10 +1,14 @@
#include "mainwindow.h"
#include <QMessageBox>
#include "ui_mainwindow.h"
#include "itemscrollbox.h"
#include "itemsettingsdialog.h"
#include "itemcreationdialog.h"
#include "../mainobject.h"
#include <QMessageBox>
#include "src/mainobject.h"
#include "src/programmode.h"
#include "src/items/poweritem.h"
MainWindow::MainWindow(MainObject * const mainObject, QWidget *parent) :
QMainWindow(parent),
@ -24,15 +28,20 @@ MainWindow::MainWindow(MainObject * const mainObject, QWidget *parent) :
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);
//Sensors
ui->sensorListView->setShowHidden(false);
ui->sensorListView->sensorsChanged(*globalSensors.getSensors());
connect(&globalSensors, &SensorStore::stateChenged, ui->sensorListView, &SensorListWidget::sensorsChanged);
//RGB Leds
connect(&colorChooser, SIGNAL(colorSelected(QColor)), this, SLOT(slotChangedRgb(QColor)));
connect(&colorChooser, &QColorDialog::colorSelected, this, &MainWindow::sigSetRgb);
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);
@ -47,25 +56,30 @@ MainWindow::~MainWindow()
void MainWindow::showPowerItemDialog()
{
ItemSettingsDialog diag(std::shared_ptr<Item>(_powerItem), this);
std::shared_ptr<PowerItem> powerItem;
for(std::shared_ptr<Item> item : *globalItems.getItems())
{
powerItem = std::dynamic_pointer_cast<PowerItem>(item);
if(powerItem)
break;
}
if(powerItem)
{
ItemSettingsDialog diag(std::shared_ptr<Item>(powerItem), this);
diag.show();
diag.exec();
}
else
{
QMessageBox::warning(this, "Error", "No power item found, refresh first");
}
}
void MainWindow::slotChangedRgb(const QColor color)
{
(void)color;
//_micro->changeRgbColor(color);
}
void MainWindow::showItemCreationDialog()
{
ItemCreationDialog diag(this);
diag.show();
if(diag.exec())
{
createdItem(diag.item);
}
}
void MainWindow::changeHeaderLableText(QString string)

View file

@ -6,8 +6,8 @@
#include <QListWidgetItem>
#include <QTime>
#include <memory>
#include "src/items/poweritem.h"
#include<src/items/item.h>
class MainObject;
@ -29,17 +29,15 @@ private:
QColorDialog colorChooser;
std::shared_ptr<PowerItem> _powerItem;
signals:
void sigSave();
void createdItem(std::shared_ptr<Item> item);
void sigSetRgb(const QColor color);
private slots:
//RGB
void slotChangedRgb(const QColor color);
void showPowerItemDialog();
void showItemCreationDialog();

View file

@ -42,7 +42,7 @@
<property name="autoFillBackground">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<layout class="QVBoxLayout" name="verticalLayout_5" stretch="1,0">
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
@ -114,44 +114,6 @@
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="button_color">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>48</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>128</height>
</size>
</property>
<property name="text">
<string>Color</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_power">
<property name="text">
<string>Config Shutdown</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@ -194,6 +156,52 @@
<property name="topMargin">
<number>0</number>
</property>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="pushButton_power">
<property name="text">
<string>Config Shutdown</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="button_color">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>128</height>
</size>
</property>
<property name="text">
<string>Color</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_refesh">
<property name="text">
@ -236,10 +244,6 @@
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>