Premise Use of Class Extension for Bindable properties possible?

Motorola Premise

etc6849

Senior Member
I'm trying to add four bindable properties to sys://Schema/X10_Devices/MotionSensor and sys://Schema/Device/MotionDetector.

The properties store the date and time for the last change of the state (boolean) property. I'm not sure why, but the properties don't seem to show up as bindable when I bind them to the home object... Any ideas? Under devices and home I see the new properties, but the binding between home and device isn't there?
 

Attachments

The Extension relationship allows you to add new properties and methods to an existing class (i.e. a core Premise class). However, the new properties, even if flagged as Bindable, will not be bindable.

It is possible to create new classes with bindable properties. However, I haven't found a way of adding bindable properties to an existing class.
 
Thanks 123! I really wish this was documenting in the help files... maybe it is and I missed it!

Anyways, what I did to solve this was to change both the home and device properties in tandem (replaced code in onChangeState with this):

Code:
For Each obj in this.GetObjectsByPropertyName("sourceObject")
	If Not obj.sourceObject Is Nothing Then
		set homeObj = obj.sourceObject
		If this.State = False Then
			this.LastOffDate = system.times.sysDate
			this.LastOffTime = system.times.sysTime 
			homeObj.LastOffDate = system.times.sysDate
			homeObj.LastOffTime = system.times.sysTime
		Else
			this.LastOnDate = system.times.sysDate
			this.LastOnTime = system.times.sysTime
			homeObj.LastOnDate = system.times.sysDate
			homeObj.LastOnTime = system.times.sysTime
		End If
	End If
Next
 
For your intended purpose (record the last activation/deactivation time and date), there's really no need to make bindable properties. The Home-level object can take care of this housekeeping on its own. The attached file contains a Module that extends the MotionDetector class with LastActivation and LastDeactivation properties.

With regards to your code example, it gets the job done but no real binding is taking place. It performs the function of binding by copying property values from one object to another (i.e. device to home). There's a way of substantially streamlining the code (eliminates the for each loop) and it involves using the BindingSource class. However, if it works for you as is then there's no need to disturb it.
 

Attachments

I'm interested in streamlining the code for learning purposes. Are you referring to something like:

set homeObj = this.BoundObject? I was getting an error when I tried it... I'm wondering if its something to do with the way the X10 driver is implemented or because I am using it in a class extension?

I ended up having to use this:
set homeObj = this.BindingLink.sourceObject

Adding the code at the home object level makes a lot of sense doesn't it! I think I'm still learning... ;)
 

Attachments

  • error.JPG
    error.JPG
    13.6 KB · Views: 14
Home objects inherit from the BindingSource class and use the BoundObject property.

Device (Driver) objects inherit from the BindingTarget class and use the Bindings property.

When one "binds" a Home object (Light) to a Device object (X10, Insteon, UPB, etc) the two binding classes permit the exchange of data (i.e. PowerState, Brightness, etc) between the two objects.



Your code sample has a superfluous for-each loop. There's only one object to inspect so there's no need for a loop. If a Home object wants to learn more about the Device object it is bound to, it can do so with one line:
set oThing = this.BoundObject

By exploring the properties of oThing you can learn about the bound Device object. For example, assuming we're talking about a Light bound to A1 of the X10 Device Driver, "oDevice.Name" would be "X10_A_01".
 
Thanks 123! I'll have to explore the bindings property tonight as I haven't used that. The boundObject property is one I used in the past for coding for your HR12A keypad idea from a different post (which I use everyday and is very handy). I didn't catch the significance of why my previous code worked and my previous code didn't until now, but I was using it with home objects when it worked and not with devices... Doh!

Probably a stupid programming question: it appears if you are trying to reference a child that may or may not exist, you need some way of checking whether or not the child is there because if you try to point to a child that isn't there you receive an error. This is why i used the getobjectsbypropertyname method as the code within the for each loop will not execute unless something is there (ie this.BindingLink is not present if the device is not bound to a home object and I wanted to protect from any future error I might have if I have a motion sensor that is not bound). Any handy method to check if a child is present before trying to set an object to it?

I'm guessing I should always try to ensure bindings are not empty using a statement like:

if not this.bindings is nothing then
set thingy = this.bindings
...
end if
 
If "if not Object is nothing" works for you then stick with it. There are some situations where it cannot be used.

For example, the following line of code will fail and cause the Premise's VBScript interpreter to halt if the Animals Module is not loaded:

set AllDogs = this.GetObjectsByType(Schema.Modules.Animals.Classes.Dogs.Path)

Ideally, it should return an empty collection but, instead, it bombs. So how can I tell that the Animal class is unavailable if I can't even test for it presence? VBScript doesn't have the "try - catch" structure found in modern object-oriented languages but you can use its distant cousin, namely "on error resume next".

Here are two ways to use "on error resume next" to solve the problem.

Code:
set AllDogs = nothing

on error resume next
set AllDogs = this.GetObjectsByType(Schema.Modules.Animals.Classes.Dogs.Path)
on error goto 0

if not AllDogs is nothing then
	debugout "We have Animals!"
else
	debugout "No Animals!"
end if
OR
Code:
err.clear
on error resume next
set AllDogs = this.GetObjectsByType(Schema.Modules.Animals.Classes.Dogs.Path)

if err.number <> 0 then 
	debugout "No Animals!"
else
	debugout "We Have Animals!"
end if
on error goto 0
 
Back
Top