Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 29 additions & 20 deletions src/ServiceDiscovery/Services.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ bool Services::Init(Store &m_variables, zmq::context_t* context_in, SlowControlC
sc_vars->Add("State",SlowControlElementType(INFO),0,0,false,false);
(*sc_vars)["State"]->SetValue(0);

sc_vars->Add("LoadConfig",SlowControlElementType(COMMAND),std::bind(&Services::LoadConfigSlowControlFunc, this, std::placeholders::_1),0,false,false);
sc_vars->Add("LoadConfig",SlowControlElementType(COMMAND),std::bind(&Services::LoadConfigSlowControlFunc, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3),0,false,false);
AlertSubscribe("LoadConfig", std::bind(&Services::LoadConfigAlertFunc, this, std::placeholders::_1, std::placeholders::_2));

sc_vars->Add("LocalConfig",SlowControlElementType(INFO),0,std::bind(&Services::SCLocalConfig, this, std::placeholders::_1),false,true); // FIXME hidden until Control page supports JSON
sc_vars->Add("LocalConfig",SlowControlElementType(INFO),0,std::bind(&Services::SCLocalConfig, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3),false,true); // FIXME hidden until Control page supports JSON


if(!m_variables.Get("service_name",m_name)) m_name="test_service";
Expand Down Expand Up @@ -1135,7 +1135,7 @@ SlowControlElement* Services::GetSlowControlVariable(std::string key){

}

bool Services::AddSlowControlVariable(std::string name, SlowControlElementType type, std::function<std::string(const char*)> change_function, std::function<std::string(const char*)> read_function){
bool Services::AddSlowControlVariable(std::string name, SlowControlElementType type, std::function<bool(const char*, const char*, std::string&)> change_function, std::function<bool(const char*, const char*, std::string&)> read_function){

return sc_vars->Add(name, type, change_function, read_function);

Expand Down Expand Up @@ -1245,15 +1245,17 @@ bool Services::LoadConfigAlertFunc(const char* alert, const char* payload){

}

std::string Services::LoadConfigSlowControlFunc(const char* payload){
bool Services::LoadConfigSlowControlFunc(const char* value, const char* sc_name, std::string& response){

(*sc_vars)["Config"]->SetValue((int)ConfigState::LoadStart);
bool success = LoadConfigAlertFunc("",payload);
bool success = LoadConfigAlertFunc("", value);
if(success)(*sc_vars)["Config"]->SetValue((int)ConfigState::LoadEnd);
else (*sc_vars)["Config"]->SetValue((int)ConfigState::LoadFail);

if(!success) return std::string("Failed to load config: ")+payload;
return std::string("Loaded config: ")+payload;
if(!success)response = std::string("Failed to load config: ")+value;
else response = std::string("Loaded config: ")+value;

return success;

}

Expand Down Expand Up @@ -1361,10 +1363,11 @@ std::string Services::GetLocalConfig(){

}

std::string Services::SCLocalConfig(const char*){
bool Services::SCLocalConfig(const char* value, const char* sc_name, std::string& response){

return "base: "+std::to_string(m_base_config_id)+", runmode:"+std::to_string(m_run_mode_config_id)+", testing:"+std::to_string(m_testing)+", config: "+m_local_config;
response = "base: "+std::to_string(m_base_config_id)+", runmode:"+std::to_string(m_run_mode_config_id)+", testing:"+std::to_string(m_testing)+", config: "+m_local_config;

return true;
}


Expand Down Expand Up @@ -1407,7 +1410,7 @@ bool Services::SetChangeConfigFunc(std::function<bool(std::string)> func){
allgood = allgood &&
sc_vars->Add("ChangeConfig",
BUTTON,
[this, func](const char*) -> std::string {
[this, func](const char*, const char*, std::string& response) -> bool {
(*sc_vars)["Config"]->SetValue((int)ConfigState::ChangeStart);
bool ok = func(m_local_config);
int new_state;
Expand All @@ -1416,13 +1419,15 @@ bool Services::SetChangeConfigFunc(std::function<bool(std::string)> func){
std::cerr<<"ChangeConfig Error"<<std::endl;
SendLog("ChangeConfig Error", LogLevel::Error);
sc_vars->SetWarning(true);
response = "Error";
} else {
new_state = (int)ConfigState::ChangeEnd;
sc_vars->SetTesting(m_testing);
response = "OK";
}
(*sc_vars)["Config"]->SetValue(new_state);
(*sc_vars)["NewConfig"]->SetValue(0);
return (ok ? "OK" : "Error");
return ok;
}, // setter
0, // getter
false, // not locked during non-testing runs, as it only allows loading configurations in line with the current run type
Expand All @@ -1432,10 +1437,11 @@ bool Services::SetChangeConfigFunc(std::function<bool(std::string)> func){
allgood = allgood &&
sc_vars->Add("ChangeToConfig",
COMMAND,
[this, func](const char* payload) -> std::string {
[this, func](const char* payload, const char*, std::string& response) -> bool {
(*sc_vars)["Config"]->SetValue((int)ConfigState::ChangeStart);
bool ok = func(payload);
int new_state = ok ? (int)ConfigState::ChangeEnd : (int)ConfigState::ChangeFail;
response = ok ? "OK" : "Error";
(*sc_vars)["Config"]->SetValue(new_state);
if(ok && m_local_config.compare(payload) !=0){
m_local_config = payload;
Expand All @@ -1447,7 +1453,7 @@ bool Services::SetChangeConfigFunc(std::function<bool(std::string)> func){
std::cerr<<"ChangeConfig Error"<<std::endl;
SendLog("ChangeConfig Error", LogLevel::Error);
}
return (ok ? "OK" : "Error");
return ok;
}, // setter
0, // getter
true, // locked during non-testing runs as it allows loading arbitrary configurations
Expand Down Expand Up @@ -1482,7 +1488,7 @@ bool Services::SetRunStopFunc(std::function<bool()> func){
allgood = allgood &&
sc_vars->Add("RunStop",
BUTTON,
[this, func](const char*) -> std::string {
[this, func](const char* payload, const char*, std::string& response) -> bool {
ResetConfigIDs();
bool ok = func();
if(!ok){
Expand All @@ -1491,7 +1497,8 @@ bool Services::SetRunStopFunc(std::function<bool()> func){
SendLog("RunStop Error", LogLevel::Error);
}
(*sc_vars)["Config"]->SetValue((int)ConfigState::Unconfigured);
return (ok ? "OK" : "Error");
response = ok ? "OK" : "Error";
return ok;
}, // setter
0, // getter
false, // not locked during non-testing runs: it is a fallback control in case alert gets missed
Expand Down Expand Up @@ -1528,21 +1535,23 @@ bool Services::SetExportConfigFunc(std::function<bool(std::string&)> func){
allgood = allgood &&
sc_vars->Add("ExportConfig",
BUTTON,
[this, func](const char*) -> std::string {
[this, func](const char* payload, const char*, std::string& response) -> bool {
bool ok = func(tmp_config);
if(!ok){
sc_vars->SetWarning(true);
std::cerr<<"ExportConfig Error"<<std::endl;
SendLog("ExportConfig Error", LogLevel::Error);
return "Error";
response = "Error";
return ok;
}
if(tmp_config.compare(m_local_config) !=0){
m_local_config = tmp_config;
m_base_config_id = 0;
m_run_mode_config_id = 0;
}

return tmp_config;
}

response = tmp_config;
return ok;
}, // setter
0, // getter
false, // not be locked during non-testing runs, since it does not change configuration
Expand Down
7 changes: 4 additions & 3 deletions src/ServiceDiscovery/Services.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <chrono>
#include <functional>
#include <SlowControlCollection.h>
#include <string>
//#include <boost/uuid/uuid.hpp> // uuid class
//#include <boost/uuid/uuid_generators.hpp> // generators
//#include <boost/uuid/uuid_io.hpp> // streaming operators etc.
Expand Down Expand Up @@ -113,7 +114,7 @@ namespace ToolFramework {

SlowControlCollection* GetSlowControlCollection();
SlowControlElement* GetSlowControlVariable(std::string key);
bool AddSlowControlVariable(std::string name, SlowControlElementType type, std::function<std::string(const char*)> change_function=nullptr, std::function<std::string(const char*)> read_function=nullptr);
bool AddSlowControlVariable(std::string name, SlowControlElementType type, std::function<bool(const char*, const char*, std::string&)> change_function=nullptr, std::function<bool(const char*, const char*, std::string&)> read_function=nullptr);
bool RemoveSlowControlVariable(std::string name);
void ClearSlowControlVariables();
void ResetConfigIDs();
Expand All @@ -138,14 +139,14 @@ namespace ToolFramework {

private:

std::string LoadConfigSlowControlFunc(const char* sc_name);
bool LoadConfigSlowControlFunc(const char* value, const char* sc_name, std::string& response);
bool LoadConfigAlertFunc(const char* alert, const char* payload);
// private methods for sending from buffer
bool SendLog(std::string& msg);
bool SendMonitoringData(std::string& msg);
static void BufferThread(Thread_args* args);
static bool BatchAndSendMulticast(BufferThreadArgs* m_args, bool log_lock, bool mon_lock);
std::string SCLocalConfig(const char*);
bool SCLocalConfig(const char* value, const char* sc_name, std::string& response);

//size_t GetMTU(std::string iface_name);
//std::set<std::string> GetInterfaces();
Expand Down
2 changes: 1 addition & 1 deletion src/ServiceDiscovery/SlowControlCollection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ bool SlowControlCollection::Init(zmq::context_t* context, int sc_port, bool new_
Add("State",SlowControlElementType(INFO),0,0,false,false);
SC_vars["State"]->SetValue(0);
Add("ClearState",SlowControlElementType(BUTTON),
[this](const char*) -> std::string { ClearState(); return "OK";},
[this](const char*, const char*, std::string&) -> bool { ClearState(); return true;},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't set response. Might want to.

0,false);

// add state to the service discovery broadcast; default is no flags (not active, no error, no warning)
Expand Down
48 changes: 40 additions & 8 deletions src/ServiceDiscovery/SlowControlElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,17 @@ std::string SlowControlElement::Print(){
mtx.lock();

if(m_read_function!=0){
std::string response="";
bool ret = false;
try{
options.Set("value",m_read_function(""));
ret = m_read_function("", m_name.c_str(), response);
if(ret) options.Set("value", response);
}
catch(...){
std::cerr<<"failed to call read fucntion"<<std::endl;
ret = false;
}
if(!ret){
std::cerr<<"failed to call read fucntion"<<m_name<<" : "<<response<<std::endl;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fucntion. :)

}
}

Expand Down Expand Up @@ -209,31 +215,49 @@ bool SlowControlElement::SetDefault(std::string value){
}



bool SlowControlElement::SetValue(const char value[]){
std::string tmp_value=value;
return SetValue(tmp_value);
}


bool SlowControlElement::SetValue(const char value[], std::string& response){
std::string tmp_value=value;
return SetValue(tmp_value, response);
}


bool SlowControlElement::SetValue(std::string value){
std::string tmp="";
return SetValue(value, tmp);

}

bool SlowControlElement::SetValue(std::string value, std::string& response){

mtx.lock();

if(m_type == SlowControlElementType(VARIABLE)){
std::stringstream tmp(value);
double val=0;
tmp>>val;
mtx.unlock();
return SetValue(val);
return SetValue(val, response);
}

if(m_change_function!=0){
bool ret = false;
try{
m_change_function(value.c_str());
ret = m_change_function(value.c_str(), m_name.c_str(), response);
}
catch(...){
std::cerr<<"failed to call change fucntion"<<std::endl;
mtx.unlock();
return false;
ret = false;
}
if(!ret){
std::cerr<<"failed to call change fucntion "<<m_name<<" : "<<response<<std::endl;

@marc1uk marc1uk Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fucntion 🙃
probably better to unlock before cout really

mtx.unlock();
return false;
}
}

Expand All @@ -254,10 +278,18 @@ bool SlowControlElement::SetValue(std::string value){


bool SlowControlElement::GetValue(std::string &value){

std::string tmp="";
return GetValue(value, tmp);
}

bool SlowControlElement::GetValue(std::string &value, std::string& response){

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does GetValue accept a value and a response....? What goes in what?

mtx.lock();
if(m_read_function!=0){
bool ret = false;
try{
options.Set("value",m_read_function(""));
ret = m_read_function("", m_name.c_str(), response);
if(ret) options.Set("value", response);
}
catch(std::exception& e){
std::cerr<<"caught "<<e.what()<<" calling read function for SlowControl "<<m_name<<std::endl;
Expand Down
47 changes: 38 additions & 9 deletions src/ServiceDiscovery/SlowControlElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace ToolFramework{

// typedef std::string (*SCFunction)(const char*);
typedef std::function<std::string(const char*)> SCFunction;
typedef std::function<bool(const char*, const char*, std::string&)> SCFunction;

enum SlowControlElementType { BUTTON, VARIABLE, OPTIONS, COMMAND, INFO };

Expand All @@ -31,9 +31,12 @@ namespace ToolFramework{
SlowControlElementType GetType();
bool AddCommand(std::string value);
bool SetValue(const char value[]);
bool SetValue(const char value[], std::string& response);
bool SetDefault(std::string value);
bool SetValue(std::string value);
bool SetValue(std::string value, std::string& response);
bool GetValue(std::string &value);
bool GetValue(std::string &value, std::string& response);
bool Lockable();
bool Hidden();

Expand Down Expand Up @@ -90,6 +93,11 @@ namespace ToolFramework{


template<typename T> bool SetValue(T value){

@marc1uk marc1uk Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we maintaining all these SetValue signatures that don't return a response?

std::string tmp ="";
return SetValue(value, tmp);
}

template<typename T> bool SetValue(T value, std::string& response){
mtx.lock();
if(m_type == SlowControlElementType(VARIABLE)){
T min;
Expand All @@ -104,13 +112,17 @@ namespace ToolFramework{
if(m_change_function!=0){
std::stringstream tmp;
tmp<<value;
bool ret = false;
try{
m_change_function(tmp.str().c_str());
ret = m_change_function(tmp.str().c_str(), m_name.c_str(), response);
}
catch(...){
std::cerr<<"failed to call change fucntion"<<std::endl;
mtx.unlock();
return false;
ret = false;
}
if(!ret){
std::cerr<<"failed to call change fucntion "<<m_name<<" : "<<response<<std::endl;

@marc1uk marc1uk Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fucntion ಠ⌣ಠ
unlock before cout

mtx.unlock();
return false;
}
}
options.Set("value", value);
Expand All @@ -123,29 +135,46 @@ namespace ToolFramework{
T tmp;
mtx.lock();
if(m_read_function!=0){
bool ret = false;
std::string response = "";
try{
options.Set("value",m_read_function(""));
ret = m_read_function("",m_name.c_str(), response);
if(ret) options.Set("value", response);
}
catch(...){
std::cerr<<"failed to call read fucntion"<<std::endl;
ret = false;
}
if(!ret){
std::cerr<<"failed to call read fucntion "<<m_name<<" : "<<response<<std::endl;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fucntion ◔ ◡ ◔
unlock before cout

mtx.unlock();
return tmp;
}
}

options.Get("value", tmp);
mtx.unlock();
return tmp;

}

template<typename T> bool GetValue(T &value){
std::string tmp ="";
return GetValue(value, tmp);
}

template<typename T> bool GetValue(T &value, std::string& response){
mtx.lock();
if(m_read_function!=0){
bool ret = false;
try{
options.Set("value",m_read_function(""));
ret = m_read_function("", m_name.c_str(), response);
if(ret) options.Set("value", response);
}
catch(...){
std::cerr<<"failed to call read fucntion"<<std::endl;
ret= false;
}
if(!ret){
std::cerr<<"failed to call read fucntion "<<m_name<<" : "<<response<<std::endl;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fucntion! ٩( ❛ᴗ❛ )۶
unlock before cout

mtx.unlock();
return false;
}
Expand Down
Loading