summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevron Rees <kevron_m_rees@linux.intel.com>2012-11-14 15:46:04 -0800
committerKevron Rees <kevron_m_rees@linux.intel.com>2012-11-14 15:46:04 -0800
commit9d87fbcec9471c1e5e17ea7658fb84d9e9e9067e (patch)
treed9d72e8009b0bea4e94d538531e6e3dba266e3bd
parent5b324b35e9717cfab996562d1c2652ea342cb421 (diff)
parent250035b8916580d198760b9e068ee39dce8bcece (diff)
downloadautomotive-message-broker-mal.tar.gz
blahmal
-rw-r--r--examples/obdsourceconfig2
-rw-r--r--plugins/demosink/demosinkplugin.h6
-rw-r--r--plugins/examplesink.cpp23
-rw-r--r--plugins/obd2plugin/CMakeLists.txt8
-rw-r--r--plugins/obd2plugin/obd2source.cpp254
-rw-r--r--plugins/obd2plugin/obd2source.h98
-rw-r--r--plugins/obd2plugin/obdlib.cpp34
-rw-r--r--plugins/obd2plugin/obdlib.h1
-rw-r--r--plugins/obd2plugin/obdpid.cpp4
-rw-r--r--plugins/obd2plugin/obdpid.h256
10 files changed, 560 insertions, 126 deletions
diff --git a/examples/obdsourceconfig b/examples/obdsourceconfig
index f7403bd1..651f7767 100644
--- a/examples/obdsourceconfig
+++ b/examples/obdsourceconfig
@@ -3,7 +3,7 @@
{
"name" : "OBD2Source",
"path" : "/usr/lib/automotive-message-broker/obd2sourceplugin.so",
- "device" : "/dev/ttyUSB0",
+ "device" : "/dev/pts/10",
"baud" : "115200",
"bluetoothAdapter" : ""
}
diff --git a/plugins/demosink/demosinkplugin.h b/plugins/demosink/demosinkplugin.h
index 02fb1914..ffd806cb 100644
--- a/plugins/demosink/demosinkplugin.h
+++ b/plugins/demosink/demosinkplugin.h
@@ -49,13 +49,13 @@ public:
DemoSinkManager(AbstractRoutingEngine* engine, map<string, string> config)
:AbstractSinkManager(engine, config)
{
-
+ DemoSink* sink = new DemoSink(routingEngine, config);
+ sink->setConfiguration(config);
}
void setConfiguration(map<string, string> config)
{
- DemoSink* sink = new DemoSink(routingEngine, config);
- sink->setConfiguration(config);
+
}
};
diff --git a/plugins/examplesink.cpp b/plugins/examplesink.cpp
index d3e6c435..56d6c60c 100644
--- a/plugins/examplesink.cpp
+++ b/plugins/examplesink.cpp
@@ -21,6 +21,9 @@
#include "abstractroutingengine.h"
#include "debugout.h"
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+
extern "C" AbstractSinkManager * create(AbstractRoutingEngine* routingengine, map<string, string> config)
{
return new ExampleSinkManager(routingengine, config);
@@ -55,6 +58,26 @@ ExampleSink::ExampleSink(AbstractRoutingEngine* engine, map<string, string> conf
routingEngine->getPropertyAsync(batteryVoltageRequest);
+ boost::posix_time::ptime start(boost::gregorian::date(2012,10,20));
+ boost::posix_time::ptime end(boost::gregorian::date(2012,10,21));
+
+ AsyncRangePropertyRequest vehicleSpeedFromLastWeek;
+ tm tmStart = boost::posix_time::to_tm(start);
+ tm tmEnd = boost::posix_time::to_tm(end);
+ vehicleSpeedFromLastWeek.begin = mktime(&tmStart);
+ vehicleSpeedFromLastWeek.end = mktime(&tmEnd);
+ vehicleSpeedFromLastWeek.property = VehicleProperty::VehicleSpeed;
+ vehicleSpeedFromLastWeek.completed = [](AsyncRangePropertyReply* reply)
+ {
+ std::list<PropertyValueTime*> values = reply->values;
+ for(auto itr = values.begin(); itr != values.end(); itr++)
+ {
+ DebugOut(0)<<"Velocity value from last week: "<<(*itr)->value->toString()<<" time: "<<(*itr)->timestamp<<endl;
+ }
+ };
+
+ routingEngine->getRangePropertyAsync(vehicleSpeedFromLastWeek);
+
}
diff --git a/plugins/obd2plugin/CMakeLists.txt b/plugins/obd2plugin/CMakeLists.txt
index ae2d3c32..5cb6958c 100644
--- a/plugins/obd2plugin/CMakeLists.txt
+++ b/plugins/obd2plugin/CMakeLists.txt
@@ -1,4 +1,4 @@
-if(obd2_plugin)
+#if(obd2_plugin)
include(CheckIncludeFiles)
@@ -9,12 +9,12 @@ pkg_check_modules(gio-unix REQUIRED gio-unix-2.0)
include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${gio_INCLUDE_DIRS} ${gio-unix_INCLUDE_DIRS} )
-set(obd2sourceplugin_headers obd2source.h obdlib.h bluetoothmanagerproxy.h bluetoothadapterproxy.h bluetoothserialproxy.h )
-set(obd2sourceplugin_sources obd2source.cpp obdlib.cpp bluetooth.hpp bluetoothmanagerproxy.c bluetoothadapterproxy.c bluetoothserialproxy.c)
+set(obd2sourceplugin_headers obd2source.h obdlib.h obdpid.h bluetoothmanagerproxy.h bluetoothadapterproxy.h bluetoothserialproxy.h )
+set(obd2sourceplugin_sources obd2source.cpp obdlib.cpp obdpid.cpp bluetooth.hpp bluetoothmanagerproxy.c bluetoothadapterproxy.c bluetoothserialproxy.c)
add_library(obd2sourceplugin MODULE ${obd2sourceplugin_sources})
set_target_properties(obd2sourceplugin PROPERTIES PREFIX "")
target_link_libraries(obd2sourceplugin amb -L${CMAKE_CURRENT_BINARY_DIR}/lib ${link_libraries} ${gio_LIBRARIES} ${gio-unix_LIBRARIES} )
install(TARGETS obd2sourceplugin LIBRARY DESTINATION lib/automotive-message-broker)
-endif(obd2_plugin)
+#endif(obd2_plugin)
diff --git a/plugins/obd2plugin/obd2source.cpp b/plugins/obd2plugin/obd2source.cpp
index 75698132..f2b4446f 100644
--- a/plugins/obd2plugin/obd2source.cpp
+++ b/plugins/obd2plugin/obd2source.cpp
@@ -32,9 +32,8 @@
#define __SMALLFILE__ std::string(__FILE__).substr(std::string(__FILE__).rfind("/")+1)
AbstractRoutingEngine *m_re;
-uint16_t Obd2Amb::velocity = 0;
-double Obd2Amb::fuelConsumptionOldTime = 0;
-
+//std::list<ObdPid*> Obd2Amb::supportedPidsList;
+Obd2Amb *obd2AmbInstance = new Obd2Amb;
int calledPersecond = 0;
@@ -58,6 +57,53 @@ bool sendElmCommand(obdLib *obd,std::string command)
}
}
+
+void connect(obdLib* obd, std::string device, std::string strbaud)
+{
+ //printf("First: %s\nSecond: %s\n",req->arg.substr(0,req->arg.find(':')).c_str(),req->arg.substr(req->arg.find(':')+1).c_str());
+ std::string port = device;
+ DebugOut() << "Obd2Source::Connect()" << device << strbaud << "\n";
+ int baud = boost::lexical_cast<int>(strbaud);
+ obd->openPort(port.c_str(),baud);
+ObdPid::ByteArray replyVector;
+std::string reply;
+ obd->sendObdRequestString("ATZ\r",4,&replyVector,500,3);
+ for (unsigned int i=0;i<replyVector.size();i++)
+ {
+ reply += replyVector[i];
+ }
+ if (reply.find("ELM") == -1)
+ {
+ //No reply found
+ //printf("Error!\n");
+ DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Error resetting ELM\n";
+ }
+ else
+ {
+ //printf("Reply to reset: %s\n",reply.c_str());
+ }
+ if (!sendElmCommand(obd,"ATSP0"))
+ {
+ //printf("Error sending echo\n");
+ DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Error setting auto protocol"<<endl;
+ }
+ if (!sendElmCommand(obd,"ATE0"))
+ {
+ //printf("Error sending echo\n");
+ DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Error turning off echo"<<endl;
+ }
+ if (!sendElmCommand(obd,"ATH0"))
+ {
+ //printf("Error sending headers off\n");
+ DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Error turning off headers"<<endl;
+ }
+ if (!sendElmCommand(obd,"ATL0"))
+ {
+ //printf("Error turning linefeeds off\n");
+ DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Error turning off linefeeds"<<endl;
+ }
+}
+
void threadLoop(gpointer data)
{
GAsyncQueue *privCommandQueue = g_async_queue_ref(((OBD2Source*)data)->commandQueue);
@@ -70,14 +116,18 @@ void threadLoop(gpointer data)
obd->setCommsCallback([](const char* mssg, void* data) { DebugOut(6)<<mssg<<endl; },NULL);
obd->setDebugCallback([](const char* mssg, void* data, obdLib::DebugLevel debugLevel) { DebugOut(debugLevel)<<mssg<<endl; },NULL);
- std::list<std::string> reqList;
- std::list<std::string> repeatReqList;
- std::map<std::string,std::string> commandMap;
- std::vector<unsigned char> replyVector;
+ std::list<ObdPid*> reqList;
+ std::list<ObdPid*> repeatReqList;
+ ObdPid::ByteArray replyVector;
std::string reply;
std::string port;
+<<<<<<< HEAD
int baud;
bool connected = false;
+=======
+ std::string baud;
+ bool connected=false;
+>>>>>>> 250035b8916580d198760b9e068ee39dce8bcece
while (true)
{
//gpointer query = g_async_queue_pop(privCommandQueue);
@@ -88,28 +138,28 @@ void threadLoop(gpointer data)
{
//printf("Got request!\n");
DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got single shot request!"<<endl;
- ObdRequest *req = (ObdRequest*)query;
- repeatReqList.push_back(req->req);
- delete req;
+ ObdPid *req = (ObdPid*)query;
+ repeatReqList.push_back(req);
}
query = g_async_queue_try_pop(privSubscriptionAddQueue);
if (query != nullptr)
{
- ObdRequest *req = (ObdRequest*)query;
- DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got subscription request for "<<req->req<<endl;
- reqList.push_back(req->req);
- delete req;
+ ObdPid *req = (ObdPid*)query;
+ //DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got subscription request for "<<req->req<<endl;
+ reqList.push_back(req);
}
query = g_async_queue_try_pop(privCommandQueue);
if (query != nullptr)
{
- ObdRequest *req = (ObdRequest*)query;
+ //ObdPid *req = (ObdPid*)query;
+ CommandRequest *req = (CommandRequest*)query;
//commandMap[req->req] = req->arg;
//printf("Command: %s\n",req->req.c_str());
DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Command:" << req->req << endl;
if (req->req == "connect")
{
+<<<<<<< HEAD
//printf("First: %s\nSecond: %s\n",req->arg.substr(0,req->arg.find(':')).c_str(),req->arg.substr(req->arg.find(':')+1).c_str());
port = req->arg.substr(0,req->arg.find(':'));
baud = boost::lexical_cast<int>(req->arg.substr(req->arg.find(':')+1));
@@ -152,6 +202,16 @@ void threadLoop(gpointer data)
}
connected = true;
}
+=======
+ connect(obd,req->arglist[0],req->arglist[1]);
+ connected = true;
+ }
+ else if (req->req == "setportandbaud")
+ {
+ port = req->arglist[0];
+ baud = req->arglist[1];
+ }
+>>>>>>> 250035b8916580d198760b9e068ee39dce8bcece
else if (req->req == "disconnect")
{
obd->closePort();
@@ -163,23 +223,40 @@ void threadLoop(gpointer data)
if (query != nullptr)
{
DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got unsubscription request\n";
- ObdRequest *req = (ObdRequest*)query;
- for (std::list<std::string>::iterator i=reqList.begin();i!= reqList.end();i++)
+ ObdPid *req = (ObdPid*)query;
+ for (std::list<ObdPid*>::iterator i=reqList.begin();i!= reqList.end();i++)
{
- if ((*i) == req->req)
+ if ((*i)->property == req->property)
{
reqList.erase(i);
+ delete (*i);
i--;
}
}
//reqList.push_back(req->req);
delete req;
}
-
- for (std::list<std::string>::iterator i=reqList.begin();i!= reqList.end();i++)
+ if (reqList.size() > 0 && !connected)
+ {
+ CommandRequest *req = new CommandRequest();
+ req->req = "connect";
+ req->arglist.push_back(port);
+ req->arglist.push_back(baud);
+ g_async_queue_push(privCommandQueue,req);
+ continue;
+ }
+ else if (reqList.size() == 0 && connected)
+ {
+ CommandRequest *req = new CommandRequest();
+ req->req = "disconnect";
+ g_async_queue_push(privCommandQueue,req);
+ continue;
+ }
+ for (std::list<ObdPid*>::iterator i=reqList.begin();i!= reqList.end();i++)
{
repeatReqList.push_back(*i);
}
+<<<<<<< HEAD
if (repeatReqList.size() == 0)
{
//Nothing in the queue, we should disconnect and sit idle.
@@ -235,6 +312,66 @@ void threadLoop(gpointer data)
}
//printf("Reply: %i %i\n",replyVector[0],replyVector[1]);
if (replyVector[0] == 0x41)
+=======
+ for (std::list<ObdPid*>::iterator i=repeatReqList.begin();i!= repeatReqList.end();i++)
+ {
+ if (!obd->sendObdRequestString((*i)->pid.c_str(),(*i)->pid.length(),&replyVector))
+ {
+ DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Unable to send request:" << (*i)->pid << "!\n";
+ continue;
+ }
+ //ObdPid *pid = ObdPid::pidFromReply(replyVector);
+ ObdPid *pid = obd2AmbInstance->createPidFromReply(replyVector);
+ if (!pid)
+ {
+ //Invalid reply
+ DebugOut() << "Invalid reply\n";
+ continue;
+ }
+ g_async_queue_push(privResponseQueue,pid);
+ //printf("Req: %s\n",(*i).c_str());
+ /*if ((*i) == "ATRV\r")
+ {
+ //printf("Requesting voltage...\n");
+ if (!obd->sendObdRequestString((*i).c_str(),(*i).length(),&replyVector))
+ {
+ //printf("Unable to request voltage!!!\n");
+ DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Unable to request voltage!\n";
+ continue;
+ }
+ std::string replystring = "";
+ for (int j=0;j<replyVector.size();j++)
+ {
+ replystring += replyVector[j];
+ }
+ //printf("Voltage reply: %s\n",replystring.c_str());
+ replystring.substr(0,replystring.find("V"));*/
+ /*ObdReply *rep = new ObdReply();
+ rep->req = "ATRV\r";
+ rep->reply = replystring;
+ g_async_queue_push(privResponseQueue,rep);*/
+ /*}
+ if (!obd->sendObdRequest((*i).c_str(),(*i).length(),&replyVector))
+ {
+ //printf("Error sending obd2 request\n");
+ DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Error sending OBD2 request\n";
+ continue;
+ }*/
+ //printf("Reply: %i %i\n",replyVector[0],replyVector[1]);
+ /*
+ /*
+ else if (replyVector[0] == 0x49)
+ {
+ /*
+ 49 02 01 00 00 00 31
+ 49 02 02 47 31 4A 43
+ 49 02 03 35 34 34 34
+ 49 02 04 52 37 32 35
+ 49 02 05 32 33 36 37
+ //VIN number reply
+ string vinstring;
+ for (int j=0;j<replyVector.size();j++)
+>>>>>>> 250035b8916580d198760b9e068ee39dce8bcece
{
if (replyVector[1] == 0x0C)
{
@@ -279,6 +416,7 @@ void threadLoop(gpointer data)
DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Unknown response type" << replyVector[1] << endl;
}
}
+<<<<<<< HEAD
else if (replyVector[0] == 0x49)
{
/*
@@ -315,10 +453,21 @@ void threadLoop(gpointer data)
}
}
else
+=======
+ /*ObdReply *rep = new ObdReply();
+ rep->req = "0902";
+ rep->reply = vinstring;
+ g_async_queue_push(privResponseQueue,rep);*/
+
+ //DebugOut()<<"Reply: "<<replyVector[2]<<" "<<replyVector[3]<<endl;
+ }
+ if (!connected)
+>>>>>>> 250035b8916580d198760b9e068ee39dce8bcece
{
usleep(10000);
}
repeatReqList.clear();
+
}
}
@@ -330,23 +479,11 @@ static int updateProperties(/*gpointer retval,*/ gpointer data)
while(gpointer retval = g_async_queue_try_pop(src->responseQueue))
{
- ObdReply *reply = (ObdReply*)retval;
-
- Obd2Amb obd2amb;
-
- if(obd2amb.propertyPidMap.count(reply->property) != 0)
- {
- std::string convValue = reply->reply;
-
- if(obd2amb.propertyConversionMap.count(reply->property))
- {
- convValue = obd2amb.propertyConversionMap[reply->property](reply->reply);
- }
+ ObdPid *reply = (ObdPid*)retval;
+ AbstractPropertyType* value = VehicleProperty::getPropertyTypeForPropertyNameValue(reply->property, reply->value);
+ src->updateProperty(reply->property, value);
- AbstractPropertyType* value = VehicleProperty::getPropertyTypeForPropertyNameValue(reply->property, convValue);
- src->updateProperty(reply->property, value);
- }
/*if (reply->req == "05")
{
@@ -456,7 +593,7 @@ void OBD2Source::setConfiguration(map<string, string> config)
//printf("OBD2Source::setConfiguration\n");
for (map<string,string>::iterator i=configuration.begin();i!=configuration.end();i++)
{
- //printf("Incoming setting: %s:%s\n",(*i).first.c_str(),(*i).second.c_str());
+ printf("Incoming setting: %s:%s\n",(*i).first.c_str(),(*i).second.c_str());
DebugOut(5) << __SMALLFILE__ <<":"<< __LINE__ << "Incoming setting:" << (*i).first << ":" << (*i).second << "\n";
if ((*i).first == "device")
{
@@ -488,10 +625,17 @@ void OBD2Source::setConfiguration(map<string, string> config)
else throw std::runtime_error("Device Error");
}
- ObdRequest *requ = new ObdRequest();
- requ->req = "connect";
- requ->arg = port + ":" + baud;
- g_async_queue_push(commandQueue,requ);
+ //connect(obd, port, baud);
+ CommandRequest *req = new CommandRequest();
+ req->req = "setportandbaud";
+ req->arglist.push_back(port);
+ req->arglist.push_back(baud);
+ g_async_queue_push(commandQueue,req);
+
+ m_port = port;
+ m_baud = baud;
+ g_thread_new("mythread",(GThreadFunc)&threadLoop,this);
+ g_idle_add(updateProperties, this);
}
OBD2Source::OBD2Source(AbstractRoutingEngine *re, map<string, string> config) : AbstractSource(re, config)
@@ -500,10 +644,11 @@ OBD2Source::OBD2Source(AbstractRoutingEngine *re, map<string, string> config) :
m_re = re;
Obd2Amb obd2amb;
+ obd = new obdLib();
- for(auto itr = obd2amb.propertyPidMap.begin(); itr != obd2amb.propertyPidMap.end(); itr++)
+ for(auto itr = obd2amb.supportedPidsList.begin(); itr != obd2amb.supportedPidsList.end(); itr++)
{
- m_supportedProperties.push_back((*itr).first);
+ m_supportedProperties.push_back((*itr)->property);
}
re->setSupported(supported(), this);
@@ -516,16 +661,8 @@ OBD2Source::OBD2Source(AbstractRoutingEngine *re, map<string, string> config) :
subscriptionRemoveQueue = g_async_queue_new();
responseQueue = g_async_queue_new();
singleShotQueue = g_async_queue_new();
- g_thread_new("mythread",(GThreadFunc)&threadLoop,this);
setConfiguration(config);
-
- //AsyncQueueWatcher * watcher = new AsyncQueueWatcher(responseQueue, (AsyncQueueWatcherCallback) updateProperties, this);
-
- //g_timeout_add(1,updateProperties, this);
- g_idle_add(updateProperties, this);
- //g_timeout_add(1000,calcCPS,NULL);
-
}
PropertyList OBD2Source::supported()
@@ -621,10 +758,9 @@ void OBD2Source::subscribeToPropertyChanges(VehicleProperty::Property property)
return;
}
- Obd2Amb obd2amb;
- ObdRequest *requ = new ObdRequest();
- requ->req = obd2amb.propertyPidMap[property];
- g_async_queue_push(subscriptionAddQueue,requ);
+
+ ObdPid *pid = obd2AmbInstance->createPidforProperty(property);
+ g_async_queue_push(subscriptionAddQueue,pid);
}
}
@@ -694,12 +830,17 @@ void OBD2Source::unsubscribeToPropertyChanges(VehicleProperty::Property property
return;
}
+<<<<<<< HEAD
Obd2Amb obd2amb;
ObdRequest *requ = new ObdRequest();
requ->property = property;
requ->req = obd2amb.propertyPidMap[property];
g_async_queue_push(subscriptionRemoveQueue,requ);
+=======
+ ObdPid *pid = obd2AmbInstance->createPidforProperty(property);
+ g_async_queue_push(subscriptionRemoveQueue,pid);
+>>>>>>> 250035b8916580d198760b9e068ee39dce8bcece
}
@@ -773,10 +914,7 @@ void OBD2Source::getPropertyAsync(AsyncPropertyReply *reply)
return;
}
- Obd2Amb obd2amb;
- ObdRequest *requ = new ObdRequest();
- requ->property = property;
- requ->req = obd2amb.propertyPidMap[property];
+ ObdPid* requ = obd2AmbInstance->createPidforProperty(property);
g_async_queue_push(singleShotQueue,requ);
}
diff --git a/plugins/obd2plugin/obd2source.h b/plugins/obd2plugin/obd2source.h
index 9f789fa4..6c628706 100644
--- a/plugins/obd2plugin/obd2source.h
+++ b/plugins/obd2plugin/obd2source.h
@@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include "obdlib.h"
#include <glib.h>
+#include "obdpid.h"
class ObdRequest
{
@@ -42,6 +43,14 @@ public:
std::string arg;
};
+
+class CommandRequest
+{
+public:
+ std::string req;
+ std::vector<std::string> arglist;
+};
+
class ObdReply
{
public:
@@ -51,70 +60,52 @@ public:
};
+
class Obd2Amb
{
public:
typedef function<std::string (std::string)> ConversionFunction;
+ typedef std::vector<unsigned char> ByteArray;
Obd2Amb()
{
- propertyPidMap[VehicleProperty::VehicleSpeed] = "010D1\r";
- propertyPidMap[VehicleProperty::EngineSpeed] = "010C1\r";
- propertyPidMap[VehicleProperty::MassAirFlow] = "01101\r";
- propertyPidMap[VehicleProperty::AirIntakeTemperature] = "010F1\r";
- propertyPidMap[VehicleProperty::ThrottlePosition] = "01111\r";
- propertyPidMap[VehicleProperty::BatteryVoltage] = "ATRV\r";
- propertyPidMap[VehicleProperty::EngineCoolantTemperature] = "0105a\r";
- propertyPidMap[VehicleProperty::EngineLoad] = "01041/r";
- propertyPidMap[VehicleProperty::VIN] = "0902/r";
- propertyPidMap[VehicleProperty::WMI] = "0902/r";
- propertyPidMap[VehicleProperty::EngineOilTemperature] = "015C1\r";
- propertyPidMap[VehicleProperty::InteriorTemperature] = "01461\r";
- propertyPidMap[VehicleProperty::FuelConsumption] = "01101\r";
-
-
-
- propertyConversionMap[VehicleProperty::VehicleSpeed] = [](std::string input)
- {
- ///velocity is used in other equations. We'll save it off in a static variable:
- stringstream vssConvert(input);
-
- vssConvert>>velocity;
-
- return input;
- };
-
- propertyConversionMap[VehicleProperty::WMI] = [](std::string input)
+ supportedPidsList.push_back(new VehicleSpeedPid());
+ supportedPidsList.push_back(new EngineSpeedPid());
+ supportedPidsList.push_back(new MassAirFlowPid());
+ supportedPidsList.push_back(new VinPid());
+ supportedPidsList.push_back(new WmiPid());
+ supportedPidsList.push_back(new FuelConsumptionPid());
+ supportedPidsList.push_back(new EngineCoolantPid());
+ }
+ ObdPid* createPidFromReply(ByteArray replyVector)
+ {
+ for(auto itr = supportedPidsList.begin(); itr != supportedPidsList.end(); itr++)
{
- return input.substr(0,3);
- };
-
- propertyConversionMap[VehicleProperty::FuelConsumption] = [](std::string input)
+ if (!(*itr)->tryParse(replyVector))
+ {
+ continue;
+ }
+
+ ObdPid* pid = (*itr)->create();
+ pid->tryParse(replyVector);
+ return pid;
+ }
+ return 0;
+ }
+ ObdPid* createPidforProperty(VehicleProperty::Property property)
+ {
+ for(auto itr = supportedPidsList.begin(); itr != supportedPidsList.end(); itr++)
{
- double maf;
- stringstream mafConvert(input);
-
- mafConvert>>maf;
-
- mafConvert<<1 / (14.75 * 6.26) * maf * 0/60;
-
- return mafConvert.str();
- };
-
-
-
+ if((*itr)->property == property)
+ {
+ ObdPid* obj = *itr;
+ return obj->create();
+ }
+ }
}
-
-
- map<VehicleProperty::Property, std::string> propertyPidMap;
- map<VehicleProperty::Property, ConversionFunction> propertyConversionMap;
-
-private:
-
- static uint16_t velocity;
- static double fuelConsumptionOldTime;
+ std::list<ObdPid*> supportedPidsList;
};
class OBD2Source : public AbstractSource
@@ -149,9 +140,12 @@ public:
void setConfiguration(map<string, string> config);
//void randomizeProperties();
std::string m_port;
+ std::string m_baud;
map<VehicleProperty::Property,AsyncPropertyReply*> propertyReplyMap;
list<VehicleProperty::Property> propertySubscriptionList;
void updateProperty(VehicleProperty::Property property,AbstractPropertyType *value);
+ obdLib * obd;
+
private:
PropertyList m_supportedProperties;
GMutex *threadQueueMutex;
diff --git a/plugins/obd2plugin/obdlib.cpp b/plugins/obd2plugin/obdlib.cpp
index 32bb43db..489d425b 100644
--- a/plugins/obd2plugin/obdlib.cpp
+++ b/plugins/obd2plugin/obdlib.cpp
@@ -160,18 +160,30 @@ int obdLib::openPort(const char *portName,int baudrate)
{
}
- newtio.c_cflag |= (CLOCAL | CREAD);
+ newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8;
+ newtio.c_cflag |= CLOCAL | CREAD;
+ newtio.c_cflag &= ~CRTSCTS;
+ newtio.c_cflag &= ~CSTOPB;
+ newtio.c_iflag=IGNBRK;
+ newtio.c_iflag &= ~(IXON|IXOFF|IXANY);
+ newtio.c_lflag=0;
+ newtio.c_oflag=0;
+ newtio.c_cc[VTIME]=1; //1/10th second timeout, reduces CPU usage but still allows for timeouts
+ newtio.c_cc[VMIN]=1; //We want a pure timer timeout
+
+
+ /*newtio.c_cflag |= (CLOCAL | CREAD);
newtio.c_lflag &= !(ICANON | ECHO | ECHOE | ISIG);
newtio.c_oflag &= !(OPOST);
newtio.c_cc[VMIN] = 0;
- newtio.c_cc[VTIME] = 100;
+ newtio.c_cc[VTIME] = 100;*/
/*
newtio.c_cflag &= ~CSIZE; //Disable byte size
newtio.c_cflag &= ~PARENB; //Disable parity
newtio.c_cflag &= ~CSTOPB; //Disable stop bits
newtio.c_cflag |= (CLOCAL | CREAD | CS8); //Set local mode, reader, and 8N1.
- newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //Disable CANON, echo, and signals
+ newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //Disausleep(10000);ble CANON, echo, and signals
newtio.c_oflag &= ~(OPOST); //Disable post processing
*/
@@ -188,6 +200,7 @@ int obdLib::openPort(const char *portName,int baudrate)
}
debug(obdLib::DEBUG_VERBOSE,"Setting baud rate to %i on port %s\n",baudrate,portName);
}
+ fcntl(portHandle, F_SETFL, 0); //Set to blocking
tcsetattr(portHandle,TCSANOW,&newtio);
//newtio.c_cc[VMIN] = 0; //Minimum number of bytes to read
//newtio.c_cc[VTIME] = 100; //Read Timeout (10.0 seconds)
@@ -213,6 +226,12 @@ int obdLib::closePort()
#endif
return 0;
}
+
+bool obdLib::connected()
+{
+
+}
+
int obdLib::initPort()
{
sendObdRequest("atz\r",4);
@@ -372,11 +391,9 @@ bool obdLib::sendObdRequestString(const char *req,int length,std::vector<byte> *
#endif
if (len < 0)
{
- printf("No Write\n");
- //delete tmp;
- //delete totalReply;
- //m_lastError = SERIALWRITEERROR;
- //return false;
+ debug(obdLib::DEBUG_ERROR,"Serial write error: %s", strerror(errno));
+
+ return false;
}
if (sleeptime == -1)
{
@@ -422,6 +439,7 @@ bool obdLib::sendObdRequestString(const char *req,int length,std::vector<byte> *
#ifdef WINVER
Sleep(10);
#else
+ printf("Timeout\n");
usleep(10000);
#endif
}
diff --git a/plugins/obd2plugin/obdlib.h b/plugins/obd2plugin/obdlib.h
index 7fdb99a2..5c3cc2b7 100644
--- a/plugins/obd2plugin/obdlib.h
+++ b/plugins/obd2plugin/obdlib.h
@@ -105,6 +105,7 @@ public:
void setPortHandle(HANDLE hdnl);
int initPort();
int closePort();
+ bool connected();
void flush();
void setDebugCallback(void (*callbackptr)(const char*,void*,obdLib::DebugLevel),void *);
void setCommsCallback(void (*callbackptr)(const char*,void*),void*);
diff --git a/plugins/obd2plugin/obdpid.cpp b/plugins/obd2plugin/obdpid.cpp
new file mode 100644
index 00000000..81f12c4e
--- /dev/null
+++ b/plugins/obd2plugin/obdpid.cpp
@@ -0,0 +1,4 @@
+#include "obdpid.h"
+
+
+double FuelConsumptionPid::oldTime=0;
diff --git a/plugins/obd2plugin/obdpid.h b/plugins/obd2plugin/obdpid.h
new file mode 100644
index 00000000..6632672a
--- /dev/null
+++ b/plugins/obd2plugin/obdpid.h
@@ -0,0 +1,256 @@
+#ifndef _OBDPID_H__H_H_
+#define _OBDPID_H__H_H_
+
+#include <vector>
+#include <string>
+#include <vehicleproperty.h>
+#include "obdlib.h"
+#include <time.h>
+
+class ObdPid
+{
+public:
+ typedef std::vector<unsigned char> ByteArray;
+
+ ObdPid(VehicleProperty::Property prop, std::string p, int i)
+ :property(prop), pid(p), id(i), type(0x41)
+ {
+
+ }
+ static ByteArray cleanup(ByteArray replyVector)
+ {
+ ByteArray tmp;
+ for (int i=0;i<replyVector.size();i++)
+ {
+ if ((replyVector[i] != 0x20) && (replyVector[i] != '\r') && (replyVector[i] != '\n'))
+ {
+ tmp.push_back(replyVector[i]);
+ }
+ }
+ return tmp;
+ }
+ static ByteArray compress(ByteArray replyVector)
+ {
+ ByteArray tmp;
+ for (int i=0;i<replyVector.size();i++)
+ {
+ tmp.push_back(obdLib::byteArrayToByte(replyVector[i],replyVector[i+1]));
+ i++;
+ }
+ return tmp;
+ }
+ virtual ObdPid* create() = 0;
+
+ virtual bool tryParse(ByteArray replyVector) = 0;
+
+ VehicleProperty::Property property;
+ std::string pid;
+ int id;
+ int type;
+ std::string value;
+};
+
+template <class T>
+class CopyMe: public ObdPid
+{
+public:
+
+ CopyMe(VehicleProperty::Property prop, std::string p, int i)
+ :ObdPid(prop, p, i)
+ {
+
+ }
+
+ ObdPid* create()
+ {
+ return new T();
+ }
+};
+
+
+class VehicleSpeedPid: public CopyMe<VehicleSpeedPid>
+{
+public:
+
+ VehicleSpeedPid()
+ :CopyMe(VehicleProperty::VehicleSpeed, "010D1\r", 0x0D)
+ {
+
+ }
+ bool tryParse(ByteArray replyVector)
+ {
+ ByteArray tmp = compress(cleanup(replyVector));
+ for (int i=0;i<tmp.size();i++)
+ {
+ printf("%i ",tmp[i]);
+ }
+ printf("\n");
+ if (tmp[1] != 0x0D)
+ {
+ return false;
+ }
+ int mph = tmp[2];
+ value = boost::lexical_cast<std::string>(mph);
+ return true;
+ }
+};
+
+class EngineSpeedPid: public CopyMe<EngineSpeedPid>
+{
+public:
+
+ EngineSpeedPid()
+ :CopyMe(VehicleProperty::VehicleSpeed,"010C1\r",0x0D)
+ {
+
+ }
+ bool tryParse(ByteArray replyVector)
+ {
+ ByteArray tmp = compress(cleanup(replyVector));
+ if (tmp[1] != 0x0C)
+ {
+ return false;
+ }
+ double rpm = ((tmp[2] << 8) + tmp[3]) / 4.0;
+ value = boost::lexical_cast<std::string>(rpm);
+ return false;
+ }
+};
+
+class EngineCoolantPid: public CopyMe<EngineCoolantPid>
+{
+public:
+
+ EngineCoolantPid()
+ :CopyMe(VehicleProperty::VehicleSpeed,"01051\r",0x0D)
+ {
+
+ }
+ bool tryParse(ByteArray replyVector)
+ {
+ ByteArray tmp = compress(cleanup(replyVector));
+ if (tmp[1] != 0x05)
+ {
+ return false;
+ }
+ int temp = tmp[2] - 40;
+ value = boost::lexical_cast<std::string>(temp);
+ return false;
+ }
+};
+
+class MassAirFlowPid: public CopyMe<MassAirFlowPid>
+{
+public:
+
+ MassAirFlowPid()
+ :CopyMe(VehicleProperty::VehicleSpeed,"01101\r",0x0D)
+ {
+
+ }
+ bool tryParse(ByteArray replyVector)
+ {
+ ByteArray tmp = compress(cleanup(replyVector));
+ if (tmp[1] != 0x10)
+ {
+ return false;
+ }
+ maf = ((tmp[2] << 8) + tmp[3]) / 100.0;
+ value = boost::lexical_cast<std::string>(maf);
+ return false;
+ }
+
+protected:
+ double maf;
+};
+
+
+class FuelConsumptionPid: public MassAirFlowPid
+{
+public:
+ FuelConsumptionPid()
+
+ {
+
+ }
+ bool tryParse(ByteArray replyVector)
+ {
+ MassAirFlowPid::tryParse(replyVector);
+ timespec t;
+ clock_gettime(CLOCK_REALTIME, &t);
+
+ double currentTime = t.tv_sec + t.tv_nsec / 1000000;
+
+ double diffTime = currentTime - oldTime;
+ oldTime = currentTime;
+
+ double consumption = 1 / (14.75 * 6.26) * maf * diffTime/60;
+
+ value = boost::lexical_cast<std::string>(consumption);
+ return false;
+ }
+
+private:
+
+ static double oldTime;
+};
+
+
+class VinPid: public CopyMe<VinPid>
+{
+public:
+
+ VinPid()
+ :CopyMe(VehicleProperty::VIN,"0902\r",0x0D)
+ {
+ type = 0x49;
+ }
+ bool tryParse(ByteArray replyVector)
+ {
+ std::string vinstring;
+ ByteArray tmp = compress(cleanup(replyVector));
+ if (tmp[0] != 0x49 && tmp[1] != 0x02)
+ {
+ return false;
+ }
+ for (int j=0;j<tmp.size();j++)
+ {
+ if(tmp[j] == 0x49 && tmp[j+1] == 0x02)
+ {
+ //We're at a reply header
+ j+=3;
+ }
+ if (tmp[j] != 0x00)
+ {
+ vinstring += (char)tmp[j];
+ //printf("VIN: %i %c\n",replyVector[j],replyVector[j]);
+ }
+ }
+
+ value = vinstring;
+ return false;
+ }
+
+};
+
+class WmiPid: public VinPid
+{
+public:
+
+ WmiPid()
+ :VinPid()
+ {
+ property = VehicleProperty::WMI;
+ }
+ bool tryParse(ByteArray replyVector)
+ {
+ VinPid::tryParse(replyVector);
+
+ value = value.substr(0,3);
+ return false;
+ }
+
+};
+
+
+#endif