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.
testmodbus-server/guivalues.cc

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 "modbussrv.h"
#include "guivalues.h"
void Value_ModStore(GtkTreeModel *model, GtkTreeIter *iter, GuiValue *g);
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, &regstowrite, regvals)) {
modbussrv.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);
modbussrv.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);
};