expand mailbox

This commit is contained in:
Michael Davidsaver
2020-02-27 08:47:50 -08:00
parent 2f8729838e
commit 8d8a371eb8
2 changed files with 54 additions and 8 deletions
+1 -3
View File
@@ -4,9 +4,7 @@ Examples
Mailbox Server
--------------
Serves a single PV name.
Any updates written (PUT) to this PV will be stored verbatim
and sent to any subscribers.
Latest version https://github.com/mdavidsaver/pvxs/blob/master/example/mailbox.cpp
.. literalinclude:: ../example/mailbox.cpp
:language: c++
+53 -5
View File
@@ -3,9 +3,16 @@
* pvxs is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* Serves a single PV name.
* Any updates written (PUT) to this PV will be stored verbatim
* and sent to any subscribers.
*/
#include <iostream>
#include <epicsTime.h>
#include <pvxs/sharedpv.h>
#include <pvxs/server.h>
#include <pvxs/nt.h>
@@ -21,12 +28,15 @@ int main(int argc, char* argv[])
}
// Read $PVXS_LOG from process environment and update
// logging configuration. eg. PVXS_LOG=*=DEBUG makes
// a lot of noise.
// logging configuration. eg.
// export PVXS_LOG=*=DEBUG
// makes a lot of noise.
logger_config_env();
// Must provide a data type for the mailbox
// Must provide a data type for the mailbox.
// Use pre-canned definition of scalar with meta-data
Value initial = nt::NTScalar{TypeCode::Float64}.create();
// (optional) Provide an initial value
initial["value"] = 42.0;
initial["alarm.severity"] = 0;
@@ -34,14 +44,48 @@ int main(int argc, char* argv[])
initial["alarm.message"] = "";
// Actually creating the mailbox PV.
// buildMailbox() includes a default PUT handler which simply
// buildMailbox() installs a default onPut() handler which
// stores whatever a client sends (subject to our data type).
server::SharedPV pv(server::SharedPV::buildMailbox());
// (optional) Replace the default PUT handler to do a range check
pv.onPut([](server::SharedPV& pv,
std::unique_ptr<server::ExecOp>&& op,
Value&& top)
{
// (optional) arbitrarily clip value to [-100.0, 100.0]
double val(top["value"].as<double>());
if(val<-100.0)
top["value"] = -100.0;
else if(val>100.0)
top["value"] = 100.0;
// (optional) Provide a timestamp if the client has not (common)
Value ts(top["timeStamp"]);
if(!ts.isMarked(true, true)) {
// use current time
epicsTimeStamp now;
if(!epicsTimeGetCurrent(&now)) {
ts["secondsPastEpoch"] = now.secPastEpoch + POSIX_TIME_AT_EPICS_EPOCH;
ts["nanoseconds"] = now.nsec;
}
}
// (optional) update the SharedPV cache and send
// a update to any subscribers
pv.post(std::move(top));
// Required. Inform client that PUT operation is complete.
op->reply();
});
// Associate a data type (and maybe initial value) with this PV
pv.open(initial);
// Build server which will server this PV
auto serv = server::Config::from_env()
// Configure using process environment.
server::Server serv = server::Config::from_env()
.build()
.addPV(argv[1], pv);
@@ -49,9 +93,13 @@ int main(int argc, char* argv[])
// with any auto-address list expanded.
std::cout<<"Effective config\n"<<serv.config();
std::cout<<"Running\n";
// Start server and run forever, or until Ctrl+c is pressed.
// Returns on SIGINT or SIGTERM
serv.run();
std::cout<<"Done\n";
return 0;
}