Light Lightness Setup Server
Light Lightness Server
Generic Power OnOff Setup Server
Generic Power OnOff Server
Generic Level Server
Generic OnOff Server
Generic Default Transition Time Server
Light Lightness Setup Server
Light Lightness Server
Generic Power OnOff Setup Server
Generic Level Server
Generic Default Transition Time Server
Generic OnOff Server
Generic Power OnOff Server
models have separate states and opcodes
order does not matter
this isn't inheritance
Generic OnOff Server
Generic OnOff = F(Light Lightness Linear)
Generic Level = G(Light Lightness Linear)
Light Lightness Actual = H(Light Lightness Linear)
Light Lightness Linear = F'(Generic OnOff)
Light Lightness Linear = G'(Generic Level)
Light Lightness Linear = H'(Light Lightness Actual)
Light Lightness Server
Generic Level Server
Generic OnOff Server
Light Lightness Server
Generic Power OnOff Server
Generic Level Server
Generic OnOff Server
Generic Default Transition Time Server
implementation detail:
keep lists in the element, identified by root model id
Light Lightness Server
Generic Power OnOff Server
Generic Level Server
Generic OnOff Server
Generic Default Transition Time Server
Light CTL Server
Light CTL Temperature Server
Generic Level Server
Main
Temperature
https://www.bluetooth.org/errata/errata_view.cfm?errata_id=16366
https://www.bluetooth.org/errata/errata_view.cfm?errata_id=11345
Config Server
Health Server
Generic DTT Server
Scene Server
Scene Setup Server
Generic OnOff Server
Generic Power OnOff Server
Generic Power OnOff Setup Server
Generic Level Server
Light Lightness Server
Light Lightness Setup Server
Light CTL Server
Light CTL Setup Server
Sensor Server
Sensor Setup Server
Generic OnOff Client
Generic Level Client
Light LC Server
Light LC Setup Server
Generic OnOff Server
Sensor Server
Sensor Setup Server
Generic OnOff Client
Generic Level Client
Generic OnOff Server
Sensor Server
Sensor Setup Server
Light CTL Temperature Server
Generic DTT Server
Scene Server
Scene Setup Server
Generic Level Server
Generic OnOff Server
Scene Client
Temperature.Generic Level = F(Temperature.Light CTL Temperature)
Temperature.Light CTL Temperature = G(Main.Light CTL)
Temperature.Light CTL Temperature = F'(Temperature.Generic Level)
Main.Light CTL = G'(Temperature.Light CTL Temperature)
Light CTL Server
Light CTL Temperature Server
Generic Level Server
Light CTL Server
Main
Temperature
Config Server
Health Server
Generic DTT Server
Scene Server
Scene Setup Server
Generic OnOff Server
Generic Power OnOff Server
Generic Power OnOff Setup Server
Generic Level Server
Light Lightness Server
Light Lightness Setup Server
Light CTL Server
Light CTL Setup Server
Sensor Server
Sensor Setup Server
Generic OnOff Client
Generic Level Client
Light LC Server
Light LC Setup Server
Generic OnOff Server
Sensor Server
Sensor Setup Server
Generic OnOff Client
Generic Level Client
Generic OnOff Server
Sensor Server
Sensor Setup Server
Light CTL Temperature Server
Generic DTT Server
Scene Server
Scene Setup Server
Generic Level Server
Generic OnOff Server
Scene Client
Node |
---|
uuid: UUID name: String features: Features elements: List<Element> |
Element |
---|
index: Integer models: Map<ModelId, Model> |
Model |
---|
ID: ModelId publication: Publication app_keys: Set<Integer> |
1
*
1
*
GenericOnOffServer |
---|
generic_on_off: Boolean |
GenericLevelServer |
---|
generic_level: Integer |
LightLightnessServer |
---|
light_lightness: Integer |
Node |
---|
uuid: UUID name: String features: Features elements: List<Element> |
Element |
---|
index: Integer subscription_lists: Map<ModelId, Set<int>> models: Map<ModelId, Model> |
Model |
---|
ID: ModelId publication: Publication app_keys: Set<Integer> subscriptions: Set<int> |
1
*
1
*
GenericOnOffServer |
---|
generic_on_off: Boolean |
GenericLevelServer |
---|
generic_level: Integer |
LightLightnessServer |
---|
light_lightness: Integer |
Node |
---|
uuid: UUID name: String features: Features elements: List<Element> |
Element |
---|
index: Integer subscription_lists: Map<ModelId, Set<int>> models: Map<ModelId, Model> |
Model |
---|
ID: ModelId publication: Publication app_keys: Set<Integer> subscriptions: Set<int> ELEMENT: ModelElement EXTEND: Map<ModelElement, Set<ModelId>> |
corresponding(ModelId, ModelElement): Model |
1
*
1
*
ModelElement |
---|
MAIN TEMPERATURE HUE SATURATION LIGHT_LC OLC ... |
class LightLCServer(Model):
ID = ModelId(None, 0x130F)
ELEMENT = ModelElement.LIGHT_LC
EXTEND = {
ModelElement.LIGHT_LC: (GenericOnOffServer,),
}
class LightLightnessServer(Model):
ID = ModelId(None, 0x1300)
ELEMENT = ModelElement.MAIN
EXTEND = {
ModelElement.MAIN: (GenericPowerOnOffServer, GenericLevelServer),
ModelElement.LIGHT_LC: (LightLCServer,),
}
light_lightness is light_lc.corresponding(LightLightnessServer, ModelElement.MAIN)
light_lc is light_lightness.corresponding(LightLCServer, ModelElement.LIGHT_LC)
You Ain't Gonna Need It ?
def diff(lhs_model, rhs_model):
assert type(lhs_model) == type(rhs_model)
# only if we own the subscription list
if lhs_model.root:
for missing_subscription in (
lhs_model.subscriptions - rhs_model.subscriptions
):
yield (StateAction.ADD, "subscriptions", missing_subscription)
for extra_subscription in rhs_model.subscriptions - lhs_model.subscriptions:
yield (StateAction.DEL, "subscriptions", missing_subscription)
if lhs_model.publication != rhs_model.publication:
yield (StateAction.SET, "publication", lhs_model.publication)
for missing_bind in lhs_model.app_keys - rhs_model.app_keys:
yield (StateAction.ADD, "app_keys", missing_bind)
for extra_bind in rhs_model.app_keys - lhs_model.app_keys:
yield (StateAction.DEL, "app_keys", extra_bind)
for attribute in lhs_model.__attrs__:
lhs_value = getattr(lhs_model, attribute.name)
rhs_value = getattr(rhs_model, attribute.name)
if lhs_value != rhs_value:
yield (StateAction.SET, attribute.name, lhs_value)
def diff(lhs_element, rhs_element):
for lhs_model, rhs_model in zip(
sorted(lhs_element.models.values()), sorted(rhs_element.models.values())
):
for (action, state, value) in lhs_model - rhs_model:
yield Diff(lhs_element.index, type(lhs_model),
state, action, value)
def diff(lhs_node, rhs_node):
for lhs_element, rhs_element in zip(lhs_node.elements, rhs_node.elements):
yield from lhs_element.diff(rhs_element)
Diff(element=0, model=GenericLevelClient, state='app_keys',
action=ADD', value=1)
Diff(element=0, model=GenericLevelClient, state='publication',
action=SET, value=Publication(publish_address=49154, app_key_index=1, ...))
Diff(element=0, model=LightLightnessServer, state='app_keys',
action=ADD, value=1)
Diff(element=0, model=LightLightnessSetupServer, state='subscriptions',
action=ADD, value=49152)
Diff(element=0, model=LightLightnessSetupServer, state='subscriptions',
action=ADD, value=49154)
Diff(element=1, model=GenericLevelClient, state='app_keys',
action=ADD, value=1)
Diff(element=1, model=GenericLevelClient, state='publication',
action='SET', value=Publication(publish_address=49156, app_key_index=1, ...)
Diff(element=1, model=LightCTLTemperatureServer, state='app_keys',
action=ADD, value=1)
Diff(element=1, model=LightCTLTemperatureServer, state='subscriptions',
action=ADD, value=49156)