ID |
Date |
Author |
Topic |
Subject |
2961
|
20 Mar 2025 |
Zaher Salman | Forum | LabView-Midas interface | Thanks Konstantin. Please send me the felabview code or let me know where I can find it.
Zaher
> > Does anyone have experience with writing a MIDAS frontends to communicate with a device that operates using LabView (e.g. superconducting magnets, cryostats etc.). Any information or experience regarding this would be highly appreciated.
>
> Yes, in the ALPHA anti-hydrogen experiment at CERN we have been doing this since 2006.
>
> Original system is very simple, labview side opens a TCP socket to the MIDAS felabview frontend
> and sends the numeric data as an ASCII string. The first four chars of the data is the name
> of the MIDAS data bank, second number is the data timestamp in seconds.
>
> LCRY 1234567 1.1 2.2 3.3
>
> A newer iteration is feGEM written by Joseph McKenna (member of this forum), it uses a more sophisticated
> labview component. Please contact him directly for more information.
>
> I can provide you with the source code for my original felabiew (pretty much unchanged from circa 2006).
>
> K.O. |
2962
|
20 Mar 2025 |
Konstantin Olchanski | Forum | LabView-Midas interface | > Thanks Konstantin. Please send me the felabview code or let me know where I can find it.
https://bitbucket.org/expalpha/a2daq/src/alpha/src/felabview.cxx
this is code circa 2006, there are now better ways to do some of that coding.
if you want bidirectional communication with labview, read/write odb, etc, simplest is probably
to write the "mjserver" that talks midas json-rpc over plain tcp, without all the http/https
gunk you need to go through mhttpd.
K.O. |
2990
|
21 Mar 2025 |
Stefan Ritt | Forum | LabView-Midas interface | > Hello,
>
> Does anyone have experience with writing a MIDAS frontends to communicate with a device that operates using LabView (e.g. superconducting magnets, cryostats etc.). Any information or experience regarding this would be highly appreciated.
>
> thanks,
> Zaher
We do have a superconducting magnet from Cryogenic, UK, which comes with a LabView control program on a Windows PC. I did the only reasonable with this: trash it in the waste basket. Do NOT use Labveiw for anything which should run more than 24h in a row. Too many bad experiences with LabView control programs
for separators at PSI and other devices. Instead of the Windows PC, we use MSCB devices and RasperryPis to communicate with the power supply directly, which has been proven to be much more stable (running for years without crashes). I'm happy to share our code with you.
Stefan |
2991
|
21 Mar 2025 |
Konstantin Olchanski | Forum | LabView-Midas interface | > > Hello,
> >
> > Does anyone have experience with writing a MIDAS frontends to communicate with a device that operates using LabView (e.g. superconducting magnets, cryostats etc.). Any information or experience regarding this would be highly appreciated.
> >
> > thanks,
> > Zaher
>
> We do have a superconducting magnet from Cryogenic, UK, which comes with a LabView control program on a Windows PC. I did the only reasonable with this: trash it in the waste basket. Do NOT use Labveiw for anything which should run more than 24h in a row. Too many bad experiences with LabView control programs
> for separators at PSI and other devices. Instead of the Windows PC, we use MSCB devices and RasperryPis to communicate with the power supply directly, which has been proven to be much more stable (running for years without crashes). I'm happy to share our code with you.
>
Our parallel experience with the CERN ALPHA anti-hydrogen experiment: they have developed a whole labview empire
to control the cryogenics, the magnets, the positron source, the anti-proton trap, anti-hydrogen trap, etc.
At some point there was a wall of monitors in the counting room - each labview computer controlled one or two things -
so there is very many computers and each had to have a monitor (and mouse and keyboard).
All the data from this labview empire is logged to MIDAS history via felabview and feGEM, and they use
the MIDAS history to look and monitor almost everything. Control is done via Labview and Labview
based FPGA sequencers (National Instruments PXI hardware, $$$$$).
This works reasonably well to publish several papers in Nature.
But not 100%:
1) difficulties with labview source control (cannot be trivially managed by git, I guess)
2) unending fight against Microsoft and CERN IT trying to reboot the computers at the wrong time
3) more recently, forced Microsoft updates require trashing perfectly good machines and buy new ones
At TRIUMF there is very little Labview. All experiments use MIDAS and EPICS for most things.
Based on this experience, I agree with Stefan, today's sweet spot is RaspberryPi machines with USB attached
gizmos to control stuff. On the software side, drive the mess with MIDAS and custom web pages.
K.O. |
2996
|
23 Mar 2025 |
Zaher Salman | Forum | LabView-Midas interface | Thanks Stefan, I would be very interested to see your code. At moment we have magnets and cryostats (3He and dilution) being delivered with Labview.
> > Hello,
> >
> > Does anyone have experience with writing a MIDAS frontends to communicate with a device that operates using LabView (e.g. superconducting magnets, cryostats etc.). Any information or experience regarding this would be highly appreciated.
> >
> > thanks,
> > Zaher
>
> We do have a superconducting magnet from Cryogenic, UK, which comes with a LabView control program on a Windows PC. I did the only reasonable with this: trash it in the waste basket. Do NOT use Labveiw for anything which should run more than 24h in a row. Too many bad experiences with LabView control programs
> for separators at PSI and other devices. Instead of the Windows PC, we use MSCB devices and RasperryPis to communicate with the power supply directly, which has been proven to be much more stable (running for years without crashes). I'm happy to share our code with you.
>
> Stefan |
1950
|
15 Jun 2020 |
Isaac Labrie Boulay | Bug Report | Killing and ODB - Removed ODB client because process pid does not exists | Hey everyone,
When I run mhttpd I get the following error message:
[mhttpd,ERROR] [odb.cxx:1720:db_open_database,ERROR] Removed ODB client
'mhttpd', index 0 because process pid 4531 does not exists
[mhttpd,INFO] Removed open record flag from "/Experiment/Security/RPC
hosts/Allowed hosts"
[mhttpd,INFO] Removed exclusive access mode from "/Experiment/Security/RPC
hosts/Allowed hosts"
[mhttpd,INFO] Removed open record flag from "/Experiment/Security/mhttpd
hosts/Allowed hosts"
[mhttpd,INFO] Removed exclusive access mode from "/Experiment/Security/mhttpd
hosts/Allowed hosts"
[mhttpd,INFO] Removed open record flag from "/Sequencer/State"
[mhttpd,INFO] Removed exclusive access mode from "/Sequencer/State"
[mhttpd,INFO] Corrected 3 ODB entries
[mhttpd,INFO] Deleted entry '/System/Clients/4531' for client 'mhttpd' because
it is not connected to ODB
[mhttpd,INFO] Client 'mhttpd' on buffer 'SYSMSG' removed by bm_open_buffer
because process pid 4531 does not exist
Mongoose web server will not use password protection
mongoose web server is listening on the HTTP port 8080
So mhttpd works as I have access to it through my browser but mlogger does not
work when I try running it (Alarm: Program Logger is not running). I've
managed to get mlogger working before and I think that the problem might be
from maybe having another instance of ODB running without me knowing.
Has anyone ever had this issue?
Thanks so much for your time.
Isaac |
2087
|
10 Feb 2021 |
Isaac Labrie Boulay | Forum | Javascript error during run transitions. | Hi all,
I am encountering a Javascript error (TypeError: client.error is undefined) when
I transition between run states. Does anybody have an idea of what my problem
might be? I have pasted an example of what MIDAS logs during such sequences.
Thanks for all the help!
Isaac
09:24:08.611 2021/02/10 [mhttpd,INFO] Executing script
"~/ANIS_20210106/scripts/start_daq.sh" from ODB "/Script/Start DAQ"
09:24:13.833 2021/02/10 [Logger,LOG] Program Logger on host localhost started
09:24:28.598 2021/02/10 [fevme,LOG] Program fevme on host localhost started
09:24:33.951 2021/02/10 [mhttpd,INFO] Run #234 started
09:26:30.970 2021/02/10 [mhttpd,ERROR] [midas.cxx:4260:cm_transition_call,ERROR]
Client "Logger" transition 2 aborted while waiting for client "fevme":
"/Runinfo/Transition in progress" was cleared
09:26:31.015 2021/02/10 [mhttpd,ERROR] [midas.cxx:5120:cm_transition,ERROR]
transition STOP aborted: "/Runinfo/Transition in progress" was cleared
09:27:27.270 2021/02/10 [mhttpd,ERROR]
[system.cxx:4937:ss_recv_net_command,ERROR] timeout receiving network command
header
09:27:27.270 2021/02/10 [mhttpd,ERROR] [midas.cxx:12262:rpc_client_call,ERROR]
call to "fevme" on "localhost" RPC "rc_transition": timeout waiting for reply |
2088
|
10 Feb 2021 |
Konstantin Olchanski | Forum | Javascript error during run transitions. | > I am encountering a Javascript error (TypeError: client.error is undefined) when
> I transition between run states. Does anybody have an idea of what my problem
> might be? I have pasted an example of what MIDAS logs during such sequences.
Not enough information. Can you do this:
a) for the javascript error, if you get it every time, open the javascript debugger
and capture the stack trace? or at least the file name, function name and line number
where the javascript exception is thrown?
b) for the run start failure, start the run from odbedit "start now -v" or from
"mtransition -v -d 1 START" (or "stop" as the case may be). capture the output, email
to me directly or put in this elog here.
K.O.
>
> Thanks for all the help!
>
> Isaac
>
>
> 09:24:08.611 2021/02/10 [mhttpd,INFO] Executing script
> "~/ANIS_20210106/scripts/start_daq.sh" from ODB "/Script/Start DAQ"
>
> 09:24:13.833 2021/02/10 [Logger,LOG] Program Logger on host localhost started
>
> 09:24:28.598 2021/02/10 [fevme,LOG] Program fevme on host localhost started
>
> 09:24:33.951 2021/02/10 [mhttpd,INFO] Run #234 started
>
> 09:26:30.970 2021/02/10 [mhttpd,ERROR] [midas.cxx:4260:cm_transition_call,ERROR]
> Client "Logger" transition 2 aborted while waiting for client "fevme":
> "/Runinfo/Transition in progress" was cleared
>
> 09:26:31.015 2021/02/10 [mhttpd,ERROR] [midas.cxx:5120:cm_transition,ERROR]
> transition STOP aborted: "/Runinfo/Transition in progress" was cleared
>
> 09:27:27.270 2021/02/10 [mhttpd,ERROR]
> [system.cxx:4937:ss_recv_net_command,ERROR] timeout receiving network command
> header
>
> 09:27:27.270 2021/02/10 [mhttpd,ERROR] [midas.cxx:12262:rpc_client_call,ERROR]
> call to "fevme" on "localhost" RPC "rc_transition": timeout waiting for reply |
2090
|
11 Feb 2021 |
Isaac Labrie Boulay | Forum | Javascript error during run transitions. |
> > I am encountering a Javascript error (TypeError: client.error is undefined) when
> > I transition between run states. Does anybody have an idea of what my problem
> > might be? I have pasted an example of what MIDAS logs during such sequences.
>
>
> Not enough information. Can you do this:
>
> a) for the javascript error, if you get it every time, open the javascript debugger
> and capture the stack trace? or at least the file name, function name and line number
> where the javascript exception is thrown?
I've attached a screenshot of the call stack showing the file names and line numbers.
> b) for the run start failure, start the run from odbedit "start now -v" or from
> "mtransition -v -d 1 START" (or "stop" as the case may be). capture the output, email
> to me directly or put in this elog here.
I have also attached a screen capture of the output.
Thanks for your help as always.
Isaac
> K.O.
>
>
> >
> > Thanks for all the help!
> >
> > Isaac
> >
> >
> > 09:24:08.611 2021/02/10 [mhttpd,INFO] Executing script
> > "~/ANIS_20210106/scripts/start_daq.sh" from ODB "/Script/Start DAQ"
> >
> > 09:24:13.833 2021/02/10 [Logger,LOG] Program Logger on host localhost started
> >
> > 09:24:28.598 2021/02/10 [fevme,LOG] Program fevme on host localhost started
> >
> > 09:24:33.951 2021/02/10 [mhttpd,INFO] Run #234 started
> >
> > 09:26:30.970 2021/02/10 [mhttpd,ERROR] [midas.cxx:4260:cm_transition_call,ERROR]
> > Client "Logger" transition 2 aborted while waiting for client "fevme":
> > "/Runinfo/Transition in progress" was cleared
> >
> > 09:26:31.015 2021/02/10 [mhttpd,ERROR] [midas.cxx:5120:cm_transition,ERROR]
> > transition STOP aborted: "/Runinfo/Transition in progress" was cleared
> >
> > 09:27:27.270 2021/02/10 [mhttpd,ERROR]
> > [system.cxx:4937:ss_recv_net_command,ERROR] timeout receiving network command
> > header
> >
> > 09:27:27.270 2021/02/10 [mhttpd,ERROR] [midas.cxx:12262:rpc_client_call,ERROR]
> > call to "fevme" on "localhost" RPC "rc_transition": timeout waiting for reply |
Attachment 1: start_now_-v.PNG
|
|
Attachment 2: Call_Stack_for_JavaScript_Error.PNG
|
|
Draft
|
25 Feb 2021 |
Konstantin Olchanski | Forum | Javascript error during run transitions. | >
> I have also attached a screen capture of the output.
>
so the error is gone?
> Thanks for your help as always.
>
> Isaac
>
> > K.O.
> >
> >
> > >
> > > Thanks for all the help!
> > >
> > > Isaac
> > >
> > >
> > > 09:24:08.611 2021/02/10 [mhttpd,INFO] Executing script
> > > "~/ANIS_20210106/scripts/start_daq.sh" from ODB "/Script/Start DAQ"
> > >
> > > 09:24:13.833 2021/02/10 [Logger,LOG] Program Logger on host localhost started
> > >
> > > 09:24:28.598 2021/02/10 [fevme,LOG] Program fevme on host localhost started
> > >
> > > 09:24:33.951 2021/02/10 [mhttpd,INFO] Run #234 started
> > >
> > > 09:26:30.970 2021/02/10 [mhttpd,ERROR] [midas.cxx:4260:cm_transition_call,ERROR]
> > > Client "Logger" transition 2 aborted while waiting for client "fevme":
> > > "/Runinfo/Transition in progress" was cleared
> > >
> > > 09:26:31.015 2021/02/10 [mhttpd,ERROR] [midas.cxx:5120:cm_transition,ERROR]
> > > transition STOP aborted: "/Runinfo/Transition in progress" was cleared
> > >
> > > 09:27:27.270 2021/02/10 [mhttpd,ERROR]
> > > [system.cxx:4937:ss_recv_net_command,ERROR] timeout receiving network command
> > > header
> > >
> > > 09:27:27.270 2021/02/10 [mhttpd,ERROR] [midas.cxx:12262:rpc_client_call,ERROR]
> > > call to "fevme" on "localhost" RPC "rc_transition": timeout waiting for reply |
2107
|
25 Feb 2021 |
Konstantin Olchanski | Forum | Javascript error during run transitions. | >
> I have also attached a screen capture of the output.
>
so the error is gone?
K.O. |
Draft
|
25 Feb 2021 |
Konstantin Olchanski | Forum | Javascript error during run transitions. | >
> I have also attached a screen capture of the output.
>
so the error is gone?
K.O. |
Draft
|
26 Feb 2021 |
Isaac Labrie Boulay | Forum | Javascript error during run transitions. | > >
> > I have also attached a screen capture of the output.
> >
>
> so the error is gone?
>
> K.O.
Hi K.O.,
No the error persists, |
1213
|
14 Oct 2016 |
Konstantin Olchanski | Info | Javascript based run start and stop pages. | I switched mhttpd to use the new javascript based run start and stop pages.
There are two new html pages:
resources/start.html - mimics the old run start page exactly - where you can enter the "edit on
start" parameters and start the run.
resources/transition.html - monitors the transition progress, shows the status of every transition
client, their sequence number, waiting list dependency, time spent making rpc calls, etc.
If the new pages do not work for you, please report it here and switch to the old pages
by editing src/mhttpd.cxx - comment-out the line "#define NEW_START_STOP 1"
K.O. |
1224
|
05 Dec 2016 |
Thomas Lindner | Info | Javascript based run start and stop pages. | > I switched mhttpd to use the new javascript based run start and stop pages.
One initial complaint: the transition.html page doesn't seem to deal well with a frontend program using
a deferred transition. Specifically, I find with my simulated frontend ([1]), which has a deferred
end-of-run transition, that two problems happen:
i) the page doesn't give any indication that a frontend has a deferred transition; in fact it says that
the frontend immediately has finished the transition.
ii) once the deferred transition has finished, the page doesn't switch to saying that the run has
stopped. In fact, even if I reload the transition page it still continues to show that the run is
ongoing; the status page, by contrast, shows that the run has stopped.
I separately still think that the transition page should automatically go away after 5 seconds
(assuming that all the transitions were successful). I think it is annoying that you need to click
back to the status page.
[1] https://github.com/thomaslindner/fesimdaq |
1232
|
01 Feb 2017 |
Konstantin Olchanski | Info | Javascript based run start and stop pages. | > > I switched mhttpd to use the new javascript based run start and stop pages.
>
> One initial complaint: the transition.html page doesn't seem to deal well with a frontend program using
> a deferred transition.
>
We now have a test frontend for deferred transitions, and this problem will likely be fixed.
>
> I separately still think that the transition page should automatically go away after 5 seconds
>
This is a user-interface philosophy issue.
Instead of using personal preferences one should follow established design principles
(there is research done and books written about this).
I did not recently look at current recommendations for this type of interaction, but generally
one expects web pages to "do things" (such as switch to a different page) only when directed
by user input (press a button).
My personal opinion is that half the users will find 5 sec delay too slow, the other half will
find 5 sec too fast and the 3rd half will wonder "what happened, the web page flashed and disappeared,
did I miss something important, how do I get back to whatever is was?!?".
One idea is to implement the transition page as a implant on the state page - after the "start" page
you go back to the status page where you can see the progress of the transition. After the transition
completes, it's progress window "collapses" into a "success/failure" display with a link to the full
transition page to see any details of what happened. Any volunteers? (I would html-ize the status page first).
K.O. |
1233
|
01 Feb 2017 |
Stefan Ritt | Info | Javascript based run start and stop pages. | > > > I switched mhttpd to use the new javascript based run start and stop pages.
> >
> > One initial complaint: the transition.html page doesn't seem to deal well with a frontend program using
> > a deferred transition.
> >
>
> We now have a test frontend for deferred transitions, and this problem will likely be fixed.
>
> >
> > I separately still think that the transition page should automatically go away after 5 seconds
> >
>
> This is a user-interface philosophy issue.
>
> Instead of using personal preferences one should follow established design principles
> (there is research done and books written about this).
>
> I did not recently look at current recommendations for this type of interaction, but generally
> one expects web pages to "do things" (such as switch to a different page) only when directed
> by user input (press a button).
>
> My personal opinion is that half the users will find 5 sec delay too slow, the other half will
> find 5 sec too fast and the 3rd half will wonder "what happened, the web page flashed and disappeared,
> did I miss something important, how do I get back to whatever is was?!?".
>
> One idea is to implement the transition page as a implant on the state page - after the "start" page
> you go back to the status page where you can see the progress of the transition. After the transition
> completes, it's progress window "collapses" into a "success/failure" display with a link to the full
> transition page to see any details of what happened. Any volunteers? (I would html-ize the status page first).
>
> K.O.
I agree with Konstantin's plans and volunteer for the "collapsable" display. We will address this during my next visit to TRIUMF. |
966
|
21 Feb 2014 |
Konstantin Olchanski | Info | Javascript ODBMLs(), modified ODBMCopy() JSON encoding | I made a few minor modifications to the ODB JSON encoder and implemented a javascript "ls" function to
report full ODB directory information as available from odbedit "ls -l" and the mhttpd odb editor page.
Using the new ODBMLs(), the existing ODBMCreate(), ODBMDelete() & etc a complete ODB editor can be
written in Javascript (or in any other AJAX-capable language).
While implementing this function, I found some problems in the ODB JSON encoder when handling
symlinks, also some problems with handling symlinks in odbedit and in the mhttpd ODB editor - these are
now fixed.
Changes to the ODB JSON encoder:
- added the missing information to the ODB KEY (access_mode, notify_count)
- added symlink target information ("link")
- changed encoding of simple variable (i.e. jcopy of /experiment/name) - when possible (i.e. ODB KEY
information is omitted), they are encoded as bare values (before, they were always encoded as structures
with variable names, etc). This change makes it possible to implement ODBGet() and ODBMGet() using the
AJAX jcopy method with JSON data encoding. Bare value encoding in ODBMCopy()/AJAX jcopy is enabled by
using the "json-nokeys-nolastwritten" encoding option.
All these changes are supposed to be backward compatible (encoding used by ODBMCopy() for simple
values and "-nokeys-nolastwritten" was previously not documented).
Documentation was updated:
https://midas.triumf.ca/MidasWiki/index.php/Mhttpd.js
K.O. |
766
|
20 Jun 2011 |
Stefan Ritt | Info | Javascript ODB interface revised | The Javascript interface to the ODB has been revised. This extends the capabilities of custom web pages requesting data from the ODB. By grouping several request together, the number of round-trips is minimized and the response time is reduced. Following functions are new or extended:
- ODBGet(path[, format]): This functions works now also with subdirectories in the ODB. The command ODBGet('/Runinfo') returns for example:
1
1
1024
0
0
0
Mon Jun 20 09:40:14 2011
1308588014
Mon Jun 20 09:40:46 2011
1308588046
- ODBGetRecord(path), ODBExtractRecord(key): While ODBGet can be used for subdirectories, an easier way is to use ODBGetRecord and ODBExtractRecord. The first function retrieves the subtree (record), while the second one can be used to extract individual items. Here is an example:
result = ODBGetRecord('/Runinfo');
run_number = ODBExtractRecord(result, 'Run number');
start_time = ODBExtractRecord(result, 'Start time');
- ODBMGet(paths[, callback, formats]): This function ("Multi-Get") can be used to obtain ODB values from different paths in one call. The ODB paths have to be supplied in an array, the result is again an array. An optional callback routine might be supplied for asynchronous operation. Optional formats might be supplied if the resulting number should be formatted in a specific way. Here is an example:
var req = new Array();
req[0] = "/Runinfo/Run number";
req[1] = "/Equipment/Trigger/Statistics/Events sent";
var result = ODBMGet(req);
run_number = result[0];
events_sent = result[1];
The new functions are implemented in mhttpd revision 5075. |
2437
|
10 Oct 2022 |
Zaher Salman | Suggestion | JSON-RPC function to read files | Hello ,
The midas sequencer uses the function js_seq_list_files to get a list of files in the /Sequencer/State/Path with extension *.msl. It would be nice to generalize this function to be able to read files with other (or any) extension.
Based on the js_seq_list_files I added a function in js_any_list_files mjsonrpc_user.cxx (attached) which does the job. Maybe a better/safer implementation can be made in midas. Are there any plans to do this?
thanks. |
Attachment 1: mjsonrpc_user.cxx
|
/********************************************************************\
Name: mjsonrpc_user.cxx
Created by: Konstantin Olchanski
Contents: handler of user-provided and experimental JSON-RPC requests
\********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <map>
#include "mjson.h"
#include "midas.h"
#include "msystem.h"
#include "mjsonrpc.h"
#include <mutex> // std::mutex
//
// example 1: extract request parameters, return up to 3 results
//
static MJsonNode* user_example1(const MJsonNode* params)
{
if (!params) {
MJSO* doc = MJSO::I();
doc->D("example of user defined RPC method that returns up to 3 results");
doc->P("arg", MJSON_STRING, "example string argment");
doc->P("optional_arg?", MJSON_INT, "optional example integer argument");
doc->R("string", MJSON_STRING, "returns the value of \"arg\" parameter");
doc->R("integer", MJSON_INT, "returns the value of \"optional_arg\" parameter");
return doc;
}
MJsonNode* error = NULL;
std::string arg = mjsonrpc_get_param(params, "arg", &error)->GetString(); if (error) return error;
int optional_arg = mjsonrpc_get_param(params, "optional_arg", NULL)->GetInt();
if (mjsonrpc_debug)
printf("user_example1(%s,%d)\n", arg.c_str(), optional_arg);
return mjsonrpc_make_result("string", MJsonNode::MakeString(arg.c_str()), "integer", MJsonNode::MakeInt(optional_arg));
}
//
// example 2: extract request parameters, return more than 3 results
//
static MJsonNode* user_example2(const MJsonNode* params)
{
if (!params) {
MJSO* doc = MJSO::I();
doc->D("example of user defined RPC method that returns more than 3 results");
doc->P("arg", MJSON_STRING, "example string argment");
doc->P("optional_arg?", MJSON_INT, "optional example integer argument");
doc->R("string1", MJSON_STRING, "returns the value of \"arg\" parameter");
doc->R("string2", MJSON_STRING, "returns \"hello\"");
doc->R("string3", MJSON_STRING, "returns \"world!\"");
doc->R("value1", MJSON_INT, "returns the value of \"optional_arg\" parameter");
doc->R("value2", MJSON_NUMBER, "returns 3.14");
return doc;
}
MJsonNode* error = NULL;
std::string arg = mjsonrpc_get_param(params, "arg", &error)->GetString(); if (error) return error;
int optional_arg = mjsonrpc_get_param(params, "optional_arg", NULL)->GetInt();
if (mjsonrpc_debug)
printf("user_example2(%s,%d)\n", arg.c_str(), optional_arg);
MJsonNode* result = MJsonNode::MakeObject();
result->AddToObject("string1", MJsonNode::MakeString(arg.c_str()));
result->AddToObject("string2", MJsonNode::MakeString("hello"));
result->AddToObject("string3", MJsonNode::MakeString("world!"));
result->AddToObject("value1", MJsonNode::MakeInt(optional_arg));
result->AddToObject("value2", MJsonNode::MakeNumber(3.14));
return mjsonrpc_make_result(result);
}
//
// example 3: return an error
//
static MJsonNode* user_example3(const MJsonNode* params)
{
if (!params) {
MJSO* doc = MJSO::I();
doc->D("example of user defined RPC method that returns an error");
doc->P("arg", MJSON_INT, "integer value, if zero, throws a JSON-RPC error");
doc->R("status", MJSON_INT, "returns the value of \"arg\" parameter");
return doc;
}
MJsonNode* error = NULL;
int arg = mjsonrpc_get_param(params, "arg", &error)->GetInt(); if (error) return error;
if (mjsonrpc_debug)
printf("user_example3(%d)\n", arg);
if (arg)
return mjsonrpc_make_result("status", MJsonNode::MakeInt(arg));
else
return mjsonrpc_make_error(15, "example error message", "example error data");
}
static MJsonNode* js_any_list_files(const MJsonNode* params)
{
if (!params) {
MJSO* doc = MJSO::I();
doc->D("js_any_list_files");
doc->P("subdir", MJSON_STRING, "List files in /Seq/State/Path/subdir");
doc->R("status", MJSON_INT, "return status of midas library calls");
doc->R("path", MJSON_STRING, "Search path");
doc->R("fileext", MJSON_STRING, "Filename extension");
doc->R("subdirs[]", MJSON_STRING, "list of subdirectories");
doc->R("files[].filename", MJSON_STRING, "script filename");
doc->R("files[].description", MJSON_STRING, "script description");
return doc;
}
MJsonNode* error = NULL;
std::string subdir = mjsonrpc_get_param(params, "subdir", &error)->GetString(); if (error) return error;
std::string fileext = mjsonrpc_get_param(params, "fileext", &error)->GetString(); if (error) return error;
std::string path = mjsonrpc_get_param(params, "path", NULL)->GetString();
if (subdir.find("..") != std::string::npos) {
return mjsonrpc_make_result("status", MJsonNode::MakeInt(DB_INVALID_PARAM));
}
int status;
HNDLE hDB;
status = cm_get_experiment_database(&hDB, NULL);
if (status != DB_SUCCESS) {
return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
}
// std::string path;
// If path is not provided get from ODB
if (path == "") {
status = db_get_value_string(hDB, 0, "/Sequencer/State/Path", 0, &path, FALSE);
}
if (status != DB_SUCCESS) {
return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
}
path = cm_expand_env(path.c_str());
if (subdir.length() > 0) {
if (path[path.length()-1] != DIR_SEPARATOR) {
path += DIR_SEPARATOR_STR;
}
path += subdir;
}
char* flist = NULL;
//printf("path: [%s]\n", path.c_str());
MJsonNode* s = MJsonNode::MakeArray();
/*---- go over subdirectories ----*/
int n = ss_dir_find(path.c_str(), "*", &flist);
for (int i=0 ; i<n ; i++) {
if (flist[i*MAX_STRING_LENGTH] != '.') {
//printf("subdir %d: [%s]\n", i, flist+i*MAX_STRING_LENGTH);
ss_repair_utf8(flist+i*MAX_STRING_LENGTH);
s->AddToArray(MJsonNode::MakeString(flist+i*MAX_STRING_LENGTH));
}
}
MJsonNode* f = MJsonNode::MakeArray();
/*---- go over files in path ----*/
n = ss_file_find(path.c_str(), fileext.c_str(), &flist);
for (int i=0 ; i<n ; i++) {
//printf("file %d: [%s]\n", i, flist+i*MAX_STRING_LENGTH);
MJsonNode* o = MJsonNode::MakeObject();
ss_repair_utf8(flist+i*MAX_STRING_LENGTH);
o->AddToObject("filename", MJsonNode::MakeString(flist+i*MAX_STRING_LENGTH));
o->AddToObject("description", MJsonNode::MakeString("description"));
f->AddToArray(o);
#if 0
char comment[512];
comment[0] = 0;
strlcpy(str, path, sizeof(str));
if (strlen(str)>1 && str[strlen(str)-1] != DIR_SEPARATOR)
strlcat(str, DIR_SEPARATOR_STR, sizeof(str));
strlcat(str, flist+i*MAX_STRING_LENGTH, sizeof(str));
if (msl_parse(str, error, sizeof(error), &error_line)) {
if (strchr(str, '.')) {
*strchr(str, '.') = 0;
strlcat(str, ".xml", sizeof(str));
}
comment[0] = 0;
if (pnseq) {
mxml_free_tree(pnseq);
pnseq = NULL;
}
pnseq = mxml_parse_file(str, error, sizeof(error), &error_line);
if (error[0]) {
strlcpy(comment, error, sizeof(comment));
} else {
if (pnseq) {
pn = mxml_find_node(pnseq, "RunSequence/Comment");
if (pn)
strlcpy(comment, mxml_get_value(pn), sizeof(comment));
else
strcpy(comment, "<No description in XML file>");
}
}
if (pnseq) {
mxml_free_tree(pnseq);
pnseq = NULL;
}
} else {
sprintf(comment, "Error in MSL: %s", error);
}
strsubst(comment, sizeof(comment), "\"", "\\\'");
r->rsprintf("<option onClick=\"document.getElementById('cmnt').innerHTML='%s'\"", comment);
r->rsprintf(" onDblClick=\"load();\">%s</option>\n", flist+i*MAX_STRING_LENGTH);
#endif
}
free(flist);
flist = NULL;
MJsonNode* r = MJsonNode::MakeObject();
r->AddToObject("status", MJsonNode::MakeInt(SUCCESS));
ss_repair_utf8(path);
r->AddToObject("path", MJsonNode::MakeString(path.c_str()));
r->AddToObject("subdirs", s);
r->AddToObject("files", f);
return mjsonrpc_make_result(r);
}
//
// to create your own rpc method handler, copy one of the examples here, register it in user_init below
//
//
// user_init function is called at startup time to register user rpc method handlers
//
void mjsonrpc_user_init()
{
if (mjsonrpc_debug) {
printf("mjsonrpc_user_init!\n");
}
// add user functions to the rpc list
mjsonrpc_add_handler("user_example1", user_example1);
mjsonrpc_add_handler("user_example2", user_example2);
mjsonrpc_add_handler("user_example3", user_example3);
mjsonrpc_add_handler("any_list_files", js_any_list_files, true);
}
/* emacs
* Local Variables:
* tab-width: 8
* c-basic-offset: 3
* indent-tabs-mode: nil
* End:
*/
|
|