I'm packaging an update up now, but I thought this is a good example for anyone that wants to know the basics of how a plugin works...
The changes in the forthcoming update will fix the "Configure..." option for the plugin. (nothing to configure, but now there is a pop up that says so.)
The next change is I added a few new states: homeLast, awayLast, alertsOn. Like every other custom state with this plugin, they are blank text blocks where you can enter anything (including a variable or device.state substitution)
As an example (for your information), how I added the "alertsOn" state to the plugin.
1) Device.xml: define the state for the "person" device.
- Code: Select all
<State id="alertsOn">
<ValueType>String</ValueType>
<TriggerLabel>Alerts On</TriggerLabel>
<ControlPageLabel>Alerts On</ControlPageLabel>
</State>
From the code, you can also see this is how that state is defined on a trigger or a control page.
2) Actions.xml: where you define what actions your plugin can take. Basically its the information for a dialog box and a field to store the data in...
The action to add data to the alertsOn state:
- Code: Select all
</Action>
<Action id="setAlertsOn" deviceFilter="self">
<Name>Set Alerts On</Name>
<CallbackMethod>setAlertsOn</CallbackMethod>
<ConfigUI>
<Field type="textfield" id="alertsOnField">
<Label>Alerts On:</Label>
</Field>
<Field id="label" type="label" fontSize="small" fontColor="darkgray">
<Label>You can insert variable substitution %%v:VARIABLEID%% or device state %%d:DEVICEID:STATEKEY%%</Label>
</Field>
</ConfigUI>
</Action>
Part of the action to update all the states of a person device:
- Code: Select all
<Field type="textfield" id="alertsOnAllField">
<Label>Alerts On:</Label>
</Field>
The last bits are in the "plugin.py" document that ties everything together with python code.
3) plugin.py:- Code: Select all
## Action to update custom state of a person device
def setAlertsOn(self, pluginAction, dev):
substitutedTitle = self.substitute(pluginAction.props.get("alertsOnField", ""))
dev.updateStateOnServer(key="alertsOn", value=substitutedTitle)
self.debugLog("Set Alerts On: " + str(pluginAction.props.get(u"alertsOnField")) + " Entered. State alertsOn set to: " + substitutedTitle)
## Part of the Action to update all states of a person device
substitutedTitle21 = self.substitute(pluginAction.props.get("alertsOnAllField", ""))
self.debugLog("21: " + str(pluginAction.props.get(u"alertsOnAllField")) + " Entered. " + "State alertsOn set to: " + substitutedTitle21)
dev.updateStateOnServer(key="alertsOn", value=substitutedTitle21)
## Part added to the actions that forward and reverse the "Now Showing" device.
self.aPersonDev.updateStateOnServer(key="alertsOn", value=alertsOn)
If you notice in the first paragraph "def setAlertsOn" is from the Actions.xml as the "CallbackMethod". You can also see where its moving around data...
alertsOn versus
alertsOnField versus
alertsOnAllField.
You may also notice in the debug log what looks like two different ways to say the same thing....
substitutedTitle versus str(pluginAction.pprops.get(u"alertsOnField")).
If you enter "Chicken Taco" in the action, the log will say:
"SetAlertsOn: Chicken Taco Entered. State alertsOn set to: Chicken Taco. However, if "Chicken Taco" is saved as a variable %%v:135790123%%, then if you enter "%%v:135790123%%" in the action, the log will say:
"SetAlertsOn: %%v:135790123%% Entered. State alertsOn set to: Chicken Taco"Thats because the first is a string of what you entered and the second is the value of what you entered. (The value is what is stored in the state for the device)