You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
282 lines
8.8 KiB
282 lines
8.8 KiB
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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++) {
|
|
for (j = 0; j < 4; j++) value[3-j] = hex[(r[i].value >> j)%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);
|
|
}
|
|
}
|
|
};
|
|
|