///////////////////////////////////////////////////////////////////////////////// // // guimodbusdata.cc is part of TestModbus-Server. // ///////////////////////////////////////////////////////////////////////////////// // // // show all modbus registers and the value // // #include "gui.h" #include "guimodbusdata.h" #include "modbus.h" extern Modbus modbus; extern GtkBuilder *_builder_; // work around for threads void mbdata_enabletoggled_cb(GtkCellRendererToggle *cellrenderer, char *path, gpointer data); #define MAXREG 0x10000 #define STEPREG 1000 GtkTreeModel *MBData_create_with_data() { GtkTreeStore *store; GtkTreeIter iter, toplevel, secondlevel; ModbusRegister r; string txt = ""; string regname, regname1, regname2; int regnum, fc; store = gtk_tree_store_new (MBDATA_COLCOUNT, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_STRING); // fill in FC1..FC4 for (fc = 1; fc <= 4; fc++) { regname = "FC" + std::to_string(fc); gtk_tree_store_append (store, &toplevel, NULL); gtk_tree_store_set (store, &toplevel, MBDATA_COL_FCREG, regname.c_str(), -1); for (regnum = 0; regnum < MAXREG; regnum++) { if (regnum % STEPREG == 0) { regname1 = "FC" + std::to_string(fc) + " " + std::to_string(regnum) + ".." + std::to_string(regnum+STEPREG); gtk_tree_store_append (store, &secondlevel, &toplevel); gtk_tree_store_set (store, &secondlevel, MBDATA_COL_FCREG, regname1.c_str(),-1); } modbus.GetRegister(fc, regnum, &r); regname2 = "FC" + std::to_string(fc) + " " + std::to_string(regnum); if (fc < 3) { if (r.value == 0) txt = "false"; else txt = "true"; } else txt = to_hex16(r.value) + " (" +std::to_string(r.value)+")"; gtk_tree_store_append (store, &iter, &secondlevel); gtk_tree_store_set (store, &iter, MBDATA_COL_FCREG, regname2.c_str(), MBDATA_COL_REQREAD, r.requested & 1, MBDATA_COL_REQWRITE, r.requested & 2, MBDATA_COL_ENABLED, (r.enabled), MBDATA_COL_VALUE, txt.c_str(), -1); } } return GTK_TREE_MODEL (store); }; void mbdata_show(GtkWidget *widget, gpointer data) { GtkWidget *view = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(data), "regs_tv")); GtkCellRenderer *renderer; GtkTreeModel *model; // renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "FC", renderer, "text", MBDATA_COL_FCREG, NULL); renderer = gtk_cell_renderer_toggle_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Req. Read", renderer, "active", MBDATA_COL_REQREAD, NULL); renderer = gtk_cell_renderer_toggle_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Req. Write", renderer, "active", MBDATA_COL_REQWRITE, NULL); renderer = gtk_cell_renderer_toggle_new (); gtk_cell_renderer_toggle_set_activatable (GTK_CELL_RENDERER_TOGGLE(renderer), true); g_signal_connect (G_OBJECT (renderer), "toggled", G_CALLBACK (mbdata_enabletoggled_cb), NULL); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Enabled", renderer, "active", MBDATA_COL_ENABLED, NULL); renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Value", renderer, "text", MBDATA_COL_VALUE, NULL); model = MBData_create_with_data(); gtk_tree_view_set_model (GTK_TREE_VIEW (view), model); g_object_unref(model); }; void mbdata_enabletoggled_cb(GtkCellRendererToggle *cellrenderer, char *path, gpointer data) { GtkWidget *mbdata = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "regs_tv")); GtkTreeIter iter; GtkTreeModel *model; int enabled; char *fcreg = NULL; int pathint[3]; int reg; int fc; // retrieve fc and register from path, return if invalid for (fc = 0; fc < 3; fc++) pathint[fc] = -1; sscanf (path, "%d:%d:%d", pathint, pathint+1, pathint+2); fc = pathint[0]+1; reg = pathint[1]*STEPREG+pathint[2]; if (pathint[2] == -1) return; // read current enable setting, inverse, set to modbus object and set in treeview model = gtk_tree_view_get_model(GTK_TREE_VIEW(mbdata)); if (gtk_tree_model_get_iter_from_string(model, &iter, path) == true) { gtk_tree_model_get(model, &iter, MBDATA_COL_FCREG, &fcreg, MBDATA_COL_ENABLED, &enabled, -1); if (fcreg != NULL) { if (enabled == 0) enabled = 1; else enabled = 0; gtk_tree_store_set(GTK_TREE_STORE(model), &iter, MBDATA_COL_ENABLED, enabled, -1); modbus.Enable(fc, reg, 1, enabled); g_free (fcreg); fcreg = NULL; } } }; // walk throught the registers and draw them.. if unknown//not yet set check for auto add void MBData_ChangeRegs (int fc, int regstart, int count, ModbusRegister *r) { GtkWidget *mbdata = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "regs_tv")); GtkTreeIter iter; GtkTreeModel *model; int i,j; gchar *v_fcreg = NULL; string path; char value[16] = "0000"; char hex[] = "0123456789ABCDEF"; model = gtk_tree_view_get_model(GTK_TREE_VIEW(mbdata)); for (i = 0; regstart < MAXREG && i < count; i++, regstart++) { strncpy(value, to_hex16(r[i].value).c_str(), 16); path = std::to_string(fc-1) + ":" + std::to_string(regstart / STEPREG) + ":" + std::to_string(regstart % STEPREG); // printf ("fc:%d reg:%d val:%d enabled:%d requested:%d path:%s\n", fc, regstart, r[i].value, r[i].enabled, r[i].requested, path.c_str()); if (gtk_tree_model_get_iter_from_string(model, &iter, path.c_str()) == true) { gtk_tree_model_get (model, &iter, MBDATA_COL_FCREG, &v_fcreg, -1); if (v_fcreg == NULL) break; if (r[i].enabled) { if (fc == 1) memcpy (&modbusdata[0][regstart], &r[i].value, 2); if (fc == 2) memcpy (&modbusdata[1][regstart], &r[i].value, 2); if (fc == 4) memcpy (&modbusdata[3][regstart], &r[i].value, 2); if (fc == 3 || fc == 6 || fc == 16) memcpy (&modbusdata[2][regstart], &r[i].value, 2); } if (fc == 1 || fc == 2) { gtk_tree_store_set(GTK_TREE_STORE(model), &iter, MBDATA_COL_FCREG, v_fcreg, MBDATA_COL_REQREAD, (r[i].requested & 1), MBDATA_COL_REQWRITE, (r[i].requested & 2), MBDATA_COL_ENABLED, r[i].enabled, MBDATA_COL_VALUE, r[i].value ? " true" : "false", -1); } if (fc == 3 || fc == 4) { gtk_tree_store_set(GTK_TREE_STORE(model), &iter, MBDATA_COL_FCREG, v_fcreg, MBDATA_COL_REQREAD, (r[i].requested & 1), MBDATA_COL_REQWRITE, (r[i].requested & 2), MBDATA_COL_ENABLED, r[i].enabled, MBDATA_COL_VALUE, ((string)value + " (" + std::to_string(r[i].value) + ")").c_str(), -1); } g_free(v_fcreg); } } }; void MBData_Enable (int fc, int regstart, int count, int onoff) { GtkWidget *mbdata = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "regs_tv")); GtkTreeIter iter; GtkTreeModel *model; int i; string path; model = gtk_tree_view_get_model(GTK_TREE_VIEW(mbdata)); for (i = 0; regstart < MAXREG && i < count; i++, regstart++) { path = std::to_string(fc-1) + ":" + std::to_string(regstart / STEPREG) + ":" + std::to_string(regstart % STEPREG); if (gtk_tree_model_get_iter_from_string(model, &iter, path.c_str()) == true) { gtk_tree_store_set(GTK_TREE_STORE(model), &iter, MBDATA_COL_ENABLED, onoff, -1); } } }; void MBData_EnableAll (int onoff) { GtkWidget *mbdata = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "regs_tv")); GtkTreeIter iter; GtkTreeModel *model; int reg, fc; string path; model = gtk_tree_view_get_model(GTK_TREE_VIEW(mbdata)); for (fc = 1; fc < 5; fc++) for (reg = 0; reg < 0x10000; reg++) { path = std::to_string(fc-1) + ":" + std::to_string(reg / STEPREG) + ":" + std::to_string(reg % STEPREG); if (gtk_tree_model_get_iter_from_string(model, &iter, path.c_str()) == true) { gtk_tree_store_set(GTK_TREE_STORE(model), &iter, MBDATA_COL_ENABLED, onoff, -1); } } }; void MBData_ReqReset () { GtkWidget *mbdata = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "regs_tv")); GtkTreeIter iter; GtkTreeModel *model; int reg, fc; string path; model = gtk_tree_view_get_model(GTK_TREE_VIEW(mbdata)); for (fc = 1; fc < 5; fc++) for (reg = 0; reg < 0x10000; reg++) { path = std::to_string(fc-1) + ":" + std::to_string(reg / STEPREG) + ":" + std::to_string(reg % STEPREG); if (gtk_tree_model_get_iter_from_string(model, &iter, path.c_str()) == true) { gtk_tree_store_set(GTK_TREE_STORE(model), &iter, MBDATA_COL_REQREAD, 0, MBDATA_COL_REQWRITE, 0, -1); } } };