[Demonstration]

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.



Initialization

### 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)



Runtime Modifications of SpiffyNet

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)

...



Instances

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"]


Typing

### 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"])