forked from SolidRun/SolidSense-MQTT
-
Notifications
You must be signed in to change notification settings - Fork 1
/
OBD_Client.py
172 lines (145 loc) · 5.19 KB
/
OBD_Client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#-------------------------------------------------------------------------------
# Name: OBD_Clent
# Purpose: Encpasulate rRPC interface to OBD Vehicle service
#
# Author: Laurent Carré
#
# Created: 15/03/2020
# Copyright: (c) Laurent Carré Sterwen Technologies 2020
# Licence: <your licence>
#-------------------------------------------------------------------------------
import os
import sys
import inspect
cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0], "../vehicle")))
sys.path.insert(0, cmd_subfolder)
import threading
import logging
import time
import grpc
import json
try:
from OBD_Service_pb2 import *
import OBD_Service_pb2_grpc
except ImportError :
print("No vehicle OBD service Software present")
class OBD_GRPC_Client() :
def __init__(self,addr,logger) :
self._logger=logger
self._logger.debug("creating grpc channel on:"+addr)
self._channel= grpc.insecure_channel(addr)
self._stub= OBD_Service_pb2_grpc.OBD_ServiceStub(self._channel)
self._streamer=None
def status(self,option="min"):
self._logger.info("Vehicle service send status request with option:"+option)
req=OBD_StatusRequest()
req.request=option
try:
resp=self._stub.Status(req)
except grpc.RpcError as err:
self._logger.error(str(err))
return None
out={}
out['connected']=resp.connected
out['engine_on']=resp.engine_on
out['autoconnect']=resp.autoconnect
out['MAC']=resp.MAC
if resp.connected :
out['protocol']=resp.protocol
out['state']=resp.state
if option != 'min' :
out['commands']=resp.commands
return out
def connect(self,mac):
self._logger.info("Vehicle service start request on MAC:"+mac)
req=Start_OBD()
req.MAC=mac
try:
resp=self._stub.Connect(req)
except grpc.RpcError as err:
self._logger.error(str(err))
return None
self._logger.debug("Connect response:"+resp.error)
out={}
out['connected']=resp.connected
out['engine_on']=resp.engine_on
out['error']=resp.error
out['timestamp']=resp.obd_time
return out
def startStreaming(self,callback,end_callback,commands=None,rules=None):
if self._streamer != None :
self._logger.info("OBD Streaming request on-going = New request rejected")
return False
rules_j=json.dumps(rules)
self._streamer=ContinuousOBDReader(self,callback,end_callback,self._logger,commands,rules_j)
self._streamer.start()
return True
def stopStreaming(self):
if self._streamer == None :
return
req=OBD_cmd()
resp=self._stub.Stop(req)
self._logger.debug("Stop vehicle streaming acknowledgement OBD connected:"+str(resp.connected))
def killStreamer(self):
if self._streamer == None :
return
self._logger.debug("Killing OBD streaming thread")
if not self._streamer.is_alive() :
self._logger.debug("OBD streamer already stopped")
self._streamer = None
return
class ContinuousOBDReader(threading.Thread):
'''
this class is used to read a continuous stream of gps event
and throwing a call for each of them
'''
def __init__(self,client,callback,end_calback,logger,commands=None,rules=None):
threading.Thread.__init__(self)
self._client=client
self._callback=callback
self._end_callback=end_calback
self._logger=logger
self._rules=rules
self._commands=commands
def run(self):
req=OBD_cmd()
if self._rules != None :
req.rules=self._rules
if self._commands != None :
req.commands=self._commands
req.request=1
else:
req.request=0
err=None
try:
for resp in self._client._stub.Read(req) :
self._logger.debug("OBD message received with:"+resp.error)
out={}
out['connected']=resp.connected
out['engine_on']=resp.engine_on
out['error']=resp.error
out['timestamp']=resp.obd_time
if resp.engine_on:
obd_cmds={}
for c in resp.values:
cmd={}
cmd['type']=c.type
if c.type == 0 :
cmd['value'] = c.f
cmd['unit'] = c.unit
else:
cmd['value']=c.s
obd_cmds[c.cmd]= cmd
out['commands']=obd_cmds
self._callback(out)
except Exception as err:
self._logger.error(str(err))
pass
self._client._streamer=None
self._logger.info("End Vehicle OBD streaming")
self._end_callback(err)
self._logger.info("End Vehicle OBD streaming callback successful")
def main():
pass
if __name__ == '__main__':
main()