Commit e6b76b41 authored by yannick legoc's avatar yannick legoc
Browse files

First version of windeta dielectrics

parent 87fa6aae
......@@ -7,6 +7,11 @@
<project>NomadServer</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers></triggers>
......@@ -87,5 +92,6 @@
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>org.jaylib.plugins.cppchecker.cppCheckerNature</nature>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
</natures>
</projectDescription>
/WindetaMessages.pb.cc
/WindetaMessages.pb.h
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include "DielectricsRemoteWindeta.h"
#include "WindetaMessages.pb.h"
#include <boost/lexical_cast.hpp>
#include <common/base/ServerProperties.h>
#include "controllers/common/family/Families.h"
#include <fstream>
#include <iostream>
namespace dielectrics {
using namespace std;
using namespace common;
using namespace boost;
using namespace cameo;
const std::string RemoteWindeta::TYPE = "dielectrics_remote_windeta";
const std::string RemoteWindeta::WINDETA_APPLICATION = "dielectrics-windeta";
const std::string RemoteWindeta::RESPONDER_NAME = "dielectrics_controller";
const std::string RemoteWindeta::PUBLISHER_NAME = "dielectrics_pub";
RemoteWindeta::RemoteWindeta(const std::string& name) :
ExperimentController(name), controller::Stoppable(this), Test(this) {
setFamily(family::ACQUISITION, family::POLARIZATIONS);
serverEndpoint.init(this, SAVE, "cameo_server");
initialized.init(this, NOSAVE, "initialized");
applicationState.init(this, NOSAVE, "remote_state");
m_driver.init(this, "driver");
}
RemoteWindeta::RemoteWindeta(const RemoteWindeta& controller) :
ExperimentController(controller), controller::Stoppable(this), Test(this) {
}
RemoteWindeta::~RemoteWindeta() {
reset();
}
void RemoteWindeta::postConfiguration() {
if (m_server.get() == nullptr) {
// Create a new server if it is not already created.
// In case of a simulated server, avoid the real remote endpoint.
if (serverEndpoint() == "" || m_driver->state() != REAL_DEVICE_CONTAINER) {
m_server.reset(new Server(application::This::getServer().getEndpoint()));
}
else {
m_server.reset(new Server(serverEndpoint()));
}
}
// Do not initialise if the controller is disabled.
if (isEnabled()) {
initialized = initApplication();
}
}
void RemoteWindeta::setEnabled(bool all, bool postconf) {
ExperimentController::setEnabled(all);
}
void RemoteWindeta::setDisabled(bool all) {
ExperimentController::setDisabled(all);
}
bool RemoteWindeta::initApplication() {
// Do not initialize if it is already done
if (initialized()) {
return true;
}
try {
// Start the Windeta server
if (!m_server->isAvailable(10000)) {
cout << "Windeta server is not available" << endl;
return false;
}
cout << "Windeta server is connected to " << getName() << endl;
m_windetaApplication = m_server->connect(WINDETA_APPLICATION);
cout << "Connected application" << endl;
if (m_windetaApplication->exists()) {
// The application exists from a previous server session
m_windetaApplication->stop();
application::State state = m_windetaApplication->waitFor();
cout << "Terminated Windeta application " << state << endl;
}
m_windetaApplication = m_server->start(WINDETA_APPLICATION);
if (!m_windetaApplication->exists()) {
cout << "No Windeta application" << endl;
return false;
}
applicationState = m_windetaApplication->waitFor(application::STARTING);
// First delete the requester if it exists.
m_requester.reset(nullptr);
// Create a new requester.
m_requester = application::Requester::create(*m_windetaApplication, RESPONDER_NAME);
if (m_requester.get() == nullptr) {
cout << "requester error" << endl;
return false;
}
// Create a new subscriber.
// m_subscriber = application::Subscriber::create(*m_windetaApplication, PUBLISHER_NAME);
//
// // Start the subscriber loop
// m_subscriberThread.reset(new boost::thread(boost::bind(&RemoteWindeta::subscriberLoop, this)));
// Application initialized.
initialized = true;
applicationState = m_windetaApplication->waitFor(application::RUNNING);
cout << "Windeta application initialized" << endl;
return true;
} catch (const std::exception & e) {
// Currently an exception can occur during isAvailable.
cout << "Unexpected exception during Windeta connection: " << e.what() << endl;
}
return false;
}
void RemoteWindeta::reset() {
// Reset if the controller was initialized.
if (initialized()) {
// Stop the subscriber
m_subscriber->cancel();
// The subscriber thread terminates
m_subscriberThread->join();
// First stop the application.
stopApplication();
// Restart the application.
initialized = false;
}
}
void RemoteWindeta::start() {
if (!initApplication()) {
return;
}
commandStatus.setRunning();
// Serialize the request.
windeta::Request requestType;
requestType.set_type(windeta::Request::START_MEASURE);
windeta::StartMeasure requestMessage;
requestMessage.set_preset("preset");
requestMessage.set_path("");
requestMessage.set_filename("test");
// // Send the message.
m_requester->sendTwoBinaryParts(requestType.SerializeAsString(), requestMessage.SerializeAsString());
cout << getName() << " sent request " << static_cast<int>(requestType.type()) << endl;
// Wait for the response synchronously.
// Note that responses can be processed asynchronously if the server is able to.
string data;
m_requester->receiveBinary(data);
windeta::Response response;
response.ParseFromString(data);
cout << "received response " << response.errorcode() << endl;
// Sleep before two requests?
}
void RemoteWindeta::stop() {
if (!initApplication()) {
return;
}
// Serialize the request.
windeta::Request requestType;
requestType.set_type(windeta::Request::STOP_MEASURE);
windeta::StopMeasure requestMessage;
// Send the message.
m_requester->sendTwoBinaryParts(requestType.SerializeAsString(), requestMessage.SerializeAsString());
cout << getName() << " sent request " << static_cast<int>(requestType.type()) << endl;
// Wait for the response synchronously.
// Note that responses can be processed asynchronously if the server is able to.
string data;
m_requester->receiveBinary(data);
windeta::Response response;
response.ParseFromString(data);
cout << "received response " << response.errorcode() << endl;
commandStatus.setIdle();
}
void RemoteWindeta::test() {
if (!initApplication()) {
return;
}
// Serialize the request.
windeta::Request requestType;
requestType.set_type(windeta::Request::TEST);
// Send the message.
m_requester->sendTwoBinaryParts(requestType.SerializeAsString(), "");
cout << getName() << " sent request " << static_cast<int>(requestType.type()) << endl;
// Wait for the response synchronously.
// Note that responses can be processed asynchronously if the server is able to.
string data;
m_requester->receiveBinary(data);
windeta::Response response;
response.ParseFromString(data);
cout << "received response " << response.errorcode() << endl;
}
void RemoteWindeta::stopApplication() {
if (!initialized()) {
return;
}
// Exit immediately if the server is not available.
if (!m_server->isAvailable(10000)) {
return;
}
// Serialize the request.
windeta::Request requestType;
requestType.set_type(windeta::Request::STOP_SERVER);
// Send the message.
m_requester->sendTwoBinaryParts(requestType.SerializeAsString(), "");
cout << getName() << " sent request " << static_cast<int>(requestType.type()) << endl;
// Wait for the response synchronously.
// Note that responses can be processed asynchronously if the server is able to.
string data;
m_requester->receiveBinary(data);
windeta::Response response;
response.ParseFromString(data);
cout << "received response " << response.errorcode() << endl;
// Stop the remote application.
m_windetaApplication->stop();
// Wait for the termination
applicationState = m_windetaApplication->waitFor();
cout << "Windeta application terminated with state " << application::toString(applicationState()) << endl;
}
void RemoteWindeta::subscriberLoop() {
// Loop on events
string data;
while (m_subscriber->receiveBinary(data)) {
}
}
}
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef DIELECTRICS_REMOTEWINDETA_H
#define DIELECTRICS_REMOTEWINDETA_H
#include <Controller.h>
#include <cameo/cameo.h>
#include "drivers/utilities/null/NullDriver.h"
namespace dielectrics {
/*!
* \brief Test command.
*/
class Test: private controller::Command {
public:
Test(ExperimentController * c) :
controller::Command(c, "test", &Test::test, this) {
}
virtual void test() = 0;
void testCommand(bool logging = false) {
command(logging, true);
}
};
class RemoteWindeta : public ExperimentController,
public controller::Stoppable,
public Test {
public:
//! Type of controller
static const std::string TYPE;
RemoteWindeta(const std::string& name);
RemoteWindeta(const RemoteWindeta& controller);
virtual ~RemoteWindeta();
virtual void postConfiguration();
virtual void setEnabled(bool all, bool postconf = true);
virtual void setDisabled(bool all = false);
virtual void start();
virtual void stop();
virtual void test();
Property<std::string> serverEndpoint;
Property<bool> initialized;
Property<int32> applicationState;
private:
void reset();
bool initApplication();
void stopApplication();
void subscriberLoop();
static const std::string WINDETA_APPLICATION;
static const std::string RESPONDER_NAME;
static const std::string PUBLISHER_NAME;
std::unique_ptr<cameo::Server> m_server;
std::unique_ptr<cameo::application::Instance> m_windetaApplication;
std::unique_ptr<cameo::application::Requester> m_requester;
std::unique_ptr<cameo::application::Subscriber> m_subscriber;
std::unique_ptr<boost::thread> m_subscriberThread;
DriverPtr<driver::NullDriver> m_driver;
};
}
#endif
<module name="remotedielectricswindeta">
<controller class="dielectrics::RemoteWindeta"/>
<include path="$(NOMAD_HOME)/../NomadModules/src"/>
<script exec="protoc --cpp_out=. WindetaMessages.proto"/>
</module>
package windeta;
option optimize_for = LITE_RUNTIME;
message Request {
enum Type {
START_MEASURE = 1;
STOP_MEASURE = 2;
STOP_SERVER = 3;
TEST = 4;
}
required Type type = 1;
}
message StartMeasure {
required string preset = 1;
required string path = 2;
required string filename = 3;
}
message StopMeasure {
}
message StopServer {
}
message Response {
required int32 errorCode = 1;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment