2 Copyright (C) 2012 Intel Corporation
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "obd2source.h"
22 #include <boost/assert.hpp>
23 #include <boost/lexical_cast.hpp>
26 #include <json-glib/json-glib.h>
27 #include <listplusplus.h>
29 #include "bluetooth.hpp"
30 #include "timestamp.h"
32 #define __SMALLFILE__ std::string(__FILE__).substr(std::string(__FILE__).rfind("/")+1)
33 AbstractRoutingEngine *m_re;
35 //std::list<ObdPid*> Obd2Amb::supportedPidsList;
36 Obd2Amb *obd2AmbInstance = new Obd2Amb;
38 int calledPersecond = 0;
40 bool sendElmCommand(obdLib *obd,std::string command)
42 std::vector<unsigned char> replyVector;
44 obd->sendObdRequestString(command.append("\r").c_str(),command.length()+1,&replyVector,10,3);
45 for (unsigned int i=0;i<replyVector.size();i++)
47 reply += replyVector[i];
49 if (reply.find("OK") == -1)
61 void connect(obdLib* obd, std::string device, std::string strbaud)
63 //printf("First: %s\nSecond: %s\n",req->arg.substr(0,req->arg.find(':')).c_str(),req->arg.substr(req->arg.find(':')+1).c_str());
64 std::string port = device;
65 DebugOut() << "Obd2Source::Connect()" << device << strbaud << "\n";
66 int baud = boost::lexical_cast<int>(strbaud);
67 obd->openPort(port.c_str(),baud);
68 ObdPid::ByteArray replyVector;
70 obd->sendObdRequestString("ATZ\r",4,&replyVector,500,3);
71 for (unsigned int i=0;i<replyVector.size();i++)
73 reply += replyVector[i];
75 if (reply.find("ELM") == -1)
79 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Error resetting ELM\n";
83 //printf("Reply to reset: %s\n",reply.c_str());
85 if (!sendElmCommand(obd,"ATSP0"))
87 //printf("Error sending echo\n");
88 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Error setting auto protocol"<<endl;
90 if (!sendElmCommand(obd,"ATE0"))
92 //printf("Error sending echo\n");
93 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Error turning off echo"<<endl;
95 if (!sendElmCommand(obd,"ATH0"))
97 //printf("Error sending headers off\n");
98 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Error turning off headers"<<endl;
100 if (!sendElmCommand(obd,"ATL0"))
102 //printf("Error turning linefeeds off\n");
103 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Error turning off linefeeds"<<endl;
105 obd->sendObdRequestString("010C1\r",6,&replyVector,500,5);
108 void threadLoop(gpointer data)
110 GAsyncQueue *privCommandQueue = g_async_queue_ref(((OBD2Source*)data)->commandQueue);
111 GAsyncQueue *privResponseQueue = g_async_queue_ref(((OBD2Source*)data)->responseQueue);
112 GAsyncQueue *privSingleShotQueue = g_async_queue_ref(((OBD2Source*)data)->singleShotQueue);
113 GAsyncQueue *privSubscriptionAddQueue = g_async_queue_ref(((OBD2Source*)data)->subscriptionAddQueue);
114 GAsyncQueue *privSubscriptionRemoveQueue = g_async_queue_ref(((OBD2Source*)data)->subscriptionRemoveQueue);
115 obdLib *obd = new obdLib();
116 OBD2Source *source = (OBD2Source*)data;
118 obd->setCommsCallback([](const char* mssg, void* data) { DebugOut(6)<<mssg<<endl; },NULL);
119 obd->setDebugCallback([](const char* mssg, void* data, obdLib::DebugLevel debugLevel) { DebugOut(debugLevel)<<mssg<<endl; },NULL);
121 std::list<ObdPid*> reqList;
122 std::list<ObdPid*> repeatReqList;
123 ObdPid::ByteArray replyVector;
127 bool connected=false;
129 int timeoutCount = 0;
130 while (source->m_threadLive)
132 //gpointer query = g_async_queue_pop(privCommandQueue);
135 gpointer query = g_async_queue_try_pop(privSingleShotQueue);
136 if (query != nullptr)
138 //printf("Got request!\n");
139 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got single shot request!"<<endl;
140 ObdPid *req = (ObdPid*)query;
141 repeatReqList.push_back(req);
143 query = g_async_queue_try_pop(privSubscriptionAddQueue);
144 if (query != nullptr)
147 ObdPid *req = (ObdPid*)query;
148 //DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got subscription request for "<<req->req<<endl;
149 reqList.push_back(req);
151 query = g_async_queue_try_pop(privCommandQueue);
152 if (query != nullptr)
154 //ObdPid *req = (ObdPid*)query;
155 CommandRequest *req = (CommandRequest*)query;
156 //commandMap[req->req] = req->arg;
157 //printf("Command: %s\n",req->req.c_str());
158 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Command:" << req->req << endl;
159 if (req->req == "connect")
162 if (source->m_isBluetooth)
164 ObdBluetoothDevice bt;
165 std::string tempPort = bt.getDeviceForAddress(source->m_btDeviceAddress, source->m_btAdapterAddress);
168 DebugOut(3)<<"Using bluetooth device \""<<source->m_btDeviceAddress<<"\" bound to: "<<tempPort<<endl;
174 port = req->arglist[0];
175 baud = req->arglist[1];
177 connect(obd,port,baud);
180 else if (req->req == "connectifnot")
184 if (source->m_isBluetooth)
186 ObdBluetoothDevice bt;
187 std::string tempPort = bt.getDeviceForAddress(source->m_btDeviceAddress, source->m_btAdapterAddress);
190 DebugOut(3)<<"Using bluetooth device \""<<source->m_btDeviceAddress<<"\" bound to: "<<tempPort<<endl;
194 connect(obd,port,baud);
198 else if (req->req == "setportandbaud")
200 port = req->arglist[0];
201 baud = req->arglist[1];
203 else if (req->req == "disconnect")
205 DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "Using queued disconnect" << (ulong)req << "\n";
207 ObdBluetoothDevice bt;
208 bt.disconnect(source->m_btDeviceAddress, source->m_btAdapterAddress);
213 query = g_async_queue_try_pop(privSubscriptionRemoveQueue);
214 if (query != nullptr)
216 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got unsubscription request\n";
217 ObdPid *req = (ObdPid*)query;
218 for (std::list<ObdPid*>::iterator i=reqList.begin();i!= reqList.end();i++)
220 if ((*i)->property == req->property)
227 //reqList.push_back(req->req);
230 if (reqList.size() > 0 && !connected)
232 /*CommandRequest *req = new CommandRequest();
233 req->req = "connect";
234 req->arglist.push_back(port);
235 req->arglist.push_back(baud);
236 g_async_queue_push(privCommandQueue,req);
239 else if (reqList.size() == 0 && connected)
242 if (emptycount < 1000)
248 CommandRequest *req = new CommandRequest();
249 req->req = "disconnect";
250 g_async_queue_push(privCommandQueue,req);
258 for (std::list<ObdPid*>::iterator i=reqList.begin();i!= reqList.end();i++)
260 repeatReqList.push_back(*i);
263 for (std::list<ObdPid*>::iterator i=repeatReqList.begin();i!= repeatReqList.end();i++)
265 if (source->m_blacklistPidCountMap.find((*i)->pid) != source->m_blacklistPidCountMap.end())
267 //Don't erase the pid, just skip over it.
268 int count = (*source->m_blacklistPidCountMap.find((*i)->pid)).second;
275 if (!obd->sendObdRequestString((*i)->pid.c_str(),(*i)->pid.length(),&replyVector))
277 //This only happens during a error with the com port. Close it and re-open it later.
278 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Unable to send request:" << (*i)->pid << "!\n";
279 if (obd->lastError() == obdLib::NODATA)
281 DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "OBDLib::NODATA for pid" << (*i)->pid << "\n";
282 if (source->m_blacklistPidCountMap.find((*i)->pid) != source->m_blacklistPidCountMap.end())
284 //pid value i not yet in the list.
285 int count = (*source->m_blacklistPidCountMap.find((*i)->pid)).second;
290 source->m_blacklistPidCountMap.erase(source->m_blacklistPidCountMap.find((*i)->pid));
291 source->m_blacklistPidCountMap.insert(pair<std::string,int>((*i)->pid,count));
295 source->m_blacklistPidCountMap.insert(pair<std::string,int>((*i)->pid,1));
299 else if (obd->lastError() == obdLib::TIMEOUT)
302 if (timeoutCount < 2)
304 DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "OBDLib::TIMEOUT for pid" << (*i)->pid << "\n";
312 CommandRequest *req = new CommandRequest();
313 DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "Queuing up a disconnect" << (ulong)req << "\n";
314 req->req = "disconnect";
315 g_async_queue_push(privCommandQueue,req);
316 i = repeatReqList.end();
320 if (source->m_blacklistPidCountMap.find((*i)->pid) != source->m_blacklistPidCountMap.end())
322 //If we get the pid response, then we want to clear out the blacklist list.
323 source->m_blacklistPidCountMap.erase(source->m_blacklistPidCountMap.find((*i)->pid));
326 //ObdPid *pid = ObdPid::pidFromReply(replyVector);
327 ObdPid *pid = obd2AmbInstance->createPidFromReply(replyVector);
331 DebugOut() << "Invalid reply"<<endl;
334 g_async_queue_push(privResponseQueue,pid);
335 //printf("Req: %s\n",(*i).c_str());
336 /*if ((*i) == "ATRV\r")
338 //printf("Requesting voltage...\n");
339 if (!obd->sendObdRequestString((*i).c_str(),(*i).length(),&replyVector))
341 //printf("Unable to request voltage!!!\n");
342 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Unable to request voltage!\n";
345 std::string replystring = "";
346 for (int j=0;j<replyVector.size();j++)
348 replystring += replyVector[j];
350 //printf("Voltage reply: %s\n",replystring.c_str());
351 replystring.substr(0,replystring.find("V"));*/
352 /*ObdReply *rep = new ObdReply();
354 rep->reply = replystring;
355 g_async_queue_push(privResponseQueue,rep);*/
357 if (!obd->sendObdRequest((*i).c_str(),(*i).length(),&replyVector))
359 //printf("Error sending obd2 request\n");
360 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Error sending OBD2 request\n";
363 //printf("Reply: %i %i\n",replyVector[0],replyVector[1]);
366 else if (replyVector[0] == 0x49)
376 for (int j=0;j<replyVector.size();j++)
378 if(replyVector[j] == 0x49 && replyVector[j+1] == 0x02)
380 //We're at a reply header
383 if (replyVector[j] != 0x00)
385 vinstring += (char)replyVector[j];
386 //printf("VIN: %i %c\n",replyVector[j],replyVector[j]);
389 /*ObdReply *rep = new ObdReply();
391 rep->reply = vinstring;
392 g_async_queue_push(privResponseQueue,rep);*/
394 //DebugOut()<<"Reply: "<<replyVector[2]<<" "<<replyVector[3]<<endl;
398 //We had zero non-blacklisted events. Pause for a moment here to keep from burning CPU.
401 repeatReqList.clear();
410 static int updateProperties(/*gpointer retval,*/ gpointer data)
413 OBD2Source* src = (OBD2Source*)data;
415 while(gpointer retval = g_async_queue_try_pop(src->responseQueue))
417 ObdPid *reply = (ObdPid*)retval;
420 AbstractPropertyType* value = VehicleProperty::getPropertyTypeForPropertyNameValue(reply->property, reply->value);
421 src->updateProperty(reply->property, value);
423 /*if (reply->req == "05")
425 VehicleProperty::EngineCoolantTemperatureType speed(reply->reply);
426 src->updateProperty(VehicleProperty::EngineCoolantTemperature,&speed);
428 else if (reply->req == "0C")
430 VehicleProperty::EngineSpeedType speed(reply->reply);
431 src->updateProperty(VehicleProperty::EngineSpeed,&speed);
433 else if (reply->req == "0D")
435 VehicleProperty::VehicleSpeedType speed(reply->reply);
436 src->updateProperty(VehicleProperty::VehicleSpeed,&speed);
438 else if (reply->req == "10")
440 VehicleProperty::MassAirFlowType mass(reply->reply);
441 src->updateProperty(VehicleProperty::MassAirFlow,&mass);
443 else if (reply->req == "ATRV\r")
445 VehicleProperty::BatteryVoltageType volts(reply->reply);
446 src->updateProperty(VehicleProperty::BatteryVoltage,&volts);
449 else if (reply->req == "0902")
452 VehicleProperty::VINType vin(reply->reply);
453 src->updateProperty(VehicleProperty::VIN,&vin);
454 VehicleProperty::WMIType wmi(reply->reply.substr(0,3));
455 src->updateProperty(VehicleProperty::WMI,&wmi);
457 else if (reply->req == "5C")
459 VehicleProperty::EngineCoolantTemperatureType ect(reply->reply);
460 src->updateProperty(VehicleProperty::EngineCoolantTemperature,&ect);
462 else if (reply->req == "46")
464 VehicleProperty::InteriorTemperatureType temp(reply->reply);
465 src->updateProperty(VehicleProperty::InteriorTemperature,&temp);
467 //5C -- engine oil temp
476 void OBD2Source::updateProperty(VehicleProperty::Property property,AbstractPropertyType* value)
478 //m_re->updateProperty(property,&value);
480 if (propertyReplyMap.find(property) != propertyReplyMap.end())
482 propertyReplyMap[property]->value = value;
483 propertyReplyMap[property]->completed(propertyReplyMap[property]);
484 propertyReplyMap.erase(property);
488 m_re->updateProperty(property,value,uuid());
492 void OBD2Source::setSupported(PropertyList list)
494 m_supportedProperties = list;
495 m_re->updateSupported(list,PropertyList());
497 /*void OBD2Source::propertySignal(VehicleProperty::Property property,boost::any value)
500 void OBD2Source::checkProperty()
503 void OBD2Source::setConfiguration(map<string, string> config)
505 // //Config has been passed, let's start stuff up.
506 configuration = config;
509 std::string port = "/dev/ttyUSB0";
510 std::string baud = "115200";
511 std::string btadapter = "";
512 m_isBluetooth = false;
515 //printf("OBD2Source::setConfiguration\n");
516 for (map<string,string>::iterator i=configuration.begin();i!=configuration.end();i++)
518 //printf("Incoming setting: %s:%s\n",(*i).first.c_str(),(*i).second.c_str());
519 DebugOut(5) << __SMALLFILE__ <<":"<< __LINE__ << "Incoming setting:" << (*i).first << ":" << (*i).second << "\n";
520 if ((*i).first == "device")
524 else if ((*i).first == "baud")
529 else if ((*i).first == "bluetoothAdapter")
531 btadapter = (*i).second;
535 if(port.find(":") != string::npos)
537 m_btDeviceAddress = port;
538 m_btAdapterAddress = btadapter;
539 m_isBluetooth = true;
541 DebugOut()<<"bluetooth device?"<<endl;
542 ObdBluetoothDevice bt;
544 std::string tempPort = bt.getDeviceForAddress(port, btadapter);
547 DebugOut(3)<<"Using bluetooth device \""<<port<<"\" bound to: "<<tempPort<<endl;
552 DebugOut(0)<<"Device Error"<<endl;
554 //throw std::runtime_error("Device Error");
558 //connect(obd, port, baud);
559 CommandRequest *req = new CommandRequest();
560 req->req = "setportandbaud";
561 req->arglist.push_back(port);
562 req->arglist.push_back(baud);
563 g_async_queue_push(commandQueue,req);
567 m_gThread = g_thread_new("mythread",(GThreadFunc)&threadLoop,this);
568 //g_idle_add(updateProperties, this);
569 g_timeout_add(10,updateProperties,this);
572 OBD2Source::OBD2Source(AbstractRoutingEngine *re, map<string, string> config)
573 : AbstractSource(re, config), Obd2Connect("Obd2Connect")
575 VehicleProperty::registerProperty(Obd2Connect,[](){ return new Obd2ConnectType(false); });
576 clientConnected = false;
583 for(auto itr = obd2amb.supportedPidsList.begin(); itr != obd2amb.supportedPidsList.end(); itr++)
585 m_supportedProperties.push_back((*itr)->property);
588 re->setSupported(supported(), this);
589 /*if (openPort(std::string("/dev/pts/7"),115200))
591 printf("Error opening OBD2 port\n");
593 commandQueue = g_async_queue_new();
594 subscriptionAddQueue = g_async_queue_new();
595 subscriptionRemoveQueue = g_async_queue_new();
596 responseQueue = g_async_queue_new();
597 singleShotQueue = g_async_queue_new();
599 setConfiguration(config);
601 OBD2Source::~OBD2Source()
603 DebugOut() << "OBD2Source Destructor called!!!"<<endl;
604 m_threadLive = false;
605 g_thread_join(m_gThread);
608 PropertyList OBD2Source::supported()
610 return m_supportedProperties;
613 int OBD2Source::supportedOperations()
618 extern "C" AbstractSource * create(AbstractRoutingEngine* routingengine, map<string, string> config)
620 return new OBD2Source(routingengine, config);
623 string OBD2Source::uuid()
625 return "f77af740-f1f8-11e1-aff1-0800200c9a66";
627 void OBD2Source::subscribeToPropertyChanges(VehicleProperty::Property property)
629 /*//printf("Subscribed to property: %s\n",property.c_str());
630 if (property == VehicleProperty::EngineSpeed)
632 ObdRequest *requ = new ObdRequest();
633 requ->req = "010C1\r";
634 g_async_queue_push(subscriptionAddQueue,requ);
636 else if (property == VehicleProperty::MassAirFlow)
638 ObdRequest *requ = new ObdRequest();
639 requ->req = "01101\r";
640 g_async_queue_push(subscriptionAddQueue,requ);
642 else if (property == VehicleProperty::VehicleSpeed)
644 ObdRequest *requ = new ObdRequest();
645 requ->req = "010D1\r";
646 g_async_queue_push(subscriptionAddQueue,requ);
648 else if (property == VehicleProperty::EngineCoolantTemperature)
650 ObdRequest *requ = new ObdRequest();
651 requ->req = "01051\r";
652 g_async_queue_push(subscriptionAddQueue,requ);
654 else if (property == VehicleProperty::VIN)
656 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "VIN subscription requested... but there's no point!\n";
658 else if (property == VehicleProperty::WMI)
660 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "WMI subscription requested... but there's no point!\n";
662 else if (property == VehicleProperty::EngineOilTemperature)
664 ObdRequest *requ = new ObdRequest();
665 requ->req = "015C1\r";
666 g_async_queue_push(subscriptionAddQueue,requ);
668 else if (property == VehicleProperty::InteriorTemperature)
670 ObdRequest *requ = new ObdRequest();
671 requ->req = "01461\r";
672 g_async_queue_push(subscriptionAddQueue,requ);
674 else if (property == VehicleProperty::BatteryVoltage)
676 ObdRequest *requ = new ObdRequest();
677 requ->req = "ATRV\r";
678 g_async_queue_push(subscriptionAddQueue,requ);
680 /*m_supportedProperties.push_back(VehicleProperty::VIN);
681 m_supportedProperties.push_back(VehicleProperty::WMI);
682 m_supportedProperties.push_back(VehicleProperty::EngineOilTemperature);
683 m_supportedProperties.push_back(VehicleProperty::InteriorTemperature);
684 m_supportedProperties.push_back(VehicleProperty::BatteryVoltage);*/
687 //printf("Unsupported property: %s\n",property.c_str());
688 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Unsupported property requested:" << property << "\n";
691 if (property == VehicleProperty::VIN)
693 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "VIN subscription requested... but there's no point!"<<endl;
695 else if (property == VehicleProperty::WMI)
697 DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "WMI subscription requested... but there's no point!"<<endl;
701 if(!ListPlusPlus<VehicleProperty::Property>(&m_supportedProperties).contains(property))
703 DebugOut(0)<<"obd plugin does not support: "<<property<<endl;
708 ObdPid *pid = obd2AmbInstance->createPidforProperty(property);
715 //If the pid is currently in the blacklist map, erase it. This allows for applications
716 //to "un-blacklist" a pid by re-subscribing to it.
717 if (m_blacklistPidCountMap.find(pid->pid) != m_blacklistPidCountMap.end())
719 m_blacklistPidCountMap.erase(m_blacklistPidCountMap.find(pid->pid));
723 g_async_queue_push(subscriptionAddQueue,pid);
724 CommandRequest *req = new CommandRequest();
725 req->req = "connectifnot";
726 g_async_queue_push(commandQueue,req);
731 void OBD2Source::unsubscribeToPropertyChanges(VehicleProperty::Property property)
734 /*if (property == VehicleProperty::EngineSpeed)
736 ObdRequest *requ = new ObdRequest();
737 requ->req = "010C1\r";
738 g_async_queue_push(subscriptionRemoveQueue,requ);
740 else if (property == VehicleProperty::MassAirFlow)
742 ObdRequest *requ = new ObdRequest();
743 requ->req = "01101\r";
744 g_async_queue_push(subscriptionRemoveQueue,requ);
746 else if (property == VehicleProperty::VehicleSpeed)
748 ObdRequest *requ = new ObdRequest();
749 requ->req = "010D1\r";
750 g_async_queue_push(subscriptionRemoveQueue,requ);
752 else if (property == VehicleProperty::EngineCoolantTemperature)
754 ObdRequest *requ = new ObdRequest();
755 requ->req = "01051\r";
756 g_async_queue_push(subscriptionRemoveQueue,requ);
758 else if (property == VehicleProperty::VIN)
760 ObdRequest *requ = new ObdRequest();
761 requ->req = "0902\r";
762 g_async_queue_push(subscriptionRemoveQueue,requ);
764 else if (property == VehicleProperty::WMI)
766 ObdRequest *requ = new ObdRequest();
767 requ->req = "0902\r";
768 g_async_queue_push(subscriptionRemoveQueue,requ);
770 else if (property == VehicleProperty::EngineOilTemperature)
772 ObdRequest *requ = new ObdRequest();
773 requ->req = "015C1\r";
774 g_async_queue_push(subscriptionRemoveQueue,requ);
776 else if (property == VehicleProperty::InteriorTemperature)
778 ObdRequest *requ = new ObdRequest();
779 requ->req = "01461\r";
780 g_async_queue_push(subscriptionRemoveQueue,requ);
782 else if (property == VehicleProperty::BatteryVoltage)
784 ObdRequest *requ = new ObdRequest();
785 requ->req = "ATRV\r";
786 g_async_queue_push(subscriptionRemoveQueue,requ);
790 if(!ListPlusPlus<VehicleProperty::Property>(&m_supportedProperties).contains(property))
792 DebugOut(0)<<"obd plugin does not support: "<<property<<endl;
796 ObdPid *pid = obd2AmbInstance->createPidforProperty(property);
797 g_async_queue_push(subscriptionRemoveQueue,pid);
801 void OBD2Source::getPropertyAsync(AsyncPropertyReply *reply)
803 propertyReplyMap[reply->property] = reply;
804 VehicleProperty::Property property = reply->property;
806 //TODO: There is a much better way to do this, but for now it's hardcoded.
807 /*if (property == VehicleProperty::EngineSpeed)
809 ObdRequest *requ = new ObdRequest();
810 requ->req = "010C\r";
811 g_async_queue_push(singleShotQueue,requ);
813 else if (property == VehicleProperty::MassAirFlow)
815 ObdRequest *requ = new ObdRequest();
816 requ->req = "0110\r";
817 g_async_queue_push(singleShotQueue,requ);
819 else if (property == VehicleProperty::VehicleSpeed)
821 ObdRequest *requ = new ObdRequest();
822 requ->req = "010D\r";
823 g_async_queue_push(singleShotQueue,requ);
825 else if (property == VehicleProperty::EngineCoolantTemperature)
827 ObdRequest *requ = new ObdRequest();
828 requ->req = "0105\r";
829 g_async_queue_push(singleShotQueue,requ);
831 else if (property == VehicleProperty::VIN)
833 ObdRequest *requ = new ObdRequest();
834 requ->req = "0902\r";
835 g_async_queue_push(singleShotQueue,requ);
837 else if (property == VehicleProperty::WMI)
839 ObdRequest *requ = new ObdRequest();
840 requ->req = "0902\r";
841 g_async_queue_push(singleShotQueue,requ);
843 else if (property == VehicleProperty::EngineOilTemperature)
845 ObdRequest *requ = new ObdRequest();
846 requ->req = "015C\r";
847 g_async_queue_push(singleShotQueue,requ);
849 else if (property == VehicleProperty::InteriorTemperature)
851 ObdRequest *requ = new ObdRequest();
852 requ->req = "0146\r";
853 g_async_queue_push(singleShotQueue,requ);
855 else if (property == VehicleProperty::BatteryVoltage)
857 ObdRequest *requ = new ObdRequest();
858 requ->req = "ATRV\r";
859 g_async_queue_push(singleShotQueue,requ);
863 ///Here's a better way:
865 if(!ListPlusPlus<VehicleProperty::Property>(&m_supportedProperties).contains(property))
867 DebugOut(0)<<"obd plugin does not support: "<<property<<endl;
871 ObdPid* requ = obd2AmbInstance->createPidforProperty(property);
872 g_async_queue_push(singleShotQueue,requ);
873 CommandRequest *req = new CommandRequest();
874 req->req = "connectifnot";
875 g_async_queue_push(commandQueue,req);
878 AsyncPropertyReply *OBD2Source::setProperty(AsyncSetPropertyRequest request )
880 AsyncPropertyReply* reply = new AsyncPropertyReply (request);
881 reply->success = false;
884 reply->completed(reply);