Please see Design Pattern: What is a Design Pattern and How Do I Use Them for information on what a DP is and how to use them.
Problem Statement
Often one faces one or more of the following situations:
- the need to perform additional logic before sending a command to a device
- the need to send a command to multiple devices based on a single event
- the need to do something different based on the state of one or more other Items
- the channel to update the state of an Item and the channel to send commands to the device cannot be combined into one Item definition without problems (e.g. an infinite loop)
In all of the above situations, a Proxy Item can be used.
Concept
A Proxy Item is simply an Item that stands in for one or more Items. Proxy Items are a special type of Design Pattern: Unbound Item (aka Virtual Item).
The Proxy Item is what gets placed on your sitemap and it is the Proxy Item which gets referenced by other Rules that may depend on the device’s state for any reason. Any command to control the device goes through the Proxy Item.
In addition to the Proxy Item, there is at least one Item bound to a binding or linked to a Channel.
One or more Rules are written which trigger on commands and/or updates to the Proxy Item. These Rules perform any additional logic and forwards the commands on to the bound or lined Items. Similarly, there may be one or more Rules which trigger on commands and/or updates to the bound or linked Items which interpret incoming States and sets the state of the Proxy Item accordingly.
Simple Example
There is a device which has two separate communications paths, one for sending commands to and one for sending updates and, for some technical reason the two cannot be combined on the same Item. Perhaps the incoming channel always causes the Item to receive a command instead of just an update or there is additional logic that needs to be performed before just blindly accepting the incoming state update.
Items
Switch ProxySwitch "nice label" <icon> // NO Binding, add label and icon because this gets put on your sitemap
Switch BoundSwitch { blah blah blah } // send commands to device
Switch BoundSwithUpdates { blah blah blah } // receive state updates from device
Rules
Python
from core.rules import rule
from core.triggers import when
from core.utils import sendCommandCheckFirst, postUpdateCheckFirst
@rule("ProxySwitch received command")
@when("Item ProxySwitch received command")
def proxy(event):
sendCommandCheckFirst("BoundSwitch", str(event.itemCommand))
@rule("BoundSwitchUpdates received update")
@when("Item BoundSwitchUpdates received update")
def bound(event):
postUpdateCheckFirst("ProxySwitch", str(event.itemState))
Rules DSL
rule "ProxySwitch received command"
when
Item ProxySwitch received command
then
if(BoundSwitch.state != receivedCommand) BoundSwitch.sendCommand(receivedCommand)
end
rule "BoundSwitchUpdates received update"
when
Item BoundSwitchUpdates received update
then
if(ProxySwitch.state != BoundSwitchUpdate.state) ProxySwitch.postUpdate(BoundSwitchUpdate.state)
end
Advantages and Limitations
This design pattern gives one a lot of control over how and when commands to and from a device occur. It also allows for the combining of multiple separate Items into one logical Item. But it enables these capabilities by adding complexity to the configuration.
Related Design Patterns
Design Pattern | How It’s Used |
---|---|
Design Pattern: Unbound Item (aka Virtual Item) | A Proxy Item is a special case for Virtual Items |
Design Pattern: Manual Trigger Detection | Uses a Proxy Items in Approach 3 |
Design Pattern: Gate Keeper | Uses a Proxy Item to centralize the commands to the constrained device |
Design Pattern: Separation of Behaviors | Uses a Proxy Item to kick off the cross cutting Rule |
Design Pattern: Sensor Aggregation | Uses a Proxy Item to track the anti-flapped presence state |
Edit: Added JSR223 Python example and cleaned up the Rules DSL version.