For the BACnet B-SS (Smart Sensor) Python example - see README.md.
This is the PICS for the example as shipped. It describes a tutorial device announcing itself as a Chipkin demo, not a product. When you turn this example into your own device, this document is one of the things you rewrite: the vendor, model and version rows all come from the
CHANGE ALL OF THIS BEFORE YOU SHIPblock at the top ofmain.py. The example has not been submitted for BTL certification.
| Vendor Name | Chipkin Automation Systems |
| Vendor Identifier | 389 |
| Product Name | CAS BACnet Stack Example - B-SS (Python) |
| Product Model Number | CAS BACnet Stack Example - B-SS |
| Application Software Version | 1.1.0 |
| Firmware Revision | 6.0.23.0 (the CAS BACnet Stack version) |
| BACnet Protocol Version | 1 |
| BACnet Protocol Revision | 30 |
Product Description: a minimal read-only BACnet/IP sensing device built on the CAS BACnet Stack. It presents three sensor objects (Analog Input, Binary Input, Multi-State Input) whose readings follow a sensor Simulation, answers ReadProperty for every required property of every object, reports a broken sensor through Analog Input 1's Reliability and the FAULT bit of Status_Flags, and is discoverable by Who-Is / I-Am and Who-Has / I-Have. It is a tutorial for implementers of the B-SS profile.
B-SS - BACnet Smart Sensor.
This device claims exactly one profile. Because the B-SS requirements are a superset of B-GENERAL's, a conformant B-SS device also satisfies B-GENERAL (Annex L.8); that is subsumption, not a second claim.
| BIBB | Description |
|---|---|
| DS-RP-B | Data Sharing - ReadProperty - B |
| DM-DDB-B | Device Management - Dynamic Device Binding - B |
| DM-DOB-B | Device Management - Dynamic Object Binding - B |
No other BIBBs are supported. In particular this device does not support DS-WP-B (WriteProperty), DS-RPM-B (ReadPropertyMultiple), DS-COV-B, any alarm and event (AE-) BIBB, scheduling (SCHED-), trending (T-*), or DM-DCC-B (DeviceCommunicationControl).
| Service | Initiate | Execute |
|---|---|---|
| ReadProperty | no | yes |
| Who-Is | no | yes |
| I-Am | yes | - |
| Who-Has | no | yes |
| I-Have | yes | - |
An unsolicited I-Am is broadcast to the local subnet at start-up, as well as in response to Who-Is.
Any other confirmed service - including WriteProperty - is rejected. That
rejection is part of the profile boundary, not a limitation to work around:
there is no BACnetStack_RegisterCallbackSetProperty* registration anywhere in
this example, so the stack has nothing to consult for a write and refuses it on
its own.
Segmentation is supported in both directions
(Segmentation_Supported = segmented-both), by the stack: at 6.x @
64b2cfac5 the customer build compiles STACK_OPTION_SEGMENTATION in (stack
#2992), and this example keeps the stack's defaults - Max_Segments_Accepted
16 and APDU_Segment_Timeout 5000 ms. Table 12-13 footnote 1: "These
properties are required if, and shall be present only if, segmentation of any
kind is supported" - they are not rows in section 11 because its generator
lists only unconditionally required properties. Max_APDU_Length_Accepted is
1476 octets, the BACnet/IP maximum.
No object is dynamically creatable or deletable, and no property of any object is writable.
| Object type | Instance | Object_Name | Optional properties supported |
|---|---|---|---|
| Device | 389001 | Chipkin Example B-SS | Description |
| Analog Input | 1 | Bronze | Reliability |
| Binary Input | 1 | Emerald | - |
| Multi-State Input | 1 | Hot Pink | State_Text |
| Network Port | 1 | Vermilion | - |
The device instance is configurable at run time with --deviceID (BACnet
requires the device instance to be configurable).
BACnet/IP (Annex J), UDP port 47808 (0xBAC0) by default, configurable at run
time with --port.
BBMD is not supported, Foreign Device registration is not supported, and BACnet/SC, MS/TP, Ethernet (Annex H) and PTP are not supported.
The stack's Network Port object still lists its BACnet/IP properties in
Property_List - including IP_DNS_Server, FD_BBMD_Address and
FD_Subscription_Lifetime - and every one of them reads as a value
(FD_BBMD_Address is a Null host, port 0: no BBMD configured). The Wire Tests
read every listed property of every object.
Static device binding is not supported. The device answers Who-Is/Who-Has and does not initiate any confirmed request, so it never needs to bind a peer.
None. The device is not a router, not a BBMD, and does not register as a foreign device.
UTF-8 (ANSI X3.4). Supporting a character set does not imply the device can handle data in all character sets.
Every object this example creates, and every REQUIRED property of each (per ANSI/ASHRAE 135-2024 clause 12 and the stack's docs/property-profile-reference.md), plus the optional properties the example turns on. Served by says who answers a ReadProperty: the stack generates it, or the app serves it from a get_property_* callback in main.py. A ⚠ row is a required property the app does not serve and the stack would fill with a default - that is a defect, not a feature.
Device 389001 "Chipkin Example B-SS" - the device itself; the instance is configurable with --deviceID. The stack rows are device-wide facts only the stack knows - the protocol version and revision it implements, the services and object types it was configured with, the live object list and address-binding table. The accepted rows are the stack's configured defaults for APDU limits, segmentation, system status and database revision; an application that answered them from its own constants could contradict the stack, so this example does not
| Property | Datatype | Served by | Writable |
|---|---|---|---|
| Object_Identifier | BACnetObjectIdentifier | stack | no |
| Object_Name | CharacterString | app | no |
| Object_Type | BACnetObjectType | stack | no |
| System_Status | BACnetDeviceStatus | stack default, accepted (Generic Enumerated default: 0) |
no |
| Vendor_Name | CharacterString | app | no |
| Vendor_Identifier | Unsigned16 | app | no |
| Model_Name | CharacterString | app | no |
| Firmware_Revision | CharacterString | app | no |
| Application_Software_Version | CharacterString | app | no |
| Description (optional, enabled) | CharacterString | app | no |
| Protocol_Version | Unsigned | stack | no |
| Protocol_Revision | Unsigned | stack | no |
| Protocol_Services_Supported | BACnetServicesSupported | stack | no |
| Protocol_Object_Types_Supported | BACnetObjectTypesSupported | stack | no |
| Object_List | BACnetARRAY[N] of BACnetObjectIdentifier | stack | no |
| Max_APDU_Length_Accepted | Unsigned | stack default, accepted (CAS_BACNET_DEVICE_DEFAULT_MAX_APDU_LENGTH_ACCEPTED) |
no |
| Segmentation_Supported | BACnetSegmentation | stack default, accepted (BACnetSegmentation::segmentedBoth with `STACK_OPTION_SEGME) |
no |
| APDU_Timeout | Unsigned | stack default, accepted (CAS_BACNET_DEVICE_DEFAULT_APDU_TIMEOUT) |
no |
| Number_Of_APDU_Retries | Unsigned | stack default, accepted (CAS_BACNET_DEVICE_DEFAULT_NUMBER_OF_APDU_RETRIES) |
no |
| Device_Address_Binding | BACnetLIST of BACnetAddressBinding | stack | no |
| Database_Revision | Unsigned | stack default, accepted (Generic UnsignedInteger default: 0) |
no |
| Property_List | BACnetARRAY[N] of BACnetPropertyIdentifier | stack | no |
Analog Input 1 "Bronze" - REAL, degrees Celsius; the sensor Simulation ramps it 18.0 .. 26.0 at 0.5 C a second. Reliability reads no-fault-detected, or open-loop while the simulated sensor wire is broken; the stack derives Status_Flags FAULT from it
| Property | Datatype | Served by | Writable |
|---|---|---|---|
| Object_Identifier | BACnetObjectIdentifier | stack | no |
| Object_Name | CharacterString | app | no |
| Object_Type | BACnetObjectType | stack | no |
| Present_Value | Real | app | no |
| Status_Flags | BACnetStatusFlags | stack | no |
| Event_State | BACnetEventState | stack default, accepted (Generic Enumerated default: 0) |
no |
| Reliability (optional, enabled) | BACnetReliability | app | no |
| Out_Of_Service | Boolean | app | no |
| Units | BACnetEngineeringUnits | app | no |
| Property_List | BACnetARRAY[N] of BACnetPropertyIdentifier | stack | no |
| Property | Datatype | Served by | Writable |
|---|---|---|---|
| Object_Identifier | BACnetObjectIdentifier | stack | no |
| Object_Name | CharacterString | app | no |
| Object_Type | BACnetObjectType | stack | no |
| Present_Value | BACnetBinaryPV | app | no |
| Status_Flags | BACnetStatusFlags | stack | no |
| Event_State | BACnetEventState | stack default, accepted (Generic Enumerated default: 0) |
no |
| Out_Of_Service | Boolean | app | no |
| Polarity | BACnetPolarity | app | no |
| Property_List | BACnetARRAY[N] of BACnetPropertyIdentifier | stack | no |
Multi-state Input 1 "Hot Pink" - 3 states: On, Off, Auto; the sensor Simulation steps 1 -> 2 -> 3 -> 1 every 4 s
| Property | Datatype | Served by | Writable |
|---|---|---|---|
| Object_Identifier | BACnetObjectIdentifier | stack | no |
| Object_Name | CharacterString | app | no |
| Object_Type | BACnetObjectType | stack | no |
| Present_Value | Unsigned | app | no |
| Status_Flags | BACnetStatusFlags | stack | no |
| Event_State | BACnetEventState | stack default, accepted (Generic Enumerated default: 0) |
no |
| Out_Of_Service | Boolean | app | no |
| Number_Of_States | Unsigned | app | no |
| State_Text (optional, enabled) | BACnetARRAY[N] of CharacterString | app | no |
| Property_List | BACnetARRAY[N] of BACnetPropertyIdentifier | stack | no |
Network Port 1 "Vermilion" - BACnet/IP; Network_Type and Protocol_Level are set from BACnetStack_AddNetworkPortObject()'s arguments (IPv4, BACnet Application) at start-up, not a GetProperty callback like the object's other app-served rows; Changes_Pending is likewise computed and answered natively by the stack's Network Port object. Reliability has no fault condition this example detects, so it is accepted at the generic default (normal)
| Property | Datatype | Served by | Writable |
|---|---|---|---|
| Object_Identifier | BACnetObjectIdentifier | stack | no |
| Object_Name | CharacterString | app | no |
| Object_Type | BACnetObjectType | stack | no |
| Status_Flags | BACnetStatusFlags | stack | no |
| Reliability | BACnetReliability | stack default, accepted (Generic Enumerated default: 0) |
no |
| Out_Of_Service | Boolean | app | no |
| Network_Type | BACnetNetworkType | app | no |
| Protocol_Level | BACnetProtocolLevel | app | no |
| Changes_Pending | Boolean | app | no |
| Property_List | BACnetARRAY[N] of BACnetPropertyIdentifier | stack | no |
- ANSI/ASHRAE Standard 135-2024, Annex A (PICS template), Annex K (BIBBs), Annex L (device profiles), Clause 12 (object types).
- README.md - what this example is and how to build it.
- TUTORIAL.md - how to extend it, and how to keep this document honest when you do.