aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2022-12-09 15:47:27 +0100
committerlonkaars <loek@pipeframe.xyz>2022-12-09 15:47:27 +0100
commit1d1799da8880b19aac0dbd2975facf97138bab61 (patch)
tree4b05c2e4d61782d5da1499435df32c9142dc38af
parent7db6cde62ee6df76df798f108b747398de8ab26b (diff)
refactor mesh connector and fix duplicate list entries on refresh
-rw-r--r--confui/mainwindow.cpp12
-rw-r--r--confui/mainwindow.h4
-rw-r--r--confui/mesh_connector.cpp170
-rw-r--r--confui/mesh_connector.h44
-rw-r--r--confui/ui_automation.cpp8
-rw-r--r--confui/ui_node.cpp6
-rw-r--r--confui/ui_tab_automations.cpp14
-rw-r--r--confui/ui_tab_automations.h4
-rw-r--r--confui/ui_tab_node_overview.cpp6
-rw-r--r--confui/ui_tab_node_overview.h4
10 files changed, 144 insertions, 128 deletions
diff --git a/confui/mainwindow.cpp b/confui/mainwindow.cpp
index 1f3e333..bc2adee 100644
--- a/confui/mainwindow.cpp
+++ b/confui/mainwindow.cpp
@@ -20,11 +20,11 @@ CDMainWindow::CDMainWindow(QWidget *parent) : QMainWindow(parent) {
QTabWidget* tab_bar_widget = new QTabWidget(this);
- automations_widget = new CDAutomationsTabWidget(this);
- node_overview_widget = new CDNodeOverviewTabWidget(this);
+ automations_tab = new CDAutomationsTabWidget(this);
+ node_overview_tab = new CDNodeOverviewTabWidget(this);
- tab_bar_widget->addTab(this->node_overview_widget, "node overview");
- tab_bar_widget->addTab(this->automations_widget, "automations");
+ tab_bar_widget->addTab(this->node_overview_tab, "node overview");
+ tab_bar_widget->addTab(this->automations_tab, "automations");
setMenuBar(menu_bar);
setCentralWidget(tab_bar_widget);
@@ -32,6 +32,10 @@ CDMainWindow::CDMainWindow(QWidget *parent) : QMainWindow(parent) {
}
void CDMainWindow::update() {
+ // update tabs (children widgets)
+ automations_tab->update();
+ node_overview_tab->update();
+
setWindowTitle("confui");
menu_bar->clear();
diff --git a/confui/mainwindow.h b/confui/mainwindow.h
index d689f2e..398ed7f 100644
--- a/confui/mainwindow.h
+++ b/confui/mainwindow.h
@@ -14,8 +14,8 @@ class CDMainWindow : public QMainWindow {
Q_OBJECT
private:
QMenuBar* menu_bar = nullptr;
- CDAutomationsTabWidget* automations_widget = nullptr;
- CDNodeOverviewTabWidget* node_overview_widget = nullptr;
+ CDAutomationsTabWidget* automations_tab = nullptr;
+ CDNodeOverviewTabWidget* node_overview_tab = nullptr;
public:
CDMeshConnector *mesh_connector = nullptr;
diff --git a/confui/mesh_connector.cpp b/confui/mesh_connector.cpp
index c87d8c5..d32855a 100644
--- a/confui/mesh_connector.cpp
+++ b/confui/mesh_connector.cpp
@@ -8,78 +8,85 @@
using std::pair;
-cd_link_t CDMeshConnector::get_new_map_id() {
- return _fresh_map_id++;
+void CDMeshConnector::refresh_config_sync() { }
+void CDMeshConnector::refresh_nodes_sync() { }
+
+cd_link_t CDMeshConnector::get_new_link_id() {
+ return _fresh_link_id++;
+}
+
+cd_uid_t CDMeshConnector::get_new_node_id() {
+ return _fresh_node_id++;
}
CDMeshConnector::CDMeshConnector() {
- printf("adding dummy node berta...\n");
-
- char* temp_node_berta_name = (char*) malloc(5);
- memcpy(temp_node_berta_name, "berta", 5);
-
- cd_s_node* temp_node_berta = (cd_s_node*) malloc(sizeof(cd_s_node));
- temp_node_berta->name = temp_node_berta_name;
- temp_node_berta->name_len = 5;
- temp_node_berta->light_on = false;
- temp_node_berta->provisioned = false;
- cd_mac_addr_t temp_node_berta_address = { 0x00, 0xff, 0x21, 0x69, 0xf2, 0x31 };
- memcpy(temp_node_berta->address, temp_node_berta_address, 6);
-
- printf("adding dummy node gerrit...\n");
- char* temp_node_gerrit_name = (char*) malloc(6);
- memcpy(temp_node_gerrit_name, "gerrit", 6);
-
- cd_s_node* temp_node_gerrit = (cd_s_node*) malloc(sizeof(cd_s_node));
- temp_node_gerrit->name = temp_node_gerrit_name;
- temp_node_gerrit->name_len = 6;
- temp_node_gerrit->light_on = false;
- temp_node_gerrit->provisioned = false;
- cd_mac_addr_t temp_node_gerrit_address = { 0x0e, 0xf9, 0x46, 0x4d, 0xe8, 0x02 };
- memcpy(temp_node_gerrit->address, temp_node_gerrit_address, 6);
-
- _nodes.push_back(temp_node_berta);
- _nodes.push_back(temp_node_gerrit);
- create_link(temp_node_berta, temp_node_berta, CD_AUTOMATION_TYPE_TOGGLE);
- create_link(temp_node_berta, temp_node_gerrit, CD_AUTOMATION_TYPE_TOGGLE);
- create_link(temp_node_gerrit, temp_node_berta, CD_AUTOMATION_TYPE_TURN_OFF);
- create_link(temp_node_gerrit, temp_node_gerrit, CD_AUTOMATION_TYPE_TURN_ON);
+ cd_uid_t berta = create_node({
+ .id = 0, // automatically assigned (satisfy compiler)
+ .address = { 0x00, 0xff, 0x21, 0x69, 0xf2, 0x31 },
+ .name_len = 5,
+ .name = "berta",
+ .light_on = false,
+ .provisioned = false,
+ });
+
+ cd_uid_t gerrit = create_node({
+ .id = 0, // automatically assigned (satisfy compiler)
+ .address = { 0x0e, 0xf9, 0x46, 0x4d, 0xe8, 0x02 },
+ .name_len = 6,
+ .name = "gerrit",
+ .light_on = false,
+ .provisioned = false,
+ });
+
+ create_link(berta, berta, CD_AUTOMATION_TYPE_TOGGLE);
+ create_link(berta, berta, CD_AUTOMATION_TYPE_TOGGLE);
+ create_link(gerrit, berta, CD_AUTOMATION_TYPE_TURN_OFF);
+ create_link(gerrit, gerrit, CD_AUTOMATION_TYPE_TURN_ON);
return;
}
-CDMeshConnector::~CDMeshConnector() {
- map<cd_link_t, cd_s_automation*> links = get_links();
- vector<cd_s_node*> nodes = get_raw_nodes();
+cd_uid_t CDMeshConnector::create_node(cd_s_node node) {
+ cd_s_node* _node = (cd_s_node*) malloc(sizeof(cd_s_node));
- // free all automation structs
- for (pair<cd_link_t, cd_s_automation*> link : links)
- remove_link(link.first);
+ // id
+ cd_uid_t id = get_new_node_id();
+ _node->id = id;
+ // address
+ memcpy(_node->address, node.address, sizeof(cd_mac_addr_t));
+ // name len
+ _node->name_len = node.name_len;
+ // name
+ char* name = (char*) malloc(node.name_len);
+ memcpy(name, node.name, node.name_len);
+ _node->name = name;
+ // light on
+ _node->light_on = node.light_on;
+ // provisioned
+ _node->provisioned = node.provisioned;
- // free all node structs
- for (cd_s_node* node : nodes)
- if (node != nullptr) free(node);
+ printf("(new) node[%d] = %.*s\n", id, (int) node.name_len, node.name);
- return;
+ _nodes[id] = _node;
+ return id;
}
-void CDMeshConnector::refresh_config_sync() {
- return;
-}
+CDMeshConnector::~CDMeshConnector() {
+ // free all automation structs
+ for (pair<cd_link_t, cd_s_automation*> link : _links)
+ remove_link(link.first);
-void CDMeshConnector::refresh_nodes_sync() {
- return;
-}
+ // free all node structs
+ for (pair<cd_uid_t, cd_s_node*> node : _nodes)
+ remove_node(node.first);
-vector<cd_s_node*> CDMeshConnector::get_raw_nodes() {
- return _nodes;
+ return;
}
-map<cd_mac_addr_cpp_t, cd_s_node*> CDMeshConnector::get_nodes(bool provisioned) {
- map<cd_mac_addr_cpp_t, cd_s_node*> nodes;
- vector<cd_s_node*> raw_nodes = get_raw_nodes();
- for (cd_s_node* node : raw_nodes) {
- if (provisioned && (node->provisioned == false)) continue;
- nodes[cd_mac_to_cpp_arr(node->address)] = node;
+map<cd_uid_t, cd_s_node*> CDMeshConnector::get_nodes(bool provisioned) {
+ map<cd_uid_t, cd_s_node*> nodes;
+ for (pair<cd_uid_t, cd_s_node*> node : _nodes) {
+ if (provisioned && (node.second->provisioned == false)) continue;
+ nodes[node.first] = node.second;
}
return nodes;
}
@@ -88,45 +95,40 @@ map<cd_link_t, cd_s_automation*> CDMeshConnector::get_links() {
return _links;
}
-vector<cd_s_automation*> CDMeshConnector::get_config() {
- vector<cd_s_automation*> automations;
- map<cd_link_t, cd_s_automation*> links = get_links();
- for (pair<cd_link_t, cd_s_automation*> link : links)
- automations.push_back(link.second);
- return automations;
-}
-
-void CDMeshConnector::set_link(cd_link_t link, cd_s_automation* automation) {
+void CDMeshConnector::update_link(cd_link_t link, cd_s_automation* automation) {
_links[link] = automation;
printf("link[%d] = %.*s %s %.*s\n", link, (int) automation->button->name_len, automation->button->name, automation->type == CD_AUTOMATION_TYPE_TOGGLE ? "toggles" : automation->type == CD_AUTOMATION_TYPE_TURN_OFF ? "turns off" : "turns on", (int) automation->light->name_len, automation->light->name);
}
-cd_link_t CDMeshConnector::create_link(cd_s_node* button, cd_s_node* light, enum cd_e_automation_type type) {
+cd_link_t CDMeshConnector::create_link(cd_uid_t button, cd_uid_t light, enum cd_e_automation_type type) {
+ cd_link_t id = get_new_link_id();
+
cd_s_automation* automation = (cd_s_automation*) malloc(sizeof(cd_s_automation));
- automation->button = button;
- automation->light = light;
+ automation->id = id;
automation->type = type;
+ automation->button = _nodes[button];
+ automation->light = _nodes[light];
- cd_link_t link = get_new_map_id();
printf("(new) ");
- set_link(link, automation);
+ update_link(id, automation);
- return link;
+ return id;
}
void CDMeshConnector::remove_link(cd_link_t link_handle) {
printf("remove link[%d]\n", link_handle);
- if (_links[link_handle] != nullptr) free(_links[link_handle]);
+ if (_links[link_handle] != nullptr)
+ free(_links[link_handle]);
_links.erase(link_handle);
return;
}
-cd_s_node* CDMeshConnector::get_node_by_id(cd_mac_addr_t address) {
- cd_s_node* node = std::find_if(_nodes.begin(), _nodes.end(),
- [address] (const cd_s_node* n) {
- return strncmp((char*)n->address, (char*)address, 6);
- })[0];
- return node;
+void CDMeshConnector::remove_node(cd_uid_t node_handle) {
+ printf("remove node[%d]\n", node_handle);
+ if (_nodes[node_handle] != nullptr)
+ free(_nodes[node_handle]);
+ _nodes.erase(node_handle);
+ return;
}
void CDMeshConnector::update_node(cd_s_node* node_ptr) {
@@ -134,19 +136,19 @@ void CDMeshConnector::update_node(cd_s_node* node_ptr) {
return;
}
-void CDMeshConnector::node_join_network(cd_s_node* node_ptr) {
+void CDMeshConnector::network_join_node(cd_s_node* node_ptr) {
node_ptr->provisioned = true;
printf("join %.*s into network\n", (int) node_ptr->name_len, node_ptr->name);
return;
}
-void CDMeshConnector::node_remove_network(cd_s_node* node_ptr) {
+void CDMeshConnector::network_remove_node(cd_s_node* node_ptr) {
node_ptr->provisioned = false;
printf("remove %.*s from network\n", (int) node_ptr->name_len, node_ptr->name);
return;
}
-string cd_mac_to_string(cd_mac_addr_t mac) {
+string CDMeshConnector::cd_mac_to_string(cd_mac_addr_t mac) {
char* addr = nullptr;
asprintf(&addr, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
string ret = addr;
@@ -154,7 +156,3 @@ string cd_mac_to_string(cd_mac_addr_t mac) {
return ret;
}
-cd_mac_addr_cpp_t cd_mac_to_cpp_arr(cd_mac_addr_t mac) {
- return { mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] };
-}
-
diff --git a/confui/mesh_connector.h b/confui/mesh_connector.h
index 220974a..7ead59a 100644
--- a/confui/mesh_connector.h
+++ b/confui/mesh_connector.h
@@ -11,9 +11,9 @@ using std::map;
using std::string;
using std::array;
+typedef uint32_t cd_uid_t;
typedef uint32_t cd_link_t;
typedef uint8_t cd_mac_addr_t[6];
-typedef array<uint8_t, 6> cd_mac_addr_cpp_t;
enum cd_e_automation_type {
CD_AUTOMATION_TYPE_TOGGLE,
@@ -22,6 +22,7 @@ enum cd_e_automation_type {
};
typedef struct {
+ cd_uid_t id;
cd_mac_addr_t address;
size_t name_len;
const char* name;
@@ -30,6 +31,7 @@ typedef struct {
} cd_s_node;
typedef struct {
+ cd_link_t id;
cd_e_automation_type type;
cd_s_node* button;
cd_s_node* light;
@@ -37,30 +39,42 @@ typedef struct {
class CDMeshConnector {
private:
- vector<cd_s_node*> _nodes;
map<cd_link_t, cd_s_automation*> _links;
- cd_link_t _fresh_map_id = 0;
- virtual cd_link_t get_new_map_id();
+ map<cd_uid_t, cd_s_node*> _nodes;
+
+ virtual cd_link_t get_new_link_id();
+ virtual cd_uid_t get_new_node_id();
+
+ cd_link_t _fresh_link_id = 0;
+ cd_uid_t _fresh_node_id = 0;
+
+ virtual cd_uid_t create_node(cd_s_node node);
+ virtual void remove_node(cd_uid_t node_handle);
+
public:
CDMeshConnector();
virtual ~CDMeshConnector();
+
+ // (UNUSED/UNIMPLEMENTED) refresh functions
virtual void refresh_nodes_sync();
virtual void refresh_config_sync();
+
+ // data fetching functions
virtual map<cd_link_t, cd_s_automation*> get_links();
- virtual map<cd_mac_addr_cpp_t, cd_s_node*> get_nodes(bool provisioned);
- virtual vector<cd_s_node*> get_raw_nodes();
- virtual vector<cd_s_automation*> get_config();
- virtual cd_link_t create_link(cd_s_node* button, cd_s_node* light, enum cd_e_automation_type action);
- virtual void set_link(cd_link_t link, cd_s_automation* automation);
+ virtual map<cd_uid_t, cd_s_node*> get_nodes(bool provisioned = false);
+
+ // network modification functions
+ virtual cd_link_t create_link(cd_uid_t button, cd_uid_t light, enum cd_e_automation_type action);
+ virtual void update_link(cd_link_t link, cd_s_automation* automation);
virtual void remove_link(cd_link_t link_handle);
- virtual cd_s_node* get_node_by_id(cd_mac_addr_t address);
+
virtual void update_node(cd_s_node* node_ptr);
- virtual void node_join_network(cd_s_node* node_ptr);
- virtual void node_remove_network(cd_s_node* node_ptr);
+ virtual void network_join_node(cd_s_node* node_ptr);
+ virtual void network_remove_node(cd_s_node* node_ptr);
+
+ // conversion functions
+ static string cd_mac_to_string(cd_mac_addr_t mac);
};
extern CDMeshConnector* g_cd_mesh_connector;
-string cd_mac_to_string(cd_mac_addr_t mac);
-cd_mac_addr_cpp_t cd_mac_to_cpp_arr(cd_mac_addr_t mac);
-
diff --git a/confui/ui_automation.cpp b/confui/ui_automation.cpp
index 3c555cd..72e2446 100644
--- a/confui/ui_automation.cpp
+++ b/confui/ui_automation.cpp
@@ -30,15 +30,15 @@ void CDAutomationWidget::set_automation(cd_link_t link, cd_s_automation* automat
void CDAutomationWidget::update() {
button_remove->setText("Delete");
- map<cd_mac_addr_cpp_t, cd_s_node*> nodes = g_cd_mesh_connector->get_nodes(false);
+ map<cd_uid_t, cd_s_node*> nodes = g_cd_mesh_connector->get_nodes(false);
dropdown_button->clear();
dropdown_light->clear();
- for (pair<cd_mac_addr_cpp_t, cd_s_node*> node : nodes) {
+ for (pair<cd_uid_t, cd_s_node*> node : nodes) {
QString label = "";
label.append(QString::fromLocal8Bit(node.second->name, node.second->name_len));
label.append(" (");
- label.append(QString::fromStdString(cd_mac_to_string(node.second->address)));
+ label.append(QString::fromStdString(CDMeshConnector::cd_mac_to_string(node.second->address)));
label.append(")");
QString userData = QString::fromLocal8Bit((char*) node.second->address, 6);
@@ -66,5 +66,5 @@ bool CDAutomationWidget::conf_valid() {
void CDAutomationWidget::apply() {
if (!conf_valid()) return;
- g_cd_mesh_connector->set_link(_id, _automation);
+ g_cd_mesh_connector->update_link(_id, _automation);
}
diff --git a/confui/ui_node.cpp b/confui/ui_node.cpp
index f369fba..41ffad6 100644
--- a/confui/ui_node.cpp
+++ b/confui/ui_node.cpp
@@ -31,7 +31,7 @@ void CDNodeWidget::update() {
QString node_name = QString::fromLocal8Bit(_node->name, _node->name_len);
label_node_name->setText(node_name);
- QString node_address = QString::fromStdString(cd_mac_to_string(_node->address));
+ QString node_address = QString::fromStdString(CDMeshConnector::cd_mac_to_string(_node->address));
node_address.prepend("(");
node_address.append(")");
label_node_address->setText(node_address);
@@ -45,8 +45,8 @@ void CDNodeWidget::update() {
}
void CDNodeWidget::toggle_provision() {
- if (_node->provisioned) g_cd_mesh_connector->node_remove_network(_node);
- else g_cd_mesh_connector->node_join_network(_node);
+ if (_node->provisioned) g_cd_mesh_connector->network_remove_node(_node);
+ else g_cd_mesh_connector->network_join_node(_node);
update();
}
diff --git a/confui/ui_tab_automations.cpp b/confui/ui_tab_automations.cpp
index 0702d20..af02ab9 100644
--- a/confui/ui_tab_automations.cpp
+++ b/confui/ui_tab_automations.cpp
@@ -4,7 +4,6 @@
#include <QPushButton>
#include "ui_tab_automations.h"
-#include "ui_automation.h"
using std::pair;
@@ -44,17 +43,16 @@ CDAutomationsTabWidget::CDAutomationsTabWidget(CDMainWindow* main_window) : QWid
void CDAutomationsTabWidget::update() {
map<cd_link_t, cd_s_automation*> links = this->mainwindow->mesh_connector->get_links();
- map<cd_link_t, CDAutomationWidget*> widgets;
for (pair<cd_link_t, cd_s_automation*> link : links) {
- if (widgets.count(link.first)) { // node is already in list
- widgets[link.first]->update();
+ if (automation_widgets.count(link.first)) { // node is already in list
+ automation_widgets[link.first]->update();
} else {
- widgets[link.first] = new CDAutomationWidget(this);
- widgets[link.first]->set_automation(link.first, link.second);
- widgets[link.first]->update();
+ automation_widgets[link.first] = new CDAutomationWidget(this);
+ automation_widgets[link.first]->set_automation(link.first, link.second);
+ automation_widgets[link.first]->update();
}
- automations->addWidget(widgets[link.first]);
+ automations->addWidget(automation_widgets[link.first]);
}
}
diff --git a/confui/ui_tab_automations.h b/confui/ui_tab_automations.h
index 3fd433a..ec34189 100644
--- a/confui/ui_tab_automations.h
+++ b/confui/ui_tab_automations.h
@@ -2,8 +2,9 @@
#include <QMainWindow>
-#include "ui_scroll_container.h"
#include "mainwindow.h"
+#include "ui_automation.h"
+#include "ui_scroll_container.h"
class CDAddAutomationWidget;
class CDAutomationsTabWidget : public QWidget {
@@ -13,6 +14,7 @@ private:
CDScrollContainerLayout* main_layout;
QVBoxLayout* automations;
CDAddAutomationWidget* new_automation_button;
+ map<cd_link_t, CDAutomationWidget*> automation_widgets;
public:
CDMainWindow *mainwindow = nullptr;
diff --git a/confui/ui_tab_node_overview.cpp b/confui/ui_tab_node_overview.cpp
index d0280cf..84f1d6e 100644
--- a/confui/ui_tab_node_overview.cpp
+++ b/confui/ui_tab_node_overview.cpp
@@ -4,7 +4,6 @@
#include <QScrollArea>
#include "ui_tab_node_overview.h"
-#include "ui_node.h"
using std::pair;
@@ -18,10 +17,9 @@ CDNodeOverviewTabWidget::CDNodeOverviewTabWidget(CDMainWindow* main_window) : QW
}
void CDNodeOverviewTabWidget::update() {
- map<cd_mac_addr_cpp_t, cd_s_node*> nodes = g_cd_mesh_connector->get_nodes(false);
- map<cd_mac_addr_cpp_t, CDNodeWidget*> node_widgets;
+ map<cd_uid_t, cd_s_node*> nodes = g_cd_mesh_connector->get_nodes(false);
- for (pair<cd_mac_addr_cpp_t, cd_s_node*> node : nodes) {
+ for (pair<cd_uid_t, cd_s_node*> node : nodes) {
if (node_widgets.count(node.first)) { // node is already in list
node_widgets[node.first]->update();
} else {
diff --git a/confui/ui_tab_node_overview.h b/confui/ui_tab_node_overview.h
index d541dc6..d2197b1 100644
--- a/confui/ui_tab_node_overview.h
+++ b/confui/ui_tab_node_overview.h
@@ -2,14 +2,16 @@
#include <QMainWindow>
-#include "ui_scroll_container.h"
#include "mainwindow.h"
+#include "ui_node.h"
+#include "ui_scroll_container.h"
class CDNodeOverviewTabWidget : public QWidget {
Q_OBJECT
private:
CDScrollContainerLayout* main_layout;
+ map<cd_uid_t, CDNodeWidget*> node_widgets;
public:
CDMainWindow *mainwindow = nullptr;