OOP For Thing
It is intuitive to think or abstract a physical device as a class (as-)in object-oriented programming. A good amount of code base exists in open source within scientific community that uses OOP to model physical devices, such as:
Interactions with a device can be segregated into properties, actions and events and operations on these interactions (for example, readproperty, invokeaction, subscribeevent). See W3C WoT for an elaborate theory - Homepage. Such interactions can be described in a JSON format in a WoT Thing Description.
Within python's class API, properties can be easily implemented with the @property decorator/property object and actions can be implemented as methods. Say a DC power supply has a voltage property that reads and writes voltage value and an action to turn the power supply ON or OFF:
Events may be supported by reactive programming libraries or pub-sub messaging.
This simplistic approach will be used as a starting point to create the object API as it is easy to understand and has a low barrier to entry. But it needs to be extended to be more robust and flexible.
Descriptors for Interaction Affordances
properties, actions and events are collectively called interaction affordances in WoT terminology.
A superset of the above code with signifcantly added functionality can be implmented using the descriptor protocol in python. Descriptor protocols are the machinery behind:
@propertydecorators, validated object attributes (param,traitlets,attrsetc.)- python bound methods,
@classmethod,@staticmethod - ORMs for database packages like
SQLAlchemy,Django ORMwhere SQL statements are auto generated
Accessing an interaction affordace should give the following behaviour:
| Affordance | Class Level Access | Instance Level Access | Descriptor Object Purpose |
|---|---|---|---|
| Properties | Property object |
Property value |
holds Property metadata and performs get, set & delete |
| Actions | unbound Action object |
bound Action |
holds Action metadata and implements __call__ with payload validation |
| Events | Event object |
event publisher | holds Event metadata and handles generation of EventPublisher |
The same DC power supply example can be rewritten using descriptors as follows:
This behaviour of descriptors allows using the same interaction affordance object in different contexts, for example with a Property such as:
- Accessing a property at the class level to get metadata like default value, schema, observability etc.
- Access at the instance level to get the current value.
Thingclass can autogenerate Thing models using the affordance objects, whereas protocols can add forms to autogenerate Thing Descriptions.ThingModels can generate Thing objects by mapping it to descriptors easily for an API first approach.