All demonstrations are built around the SpiffyNet home automation network.
>The SpiffyNet system provides a "mobile ambient;" a Haunt in VooodooWarez's Object Platform parlance, which serves as a self contained operating environment for control over the SpiffyNet system.
### minimum setup : all that is required for a working SpiffyNet system ###
>>> load("spiffynet.dll")
>>> mySpiffyNet = SpiffyHaunt()
### the entire network is now completely operational ###
### more typically, SpiffyNet will be just one Haunt in the set of Haunts ###
>>> load("spiffynet.dll")
>>> rootHaunt = Shadow()
>>> spiffyHaunt = SpiffyHaunt()
>>> rootHaunt.Add(spiffyHaunt)
The following scripts illustrate runtime modification of the Spiffy Home Automation Network
### examine's spiffyHaunt's NodeFinder : NodeFinder is responsible for tracking the presence and absence of nodes ###
>>> dir(spiffyHaunt]["NodeFinder"])
[[[ ]]]
### setup additional debugging printouts to view network activity ###
>>> rootHaunt["spiffyHaunt"]["NodeFinder"].nodeConnect += def interceptConnect (newnode as SpiffyNode):
... print ("new node of type " + newnode.friendlyTypeName + " named " + newnode.name " found")
... foreach d as SpiffyDevice in newnode.devices:
... print (" node contains " + d.Name + " which is a " + d. + "device")
### plug in SpiffyNet network node ###
[[[ new node of type SpiffyDevice named LivingRoom Node found]]
[[[ node contains Living Room Light which is a Spiffy Light device ]]]
[[[ node contains Desklamp which is a Spiffy Light device ]]
[[[ node contains Wallswitch which is a Spiffy Switch device ]]
### setup additional debugging to witness network disconnects ###
>>> spiffyHaunt["NodeFinder"].nodeDisconect += def(donenode as SpiffyNode):
... print("node " + donenode.name + " has disconnected")
... donenode.name += " [disconnected]"
...
### physically disconnect node ###
[[[ node LivingRoom Node has disconnected ]]]
### physically reconnect node ###
[[[ new node of type SpiffyDevice named LivingRoom Node [disconnected] found]]
[[[ node contains Living Room Light which is a Spiffy Light device ]]]
[[[ node contains Desklamp which is a Spiffy Light device ]]
[[[ node contains Wallswitch which is a Spiffy Switch device ]]
### various means of adding the UpnpHaunt mixin to the SpiffyHaunt ###
>>> spiffyHaunt.Add( UpnpHaunt("MyUpnp") )
>>> upnpFirstHaunt = SpiffyHaunt["MyUpnp"]
>>> upnpSecondHaunt = UpnpHaunt("SecondUpnp")
>>> spiffyHaunt.Add(upnpSecondHaunt)
### all nodes in SpiffyHaunt are now have two unique Upnp exposures ###
### debug output on SetLoadLevelTarget event for DeskLamp under upnpFirstHaunt exposure ###
>>> deskLampUpnp = upnpFirstHaunt["LivingRoom node"]["Desklamp"] as SpiffyDevice
>>> deskLampUpnp["SetLoadLevelTarget"].postDefine ( def (val as byte):
... print("changing brightness to " + val.ToString())
...
### turn on lamp whenever we adjust the light level for all exposures ##
>>> deskLamp = spiffyHaunt["Desklamp"]
>>> deskLamp["DimmingService"]["SetLoadLevelTarget"].postDefine = def (val as byte):
... deskLamp["SwitchPower"].SetStatus(true)
...
next up are instances.
they are very wacky.
### lampOn is simply an instance of a deskLamp, exactly like a normal deskLamp SpiffyDevice ###
>>> lampSave = deskLamp.instance;
>>> lampOn = deskLamp.instance["on"]
>>> lampOn["SwitchPower].Status = true
>>> lampOn["DimmingService"].LoadLevelTarget = 255
>>> deskLamp.instance = lampOn
### deskLamp goes on ###
>>> deskLamp.instance = lampSave
### deskLamp goes back to previous state ###
### transactions are nested and aliased ###
>>> lampOn.instance["dimmed"].LoadLevelTarget = 192
>>> lampOn.instance["dark"].LoadLevelTarget = 128
>>> lampOn.instance["dark"].instance["verydark"].LoadLevelTarget = 96
>>> deskLamp.instance = deskLamp.instance["On"].instance["dimmed"]
>>> deskLamp.instance = lampOn["dark"]["verydark"]
### construct a composite light from dynamic typing ###
>>> lampMulti = UpnpHaunt.hollowTypes["devices"].["Spiffy Light"]
### hollow types do not active real objects, they are simply unmapped inactive interfaces of a type ###
>>> lampMulti.AddPostDefine(deskLamp)
>>> lampMulti.AddPostDefine(myFirstHaunt["Living Room Light"])
### Add automatically mixes in unmapped capabilities ala predicate typing ###
### AddPostDefine does the same but postfixes incoming fields, methods, events, members to existing mappings ###
>>> mySecondHaunt.Add("MultiLight", lampMulti)
### mySecondHaunt now has a new UPnP device called MultiLight
### alter lampMulti so that turning it off does not turn off the living room light ###
>>> lampMulti["SwitchPower"].reDefine("SetStatus", myFirstHaunt["Living Room Light"], def (val as bool):
... if val:
... myFirstHaunt["Living Room Light"].SetStatus(val)
...
### in the future : ###
>>> lampMulti["SwitchPower"]["SetStatus"].unDefine(myFirstHaunt["Living Room Light"])