From 8b6c0b9411d5825b79b13500a11a7ecee0bbe7aa Mon Sep 17 00:00:00 2001 From: Kevron Rees Date: Fri, 2 Nov 2012 10:48:56 -0700 Subject: start of obd2 refactoring --- plugins/demosink/demosinkplugin.h | 6 +- plugins/examplesink.cpp | 23 +++++ plugins/obd2plugin/CMakeLists.txt | 4 +- plugins/obd2plugin/obd2source.cpp | 171 ++++++++++++++------------------ plugins/obd2plugin/obd2source.h | 91 ++++------------- plugins/obd2plugin/obdlib.cpp | 14 ++- plugins/obd2plugin/obdlib.h | 1 + plugins/obd2plugin/obdpid.cpp | 4 + plugins/obd2plugin/obdpid.h | 204 ++++++++++++++++++++++++++++++++++++++ 9 files changed, 341 insertions(+), 177 deletions(-) create mode 100644 plugins/obd2plugin/obdpid.cpp create mode 100644 plugins/obd2plugin/obdpid.h 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 config) :AbstractSinkManager(engine, config) { - + DemoSink* sink = new DemoSink(routingEngine, config); + sink->setConfiguration(config); } void setConfiguration(map 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 + + extern "C" AbstractSinkManager * create(AbstractRoutingEngine* routingengine, map config) { return new ExampleSinkManager(routingengine, config); @@ -55,6 +58,26 @@ ExampleSink::ExampleSink(AbstractRoutingEngine* engine, map 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 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<getRangePropertyAsync(vehicleSpeedFromLastWeek); + } diff --git a/plugins/obd2plugin/CMakeLists.txt b/plugins/obd2plugin/CMakeLists.txt index ae2d3c32..2f2bfc15 100644 --- a/plugins/obd2plugin/CMakeLists.txt +++ b/plugins/obd2plugin/CMakeLists.txt @@ -9,8 +9,8 @@ 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} ) diff --git a/plugins/obd2plugin/obd2source.cpp b/plugins/obd2plugin/obd2source.cpp index 1bb227d3..b01c779b 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 Obd2Amb::supportedPidsList; +Obd2Amb *obd2AmbInstance = new Obd2Amb; int calledPersecond = 0; @@ -58,6 +57,51 @@ 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; + int baud = boost::lexical_cast(strbaud); + obd->openPort(port.c_str(),baud); + + obd->sendObdRequestString("ATZ\r",4,&replyVector,500,3); + for (unsigned int i=0;icommandQueue); @@ -70,10 +114,9 @@ void threadLoop(gpointer data) obd->setCommsCallback([](const char* mssg, void* data) { DebugOut(6)<setDebugCallback([](const char* mssg, void* data, obdLib::DebugLevel debugLevel) { DebugOut(debugLevel)< reqList; - std::list repeatReqList; - std::map commandMap; - std::vector replyVector; + std::list reqList; + std::list repeatReqList; + ObdPid::ByteArray replyVector; std::string reply; while (true) { @@ -85,68 +128,27 @@ void threadLoop(gpointer data) { //printf("Got request!\n"); DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got single shot request!"<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; + ObdPid *req = (ObdPid*)query; DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got subscription request for "<req<req); - delete req; + reqList.push_back(req); } query = g_async_queue_try_pop(privCommandQueue); if (query != nullptr) { - ObdRequest *req = (ObdRequest*)query; + ObdPid *req = (ObdPid*)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") + DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Command:" << req->property << endl; + if (req->property == "connect") { - //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 = req->arg.substr(0,req->arg.find(':')); - int baud = boost::lexical_cast(req->arg.substr(req->arg.find(':')+1)); - obd->openPort(port.c_str(),baud); - - obd->sendObdRequestString("ATZ\r",4,&replyVector,500,3); - for (unsigned int i=0;iresponseQueue)) { - ObdReply *reply = (ObdReply*)retval; + ObdPid *reply = (ObdPid*)retval; - Obd2Amb obd2amb; + AbstractPropertyType* value = VehicleProperty::getPropertyTypeForPropertyNameValue(reply->property, reply->value); + src->updateProperty(reply->property, value); - 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); - } - - - AbstractPropertyType* value = VehicleProperty::getPropertyTypeForPropertyNameValue(reply->property, convValue); - src->updateProperty(reply->property, value); - } /*if (reply->req == "05") { @@ -452,10 +442,9 @@ void OBD2Source::setConfiguration(map 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); + g_thread_new("mythread",(GThreadFunc)&threadLoop,this); + g_idle_add(updateProperties, this); } OBD2Source::OBD2Source(AbstractRoutingEngine *re, map config) : AbstractSource(re, config) @@ -464,10 +453,11 @@ OBD2Source::OBD2Source(AbstractRoutingEngine *re, map 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); @@ -480,16 +470,8 @@ OBD2Source::OBD2Source(AbstractRoutingEngine *re, map 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() @@ -585,10 +567,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 = Obd2Amb::createPidforProperty(property); + g_async_queue_push(subscriptionAddQueue,pid); } } @@ -658,11 +639,8 @@ void OBD2Source::unsubscribeToPropertyChanges(VehicleProperty::Property property return; } - Obd2Amb obd2amb; - ObdRequest *requ = new ObdRequest(); - requ->property = property; - requ->req = obd2amb.propertyPidMap[property]; - g_async_queue_push(subscriptionRemoveQueue,requ); + ObdPid *pid = Obd2Amb::createPidforProperty(property); + g_async_queue_push(subscriptionRemoveQueue,pid); } @@ -736,10 +714,7 @@ void OBD2Source::getPropertyAsync(AsyncPropertyReply *reply) return; } - Obd2Amb obd2amb; - ObdRequest *requ = new ObdRequest(); - requ->property = property; - requ->req = obd2amb.propertyPidMap[property]; + ObdPid* requ = Obd2Amb::createPidforProperty(property); g_async_queue_push(singleShotQueue,requ); } diff --git a/plugins/obd2plugin/obd2source.h b/plugins/obd2plugin/obd2source.h index 603133d7..482be63a 100644 --- a/plugins/obd2plugin/obd2source.h +++ b/plugins/obd2plugin/obd2source.h @@ -33,23 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "obdlib.h" #include - -class ObdRequest -{ -public: - VehicleProperty::Property property; - std::string req; - std::string arg; -}; - -class ObdReply -{ -public: - VehicleProperty::Property property; - std::string req; - std::string reply; -}; - +#include "obdpid.h" class Obd2Amb { @@ -57,64 +41,31 @@ public: typedef function ConversionFunction; + 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) - { - return input.substr(0,3); - }; + 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()); + } - propertyConversionMap[VehicleProperty::FuelConsumption] = [](std::string input) + static 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 propertyPidMap; - map propertyConversionMap; - -private: - - static uint16_t velocity; - static double fuelConsumptionOldTime; + static std::list supportedPidsList; }; class OBD2Source : public AbstractSource @@ -151,6 +102,8 @@ public: std::string m_port; map propertyReplyMap; 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..9939cd7f 100644 --- a/plugins/obd2plugin/obdlib.cpp +++ b/plugins/obd2plugin/obdlib.cpp @@ -213,6 +213,12 @@ int obdLib::closePort() #endif return 0; } + +bool obdLib::connected() +{ + +} + int obdLib::initPort() { sendObdRequest("atz\r",4); @@ -372,11 +378,9 @@ bool obdLib::sendObdRequestString(const char *req,int length,std::vector * #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) { 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..b21c81fe --- /dev/null +++ b/plugins/obd2plugin/obdpid.h @@ -0,0 +1,204 @@ +#ifndef _OBDPID_H__H_H_ +#define _OBDPID_H__H_H_ + +#include +#include +#include +#include + +class ObdPid +{ +public: + typedef std::vector ByteArray; + + ObdPid(VehicleProperty::Property prop, std::string p, int i) + :property(prop), pid(p), id(i), type(0x41) + { + + } + + virtual ObdPid* create() = 0; + + virtual void parse(ByteArray replyVector) = 0; + + VehicleProperty::Property property; + std::string pid; + int id; + int type; + std::string value; +}; + +template +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 +{ +public: + + VehicleSpeedPid() + :CopyMe(VehicleProperty::VehicleSpeed, "010D1\r", 0x0D) + { + + } + + void parse(ByteArray replyVector) + { + int mph = replyVector[2]; + value = boost::lexical_cast(mph); + } +}; + +class EngineSpeedPid: public CopyMe +{ +public: + + EngineSpeedPid() + :CopyMe(VehicleProperty::VehicleSpeed,"010C1\r",0x0D) + { + + } + + void parse(ByteArray replyVector) + { + double rpm = ((replyVector[2] << 8) + replyVector[3]) / 4.0; + value = boost::lexical_cast(rpm); + } +}; + +class EngineCoolantPid: public CopyMe +{ +public: + + EngineCoolantPid() + :CopyMe(VehicleProperty::VehicleSpeed,"01051\r",0x0D) + { + + } + + void parse(ByteArray replyVector) + { + int temp = replyVector[2] - 40; + value = boost::lexical_cast(temp); + } +}; + +class MassAirFlowPid: public CopyMe +{ +public: + + MassAirFlowPid() + :CopyMe(VehicleProperty::VehicleSpeed,"01101\r",0x0D) + { + + } + + virtual void parse(ByteArray replyVector) + { + maf = ((replyVector[2] << 8) + replyVector[3]) / 100.0; + value = boost::lexical_cast(maf); + } + +protected: + double maf; +}; + + +class FuelConsumptionPid: public MassAirFlowPid +{ +public: + FuelConsumptionPid() + + { + + } + + virtual void parse(ByteArray replyVector) + { + MassAirFlowPid::parse(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(consumption); + } + +private: + + static double oldTime; +}; + + +class VinPid: public CopyMe +{ +public: + + VinPid() + :CopyMe(VehicleProperty::VIN,"0902\r",0x0D) + { + type = 0x49; + } + + virtual void parse(ByteArray replyVector) + { + std::string vinstring; + for (int j=0;j Date: Tue, 13 Nov 2012 21:20:34 -0500 Subject: Continuation of Kevron's refactoring, including connect on first subscribe --- examples/obdsourceconfig | 2 +- plugins/obd2plugin/CMakeLists.txt | 4 +- plugins/obd2plugin/obd2source.cpp | 154 +++++++++++++++++++------------------- plugins/obd2plugin/obd2source.h | 49 +++++++++++- plugins/obd2plugin/obdpid.h | 104 ++++++++++++++++++------- 5 files changed, 204 insertions(+), 109 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/obd2plugin/CMakeLists.txt b/plugins/obd2plugin/CMakeLists.txt index 2f2bfc15..5cb6958c 100644 --- a/plugins/obd2plugin/CMakeLists.txt +++ b/plugins/obd2plugin/CMakeLists.txt @@ -1,4 +1,4 @@ -if(obd2_plugin) +#if(obd2_plugin) include(CheckIncludeFiles) @@ -17,4 +17,4 @@ target_link_libraries(obd2sourceplugin amb -L${CMAKE_CURRENT_BINARY_DIR}/lib ${l 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 b01c779b..c46c3ac3 100644 --- a/plugins/obd2plugin/obd2source.cpp +++ b/plugins/obd2plugin/obd2source.cpp @@ -32,7 +32,7 @@ #define __SMALLFILE__ std::string(__FILE__).substr(std::string(__FILE__).rfind("/")+1) AbstractRoutingEngine *m_re; -std::list Obd2Amb::supportedPidsList; +//std::list Obd2Amb::supportedPidsList; Obd2Amb *obd2AmbInstance = new Obd2Amb; int calledPersecond = 0; @@ -62,9 +62,11 @@ 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(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 repeatReqList; ObdPid::ByteArray replyVector; std::string reply; + std::string port; + std::string baud; + bool connected=false; while (true) { //gpointer query = g_async_queue_pop(privCommandQueue); @@ -136,19 +141,31 @@ void threadLoop(gpointer data) { ObdPid *req = (ObdPid*)query; - DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got subscription request for "<req<req<req] = req->arg; //printf("Command: %s\n",req->req.c_str()); - DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Command:" << req->property << endl; - if (req->property == "connect") + DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Command:" << req->req << endl; + if (req->req == "connect") { - connect(obd); + connect(obd,req->arglist[0],req->arglist[1]); + connected = true; + } + else if (req->req == "setportandbaud") + { + port = req->arglist[0]; + baud = req->arglist[1]; + } + else if (req->req == "disconnect") + { + obd->closePort(); + connected = false; } delete req; } @@ -156,27 +173,50 @@ void threadLoop(gpointer data) if (query != nullptr) { DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got unsubscription request\n"; - ObdRequest *req = (ObdRequest*)query; - for (std::list::iterator i=reqList.begin();i!= reqList.end();i++) + ObdPid *req = (ObdPid*)query; + for (std::list::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::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; + } + for (std::list::iterator i=reqList.begin();i!= reqList.end();i++) { repeatReqList.push_back(*i); } - for (std::list::iterator i=repeatReqList.begin();i!= repeatReqList.end();i++) + for (std::list::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") + /*if ((*i) == "ATRV\r") { //printf("Requesting voltage...\n"); if (!obd->sendObdRequestString((*i).c_str(),(*i).length(),&replyVector)) @@ -191,73 +231,29 @@ void threadLoop(gpointer data) replystring += replyVector[j]; } //printf("Voltage reply: %s\n",replystring.c_str()); - replystring.substr(0,replystring.find("V")); - ObdReply *rep = new ObdReply(); + replystring.substr(0,replystring.find("V"));*/ + /*ObdReply *rep = new ObdReply(); rep->req = "ATRV\r"; rep->reply = replystring; - g_async_queue_push(privResponseQueue,rep); - } + 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]); - if (replyVector[0] == 0x41) - { - if (replyVector[1] == 0x0C) - { - double rpm = ((replyVector[2] << 8) + replyVector[3]) / 4.0; - ObdReply *rep = new ObdReply(); - rep->req = "0C"; - rep->property = VehicleProperty::EngineSpeed; - rep->reply = boost::lexical_cast(rpm); - g_async_queue_push(privResponseQueue,rep); - //printf("RPM: %f\n",rpm); - } - else if (replyVector[1] == 0x0D) - { - int mph = replyVector[2]; - ObdReply *rep = new ObdReply(); - rep->req = "0D"; - rep->property = VehicleProperty::VehicleSpeed; - rep->reply = boost::lexical_cast(mph); - g_async_queue_push(privResponseQueue,rep); - } - else if (replyVector[1] == 0x05) - { - int temp = replyVector[2] - 40; - ObdReply *rep = new ObdReply(); - rep->req = "05"; - rep->property = VehicleProperty::EngineCoolantTemperature; - rep->reply = boost::lexical_cast(temp); - g_async_queue_push(privResponseQueue,rep); - } - else if (replyVector[1] == 0x10) - { - double maf = ((replyVector[2] << 8) + replyVector[3]) / 100.0; - ObdReply *rep = new ObdReply(); - rep->req = "10"; - rep->property = VehicleProperty::MassAirFlow; - rep->reply = boost::lexical_cast(maf); - g_async_queue_push(privResponseQueue,rep); - } - else - { - //printf("Unknown response type: %i\n",replyVector[1]); - DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Unknown response type" << replyVector[1] << endl; - } - } + /* + /* 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;jreq = "0902"; rep->reply = vinstring; - g_async_queue_push(privResponseQueue,rep); - //printf("VIN Number: %i %s\n",replyVector.size(),vinstring.c_str()); + g_async_queue_push(privResponseQueue,rep);*/ - } - //DebugOut()<<"Reply: "< config) //printf("OBD2Source::setConfiguration\n"); for (map::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") { @@ -442,7 +436,15 @@ void OBD2Source::setConfiguration(map config) else throw std::runtime_error("Device Error"); } - connect(obd, port, baud); + //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); } @@ -568,7 +570,7 @@ void OBD2Source::subscribeToPropertyChanges(VehicleProperty::Property property) } - ObdPid *pid = Obd2Amb::createPidforProperty(property); + ObdPid *pid = obd2AmbInstance->createPidforProperty(property); g_async_queue_push(subscriptionAddQueue,pid); } } @@ -639,7 +641,7 @@ void OBD2Source::unsubscribeToPropertyChanges(VehicleProperty::Property property return; } - ObdPid *pid = Obd2Amb::createPidforProperty(property); + ObdPid *pid = obd2AmbInstance->createPidforProperty(property); g_async_queue_push(subscriptionRemoveQueue,pid); } @@ -714,7 +716,7 @@ void OBD2Source::getPropertyAsync(AsyncPropertyReply *reply) return; } - ObdPid* requ = Obd2Amb::createPidforProperty(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 482be63a..a37b694a 100644 --- a/plugins/obd2plugin/obd2source.h +++ b/plugins/obd2plugin/obd2source.h @@ -35,13 +35,39 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "obdpid.h" +class ObdRequest +{ +public: + VehicleProperty::Property property; + std::string req; + std::string arg; +}; + + +class CommandRequest +{ +public: + std::string req; + std::vector arglist; +}; + +class ObdReply +{ +public: + VehicleProperty::Property property; + std::string req; + std::string reply; +}; + + + class Obd2Amb { public: typedef function ConversionFunction; - + typedef std::vector ByteArray; Obd2Amb() { supportedPidsList.push_back(new VehicleSpeedPid()); @@ -52,8 +78,22 @@ public: supportedPidsList.push_back(new FuelConsumptionPid()); supportedPidsList.push_back(new EngineCoolantPid()); } - - static ObdPid* createPidforProperty(VehicleProperty::Property property) + ObdPid* createPidFromReply(ByteArray replyVector) + { + for(auto itr = supportedPidsList.begin(); itr != supportedPidsList.end(); itr++) + { + 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++) { @@ -65,7 +105,7 @@ public: } } - static std::list supportedPidsList; + std::list supportedPidsList; }; class OBD2Source : public AbstractSource @@ -100,6 +140,7 @@ public: void setConfiguration(map config); //void randomizeProperties(); std::string m_port; + std::string m_baud; map propertyReplyMap; void updateProperty(VehicleProperty::Property property,AbstractPropertyType *value); obdLib * obd; diff --git a/plugins/obd2plugin/obdpid.h b/plugins/obd2plugin/obdpid.h index b21c81fe..6632672a 100644 --- a/plugins/obd2plugin/obdpid.h +++ b/plugins/obd2plugin/obdpid.h @@ -4,6 +4,7 @@ #include #include #include +#include "obdlib.h" #include class ObdPid @@ -16,10 +17,31 @@ public: { } - + static ByteArray cleanup(ByteArray replyVector) + { + ByteArray tmp; + for (int i=0;i(mph); + return true; } }; @@ -72,11 +104,16 @@ public: { } - - void parse(ByteArray replyVector) + bool tryParse(ByteArray replyVector) { - double rpm = ((replyVector[2] << 8) + replyVector[3]) / 4.0; + ByteArray tmp = compress(cleanup(replyVector)); + if (tmp[1] != 0x0C) + { + return false; + } + double rpm = ((tmp[2] << 8) + tmp[3]) / 4.0; value = boost::lexical_cast(rpm); + return false; } }; @@ -89,11 +126,16 @@ public: { } - - void parse(ByteArray replyVector) + bool tryParse(ByteArray replyVector) { - int temp = replyVector[2] - 40; + ByteArray tmp = compress(cleanup(replyVector)); + if (tmp[1] != 0x05) + { + return false; + } + int temp = tmp[2] - 40; value = boost::lexical_cast(temp); + return false; } }; @@ -106,11 +148,16 @@ public: { } - - virtual void parse(ByteArray replyVector) + bool tryParse(ByteArray replyVector) { - maf = ((replyVector[2] << 8) + replyVector[3]) / 100.0; + ByteArray tmp = compress(cleanup(replyVector)); + if (tmp[1] != 0x10) + { + return false; + } + maf = ((tmp[2] << 8) + tmp[3]) / 100.0; value = boost::lexical_cast(maf); + return false; } protected: @@ -126,10 +173,9 @@ public: { } - - virtual void parse(ByteArray replyVector) + bool tryParse(ByteArray replyVector) { - MassAirFlowPid::parse(replyVector); + MassAirFlowPid::tryParse(replyVector); timespec t; clock_gettime(CLOCK_REALTIME, &t); @@ -141,6 +187,7 @@ public: double consumption = 1 / (14.75 * 6.26) * maf * diffTime/60; value = boost::lexical_cast(consumption); + return false; } private: @@ -158,25 +205,30 @@ public: { type = 0x49; } - - virtual void parse(ByteArray replyVector) + bool tryParse(ByteArray replyVector) { std::string vinstring; - for (int j=0;j Date: Tue, 13 Nov 2012 21:30:56 -0500 Subject: Addition of disconnect on last unsubscribe and extra debugging --- plugins/obd2plugin/obd2source.cpp | 12 +++++++++++- plugins/obd2plugin/obdlib.cpp | 20 +++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/plugins/obd2plugin/obd2source.cpp b/plugins/obd2plugin/obd2source.cpp index c46c3ac3..3fe54b03 100644 --- a/plugins/obd2plugin/obd2source.cpp +++ b/plugins/obd2plugin/obd2source.cpp @@ -195,6 +195,13 @@ void threadLoop(gpointer data) 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::iterator i=reqList.begin();i!= reqList.end();i++) { repeatReqList.push_back(*i); @@ -276,7 +283,10 @@ void threadLoop(gpointer data) //DebugOut()<<"Reply: "< * #ifdef WINVER Sleep(10); #else + printf("Timeout\n"); usleep(10000); #endif } -- cgit v1.2.1