There is a reasonably mature python library called canopen that looked like it might be a good base. Unfortunately I've run into a bit of a problem with the implementation of CANopen SDO in openinverter. It seems that the upload/download semantics have been inverted from the standard implementation. For example, a simple fetch of the "boost" parameter would look something like:
Code: Select all
network = canopen.Network()
network.connect(bustype='socketcan', channel='can0', bitrate=500000)
network.check()
# Add a node with corresponding Object Dictionaries
dict = canopen.ObjectDictionary()
dict.add_object(canopen.objectdictionary.Variable('boost', 0x2000, 0x0))
node = canopen.BaseNode402(1, dict)
network.add_node(node)
# "Upload" a value from the remote node
print("remotevalue:", node.sdo.upload(0x2000, 0))
Code: Select all
40 00 20 00 00 00 00 00
Code: Select all
22 00 20 00 00 00 00 00
Code: Select all
node.sdo.download(0x2000, 1, b'\x80\x0C\x00\x00')
Code: Select all
23 00 20 01 80 0c 00 00
Code: Select all
40 00 20 01 80 0C 00 00
I've cross checked the python canopen library with Wireshark's CANopen dissector and the open source canopen-stack firmware stack and I believe it is doing the right thing. It should be possible to use the "CiA 301 - CANopen application layer and communication profile" spec but it's a pretty impenetrable industry spec and I found it difficult to follow.

Not sure what to do here. Main options seem to be:
- Leave openinverter as-is, fork and heavily modify the python canopen library (it does a lot of useful stuff) and create a new Wireshark dissector
- Fix openinverter to implement the standard so as to use existing tools but break all existing users (are there any?)
I'm leaning towards the first but it is a ton of non-standard work. CANopen is an over-complicated hot mess and I'm not sure it makes sense to use it as a guide for the other command-and-control requests needed to replace the serial commands. Thoughts?