25#include <simgear/debug/logstream.hxx>
26#include <simgear/props/props.hxx>
27#include <simgear/structure/commands.hxx>
29#include <simgear/props/props_io.hxx>
45 if ( NULL == json )
return;
46 switch ( json->type ) {
48 prop->setStringValue(json->valuestring);
52 prop->setDoubleValue(json->valuedouble);
56 prop->setBoolValue(
true);
60 prop->setBoolValue(
false);
70 cJSON * value = cJSON_GetObjectItem(json,
"value");
71 if ( NULL != value ) {
72 if (nodes.size() > 1) {
73 SG_LOG(SG_NETWORK, SG_WARN,
"httpd: WS set: insufficent values for nodes:" << nodes.size());
77 SGPropertyNode_ptr n =
fgGetNode(nodes.front());
79 SG_LOG(SG_NETWORK, SG_WARN,
"httpd: set '" << nodes.front() <<
"' not found");
87 cJSON * values = cJSON_GetObjectItem(json,
"values");
88 if ( ( NULL == values ) || (
static_cast<size_t>(cJSON_GetArraySize(values)) != nodes.size()) ) {
89 SG_LOG(SG_NETWORK, SG_WARN,
"httpd: WS set: mismatched nodes/values sizes:" << nodes.size());
93 string_list::const_iterator it;
95 for (it = nodes.begin(); it != nodes.end(); ++it, ++
i) {
98 SG_LOG(SG_NETWORK, SG_WARN,
"httpd: get '" << *it <<
"' not found");
108 cJSON*
name = cJSON_GetObjectItem(json,
"fgcommand");
109 if ((NULL ==
name )|| (NULL ==
name->valuestring)) {
110 SG_LOG(SG_NETWORK, SG_WARN,
"httpd: exec: no fgcommand name");
114 SGPropertyNode_ptr arg(
new SGPropertyNode);
117 globals->get_commands()->execute(
name->valuestring, arg,
nullptr);
122 _propertyChangeObserver(propertyChangeObserver),
123 _minTriggerInterval(
fgGetDouble(
"/sim/http/property-websocket/update-interval-secs", 0.05)),
134 SG_LOG(SG_NETWORK, SG_INFO,
"closing PropertyChangeWebsocket #" <<
id);
135 _watchedNodes.clear();
141 string_list::const_iterator it;
142 for (it = nodes.begin(); it != nodes.end(); ++it) {
145 SG_LOG(SG_NETWORK, SG_WARN,
"httpd: get '" << *it <<
"' not found");
155 if (request.
Content.empty())
return;
168 cJSON * json = cJSON_Parse(request.
Content.c_str());
171 cJSON * j = cJSON_GetObjectItem(json,
"command");
172 if ( NULL != j && NULL != j->valuestring) {
178 j = cJSON_GetObjectItem(json,
"node");
179 if ( NULL != j && NULL != j->valuestring) {
180 nodeNames.push_back(simgear::strutils::strip(
string(j->valuestring)));
183 cJSON * nodes = cJSON_GetObjectItem(json,
"nodes");
184 if ( NULL != nodes) {
185 for (
int i = 0;
i < cJSON_GetArraySize(nodes);
i++) {
186 cJSON * node = cJSON_GetArrayItem(nodes,
i);
187 if ( NULL == node)
continue;
188 if ( NULL == node->valuestring)
continue;
189 nodeNames.push_back(simgear::strutils::strip(
string(node->valuestring)));
194 handleGetCommand(nodeNames, writer);
197 }
else if (
command ==
"exec") {
200 string_list::const_iterator it;
201 for (it = nodeNames.begin(); it != nodeNames.end(); ++it) {
202 _watchedNodes.handleCommand(
command, *it, _propertyChangeObserver);
214 if( _minTriggerInterval > .0 ) {
215 if( now - _lastTrigger <= _minTriggerInterval )
221 for (WatchedNodesList::iterator it = _watchedNodes.begin(); it != _watchedNodes.end(); ++it) {
222 SGPropertyNode_ptr node = *it;
225 if (_propertyChangeObserver->isChangedValue(node)) {
227 SG_LOG(SG_NETWORK, SG_DEBUG,
"PropertyChangeWebsocket::poll() new Value for " << node->getPath(
true) <<
" '" << node->getStringValue() <<
"' #" <<
id <<
": " << out );
233void PropertyChangeWebsocket::WatchedNodesList::handleCommand(
const string &
command,
const string & node,
236 if (
command ==
"addListener") {
237 for (iterator it = begin(); it != end(); ++it) {
238 if (node == (*it)->getPath(
true)) {
239 SG_LOG(SG_NETWORK, SG_WARN,
"httpd: " <<
command <<
" '" << node <<
"' ignored (duplicate)");
243 SGPropertyNode_ptr n = propertyChangeObserver->
addObservation(node);
244 if (n.valid()) push_back(n);
245 SG_LOG(SG_NETWORK, SG_INFO,
"httpd: " <<
command <<
" '" << node <<
"' success");
247 }
else if (
command ==
"removeListener") {
248 for (iterator it = begin(); it != end(); ++it) {
249 if (node == (*it)->getPath(
true)) {
251 SG_LOG(SG_NETWORK, SG_INFO,
"httpd: " <<
command <<
" '" << node <<
"' success");
255 SG_LOG(SG_NETWORK, SG_WARN,
"httpd: " <<
command <<
" '" << node <<
"' ignored (not found)");
static std::string toJsonString(bool indent, SGPropertyNode_ptr n, int depth, double timestamp=-1.0)
static void addChildrenToProp(cJSON *json, SGPropertyNode_ptr base)
const SGPropertyNode_ptr addObservation(const std::string propertyName)
virtual void handleRequest(const HTTPRequest &request, WebsocketWriter &writer)
virtual ~PropertyChangeWebsocket()
PropertyChangeWebsocket(PropertyChangeObserver *propertyChangeObserver)
virtual void poll(WebsocketWriter &writer)
int writeText(const char *data, size_t len)
SGCommandMgr::command_t command
std::vector< std::string > string_list
static void setPropertyFromJson(SGPropertyNode_ptr prop, cJSON *json)
static void handleSetCommand(const string_list &nodes, cJSON *json, WebsocketWriter &writer)
static void handleExecCommand(cJSON *json)
FlightPlan.hxx - defines a full flight-plan object, including departure, cruise, arrival information ...
SGCommandMgr::command_t command
double fgGetDouble(const char *name, double defaultValue)
Get a double value for a property.
SGPropertyNode * fgGetNode(const char *path, bool create)
Get a property node.