Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revisionBoth sides next revision | ||
livebox:hah_plugboard_v2 [2012/03/03 19:16] – [BSC Command helper functions] brett | livebox:hah_plugboard_v2 [2014/01/03 04:08] – [Timer] brett | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== xAP Plugboard (V2 script engine) ====== | ====== xAP Plugboard (V2 script engine) ====== | ||
+ | |||
+ | <box red 40% round> | ||
Whilst developing the [[HAH]] project I noticed there was an architectural component that would simplify the interactions between xAP compliant devices and daemons. | Whilst developing the [[HAH]] project I noticed there was an architectural component that would simplify the interactions between xAP compliant devices and daemons. | ||
Line 6: | Line 8: | ||
Consider the following use cases: | Consider the following use cases: | ||
- | * Send a twitter message when the power being monitored with currentcost | + | * Send a twitter message when the power being monitored with Current Cost goes above 2kW |
* If the temperature drops below 10C turn on a heater turning it off again when it reaches 12C | * If the temperature drops below 10C turn on a heater turning it off again when it reaches 12C | ||
- | * When a currentcost/ | + | * When a Current Cost/ |
* If Input 1 goes high turn on Relay 1 | * If Input 1 goes high turn on Relay 1 | ||
* If RF 1 is turned on schedule a Google calendar event to turn it off in 1 hour | * If RF 1 is turned on schedule a Google calendar event to turn it off in 1 hour | ||
- | * Log a calendar event whenever Input 2 changes state | + | * Log a Google |
* If no change is detected on Input 3 during the last 2 hours, send an SMS message | * If no change is detected on Input 3 during the last 2 hours, send an SMS message | ||
- | * If a change is detected on Input 4 AND a named calendar event is still active, send an email | + | * If a change is detected on Input 4 AND a named Google |
* If ' | * If ' | ||
- | It's possible to cascade rules in the plug-board. It's also possible to code circular dependency which the script-er | + | It's possible to cascade rules in the plug-board. It's also possible to code circular dependency which the scripter |
- | In this model we want to decouple the producers from the consumers and use a scripting intermediary, | + | In this model we want to decouple the producers from the consumers and use a scripting intermediary, |
Example of how the script engine is used to interpret a tweet command to turn on a relay. | Example of how the script engine is used to interpret a tweet command to turn on a relay. | ||
Line 27: | Line 29: | ||
* This message is picked up by the xap-twitter components and broadcast as an xAP alias command | * This message is picked up by the xap-twitter components and broadcast as an xAP alias command | ||
* The script engine interprets this alias and re-transmits a 'RELAY on' command | * The script engine interprets this alias and re-transmits a 'RELAY on' command | ||
- | * 'Relay on' is seen by the adapter and is processed as a control for the HAH hardware | + | * 'Relay on' is seen by the adapter and is processed as a control for the HAH hardware, thus turning the relay on |
Examples of daemons that currently conform to this model are: | Examples of daemons that currently conform to this model are: | ||
Line 34: | Line 36: | ||
* CONSUMER: for sending a tweet. | * CONSUMER: for sending a tweet. | ||
* xap-googlecal | * xap-googlecal | ||
- | * PRODUCER: monitors | + | * PRODUCER: monitors |
- | * CONSUMER: used as a service to create calendar events. | + | * CONSUMER: used as a service to create |
* xap-sms | * xap-sms | ||
* PRODUCER: emits an xAP message when an SMS is received | * PRODUCER: emits an xAP message when an SMS is received | ||
Line 58: | Line 60: | ||
* [[http:// | * [[http:// | ||
* [[http:// | * [[http:// | ||
- | * [[http:// | + | * [[http:// |
- | * [[http:// | + | * [[http:// |
For more about each of these libraries see their associated reference pages. | For more about each of these libraries see their associated reference pages. | ||
Line 68: | Line 70: | ||
===== Basics ===== | ===== Basics ===== | ||
+ | The first thing to note is that using the plugboard generally takes a little personal effort. There are sample scripts available to help get you going, but it is assumed that you can prepare a script, get it onto the HAH and run it. Being familiar with tools such as FTP & vi, together with a basic knowledge of some Unix commands will make your work with the plugboard a lot easier. Familiarity of how [[http:// | ||
There are only two calls that are needed to build an xAP Lua application. | There are only two calls that are needed to build an xAP Lua application. | ||
^^ **Return Type** ^^ **Method** ^^ **Description** ^^ | ^^ **Return Type** ^^ **Method** ^^ **Description** ^^ | ||
- | || void|| xap.init(source, | + | || void|| xap.init(source, |
+ | || void|| xap.init{vendorid=, | ||
|| void|| xap.process() || Enter the xAP processing loop || | || void|| xap.process() || Enter the xAP processing loop || | ||
|| void|| xap.send(msg) || Send RAW data on the well known xAP UDP port 3639 || | || void|| xap.send(msg) || Send RAW data on the well known xAP UDP port 3639 || | ||
|| String || xap.expandShortMsg(msg) || Inject/ | || String || xap.expandShortMsg(msg) || Inject/ | ||
|| void|| xap.sendShort(msg) || A shortcut for send(expandShortMsg(msg)) || | || void|| xap.sendShort(msg) || A shortcut for send(expandShortMsg(msg)) || | ||
+ | || String || xap.buildXapAdddress{vendorid=, | ||
+ | || String || xap.getDeviceID() || Returns the resolved deviceid, either hostname or / | ||
In its most simplistic form a basic application would look like this; It wouldn' | In its most simplistic form a basic application would look like this; It wouldn' | ||
Line 82: | Line 88: | ||
<code lua> | <code lua> | ||
require(" | require(" | ||
- | xap.init("dbzoo.lua.simple"," | + | xap.init{instance=" |
xap.process() | xap.process() | ||
</ | </ | ||
When building plugboard applets these calls won't need to be made as the plugboard engine will take care of it. They will be needed if writing standalone Lua applications something you'll do whilst in development/ | When building plugboard applets these calls won't need to be made as the plugboard engine will take care of it. They will be needed if writing standalone Lua applications something you'll do whilst in development/ | ||
- | |||
===== Frame ===== | ===== Frame ===== | ||
Line 124: | Line 129: | ||
print(f) -- Implicitly calls the tostring() method as above. | print(f) -- Implicitly calls the tostring() method as above. | ||
- | -- These assertion | + | -- These assertions |
assert(f: | assert(f: | ||
Line 162: | Line 167: | ||
^^ **Return Type** ^^ **Method** ^^ **Description** ^^ | ^^ **Return Type** ^^ **Method** ^^ **Description** ^^ | ||
|| Filter || xap.Filter(filter) || Constructor || | || Filter || xap.Filter(filter) || Constructor || | ||
+ | || void || < | ||
|| void || < | || void || < | ||
+ | || void || < | ||
|| void || < | || void || < | ||
Line 182: | Line 189: | ||
</ | </ | ||
- | The constructor can also accept a set of filter patterns directly these are equivalent. | + | The constructor can also accept a set of filter patterns directly; these are equivalent. |
- | < | + | < |
filter = xap.Filter() | filter = xap.Filter() | ||
filter: | filter: | ||
Line 224: | Line 231: | ||
end | end | ||
- | xap.init("dbzoo.lua.test"," | + | xap.init{instance=" |
f = xap.Filter() | f = xap.Filter() | ||
f: | f: | ||
Line 251: | Line 258: | ||
<code lua> | <code lua> | ||
+ | require " | ||
elapsed = 0 | elapsed = 0 | ||
- | function tick(self) | + | function tick(self, userdata) |
elapsed = elapsed + self.interval | elapsed = elapsed + self.interval | ||
print(" | print(" | ||
if elapsed > 10 then | if elapsed > 10 then | ||
- | print(self.userdata) | + | print(userdata) |
self:stop() | self:stop() | ||
end | end | ||
Line 263: | Line 271: | ||
xap.Timer(tick, | xap.Timer(tick, | ||
+ | xap.process() | ||
</ | </ | ||
===== Select ===== | ===== Select ===== | ||
- | The select object allows a program to monitor multiple file descriptors, | + | The select object allows a program to monitor multiple file descriptors, |
^^ **Return Type** ^^ **Method** ^^ **Description** ^^ | ^^ **Return Type** ^^ **Method** ^^ **Description** ^^ | ||
Line 275: | Line 284: | ||
**Sample usage** | **Sample usage** | ||
- | As this is complex class, although simple enough to use, the sample will be a little larger then normal to show fully how this works. | + | As this is a complex class, although simple enough to use, the sample will be a little larger then normal to show fully how this works. The code is split into two pieces; the server and the client. |
The assert() wrapper just makes sure that the call worked ... if not, the code stops at that point. | The assert() wrapper just makes sure that the call worked ... if not, the code stops at that point. | ||
Line 315: | Line 324: | ||
end | end | ||
- | xap.init("dbzoo.lua.socket"," | + | xap.init{instance=" |
print(" | print(" | ||
Line 358: | Line 367: | ||
===== BSC ===== | ===== BSC ===== | ||
- | This class allows the easy construction of BSC endpoints. | + | This class allows the easy construction of [[http:// |
* responding to a xAPBSC.query with an xAPBSC.info message | * responding to a xAPBSC.query with an xAPBSC.info message | ||
* sending a xAPBSC.info message every 2 mins | * sending a xAPBSC.info message every 2 mins | ||
Line 365: | Line 374: | ||
^^ **Return Type** ^^ **Method** ^^ **Description** ^^ | ^^ **Return Type** ^^ **Method** ^^ **Description** ^^ | ||
|| Endpoint || Endpoint(table) || Constructor: | || Endpoint || Endpoint(table) || Constructor: | ||
+ | || nil || < | ||
|| nil || < | || nil || < | ||
|| nil || < | || nil || < | ||
|| nil || < | || nil || < | ||
|| nil || < | || nil || < | ||
- | || nil || < | + | || nil || < |
- | || state || decodeState(string) || helper function to decode a string into a bsc STATE constant, the following | + | || state || decodeState(string) || helper function to decode a string into a BSC state constant, the following |
- | The following constants can be used when dealing with the state. | + | The following constants can be used when dealing with the state: |
* bsc.STATE_ON | * bsc.STATE_ON | ||
* bsc.STATE_OFF | * bsc.STATE_OFF | ||
* bsc.STATE_TOGGLE | * bsc.STATE_TOGGLE | ||
- | More about the Endpoint(table) constructor. | + | More about the Endpoint(table) constructor. |
- | **name**: | + | **name** : Append |
+ | |||
+ | **instance**: | ||
**direction**: | **direction**: | ||
Line 402: | Line 414: | ||
**displaytext** An additional parameter that may be include in an EVENT of INFO message, configurable with a infoEventCB callback function. | **displaytext** An additional parameter that may be include in an EVENT of INFO message, configurable with a infoEventCB callback function. | ||
- | |||
- | **source** The fully qualified target endpoint name. Such as dbzoo.livebox.plugboard: | ||
**uid** UID key. If nothing is provide one will be automatically assigned based on the order of BSC endpoints created so far. | **uid** UID key. If nothing is provide one will be automatically assigned based on the order of BSC endpoints created so far. | ||
Line 425: | Line 435: | ||
end | end | ||
- | xap.init("dbzoo.livebox.test"," | + | xap.init{instance=" |
+ | -- Form 1 : Constructed using the xAP address from xap.init() | ||
+ | -- creates -> dbzoo.livebox.test: | ||
bsc.Endpoint{name=" | bsc.Endpoint{name=" | ||
bsc.Endpoint{name=" | bsc.Endpoint{name=" | ||
bsc.Endpoint{name=" | bsc.Endpoint{name=" | ||
+ | |||
+ | -- Form 2 : vendorid and deviceid default, remaining from instance is appended | ||
+ | -- creates -> dbzoo.livebox.my: | ||
+ | bsc.Endpoint{instance=" | ||
+ | |||
+ | -- Form 3 : vendorid defaults, override deviceid. | ||
+ | -- creates -> dbzoo.test.my: | ||
+ | bsc.Endpoint{deviceid=" | ||
+ | |||
+ | -- Form 4 : full override all keys | ||
+ | -- creates -> hello.test.my: | ||
+ | bsc.Endpoint{vendorid=" | ||
+ | |||
+ | -- Form 5 : Shorter way of doing form 4. | ||
+ | -- creates -> helloworld.test.my: | ||
+ | bsc.Endpoint{source=" | ||
xap.process() | xap.process() | ||
Line 457: | Line 485: | ||
function init() | function init() | ||
- | local e = bsc.Endpoint{source="dbzoo.livebox.Plugboard: | + | |
+ | | ||
xap.Timer(update, | xap.Timer(update, | ||
end | end | ||
Line 470: | Line 499: | ||
* bsc.sendText(target, | * bsc.sendText(target, | ||
* bsc.sendLevel(target, | * bsc.sendLevel(target, | ||
- | * bsc.send{} -- takes table of elements. | + | * bsc.send{} -- takes table of elements. |
- | Its a RAW low level control function that is utilized by the higher level functions: | + | It' |
STATE can be any of the following: on, off, true, false, 1, 0, toggle (Nominally you would use on and off) | STATE can be any of the following: on, off, true, false, 1, 0, toggle (Nominally you would use on and off) | ||
Line 501: | Line 530: | ||
require(" | require(" | ||
- | xap.init("dbzoo.livebox.test"," | + | xap.init{instance=" |
bsc.sendState(" | bsc.sendState(" | ||
Line 528: | Line 557: | ||
</ | </ | ||
- | The **init()** function will be invoked when the applet | + | The **init()** function will be invoked when the applet |
To be automatically loaded they must be placed in the / | To be automatically loaded they must be placed in the / | ||
Line 554: | Line 583: | ||
end | end | ||
- | xap.init("dbzoo.lua.example"," | + | xap.init{instance=" |
init() | init() | ||
xap.process() | xap.process() | ||
Line 561: | Line 590: | ||
This allows you to work in another directory without constantly stopping and starting applets already in place when developing something new. | This allows you to work in another directory without constantly stopping and starting applets already in place when developing something new. | ||
- | How to you run these code fragments? | + | How do you run these code fragments? |
< | < | ||
# lua standAloneProgram.lua | # lua standAloneProgram.lua | ||
Line 568: | Line 597: | ||
====== More samples ====== | ====== More samples ====== | ||
- | Whilst there is flash space some samples will be included with the firmware | + | Whilst there is flash space available, |
< | < | ||
cd / | cd / |