JoelBender / bacpypes

BACpypes provides a BACnet application layer and network layer written in Python for daemons, scripting, and graphical interfaces.
MIT License
294 stars 130 forks source link

Serial Communication to Bacnet #203

Open Hoarfrost opened 6 years ago

Hoarfrost commented 6 years ago

I'm trying to create a program that translates communication over a non-BACnet serial communication bus (similar to Modbus/485) to a simulated BACnet device or simulated BACnet virtual lan.

The sample program "IP2VLANRouter.py" seems to be a pretty good start towards this goal.

My question is concerning getting serial IO requests to and from Bacppypes. It looks like the IOController and IOCB classes might be a good fit for this use. It seems the the IOController needs to be integrated into ReadProperty and WriteProperty of Object.Properties in order for this to work.

Is this the correct approach?

Are there any built in mechanisms to attach IOControllers to properties of Objects such an AnalogueInputObject?

Are there any examples that are applicable?

Thank you.

JoelBender commented 6 years ago

I have some very old code that implemented a mostly hideous hardware handshake (RTS/CTS) half-duplex master/slave protocol using the pySerial library. Because it didn't have a select() socket-like API all the send/receive calls were done in a separate thread. I was using something that is probably called the "legacy API" since this was back in the late Python2.4 and early Python2.5 days!

In one world you are basically correct. Assuming your serial protocol is master/slave and you are providing the slave implementation, then at the time it knows it has a complete PDU it creates a read/write property request, stuffs it in an IOCB and sends it to the ApplicationIOController instance.

However, it might be easier for you to "directly" reference the object and property values. Again on the slave side, if you get a read oat\n message then maybe your code would be as simple as return str(some_map['oat'].presentValue) + '\n' assuming that some_map['oat'] = AnalogValueObject(...) is someplace in the initialization of your application. Note that getattr(obj, 'presentValue') is very similar to obj.ReadProperty('presentValue') but different, and setattr(obj, 'presentValue', 75.3) is not the same as obj.WriteProperty('presentValue', 75.3).

So it's not quite the same as attaching an IOController to an object or a property of an object. I'm guessing that you want to keep the BACnet/IP stack happily running while this is going on, and that mapping the serial traffic to BACnet services is not a key feature of your design so much as making sure the serial side and BACnet/IP side have a unified view of object values, correct?

(It's kinda sad that BACpypes doesn't have asyncio support support yet.)