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.
555 lines
14 KiB
555 lines
14 KiB
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// guivalues.cc is part of TestModbus-Server.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
//
|
|
// show all variables and the value
|
|
//
|
|
//
|
|
|
|
#include <sys/time.h>
|
|
#include <math.h>
|
|
|
|
#include "gui.h"
|
|
#include "config.h"
|
|
#include "mbsconfig.h"
|
|
#include "modbus.h"
|
|
#include "guivalues.h"
|
|
|
|
|
|
extern GtkBuilder *_builder_; // work around for threads
|
|
|
|
GuiValue::GuiValue() {
|
|
sim = "";
|
|
name = "";
|
|
type = "";
|
|
fc = 0;
|
|
reg = 0;
|
|
};
|
|
|
|
|
|
GuiValue::~GuiValue() {
|
|
|
|
};
|
|
|
|
|
|
// walk throught the registers and draw them.. if unknown//not yet set check for auto add
|
|
void Values_ChangeRegs (int fc, int regstart, int count, ModbusRegister *r) {
|
|
int autoadd = 0;
|
|
int reg, idx;
|
|
GtkWidget *cb_autovalue = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "conf_autoaddvalues"));
|
|
GtkWidget *vars = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vars_tv"));
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
gboolean result;
|
|
gchar *v_name = NULL;
|
|
gchar *v_fc = NULL;
|
|
gchar *v_reg = NULL;
|
|
gchar *v_type = NULL;
|
|
gchar *v_sim = NULL;
|
|
int found = 0;
|
|
int regsize = 1;
|
|
|
|
|
|
model = gtk_tree_view_get_model(GTK_TREE_VIEW(vars));
|
|
autoadd = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cb_autovalue));
|
|
|
|
for (idx = 0, reg = regstart; idx < count; reg++, idx++) {
|
|
for (found = 0, result = gtk_tree_model_get_iter_first(model, &iter); found == 0 && result == TRUE;
|
|
result = gtk_tree_model_iter_next(model, &iter)) {
|
|
gtk_tree_model_get (model, &iter,
|
|
VALDATA_COL_NAME, &v_name,
|
|
VALDATA_COL_FC, &v_fc,
|
|
VALDATA_COL_REGSTART, &v_reg,
|
|
VALDATA_COL_TYPE, &v_type,
|
|
VALDATA_COL_SIM, &v_sim,
|
|
-1);
|
|
|
|
if (v_name == NULL || v_reg == NULL || v_fc == NULL || v_type == NULL) {
|
|
if (v_name != NULL) g_free(v_name);
|
|
if (v_reg != NULL) g_free(v_reg);
|
|
if (v_fc != NULL) g_free(v_fc);
|
|
if (v_type != NULL) g_free(v_type);
|
|
if (v_sim != NULL) g_free(v_sim);
|
|
break;
|
|
}
|
|
|
|
regsize = Value_GetSize(v_type);
|
|
if (atoi(v_fc) == fc && reg >= atoi(v_reg) && reg < (atoi(v_reg) + regsize)) {
|
|
found = 1;
|
|
GuiValue v;
|
|
v.name = v_name;
|
|
v.fc = atoi(v_fc);
|
|
v.reg = atoi(v_reg);
|
|
v.type = v_type;
|
|
v.sim = v_sim;
|
|
Value_Set (&v);
|
|
}
|
|
|
|
g_free(v_name);
|
|
g_free(v_fc);
|
|
g_free(v_reg);
|
|
g_free(v_sim);
|
|
g_free(v_type);
|
|
}
|
|
|
|
if (autoadd && found == 0) {
|
|
GuiValue v;
|
|
v.name = "_auto_FC" + std::to_string(fc) + "_REG_" + std::to_string (reg);
|
|
v.sim = "NONE";
|
|
v.fc = fc;
|
|
v.reg = reg;
|
|
if (v.fc == 1 || v.fc == 2) v.type = "BOOL";
|
|
else v.type = "WORD";
|
|
Value_Set (&v);
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
std::string findparm(std::string t, std::string parm) {
|
|
std::string res = "";
|
|
string::size_type i = t.find(parm+"=");
|
|
string::size_type j,k;
|
|
|
|
if (i != string::npos) {
|
|
res = t.substr (i, string::npos);
|
|
j = res.find("=");
|
|
k = res.find(";");
|
|
if (k != string::npos) k = k -j -1;
|
|
if (j != string::npos) res = res.substr(j+1, k);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
int Value_Simulation(GuiValue *v) {
|
|
struct timeval tv;
|
|
string s;
|
|
|
|
gettimeofday (&tv, NULL);
|
|
string sim = v->sim.substr(0, v->sim.find(";"));
|
|
|
|
if (sim.compare("PULSE") == 0) {
|
|
int ton = 10;
|
|
s = findparm(v->sim, "ton");
|
|
if(s.length()>0) ton = atoi(s.c_str());
|
|
|
|
int toff = 50;
|
|
s = findparm(v->sim, "toff");
|
|
if(s.length()>0) toff = atoi(s.c_str());
|
|
|
|
int td = ton +toff;
|
|
td = tv.tv_sec % td;
|
|
if (td <= ton) v->value = "true";
|
|
else v->value = "false";
|
|
|
|
return 1;
|
|
}
|
|
else if (sim.compare("SIN") == 0) {
|
|
int td = 60;
|
|
s = findparm(v->sim, "t");
|
|
if(s.length()>0) td = atoi(s.c_str());
|
|
|
|
float min = -100;
|
|
s = findparm(v->sim, "min");
|
|
if(s.length()>0) min = atof(s.c_str());
|
|
|
|
float max = 100;
|
|
s = findparm(v->sim, "max");
|
|
if(s.length()>0) max = atof(s.c_str());
|
|
|
|
float t = ((float)(tv.tv_sec % td)) + (((float)tv.tv_usec) / 1000000);
|
|
t = 4.0 * t * M_PI / td;
|
|
v->value = std::to_string((0.5*(max-min)*sin(t))+(min+max)*0.5);
|
|
|
|
return 1;
|
|
}
|
|
else if (sim.compare("SAW") == 0) {
|
|
int td = 60;
|
|
s = findparm(v->sim, "t");
|
|
if(s.length()>0) td = atoi(s.c_str());
|
|
|
|
float min = -100;
|
|
s = findparm(v->sim, "min");
|
|
if(s.length()>0) min = atof(s.c_str());
|
|
|
|
float max = 100;
|
|
s = findparm(v->sim, "max");
|
|
if(s.length()>0) max = atof(s.c_str());
|
|
|
|
float t = ((float)(tv.tv_sec % td)) + (((float)tv.tv_usec) / 1000000);
|
|
t = t / td;
|
|
v->value = std::to_string((max-min)*t+min);
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
};
|
|
|
|
|
|
gboolean Value_Loop(gpointer data) {
|
|
GtkWidget *vars = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vars_tv"));
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
gboolean result;
|
|
gchar *v_name = NULL;
|
|
gchar *v_type = NULL;
|
|
gchar *v_value = NULL;
|
|
gchar *v_sim = NULL;
|
|
gchar *v_fc = NULL;
|
|
gchar *v_reg = NULL;
|
|
GuiValue v;
|
|
int changed = 0;
|
|
|
|
model = gtk_tree_view_get_model(GTK_TREE_VIEW(vars));
|
|
for (result = gtk_tree_model_get_iter_first(model, &iter); result == TRUE;
|
|
result = gtk_tree_model_iter_next(model, &iter)) {
|
|
gtk_tree_model_get (model, &iter,
|
|
VALDATA_COL_NAME, &v_name,
|
|
VALDATA_COL_TYPE, &v_type,
|
|
VALDATA_COL_SIM, &v_sim,
|
|
VALDATA_COL_VALUE, &v_value,
|
|
VALDATA_COL_FC, &v_fc,
|
|
VALDATA_COL_REGSTART, &v_reg,
|
|
-1);
|
|
if (v_name == NULL) break;
|
|
|
|
GuiValue v;
|
|
v.name = v_name;
|
|
v.fc = atoi(v_fc);
|
|
v.reg = atoi(v_reg);
|
|
v.type = v_type;
|
|
v.sim = v_sim;
|
|
Value_Set (&v);
|
|
|
|
changed = Value_Simulation(&v);
|
|
if (changed) {
|
|
uint16_t regvals[4];
|
|
int regstowrite = 1;
|
|
if (Value_SetValue(v.value, v.type, v.fc, ®stowrite, regvals)) {
|
|
modbus.SetRegValue(v.fc, v.reg, regstowrite, (uint16_t*)regvals);
|
|
}
|
|
}
|
|
|
|
g_free(v_name);
|
|
g_free(v_type);
|
|
g_free(v_sim);
|
|
g_free(v_value);
|
|
g_free(v_reg);
|
|
g_free(v_fc);
|
|
}
|
|
|
|
return TRUE; // continue timer
|
|
}
|
|
|
|
void Value_Set(GuiValue *g) {
|
|
GtkWidget *vars = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vars_tv"));
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
gboolean result;
|
|
gchar *v_name = NULL;
|
|
int changed = 0;
|
|
|
|
model = gtk_tree_view_get_model(GTK_TREE_VIEW(vars));
|
|
for (result = gtk_tree_model_get_iter_first(model, &iter); result == TRUE && changed == 0;
|
|
result = gtk_tree_model_iter_next(model, &iter)) {
|
|
gtk_tree_model_get (model, &iter,
|
|
VALDATA_COL_NAME, &v_name,
|
|
-1);
|
|
if (v_name == NULL) break;
|
|
if (strcmp(v_name, g->name.c_str()) == 0) {
|
|
Value_ModStore(model, &iter, g);
|
|
changed = 1;
|
|
}
|
|
g_free(v_name);
|
|
}
|
|
|
|
if (changed == 0)
|
|
Value_Add(g);
|
|
}
|
|
|
|
|
|
int Value_GetSize(std::string type) {
|
|
if (type.compare("WORD") == 0) return 1;
|
|
if (type.compare("DWORD") == 0) return 2;
|
|
if (type.compare("FLOAT") == 0) return 2;
|
|
if (type.compare("DWORD_SWAP") == 0) return 2;
|
|
if (type.compare("FLOAT_SWAP") == 0) return 2;
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
void Value_Add(GuiValue *g) {
|
|
GtkWidget *vars = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vars_tv"));
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
int count;
|
|
|
|
model = gtk_tree_view_get_model(GTK_TREE_VIEW(vars));
|
|
gtk_list_store_append (GTK_LIST_STORE(model), &iter);
|
|
Value_ModStore(model, &iter, g);
|
|
|
|
count = Value_GetSize(g->type);
|
|
modbus.Enable(g->fc, g->reg, count, 1);
|
|
MBData_Enable(g->fc, g->reg, count, 1);
|
|
}
|
|
|
|
|
|
void Value_ModStore(GtkTreeModel *model, GtkTreeIter *iter, GuiValue *g) {
|
|
g->value = Value_GetValue(g->fc, g->reg, g->type);
|
|
gtk_list_store_set(GTK_LIST_STORE(model), iter,
|
|
VALDATA_COL_NAME, g->name.c_str(),
|
|
VALDATA_COL_FC, std::to_string(g->fc).c_str(),
|
|
VALDATA_COL_REGSTART, std::to_string(g->reg).c_str(),
|
|
VALDATA_COL_TYPE, g->type.c_str(),
|
|
VALDATA_COL_VALUE, Value_GetValue(g->fc, g->reg, g->type).c_str(),
|
|
VALDATA_COL_SIM, g->sim.c_str(),
|
|
-1);
|
|
|
|
// for (int i = 0; i < 10; i++) {
|
|
// float *f = (float *)&modbusdata[2][i];
|
|
// printf ("%f ", *f);
|
|
// }
|
|
// printf ("\n");
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////
|
|
// return valuze as string
|
|
std::string Value_GetValue(int fc, int reg, string type) {
|
|
std::string result = "";
|
|
|
|
if (fc == 1 || fc == 2) {
|
|
if (modbusdata[fc-1][reg]) result = "true";
|
|
else result = "false";
|
|
}
|
|
else if (fc == 3 || fc == 4) {
|
|
if (type.compare ("WORD") == 0) result = std::to_string(modbusdata[fc-1][reg]);
|
|
else if (type.compare ("FLOAT") == 0) {
|
|
uint8_t data[4];
|
|
float *f = (float*)&data;
|
|
|
|
memcpy (data, &modbusdata[fc-1][reg], 2);
|
|
memcpy (data+2, &modbusdata[fc-1][reg+1], 2);
|
|
|
|
result = std::to_string(*f);
|
|
}
|
|
else if (type.compare ("FLOAT_SWAP") == 0) {
|
|
uint8_t data[4];
|
|
float *f = (float*)&data;
|
|
|
|
memcpy (data, &modbusdata[fc-1][reg+1], 2);
|
|
memcpy (data+2, &modbusdata[fc-1][reg], 2);
|
|
|
|
result = std::to_string((double)*f);
|
|
}
|
|
else if (type.compare ("DWORD") == 0) {
|
|
uint8_t data[4];
|
|
uint32_t *f = (uint32_t*)&data;
|
|
|
|
memcpy (data, &modbusdata[fc-1][reg], 2);
|
|
memcpy (data+2, &modbusdata[fc-1][reg+1], 2);
|
|
|
|
result = std::to_string(*f);
|
|
}
|
|
else if (type.compare ("DWORD_SWAP") == 0) {
|
|
uint8_t data[4];
|
|
uint32_t *f = (uint32_t*)&data;
|
|
|
|
memcpy (data, &modbusdata[fc-1][reg+1], 2);
|
|
memcpy (data+2, &modbusdata[fc-1][reg], 2);
|
|
|
|
result = std::to_string(*f);
|
|
}
|
|
else if (type.compare ("BOOL") == 0) {
|
|
int c;
|
|
|
|
for (result = "", c = 0; c < 16; c++) {
|
|
if (modbusdata[fc-1][reg] & (1<<c)) result = "1" + result;
|
|
else result = "0" + result;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
printf ("%s:%d Some Error fc:%d\n", __FILE__, __LINE__, fc);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
int Value_SetValue(string value, string type, int fc, int *regcnt, uint16_t *regvalues) {
|
|
uint8_t data[4];
|
|
|
|
if (fc == 1 || fc == 2) {
|
|
*regcnt = 1;
|
|
if (value.compare("false") == 0 || value.compare("0") == 0)
|
|
*regvalues = 0;
|
|
else *regvalues = 1;
|
|
}
|
|
|
|
else {
|
|
if (type.compare("FLOAT") == 0) {
|
|
float *f = (float*)data;
|
|
*f = (float) atof (value.c_str());
|
|
memcpy (regvalues, data, 2);
|
|
memcpy (regvalues+1, data+2, 2);
|
|
*regcnt = 2;
|
|
}
|
|
else if (type.compare("FLOAT_SWAP") == 0) {
|
|
float *f = (float*)data;
|
|
*f = (float) atof (value.c_str());
|
|
memcpy (regvalues+1, data, 2);
|
|
memcpy (regvalues, data+2, 2);
|
|
*regcnt = 2;
|
|
}
|
|
else if (type.compare("WORD") == 0) {
|
|
uint16_t i16;
|
|
i16 = (uint16_t) atoi (value.c_str());
|
|
memcpy (regvalues, &i16, 2);
|
|
*regcnt = 1;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
// delete Value from list
|
|
void Value_Del(string name) {
|
|
gboolean res = false;
|
|
GtkWidget *vars = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vars_tv"));
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
gboolean result;
|
|
gchar *v_name = NULL;
|
|
|
|
printf ("%s:%d Delete: %s\n", __FILE__, __LINE__, name.c_str());
|
|
|
|
model = gtk_tree_view_get_model(GTK_TREE_VIEW(vars));
|
|
for (result = gtk_tree_model_get_iter_first(model, &iter); result == true && res == false;
|
|
result = gtk_tree_model_iter_next(model, &iter)) {
|
|
gtk_tree_model_get (model, &iter,
|
|
VALDATA_COL_NAME, &v_name,
|
|
-1);
|
|
if (v_name == NULL) break;
|
|
if (strcmp(v_name, name.c_str()) == 0) {
|
|
printf ("Found\n");
|
|
gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
|
|
res = true;
|
|
}
|
|
g_free(v_name);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
// delete all values
|
|
void Value_DelAll() {
|
|
GtkWidget *vars = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vars_tv"));
|
|
GtkTreeModel *model;
|
|
|
|
printf ("%s:%d Delete All\n", __FILE__, __LINE__);
|
|
|
|
model = gtk_tree_view_get_model(GTK_TREE_VIEW(vars));
|
|
gtk_list_store_clear(GTK_LIST_STORE(model));
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
// check if Value is already set
|
|
gboolean Value_Exist(std::string name) {
|
|
gboolean res = false;
|
|
GtkWidget *vars = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vars_tv"));
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
gboolean result;
|
|
gchar *v_name = NULL;
|
|
|
|
model = gtk_tree_view_get_model(GTK_TREE_VIEW(vars));
|
|
for (result = gtk_tree_model_get_iter_first(model, &iter); result == true && res == true;
|
|
result = gtk_tree_model_iter_next(model, &iter)) {
|
|
gtk_tree_model_get (model, &iter,
|
|
VALDATA_COL_NAME, &v_name,
|
|
-1);
|
|
if (v_name == NULL) break;
|
|
if (strcmp(v_name, name.c_str()) == 0) {
|
|
res = true;
|
|
}
|
|
g_free(v_name);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
void valdata_show(GtkWidget *widget, gpointer data) {
|
|
GtkWidget *view = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(data), "vars_tv"));
|
|
GtkCellRenderer *renderer;
|
|
GtkTreeModel *model;
|
|
|
|
//
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
|
|
-1,
|
|
"Name",
|
|
renderer,
|
|
"text", VALDATA_COL_NAME,
|
|
NULL);
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
|
|
-1,
|
|
"FC",
|
|
renderer,
|
|
"text", VALDATA_COL_FC,
|
|
NULL);
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
|
|
-1,
|
|
"Register",
|
|
renderer,
|
|
"text", VALDATA_COL_REGSTART,
|
|
NULL);
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
|
|
-1,
|
|
"Type",
|
|
renderer,
|
|
"text", VALDATA_COL_TYPE,
|
|
NULL);
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
|
|
-1,
|
|
"Simulation",
|
|
renderer,
|
|
"text", VALDATA_COL_SIM,
|
|
NULL);
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
|
|
-1,
|
|
"Value",
|
|
renderer,
|
|
"text", VALDATA_COL_VALUE,
|
|
NULL);
|
|
|
|
|
|
model = GTK_TREE_MODEL(gtk_list_store_new (VALDATA_COLCOUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING));
|
|
gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
|
|
|
|
g_object_unref(model);
|
|
};
|
|
|