summaryrefslogtreecommitdiff
path: root/plugins/obd2plugin/obdpid.h
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/obd2plugin/obdpid.h')
-rw-r--r--plugins/obd2plugin/obdpid.h447
1 files changed, 447 insertions, 0 deletions
diff --git a/plugins/obd2plugin/obdpid.h b/plugins/obd2plugin/obdpid.h
new file mode 100644
index 00000000..20db314a
--- /dev/null
+++ b/plugins/obd2plugin/obdpid.h
@@ -0,0 +1,447 @@
+#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)
+ {
+ isValidVal = false;
+ }
+ 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()-1;i++)
+ {
+ tmp.push_back(obdLib::byteArrayToByte(replyVector[i], replyVector[i+1]));
+ i++;
+ }
+ return tmp;
+ }
+ virtual ObdPid* create() = 0;
+
+ bool tryParse(ByteArray replyVector)
+ {
+ if (!isValid(replyVector))
+ {
+ return false;
+ }
+ parse(replyVector);
+ return true;
+ }
+ virtual void parse(const ByteArray &replyVector) = 0;
+ virtual bool isValid(const ByteArray &replyVector) = 0;
+ virtual bool needsCompress() { return true; }
+
+ VehicleProperty::Property property;
+ std::string pid;
+ int id;
+ int type;
+ std::string value;
+ bool isValidVal;
+};
+
+template <class T>
+class CopyMe: public ObdPid
+{
+public:
+
+ CopyMe(VehicleProperty::Property prop, std::string p, int i)
+ :ObdPid(prop, p, i)
+ {
+ }
+
+ ObdPid* create()
+ {
+ T* t = new T();
+ t->value = value;
+ t->isValidVal = isValidVal;
+ return t;
+ }
+};
+
+
+class VehicleSpeedPid: public CopyMe<VehicleSpeedPid>
+{
+public:
+
+ VehicleSpeedPid()
+ :CopyMe(VehicleProperty::VehicleSpeed, "010D1\r", 0x0D)
+ {
+
+ }
+ bool isValid(const ByteArray &replyVector)
+ {
+ isValidVal = true;
+ if (replyVector[1] != id)
+ {
+ return isValidVal = false;
+ }
+
+ return isValidVal;
+ }
+ void parse(const ByteArray &replyVector)
+ {
+ if (!isValidVal)
+ {
+ //TODO: Determine if we should throw an exception here, rather than just returning without a value?
+ return;
+ }
+
+ int mph = replyVector[2];
+ value = boost::lexical_cast<std::string>(mph);
+ }
+};
+
+class EngineSpeedPid: public CopyMe<EngineSpeedPid>
+{
+public:
+
+ EngineSpeedPid()
+ :CopyMe(VehicleProperty::EngineSpeed,"010C1\r",0x0C)
+ {
+
+ }
+ bool isValid(const ByteArray &replyVector)
+ {
+ if (replyVector[1] != id)
+ {
+ isValidVal = false;
+ return false;
+ }
+ isValidVal = true;
+ return true;
+ }
+ void parse(const ByteArray &replyVector)
+ {
+ if (!isValidVal)
+ {
+ //TODO: Determine if we should throw an exception here, rather than just returning without a value?
+ return;
+ }
+ double rpm = ((replyVector[2] << 8) + replyVector[3]) / 4.0;
+ value = boost::lexical_cast<std::string>(rpm);
+ }
+};
+
+class EngineCoolantPid: public CopyMe<EngineCoolantPid>
+{
+public:
+
+ EngineCoolantPid()
+ :CopyMe(VehicleProperty::EngineCoolantTemperature,"01051\r",0x05)
+ {
+
+ }
+ bool isValid(const ByteArray &replyVector)
+ {
+ if (replyVector[1] != id)
+ {
+ isValidVal = false;
+ return false;
+ }
+ isValidVal = true;
+ return true;
+ }
+ void parse(const ByteArray &replyVector)
+ {
+ if (!isValidVal)
+ {
+ //TODO: Determine if we should throw an exception here, rather than just returning without a value?
+ return;
+ }
+ int temp = replyVector[2] - 40;
+ value = boost::lexical_cast<std::string>(temp);
+ }
+};
+
+class MassAirFlowPid: public CopyMe<MassAirFlowPid>
+{
+public:
+
+ MassAirFlowPid()
+ :CopyMe(VehicleProperty::MassAirFlow,"01101\r", 0x10)
+ {
+
+ }
+ bool isValid(const ByteArray &replyVector)
+ {
+ if (replyVector[1] != id)
+ {
+ isValidVal = false;
+ return false;
+ }
+ isValidVal = true;
+ return true;
+ }
+ void parse(const ByteArray &replyVector)
+ {
+ if (!isValidVal)
+ {
+ //TODO: Determine if we should throw an exception here, rather than just returning without a value?
+ return;
+ }
+
+ maf = ((replyVector[2] << 8) + replyVector[3]) / 100.0;
+ value = boost::lexical_cast<std::string>(maf);
+ }
+
+protected:
+ double maf;
+};
+
+
+class FuelConsumptionPid: public MassAirFlowPid
+{
+public:
+ FuelConsumptionPid()
+
+ {
+
+ }
+ bool isValid(const ByteArray &replyVector)
+ {
+ return isValidVal = MassAirFlowPid::isValid(replyVector);
+ }
+ void parse(const ByteArray & replyVector)
+ {
+ if (!isValidVal)
+ {
+ //TODO: Determine if we should throw an exception here, rather than just returning without a value?
+ return;
+ }
+
+ 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);
+ }
+
+private:
+
+ static double oldTime;
+};
+
+
+class VinPid: public CopyMe<VinPid>
+{
+public:
+
+ VinPid()
+ :CopyMe(VehicleProperty::VIN,"0902\r",0x02)
+ {
+ type = 0x49;
+ }
+ bool isValid(const ByteArray & replyVector)
+ {
+ isValidVal = true;
+
+ if (replyVector[0] != 0x49 || replyVector[1] != 0x02)
+ {
+ isValidVal = false;
+
+ }
+ return isValidVal;
+ }
+ void parse(const ByteArray & replyVector)
+ {
+ if (!isValidVal)
+ {
+ //TODO: Determine if we should throw an exception here, rather than just returning without a value?
+ return;
+ }
+ std::string vinstring;
+ for (int j=0;j<replyVector.size();j++)
+ {
+ if(replyVector[j] == 0x49 && replyVector[j+1] == 0x02)
+ {
+ //We're at a reply header
+ j+=3;
+ }
+ if (replyVector[j] != 0x00)
+ {
+ vinstring += (char)replyVector[j];
+ //printf("VIN: %i %c\n",replyVector[j],replyVector[j]);
+ }
+ }
+
+ value = vinstring;
+ }
+};
+
+class WmiPid: public VinPid
+{
+public:
+
+ WmiPid()
+ :VinPid()
+ {
+ property = VehicleProperty::WMI;
+ }
+ bool isValid(const ByteArray & replyVector)
+ {
+ return isValidVal = VinPid::isValid(replyVector);
+ }
+ void parse(const ByteArray &replyVector)
+ {
+ if (!isValidVal)
+ {
+ //TODO: Determine if we should throw an exception here, rather than just returning without a value?
+ return;
+ }
+ VinPid::parse(replyVector);
+ value = value.substr(0,3);
+ }
+};
+
+class AirIntakeTemperaturePid: public CopyMe<AirIntakeTemperaturePid>
+{
+public:
+ AirIntakeTemperaturePid()
+ :CopyMe(VehicleProperty::AirIntakeTemperature,"010F1\r",0x0F)
+ {
+
+ }
+ bool isValid(const ByteArray & replyVector)
+ {
+ if (replyVector[1] != id)
+ {
+ isValidVal = false;
+ return false;
+ }
+ isValidVal = true;
+ return true;
+ }
+ void parse(const ByteArray & replyVector)
+ {
+ if (!isValidVal)
+ {
+ //TODO: Determine if we should throw an exception here, rather than just returning without a value?
+ return;
+ }
+ int temp = replyVector[2] - 40;
+ value = boost::lexical_cast<std::string>(temp);
+ }
+};
+
+class EngineLoadPid: public CopyMe<EngineCoolantPid>
+{
+public:
+ EngineLoadPid()
+ :CopyMe(VehicleProperty::EngineLoad,"01041\r",0x04)
+ {
+
+ }
+ bool isValid(const ByteArray & replyVector)
+ {
+ if (replyVector[1] != id)
+ {
+ isValidVal = false;
+ return false;
+ }
+ isValidVal = true;
+ return true;
+ }
+ void parse(const ByteArray &replyVector)
+ {
+ if (!isValidVal)
+ {
+ //TODO: Determine if we should throw an exception here, rather than just returning without a value?
+ return;
+ }
+ int load = replyVector[2]*100.0/255.0;
+ value = boost::lexical_cast<std::string>(load);
+ }
+};
+
+class ThrottlePositionPid: public CopyMe<ThrottlePositionPid>
+{
+public:
+ ThrottlePositionPid()
+ :CopyMe(VehicleProperty::ThrottlePosition,"01111\r",0x11)
+ {
+
+ }
+ bool isValid(const ByteArray & replyVector)
+ {
+ if (replyVector[1] != id)
+ {
+ isValidVal = false;
+ return false;
+ }
+ isValidVal = true;
+ return true;
+ }
+ void parse(const ByteArray & replyVector)
+ {
+ if (!isValidVal)
+ {
+ //TODO: Determine if we should throw an exception here, rather than just returning without a value?
+ return;
+ }
+ int temp = replyVector[2]*100.0/255.0;
+ value = boost::lexical_cast<std::string>(temp);
+ }
+};
+
+class BatteryVoltagePid: public CopyMe<BatteryVoltagePid>
+{
+public:
+ BatteryVoltagePid()
+ :CopyMe(VehicleProperty::BatteryVoltage,"ATRV\r",0)
+ {
+
+ }
+
+ bool needsCompress() { return false; }
+
+ bool isValid(const ByteArray & replyVector)
+ {
+ if(replyVector[replyVector.size() - 1] == 'V')
+ {
+ return isValidVal = true;
+ }
+ return false;
+ }
+
+ void parse(const ByteArray & replyVector)
+ {
+ value = "";
+ for(int i=0; i<replyVector.size() - 1; i++)
+ {
+ value += replyVector[i];
+ }
+ }
+
+};
+
+#endif