Definition
Thing Model (Thing Model) is a digital description of IoT devices, defining device Property (properties), Event (events), Service (services), and other capabilities. Data from different protocols is mapped to a unified thing model through Protocol Adaptation, so upper-layer applications do not need to worry about underlying protocol differences.
Core Components
- Property: Status attributes of the device that can be read and written, such as temperature, humidity
- Event: Discrete events reported by the device, such as alarms, fault codes
- Service: Services that the device can invoke, such as rebooting, parameter setting
Relationship with data flow
Property corresponds to the reporting of Telemetry data and the read/write of Device Shadow; Event corresponds to event messages, which can trigger the Rule Engine; Service corresponds to the invocation of Downstream Command. The device model is a contract between the device and the platform/application. Different protocols (MQTT, LwM2M, Modbus, etc.) are mapped to a unified device model through Protocol Adaptation, so that upper-layer applications do not need to care about protocol differences.
Device Model Management
Device models are usually defined at the product level and support version management, inheritance, and extension. The platform provides a device model editor or JSON/DSL import, allowing the definition of attribute data types, value ranges, units, event parameters, service input and output parameters, etc. Changes in the device model need to consider compatibility to avoid affecting parsing of already deployed devices and applications.
Property, event, and service contracts are not interchangeable
A thing model is the contract between devices of one product and the platform, and it splits the exchange into three kinds. A property is a state or a measurement that can be read. It may be reported on a period, or a desired value may be written to it. An event is a notice that should be recorded once it happens, with a time and parameters. It is a poor fit for a continuous curve. A service is the platform asking the device to do something. It must have inputs, outputs, and a receipt of whether it finished. Define restart as a writable property and the platform only sees the value changed to true. It does not know whether the device accepted it or finished running it.
Names must be stable within the product. Units and allowed ranges are written in the model, not in each application's parsing code. One physical quantity keeps one property identifier. Registers, object nodes, and resource paths on the protocol side point at that identifier through a mapping. The mapping may change. The identifier does not. Upper-layer APIs and storage both cite the identifier. When the field protocol is replaced, history and rules do not have to follow the address. Enumerate values with their meanings. A value that is not listed should be treated as unknown and the original value kept. Do not drop it on ingest, or a state added by new firmware becomes empty.
After a version upgrade, old devices must still be able to parse
A model can ship a new version, but devices already in the field are still on the old one. Adding an optional property or a new event is generally compatible: old devices do not report those items, and the platform treats them as absent. Deleting a property, changing its type, changing its unit, or changing the meaning of an enumeration is not compatible. An incompatible change should use a new identifier or an explicit new version, and rules and reports should declare which version they depend on. Do not change "an integer in degrees Celsius" into "a decimal in millidegrees" on the same identifier. Old points and new points then join into a curve that cannot be read.
The publish order is: the platform learns the new model first, then devices upgrade and report against it. If the device upgrades first and the platform still rejects unknown fields under the old model, data after the upgrade is dropped at the access layer. The same applies to service inputs. If a new version adds a required parameter, every old caller fails. During the transition, a new parameter should have a default. Do not copy one product's model into private versions, one per project, that can never be merged. Express project differences with a small number of extension properties, and mark in the documentation which are common and which are extensions. Time-series storage lands points by property identifier. See the tag design of the time-series database. An unstable model identifier becomes a new series directly.
Building a separate service for every register
When the field point table is long, it is tempting to make every register a service, or every register an event. Once the number of services grows, callers cannot tell which items are actions a person may trigger and which are only internal readings. A reading is a property, handled by the collection period or by a shadow read. Only an action that needs the device to execute and return a receipt is a service. An alarm occurring is an event. Whether the alarm is currently present can also be a separate property. The two do not replace each other.
Another mistake is to put all data into one unstructured string property and reduce the model to a pass-through channel. The platform then cannot check types, convert units, or apply permission per item. Diagnostic information that is not modeled yet can temporarily use a structured extension field, but a quantity that enters regular monitoring should be promoted to a formal property. If copying a model also copies experimental fields into a new product, production shows items that no device will ever report, and reports count the absence as zero. Before publishing, remove items no device will implement, and mark whether each service may be called in bulk. A service that allows bulk calls must tolerate a repeated request, because a bulk retry is more common than a single-device retry.
At model review, ask of each item: is this a quantity that can be read continuously, a notice of one occurrence, or an action that needs a receipt? If the classification is uncertain, do not publish it yet. The release note should give the difference from the previous version: added, retired, and whether a meaning changed. On the platform, mark a retired item as read-only history. Access checks for new devices no longer require it to be present. The test fixture should generate, from the model, one legal sample and one sample that deliberately omits a field. The access check must reject the sample that lacks a required item. Without that test, an incompatible change is discovered only after production devices have upgraded.