A thought experiment to map a coffee machine to Apple HomeKits format.
{
"name": "Machine A",
"serialNumber": "A343-GXOERK",
"model": "frank-17273-rev23",
"modelFriendly": "Coffeemaker A232",
"customerID": 1337,
"characteristics": [
{
"iid": 1,
"type": "hardware",
"permission": ["read"],
"format": "stringarray",
"value": ["ethernet-100", "usb-a", "grinder-v1", "milk-heater-v2"]
},
{
"iid": 2,
"type": "has-umts",
"permission": ["read"],
"format": "bool",
"value": true
},
{
"iid": 3,
"type": "milk-target-temperature",
"permission": ["read", "write"],
"format": "int",
"value": 70,
"minValue": 30,
"maxValue": 90,
"unit": "celsius"
},
{
"iid": 4,
"type": "milk-current-temperature",
"permission": ["read"],
"format": "int",
"value": 60,
"minValue": 30,
"maxValue": 90,
"unit": "celsius"
}
]
}
The type
field have to be defined in a specification.
For example the spec would say: A machine which exposes the hardware "milk-heater-v2", has to provide the characteristics "milk-target-temperature" and "milk-current-temperature".
The iid
field is just incrementing and must be used over the array index.
This advantage of this format is that the UI can decide how to render the data. It can render the data based on the spec, or fallback to generic input.
// rendering a specific UI element
<div v-if="machine.hasHardware('milk-heater-v2')">
<input type="number" :value="machine.char('milk-current-temperature').value" v-on:change="machine.updateChar('milk-target-temperature', $event.target.value)" />
</div>
// rendering generic
<div v-for="(c) in machine.characteristics">
<input type="machine.char(c).format" :value="machine.char(c).format" readonly="machine.char(c).permission" />
</div>
The specification has to be enforced with tooling, to prevent human errors. For example a characteristics with format "int" can never hold value of type string.
The tooling should warn the developers when a type
is used which is not explained in the spec.