3

I am trying to connect to the CAN-bus of my car. The connection is working and the data is printing to the terminal without any problems.

bus = can.interface.Bus("can0", bustype="socketcan")
notifier = can.Notifier(bus, [can.Printer()])

I am using Python Can 2.2 and python 3.7.

I want to add a new listener with some sort of switch-case statement on the can.dlc. Would the pseudocode below be the best way to do that?

import can

def parse_data(can):
    SingleCanFrame = can.Message
    print(SingleCanFrame)
    if SingleCanFrame.arbitration_id == 304:    #car voltage
        #convert data 
        #save to DB table 1
    elif SingleCanFrame.arbitration_id == 400:  #car speed
        #convert data 
        #save to DB table 2
    elif SingleCanFrame.arbitration_id == 401:  #car tachometer
        #convert data 
        #save to DB table 3
    else:
        #save to DB errorlog
    
bus = can.interface.Bus("can0", bustype="socketcan")    
notifier = can.Notifier(bus, [parse_data(can)]) 

Edit 1:

forgot the parameter: def parse_data(can)

Edit 2:

New code

import can

CAR = {"voltage": 304, "speed": 400, "tachometer": 401}

def cellvoltage(SingleCanFrame, MyDB):
    #convert data 
    #save to DB table 1
def packcurrent(SingleCanFrame, MyDB):
    #convert data 
    #save to DB table 2
def tachometer(SingleCanFrame, MyDB):
    #convert data 
    #save to DB table 3

def parse_data(can):
    SingleCanFrame = can.Message
    MyDB = SomeDB.Connect()
    print(SingleCanFrame)
    if SingleCanFrame.arbitration_id == CAR["voltage"]: #car voltage
        cellvoltage(SingleCanFrame, MyDB)
    elif SingleCanFrame.arbitration_id == CAR["speed"]: #car speed
        packcurrent(SingleCanFrame, MyDB)
    elif SingleCanFrame.arbitration_id == CAR["tachometer"]:    #car tachometer
        tachometer(SingleCanFrame, MyDB)
    else:
        #save to DB errorlog
    
bus = can.interface.Bus("can0", bustype="socketcan")    
notifier = can.Notifier(bus, [parse_data(can)]) 
Ismael Padilla
  • 5,246
  • 4
  • 23
  • 35
Mindfuucker
  • 31
  • 2
  • 6

1 Answers1

2

Essentially, that would be a fine way to do that.

However, if you would like to express your intent more clearly, a dictionary would be helpful:

CAR = {"voltage": 304, "speed": 400, "tachometer": 401} # capital var name as this a constant var

Then you could just refer to the values as if SingleCanFrame.dlc == CAR["voltage"]: which is less error-prone.

RealPawPaw
  • 988
  • 5
  • 9
  • A dictionary would indeed be a excellent way to do it. Would it make sense to further split the functionality into functions? – Mindfuucker Aug 13 '18 at 09:19
  • I'd need some more context to speak for that on the 'functionality' and 'functions'. Though the rule of thumb is that any code that is reusable or will be reused with minor changes should be put in a function - which the "convert data" and "save to DB table" could be candidates. – RealPawPaw Aug 13 '18 at 09:22