diff options
author | Kevron Rees <kevron_m_rees@linux.intel.com> | 2012-11-14 15:46:04 -0800 |
---|---|---|
committer | Kevron Rees <kevron_m_rees@linux.intel.com> | 2012-11-14 15:46:04 -0800 |
commit | 9d87fbcec9471c1e5e17ea7658fb84d9e9e9067e (patch) | |
tree | d9d72e8009b0bea4e94d538531e6e3dba266e3bd | |
parent | 5b324b35e9717cfab996562d1c2652ea342cb421 (diff) | |
parent | 250035b8916580d198760b9e068ee39dce8bcece (diff) | |
download | automotive-message-broker-mal.tar.gz |
blahmal
-rw-r--r-- | examples/obdsourceconfig | 2 | ||||
-rw-r--r-- | plugins/demosink/demosinkplugin.h | 6 | ||||
-rw-r--r-- | plugins/examplesink.cpp | 23 | ||||
-rw-r--r-- | plugins/obd2plugin/CMakeLists.txt | 8 | ||||
-rw-r--r-- | plugins/obd2plugin/obd2source.cpp | 254 | ||||
-rw-r--r-- | plugins/obd2plugin/obd2source.h | 98 | ||||
-rw-r--r-- | plugins/obd2plugin/obdlib.cpp | 34 | ||||
-rw-r--r-- | plugins/obd2plugin/obdlib.h | 1 | ||||
-rw-r--r-- | plugins/obd2plugin/obdpid.cpp | 4 | ||||
-rw-r--r-- | plugins/obd2plugin/obdpid.h | 256 |
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 |