* form of data[n].name/data[n].value
* errorCB: error callback, called with error message string
*
+* Function name: getHistory(event, startTime, endTime, successCB, errorCB)
+* Description:
+* Retrieves a list of event/value pairs for a target list of event names
+* Required arguments:
+* event: event to read
+* startTime: start date/time
+* endTime: end date/time
+* successCB: success callback, gets called with the event/value pair list
+* for all requested events. The list is the in the
+* form of data[n].name/data[n].value
+* errorCB: error callback, called with error message string
+*
+*
* Function name: set(eventlist, valuelist, successCB, errorCB)
* Description:
* Sets a gourp of event's values (triggers error on read-only events)
this.send(obj, successCB, errorCB);
}
+Vehicle.prototype.getHistory = function(event, startTime, endTime, successCB, errorCB)
+{
+ var obj = {
+ "type" : "method",
+ "name": "getHistory",
+ "transactionid" : this.generateTransactionId(),
+ "data" : [event, (startTime.getTime()/1000).toString(), (endTime.getTime()/1000).toString()]
+ };
+
+ this.send(obj, successCB, errorCB);
+
+}
+
Vehicle.prototype.set = function(namelist, valuelist, successCB, errorCB)
{
if((namelist.length != valuelist.length)||(namelist.length <= 0))
return;
}
- if((event == undefined)||(event.type == undefined)||
- (event.name == undefined))
+ if((event === undefined)||(event.type === undefined)||
+ (event.name === undefined))
{
self.iErrorCB("BADLY FORMED MESSAGE: "+msg);
return;
}
context = libwebsocket_create_context(port, interface.c_str(), protocollist,libwebsocket_internal_extensions,ssl_cert_path, ssl_key_path, -1, -1, options);
}
+
void WebSocketSinkManager::addSingleShotSink(libwebsocket* socket, VehicleProperty::Property property,string id)
{
AsyncPropertyRequest velocityRequest;
//TODO: run valgrind on this. libwebsocket's documentation says NOTHING about this, yet malloc insists it's true.
//delete new_response; <- Unneeded. Apparently libwebsocket free's it.
delete (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING); //Needs to subtract pre-padding, to get back to the start of the pointer.
-
+ delete reply;
};
AsyncPropertyReply* reply = routingEngine->getPropertyAsync(velocityRequest);
}
+
+void WebSocketSinkManager::addSingleShotRangedSink(libwebsocket* socket, VehicleProperty::Property property, double start, double end, string id)
+{
+ AsyncRangePropertyRequest rangedRequest;
+
+ rangedRequest.begin = start;
+ rangedRequest.end = end;
+
+ if (property == "running_status_speedometer")
+ {
+ rangedRequest.property = VehicleProperty::VehicleSpeed;
+ }
+ else if (property == "running_status_engine_speed")
+ {
+ rangedRequest.property = VehicleProperty::EngineSpeed;
+ }
+ else if (property == "running_status_steering_wheel_angle")
+ {
+ rangedRequest.property = VehicleProperty::SteeringWheelAngle;
+ }
+ else if (property == "running_status_transmission_gear_status")
+ {
+ rangedRequest.property = VehicleProperty::TransmissionShiftPosition;
+ }
+ else
+ {
+ PropertyList foo = VehicleProperty::capabilities();
+ if (ListPlusPlus<VehicleProperty::Property>(&foo).contains(property))
+ {
+ rangedRequest.property = property;
+ }
+ else
+ {
+ DebugOut(0)<<"websocketsink: Invalid property requested: "<<property;
+ return;
+ }
+
+ }
+ rangedRequest.completed = [socket,id](AsyncRangePropertyReply* reply)
+ {
+ stringstream s;
+
+ //TODO: Dirty hack hardcoded stuff, jsut to make it work.
+ stringstream data ("[");
+ std::list<PropertyValueTime*> values = reply->values;
+ for(auto itr = values.begin(); itr != values.end(); itr++)
+ {
+ if(itr != values.begin())
+ {
+ data<<",";
+ }
+
+ data << "{ \"value\" : " << "\"" << (*itr)->value->toString() << "\", \"time\" : \"" << (*itr)->timestamp << "\" }";
+ }
+
+ data<<"]";
+
+ s << "{\"type\":\"methodReply\",\"name\":\"getHistory\",\"data\":"<<data<<",\"transactionid\":\"" << id << "\"}";
+
+ string replystr = s.str();
+ //printf("Reply: %s\n",replystr.c_str());
+ DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Reply:" << replystr << "\n";
+
+ char *new_response = new char[LWS_SEND_BUFFER_PRE_PADDING + strlen(replystr.c_str()) + LWS_SEND_BUFFER_POST_PADDING];
+ new_response+=LWS_SEND_BUFFER_PRE_PADDING;
+ strcpy(new_response,replystr.c_str());
+ libwebsocket_write(socket, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
+
+ //TODO: run valgrind on this. libwebsocket's documentation says NOTHING about this, yet malloc insists it's true.
+ //delete new_response; <- Unneeded. Apparently libwebsocket free's it.
+ delete (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING); //Needs to subtract pre-padding, to get back to the start of the pointer.
+ delete reply;
+ };
+
+ AsyncRangePropertyReply* reply = routingEngine->getRangePropertyAsync(rangedRequest);
+}
+
void WebSocketSinkManager::removeSink(libwebsocket* socket,VehicleProperty::Property property, string uuid)
{
if (m_sinkMap.find(property) != m_sinkMap.end())
name = json_reader_get_string_value(reader);
json_reader_end_member(reader);
- list<string> data;
+ vector<string> data;
list<string> key;
list<string> value;
json_reader_read_member(reader,"data");
//GetProperty is going to be a singleshot sink.
//string arg = arguments.front();
sinkManager->addSingleShotSink(wsi,data.front(),id);
- /*if (data.front()== "running_status_speedometer")
- {
- sinkManager->addSingleShotSink(wsi,VehicleProperty::VehicleSpeed,id);
- }
- else if (data.front() == "running_status_engine_speed")
- {
- sinkManager->addSingleShotSink(wsi,VehicleProperty::EngineSpeed,id);
- }
- else if (data.front() == "running_status_steering_wheel_angle")
- {
- sinkManager->addSingleShotSink(wsi,VehicleProperty::SteeringWheelAngle,id);
- }
- else if (data.front() == "running_status_transmission_gear_status")
- {
- sinkManager->addSingleShotSink(wsi,VehicleProperty::TransmissionShiftPosition,id);
- }
- else
- {
- PropertyList foo = VehicleProperty::capabilities();
- if (ListPlusPlus<VehicleProperty::Property>(&foo).contains(data.front()))
- {
- sinkManager->addSingleShotSink(wsi,data.front(),id);
- }
- }*/
}
else
{
else if (name == "subscribe")
{
//Websocket wants to subscribe to an event, data.front();
- for (list<string>::iterator i=data.begin();i!=data.end();i++)
+ for (auto i=data.begin();i!=data.end();i++)
{
sinkManager->addSink(wsi,(*i),id);
}
else if (name == "unsubscribe")
{
//Websocket wants to unsubscribe to an event, data.front();
- for (list<string>::iterator i=data.begin();i!=data.end();i++)
+ for (auto i=data.begin();i!=data.end();i++)
{
sinkManager->removeSink(wsi,(*i),id);
}
}
+ else if (name == "getHistory")
+ {
+ if(data.size() == 3)
+ {
+ std::string property = data[0];
+ std::string startStr = data[1];
+ std::string endStr = data[2];
+
+ sinkManager->addSingleShotRangedSink(wsi,property,
+ boost::lexical_cast<double,std::string>(startStr),
+ boost::lexical_cast<double,std::string>(endStr), id);
+ }
+
+ else
+ {
+ //TODO: error, "invalid arguments" should be sent in reply to this.
+ }
+ }
else if (name == "getSupportedEventTypes")
{
//If data.front() dosen't contain a property name, return a list of properties supported.
libwebsocket_write(wsi, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT);
delete (char*)(new_response-LWS_SEND_BUFFER_PRE_PADDING);
}
+ else
+ {
+ DebugOut(0)<<"Unknown method called."<<endl;
+ }
}
break;
}