diff --git a/CMakeLists.txt b/CMakeLists.txt index ea99bbe..924e5f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) add_compile_options(-Wall) # Find Qt packages -find_package(Qt6 COMPONENTS Core Gui Widgets Network Multimedia SerialPort Mqtt WebSockets REQUIRED) +find_package(Qt6 COMPONENTS Core Gui Widgets Network Multimedia SerialPort Mqtt REQUIRED) # Find dependencies using pkg-config find_package(PkgConfig REQUIRED) @@ -49,12 +49,8 @@ target_sources(SHinterface src/service/service.cpp src/service/tcpclient.h src/service/tcpclient.cpp - src/service/server.h - src/service/server.cpp src/service/tcpserver.h src/service/tcpserver.cpp - src/service/websocketserver.h - src/service/websocketserver.cpp src/actors/actor.h src/actors/actor.cpp @@ -170,7 +166,6 @@ target_link_libraries(SHinterface Qt6::Multimedia Qt6::SerialPort Qt6::Mqtt - Qt6::WebSockets ${PIPEWIRE_LIBRARIES} ${LIBNL3_LIBRARIES} ) diff --git a/UVOSicon.bmp b/UVOSicon.bmp index fd0d9a2..9565919 100644 Binary files a/UVOSicon.bmp and b/UVOSicon.bmp differ diff --git a/src/actors/polynomalactor.cpp b/src/actors/polynomalactor.cpp index f846c0e..053dc30 100644 --- a/src/actors/polynomalactor.cpp +++ b/src/actors/polynomalactor.cpp @@ -65,7 +65,7 @@ void PolynomalActor::load(const QJsonObject& json, bool preserve) pow2_ = json["Pow2"].toDouble(0); pow1_ = json["Pow1"].toDouble(1); pow0_ = json["Pow0"].toDouble(0); - sensor_.type = static_cast(json["SensorType"].toInt(0)); + sensor_.type = json["SensorType"].toInt(0); sensor_.id = json["SensorId"].toInt(0); sensor_.field = json["SensorField"].toInt(0); sensor_.name = json["SensorName"].toString("Sensor"); diff --git a/src/actors/regulator.cpp b/src/actors/regulator.cpp index 2287b7b..b3ea5f6 100644 --- a/src/actors/regulator.cpp +++ b/src/actors/regulator.cpp @@ -100,7 +100,7 @@ void Regulator::load(const QJsonObject& json, bool preserve) setPoint_ = json["SetPoint"].toDouble(22); safeValue_ = json["SafeValue"].toDouble(0); timeout_ = json["Timeout"].toDouble(1800); - sensor_.type = static_cast(json["SensorType"].toInt(0)); + sensor_.type = json["SensorType"].toInt(0); sensor_.id = json["SensorId"].toInt(0); sensor_.field = json["SensorField"].toInt(0); sensor_.name = json["SensorName"].toString("Sensor"); diff --git a/src/actors/sensoractor.cpp b/src/actors/sensoractor.cpp index 758b761..0be3ffa 100644 --- a/src/actors/sensoractor.cpp +++ b/src/actors/sensoractor.cpp @@ -65,7 +65,7 @@ void SensorActor::load(const QJsonObject& json, bool preserve) Actor::load(json, preserve); sloap_ = json["Sloap"].toInt(0); threshold_ = json["Threshold"].toDouble(0); - sensor_.type = static_cast(json["SensorType"].toInt(0)); + sensor_.type = json["SensorType"].toInt(0); sensor_.id = json["SensorId"].toInt(0); sensor_.field = json["SensorField"].toInt(0); sensor_.name = json["SensorName"].toString("Sensor"); diff --git a/src/items/item.cpp b/src/items/item.cpp index 53790ae..e297094 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -79,7 +79,7 @@ bool ItemData::hasChanged(const ItemData& other) return false; } -bool ItemData::isHidden() const +bool ItemData::isHidden() { return hidden_; } @@ -126,7 +126,6 @@ void Item::store(QJsonObject &json) } } json["Actors"] = actorsArray; - json["ValueType"] = type_; } void Item::load(const QJsonObject &json, const bool preserve) @@ -145,30 +144,6 @@ void Item::load(const QJsonObject &json, const bool preserve) } } -Item& Item::operator=(const ItemData& other) -{ - name_ = other.getName(); - value_ = other.getValue(); - itemId_ = other.id(); - hidden_ = other.isHidden(); - return *this; -} - -void Item::requestUpdate(ItemUpdateRequest update) -{ - if(!hasChanged(update.data)) - return; - - if(update.type == ITEM_UPDATE_USER || (update.type == ITEM_UPDATE_ACTOR && !override_) || update.type == ITEM_UPDATE_REMOTE) - { - if(programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY) - enactValue(update.data.getValue()); - *this = update.data; - update.data = *this; - updated(update); - } -} - void Item::actorSetValue(uint8_t value) { if(!override_ && (programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY)) @@ -179,7 +154,6 @@ void Item::setValue(uint8_t value) { qDebug()<<__func__; informValue(value); - updated(*this); if(programMode == PROGRAM_MODE_PRIMARY || programMode == PROGRAM_MODE_HEADLESS_PRIMARY) enactValue(value); } @@ -190,6 +164,7 @@ void Item::informValue(uint8_t value) { value_ = value; valueChanged(value_); + updated(*this); } } @@ -274,22 +249,30 @@ void Item::mergeLoaded(Item& item) std::shared_ptr Item::loadItem(const QJsonObject& json) { std::shared_ptr newItem = nullptr; - if(json["Type"].toString("Item") == "Item") - newItem = std::shared_ptr(new Item); - else if(json["Type"].toString("") == "Relay") + 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); - else - qWarning()<<"Unable to load unkown item type: "<load(json); diff --git a/src/items/item.h b/src/items/item.h index 4fbf23f..1aaa090 100644 --- a/src/items/item.h +++ b/src/items/item.h @@ -14,12 +14,6 @@ typedef enum { ITEM_VALUE_NO_VALUE } item_value_type_t; -typedef enum { - ITEM_UPDATE_USER = 0, - ITEM_UPDATE_ACTOR, - ITEM_UPDATE_REMOTE -} item_update_type_t; - class ItemData { protected: @@ -54,7 +48,7 @@ public: uint8_t getValue() const; bool getLoaded() const; void setLoaded(bool loaded); - bool isHidden() const; + bool isHidden(); void setHidden(bool hidden); item_value_type_t getValueType(); virtual QString getName() const; @@ -62,26 +56,24 @@ public: virtual void load(const QJsonObject& json, const bool preserve = false); }; -struct ItemUpdateRequest -{ - item_update_type_t type; - ItemData data; - bool valueOnly; -}; - class Item: public QObject, public ItemData { Q_OBJECT private: std::vector< std::shared_ptr > actors_; + bool override_ = false; signals: - void updated(ItemUpdateRequest update); + void valueChanged(uint8_t value); + void updated(ItemData data); + +private slots: + virtual void actorSetValue(uint8_t value); public slots: - void requestUpdate(ItemUpdateRequest update); + void setValue(uint8_t value); public: @@ -91,7 +83,6 @@ public: virtual ~Item(); - Item& operator=(const ItemData& other); std::vector< std::shared_ptr >& getActors(); bool hasActors(); void addActor(std::shared_ptr actor); @@ -100,6 +91,7 @@ public: void setActorsActive(bool in); void setOverride(const bool in); bool getOverride(); + void informValue(uint8_t value); void mergeLoaded(Item& item); virtual void store(QJsonObject& json); diff --git a/src/items/itemstore.cpp b/src/items/itemstore.cpp index e601aee..1242afc 100644 --- a/src/items/itemstore.cpp +++ b/src/items/itemstore.cpp @@ -95,9 +95,8 @@ void ItemStore::updateItem(const ItemData& item, bool inform) else items_[i]->setValue(item.getValue()); } - qDebug()<<"Item"<getName()<<"updated"<<(inform ? "with inform" : ""); - if(!inform) - itemUpdated(items_[i]); + qDebug()<<"Item"<getName()<<"updated"; + itemUpdated(items_[i]); } } } @@ -120,10 +119,7 @@ void ItemStore::itemUpdateSlot(ItemData data) for(std::shared_ptr& item: items_) { if(*item == data) - { - qDebug()<<"Item"<(item)); - } } } diff --git a/src/main.cpp b/src/main.cpp index 75c8e3d..8e5ca4c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,7 +35,7 @@ int main(int argc, char *argv[]) parser.addOption(masterOption); QCommandLineOption hostOption(QStringList() << "H" << "host", QCoreApplication::translate("main", "Set server host ip addres"), "address", "0.0.0.0"); parser.addOption(hostOption); - QCommandLineOption portOption(QStringList() << "p" << "port", QCoreApplication::translate("main", "Set server Port"), "port", "38940"); + QCommandLineOption portOption(QStringList() << "p" << "port", QCoreApplication::translate("main", "Set server Port"), "port", "104476"); parser.addOption(portOption); QCommandLineOption settingsPathOption(QStringList()<<"c"<<"config", QCoreApplication::translate("main", "Set config file"), "configFilePath", QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/shinterface.json"); diff --git a/src/mainobject.cpp b/src/mainobject.cpp index eed22d7..0f41d19 100644 --- a/src/mainobject.cpp +++ b/src/mainobject.cpp @@ -72,15 +72,13 @@ PrimaryMainObject::PrimaryMainObject(QIODevice* microDevice, const QString& sett MainObject(parent), settingsPath(settingsPath), micro(microDevice), - tcpServer(new TcpServer(this)), - webServer(new WebSocketServer("shinterface", this)), + tcpServer(new TcpServer), sunSensorSource(49.824972, 8.702194), fixedItems(µ) { //connect sensors subsystem connect(&globalSensors, &SensorStore::sensorChangedState, tcpServer, &TcpServer::sensorEvent); connect(tcpServer, &TcpServer::gotSensor, &globalSensors, &SensorStore::sensorGotState); - connect(webServer, &WebSocketServer::gotSensor, &globalSensors, &SensorStore::sensorGotState); connect(&sunSensorSource, &SunSensorSource::stateChanged, &globalSensors, &SensorStore::sensorGotState); connect(µ, &Microcontroller::gotSensorState, &globalSensors, &SensorStore::sensorGotState); connect(&mqttSensorSource, &MqttSensorSource::stateChanged, &globalSensors, &SensorStore::sensorGotState); @@ -89,7 +87,6 @@ PrimaryMainObject::PrimaryMainObject(QIODevice* microDevice, const QString& sett globalItems.registerItemSource(&fixedItems); globalItems.registerItemSource(tcpServer); - globalItems.registerItemSource(webServer); globalItems.registerItemSource(µ); globalItems.registerItemSource(&itemLoader); @@ -101,9 +98,7 @@ PrimaryMainObject::PrimaryMainObject(QIODevice* microDevice, const QString& sett mqttSensorSource.start(mqttJson); tcpServer->launch(QHostAddress(host), port); - webServer->launch(QHostAddress(host), port+1); connect(&globalItems, &ItemStore::itemUpdated, tcpServer, &TcpServer::itemUpdated); - connect(&globalItems, &ItemStore::itemUpdated, webServer, &WebSocketServer::itemUpdated); } PrimaryMainObject::~PrimaryMainObject() diff --git a/src/mainobject.h b/src/mainobject.h index 48835dc..7f582d8 100644 --- a/src/mainobject.h +++ b/src/mainobject.h @@ -19,7 +19,6 @@ #include "items/itemloadersource.h" #include "service/tcpclient.h" #include "service/tcpserver.h" -#include "service/websocketserver.h" class MainObject : public QObject { @@ -45,7 +44,6 @@ public: Microcontroller micro; TcpServer* tcpServer; - WebSocketServer* webServer; //sensors SunSensorSource sunSensorSource; diff --git a/src/sensors/sensor.cpp b/src/sensors/sensor.cpp index 576d1db..e2a262f 100644 --- a/src/sensors/sensor.cpp +++ b/src/sensors/sensor.cpp @@ -6,8 +6,8 @@ SensorStore globalSensors; SensorStore::SensorStore(QObject *parent): QObject(parent) { - sensors_.push_back(Sensor(Sensor::TYPE_DOOR,1,0,"Front door")); - sensors_.push_back(Sensor(Sensor::TYPE_DOOR,0,0,"Bedroom door")); + sensors_.push_back(Sensor(0,1,0,"Front door")); + sensors_.push_back(Sensor(0,0,0,"Bedroom door")); } void SensorStore::sensorGotState(const Sensor& sensor) diff --git a/src/sensors/sensor.h b/src/sensors/sensor.h index 86fa5cb..bc5e748 100644 --- a/src/sensors/sensor.h +++ b/src/sensors/sensor.h @@ -10,34 +10,32 @@ class Sensor { public: - typedef enum { - TYPE_DOOR = 0, - TYPE_TEMPERATURE, - TYPE_HUMIDITY, - TYPE_PRESSURE, - TYPE_BRIGHTNESS, - TYPE_BUTTON, - TYPE_ADC, - TYPE_CO2, - TYPE_FORMALDEHYD, - TYPE_PM25, - TYPE_TOTAL_VOC, - TYPE_LOWBATTERY = 128, - TYPE_SHUTDOWN_IMMINENT = 251, - TYPE_OCUPANCY, - TYPE_SUN_ALTITUDE, - TYPE_AUDIO_OUTPUT, - TYPE_DUMMY, - } sensor_type_t; + static constexpr uint8_t TYPE_DOOR = 0; + static constexpr uint8_t TYPE_TEMPERATURE = 1; + static constexpr uint8_t TYPE_HUMIDITY = 2; + static constexpr uint8_t TYPE_PRESSURE = 3; + 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; + static constexpr uint8_t TYPE_SUN_ALTITUDE = 253; + static constexpr uint8_t TYPE_AUDIO_OUTPUT = 254; + static constexpr uint8_t TYPE_DUMMY = 255; - sensor_type_t type; + uint8_t type; uint64_t id; float field; QString name; QDateTime lastSeen; bool hidden; - Sensor(sensor_type_t typeIn, uint64_t idIn, float fieldIn = 0, QString nameIn = "", bool hiddenIn = false): type(typeIn), + Sensor(uint64_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(); @@ -50,14 +48,12 @@ public: } Sensor(const QJsonObject& json) { - type = static_cast(json["SensorType"].toInt(0)); + 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); - name = json["Name"].toString(); - if(name == "") - generateName(); } inline bool operator==(const Sensor& in) const { @@ -76,7 +72,7 @@ public: QStringList bufferList = str.split(' '); if(bufferList.size() >= 7) { - Sensor sensor(static_cast(bufferList[2].toUInt()), bufferList[4].toUInt(), bufferList[6].toUInt()); + Sensor sensor(bufferList[2].toUInt(), bufferList[4].toUInt(), bufferList[6].toUInt()); if(sensor.type == Sensor::TYPE_HUMIDITY || sensor.type == Sensor::TYPE_TEMPERATURE) sensor.field = sensor.field/10; @@ -104,7 +100,6 @@ public: json["Name"] = name; json["LastSeen"] = lastSeen.toString(); json["Hidden"] = hidden; - json["Unit"] = getUnit(); } inline void generateName() { @@ -124,31 +119,6 @@ public: name = "Shutdown Imminent"; else name = "Sensor Type " + QString::number(type) + " Id " + QString::number(id); } - QString getUnit() - { - switch(type) - { - case TYPE_TEMPERATURE: - return "°C"; - case TYPE_HUMIDITY: - return "%"; - case TYPE_PRESSURE: - return "hPa"; - case TYPE_BRIGHTNESS: - return "lx"; - case TYPE_CO2: - return "ppm"; - case TYPE_FORMALDEHYD: - case TYPE_PM25: - return "µg/m³"; - case TYPE_TOTAL_VOC: - return "ppb"; - case TYPE_SUN_ALTITUDE: - return "°"; - default: - return ""; - } - } }; class SensorStore: public QObject diff --git a/src/service/server.cpp b/src/service/server.cpp deleted file mode 100644 index e01ba4c..0000000 --- a/src/service/server.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include - -#include "items/item.h" -#include "service.h" -#include "server.h" - -Server::Server(QObject* parent) - : Service(parent) -{ -} - -Server::~Server() -{ -} - -void Server::processIncomeingJson(const QByteArray& jsonbytes) -{ - QJsonDocument doc = QJsonDocument::fromJson(jsonbytes); - QJsonObject json = doc.object(); - QString type = json["MessageType"].toString(); - if(type == "ItemUpdate") - { - 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); - if(item) - { - qDebug()<<"Server got item"<getName(); - item->setLoaded(FullList); - items.push_back(item); - } - } - if(FullList && !items.empty()) - { - requestReplaceItems(items); - sigRequestSave(); - } - else if(!items.empty()) - { - gotItems(items, false); - } - } - else - { - Service::processIncomeingJson(jsonbytes); - } -} - -void Server::handleSocketError() -{ - QObject* obj = sender(); - if (obj) { - removeClient(static_cast(obj)); - } -} - -void Server::handleSocketDisconnect() -{ - QObject* obj = sender(); - if (obj) { - removeClient(static_cast(obj)); - } -} - -void Server::removeClient(QTcpSocket* socket) -{ - for(size_t i = 0; i < clients.size(); i++) - { - if(clients[i].socket.tcpSocket == socket) - { - clients.erase(clients.begin() + i); - --i; - } - } -} - -void Server::removeClient(QWebSocket* socket) -{ - for(size_t i = 0; i < clients.size(); i++) - { - if(clients[i].socket.webSocket == socket) - { - clients.erase(clients.begin() + i); - --i; - } - } -} diff --git a/src/service/server.h b/src/service/server.h deleted file mode 100644 index 6c27062..0000000 --- a/src/service/server.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef SERVER_BASE_H -#define SERVER_BASE_H - -#include -#include -#include - -#include "service.h" - -class Server : public Service -{ - Q_OBJECT - -protected: - typedef enum - { - STATE_IDLE, - STATE_RECV_JSON, - } client_state_t; - - struct Client - { - union { - QTcpSocket* tcpSocket; - QWebSocket* webSocket; - } socket; - QByteArray buffer; - client_state_t state = STATE_IDLE; - long long recievebytes = 0; - }; - - std::vector clients; - -public: - Server(QObject* parent = nullptr); - virtual ~Server(); - -protected: - virtual void processIncomeingJson(const QByteArray& jsonbytes) override; - void handleSocketError(); - void handleSocketDisconnect(); - void removeClient(QTcpSocket* socket); - void removeClient(QWebSocket* socket); - -signals: - void sigRequestSave(); -}; - -#endif // SERVER_BASE_H diff --git a/src/service/service.cpp b/src/service/service.cpp index eb27ee0..5129512 100644 --- a/src/service/service.cpp +++ b/src/service/service.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "items/item.h" #include "items/itemstore.h" @@ -31,7 +32,7 @@ void Service::sensorEvent(Sensor sensor) void Service::itemUpdated(std::weak_ptr item) { - qDebug()<<"Service sending item"<getName(); + qDebug()<<__func__; QJsonArray items; QJsonObject itemjson; item.lock()->store(itemjson); @@ -77,6 +78,7 @@ void Service::sendItems() void Service::processIncomeingJson(const QByteArray& jsonbytes) { QJsonDocument doc = QJsonDocument::fromJson(jsonbytes); + qDebug()<<"Got Json:"<> items; for(QJsonValueRef itemjson : data) @@ -41,7 +42,6 @@ void TcpClient::processIncomeingJson(const QByteArray& jsonbytes) std::shared_ptr item = Item::loadItem(jsonobject); if(item) { - qDebug()<<"Client got item"<getName(); item->setLoaded(false); items.push_back(item); } diff --git a/src/service/tcpserver.cpp b/src/service/tcpserver.cpp index ed1b620..b5b780f 100644 --- a/src/service/tcpserver.cpp +++ b/src/service/tcpserver.cpp @@ -4,11 +4,11 @@ #include #include "items/item.h" -#include "server.h" +#include "service.h" #include "tcpserver.h" TcpServer::TcpServer(QObject* parent): - Server(parent), + Service(parent), server(this) { connect(&server, &QTcpServer::newConnection, this, &TcpServer::incomingConnection); @@ -16,23 +16,50 @@ TcpServer::TcpServer(QObject* parent): void TcpServer::sendJson(const QJsonObject& json) { - for(auto& client: clients) + for(auto client: clients) { - if(client.socket.tcpSocket) { - QByteArray jsonData = QJsonDocument(json).toJson(); - client.socket.tcpSocket->write(QString("MSG JSON LEN " + QString::number(jsonData.size()) + "\n").toLatin1() + jsonData); - } + 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) { - Server::processIncomeingJson(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 + { + Service::processIncomeingJson(jsonbytes); + } } bool TcpServer::launch(const QHostAddress &address, quint16 port) { - qInfo()<<"Tcp server launched on"<peerAddress().toString(); if(client) { - Client c; - c.socket.tcpSocket = client; - clients.push_back(c); - connect(client, &QTcpSocket::errorOccurred, this, [this, client]() { removeClient(client); }); - connect(client, &QTcpSocket::disconnected, this, [this, client]() { removeClient(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 ")) @@ -68,15 +117,15 @@ void TcpServer::socketReadyRead() { for(size_t i = 0; i < clients.size(); i++) { - QTcpSocket* tcp = clients[i].socket.tcpSocket; - if(tcp && tcp == sender()) + if(clients[i].socket == sender()) { - QByteArray newChars = tcp->readAll(); + QByteArray newChars = clients[i].socket->readAll(); clients[i].buffer += newChars; bool remianing = true; while(remianing) { + qDebug()< #include -#include "server.h" +#include "service.h" -class TcpServer : public Server +class TcpServer : public Service { Q_OBJECT + struct Client + { + QTcpSocket* socket; + QByteArray buffer; + client_state_t state = STATE_IDLE; + long long recievebytes = 0; + }; + + std::vector clients; QTcpServer server; public: @@ -22,6 +31,8 @@ signals: private slots: void incomingConnection(); + void socketError(QAbstractSocket::SocketError socketError); + void socketDisconnect(); void socketReadyRead(); protected: diff --git a/src/service/websocketserver.cpp b/src/service/websocketserver.cpp deleted file mode 100644 index 2a34bc1..0000000 --- a/src/service/websocketserver.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include -#include -#include - -#include "items/item.h" -#include "server.h" -#include "websocketserver.h" - -WebSocketServer::WebSocketServer(const QString &serverName, QObject* parent) - : Server(parent), - server(serverName, QWebSocketServer::NonSecureMode, this) -{ - connect(&server, &QWebSocketServer::newConnection, this, &WebSocketServer::incomingConnection); -} - -WebSocketServer::~WebSocketServer() -{ - // Clean up WebSocket clients (they need special handling) - for(auto& client : clients) - { - if(client.socket.webSocket) - { - client.socket.webSocket->close(); - delete client.socket.webSocket; - } - } -} - -void WebSocketServer::sendJson(const QJsonObject& json) -{ - QByteArray jsonData = QJsonDocument(json).toJson(); - for(auto& client : clients) - { - if(client.socket.webSocket && client.socket.webSocket->state() == QAbstractSocket::ConnectedState) - { - client.socket.webSocket->sendTextMessage(QString::fromUtf8(jsonData)); - } - } -} - -void WebSocketServer::processIncomeingJson(const QByteArray& jsonbytes) -{ - // Validate JSON first (WebSockets may receive malformed data) - QJsonDocument doc = QJsonDocument::fromJson(jsonbytes); - if(!doc.isObject()) - { - qWarning() << "Invalid JSON received:" << QString::fromUtf8(jsonbytes); - return; - } - - Server::processIncomeingJson(jsonbytes); -} - -bool WebSocketServer::launch(const QHostAddress &address, quint16 port) -{ - qInfo()<<"WebSocket server launched on"<peerAddress().toString(); - if(client) - { - Client c; - c.socket.webSocket = client; - clients.push_back(c); - connect(client, &QWebSocket::errorOccurred, this, [this, client]() { removeClient(client); }); - connect(client, &QWebSocket::disconnected, this, [this, client]() { removeClient(client); }); - connect(client, &QWebSocket::textMessageReceived, this, &WebSocketServer::textMessageReceived); - } - } -} - -void WebSocketServer::textMessageReceived(const QString &message) -{ - QByteArray jsonData = message.toUtf8(); - processIncomeingJson(jsonData); -} diff --git a/src/service/websocketserver.h b/src/service/websocketserver.h deleted file mode 100644 index 73d74de..0000000 --- a/src/service/websocketserver.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef WEBSOCKETSERVER_SERVER_H -#define WEBSOCKETSERVER_SERVER_H - -#include -#include - -#include "server.h" - -class WebSocketServer : public Server -{ - Q_OBJECT - - QWebSocketServer server; - -public: - WebSocketServer(const QString &serverName, QObject* parent = nullptr); - virtual ~WebSocketServer(); - virtual bool launch(const QHostAddress &address = QHostAddress::Any, quint16 port = 0) override; - virtual void sendJson(const QJsonObject& json) override; - -private slots: - void incomingConnection(); - void textMessageReceived(const QString &message); - -protected: - virtual void processIncomeingJson(const QByteArray& jsonbytes) override; - -signals: - void sigRequestSave(); -}; - -#endif // WEBSOCKETSERVER_SERVER_H diff --git a/src/ui/itemwidget.ui b/src/ui/itemwidget.ui index 96b625e..91d92f5 100644 --- a/src/ui/itemwidget.ui +++ b/src/ui/itemwidget.ui @@ -46,17 +46,11 @@ 255 - true + false Qt::Orientation::Horizontal - - false - - - false - diff --git a/src/ui/mainwindow.ui b/src/ui/mainwindow.ui index baa31c8..0e6732c 100644 --- a/src/ui/mainwindow.ui +++ b/src/ui/mainwindow.ui @@ -94,7 +94,7 @@ - 400 + 300 0 diff --git a/src/ui/sensorlistwidget.cpp b/src/ui/sensorlistwidget.cpp index b732362..827ab2e 100644 --- a/src/ui/sensorlistwidget.cpp +++ b/src/ui/sensorlistwidget.cpp @@ -55,11 +55,6 @@ void SensorListWidget::sensorsChanged(std::vector sensors) itemString.append("\"Playing\""); else itemString.append("\"Silent\""); } - else if(!sensors[i].getUnit().isEmpty()) - { - itemString.append(" "); - itemString.append(sensors[i].getUnit()); - } setItem(static_cast(row), 0, new SensorListItem(sensors[i].name + (sensors[i].hidden ? " (H)" : ""), sensors[i])); setItem(static_cast(row), 1, new QTableWidgetItem(itemString));