Premise School of Hard Knocks

Motorola Premise

123

Senior Member
Please add to this thread things you've learned about Premise that will save other people time and effort.
NOTE: Please discuss issues elsewhere and only post confirmed quirks here.

PROGRAMMING

Never name a property "ID"!
Premise stores all objects in XML format. Each object has a unique (hidden) identifier called "ID". If you name a property "ID" it will duplicate the existing object identifier ... and that violates an XML structural rule.

Nothing bad happens immediately. However, when Premise SYS Server starts up it loads the most recent backup of the XML data and halts on the line containing the duplicate identifiers. It discards the whole backup file and attempts to load an older backup copy. It will keep doing this until it finds a valid XML backup. If it runs out of available backups it reverts to a blank slate.

I discovered this while developing a new Module. Every backup copy had the duplicated "ID" so SYS Server was unable to load any of them! To find the offending line, change the backup file's extension from XDO to XML and open it with Internet Explorer. IE will display the XML file, halt at the offending line, and print an error message.

In conclusion, you should avoid creating any two properties with the same name!


Steer clear of special characters when scripting!
This is another XML bugaboo. XML stores special characters like ampersand (&) and single quote ('), and several others, in an encoded format. Ideally, when you enter the "&" character in a script, Premise should store it as "&" in the XML file. It does not do this so, once again, SYS Server will fail to load the XML file. Phooey! And so in my script comments, you won't find much more than a-z and 0-9. This topic is documented in greater detail in this post.
 
Don't use an existing Module to create a new one.

If you want to build a new Module be sure to create one from scratch. Do not simply modify an existing one and give it a new name.

DO NOT DO THIS:
You have an existing module called "DoorControl".
You export it to create a backup ("DoorControl.xdo").
You rename the "DoorControl" Module to "GarageDoorControl" and modify its code.
You export "GarageDoorControl".
You now want "DoorControl" as well so you import "DoorControl.xdo" and ... uh-oh ... now you've learned a painful lesson!


Both Modules have the same GUID (uh-oh)! When you import DoorControl.xdo it overlays itself onto the existing GarageDoorControl module. You now have a software version of "The Fly" ... a tangled combination of code from both modules.

All is not lost because you can use a text-editor to replace the duplicated GUIDs in GarageDoorControl.xdo ... assuming you remembered to export the GarageDoorControl module before you trounced it. Be advised that this is a tedious task and is a last resort to avoid losing the new Module. To create unique GUIDs, you can use Microsoft's guidgen.exe or guidgen.com. And yes, it happened to me. :(
 
IRemotePremiseObjectCollection doesn't play nice with a foreach loop.

IRemotePremiseObjectCollection is a MiniBroker class that represents a collection of Premise objects. For example, assuming "Home" represents the Premise Home object, this line of code returns a collection of Lighting objects.

Code:
IRemotePremiseObjectCollection Lights = Home.GetObjectsByType("sys://Schema/Device/Lighting/Lighting", true);

IRemotePremiseObjectCollection includes a method called Count that reveals the number of elements in the collection. The following for loop will print the name of each light in the collection.

Code:
	// List all lights using a for loop.
	for (int x = 0; x < Lights.Count; x++)
		Debug.WriteLine(Lights.Item(x).Name);

A neater way of iterating through each element in the collection is to use a foreach loop. Unfortunately, when used with a foreach loop, the collection behaves as if it has Count+1 elements! The foreach loop attempts to look at one more element than actually exists in the collection and fails.

Code:
	// List all lights using a foreach loop.
	// This will fail!
	foreach (IRemotePremiseObject Light in Lights)
		Debug.WriteLine(Light.Name);

The workaround is to simply use a for loop or to wrap the foreach in a try-catch like so:
Code:
	// List all lights using a foreach loop in a try-catch.
	try
	{
		foreach (IRemotePremiseObject Light in Lights)
			Debug.WriteLine(Light.Name);
	}
	catch
	{
		// Bug: We are here because the collection behaves as if there are Count+1 elements.
	}
 
Unable to extend an existing Unit class.

I tried to extend the Velocity class so that, in addition to MetersPerSecond and FeetPerSecond, it would have built-in conversions for KilometersPerHour and MilesPerHour. I was unsuccessful and I'm going to assume this is because Premise does not allow you to extend a "core" Premise class (i.e. classes in Schema.System).

A Unit's "conversion" is actually a class called "UnitChild". Builder doesn't let you add them to a new class. To get around this limitation, I exported my class into an XDO, manually appended the "UnitChild" classes, and then re-imported the XDO. Premise didn't complain about the new extended Velocity class but it didn't use it either.

In contrast, if I create a class that inherits from Velocity, the new conversions work ... sort of. It should've inherited the existing conversions (m/s and ft/s) but all that appears in the editor are the new conversions (kph and mph).

The results of my tests are summarized in the attached image.
 

Attachments

  • Unable_to_extend_Velocity_class.png
    Unable_to_extend_Velocity_class.png
    95.4 KB · Views: 85
Sysevent.SrcProperty.Name becomes "trigger" when a property is called using a macro!

I think 123 and I have discussed this before, but I couldn't find it so I'll post it here.

Scenario
You are making a module for an RS232 controlled lighting network. You have a property called Brightness that also changes PowerState if a light is off to turn it on. To prevent PowerState from also sending RS232 code that would turn the light on (cuts down on RS232 traffic), you use a statement such as:
Code:
if sysevent.srcProperty.name <> "Brightness" then ... end if
within the OnChangePowerState script for the lighting class.


The danger here is trusting that sysevent.srcProperty.name will always be "Brightness" if brightness is changed! In reality, if a scriptMacro changes the brightness and not the user directly, sysevent.srcProperty.name becomes "Trigger" and the RS232 command is sent twice: once for the OnChangeBrightness script and once for the OnChangePowerState script, doh!

The easiest solution I can think of is to use a simple Boolean flag called "BrightnessChanging" and set it to true before Brightness sets the PowerState and false once the OnChangeBrightness script is finished. OnChangePowerState would in turn check that this flag is false before processing anything so only a single RS232 command is sent to the lighting network.
 
Not enough disk space ?

I Have had a problem of disk space. few kilo octets only...
But, premise has rewrite the main XDO, so to write, premise has opened the file and ... not enough disk space to rewrite and close the file...

consequence : soft reset...

Jean-Michel
 
Never name a method SendMessage!
 
I kept getting an error on line 3 (no code was there) OR I'd get no error and be taken to:
Services.Scripting.Languages.VBScript.StackFrames !?!
 
I renamed the method to Send_Message and all is well.
 
BUG WARNING: Premise's Units contain special (illegal) characters.
 
The following Units contain special characters:
  1. Area (ft2​)
  2. Volume (ft3)
  3. Density (g/m3)
  4. Acceleration (ft/s2)
The illegal characters are superscripts, 2 to denote square (like square feet for Area and feet per second squared for Acceleration) and 3 for cube (like cubic feet for Volume).
 
If you create a custom device with these Units, the superscript characters will be stored in Premise's slserver.xdo file and all backup copies. They are not encoded correctly for XML but are stored as extended ASCII characters (illegal). Whenever Premise Server restarts, it will fail to load any of these files.
 
This is an example of the first tip in this thread: "Steer clear of special characters when scripting!" The problem here is that the superscript characters are in the Units so they're unavoidable if you create properties based on Area, Volume, Density, or Acceleration.
 
 
The Units are not defined in a text-based schema file (which you could easily edit and correct) but are stored in a binary file that is loaded when Premise Server starts. The workaround is a bit of a kludge. You can create a script that modifies the problematic Units. Make it run upon startup so the troublesome Units are displayed and (most importantly) stored without superscript characters. I've tested it and it works.
 

Schema.System.Units.Area.Meter.Abbreviation = "sq m"


Schema.System.Units.Area.Inch.Abbreviation = "sq in"

Schema.System.Units.Volume.Meter.Abbreviation = "cu m"
Schema.System.Units.Volume.Foot.Abbreviation = "cu ft"
Schema.System.Units.Volume.Inch.Abbreviation = "cu in"

Schema.System.Units.Density.GramsPerCubicMeter.Abbreviation = "g/cu m"
Schema.System.Units.Density.GramsPerCubicMeter.StandardName = "GR/M3"

Schema.System.Units.Acceleration.MetersPerSecondSquared.Abbreviation = "m/s sq"
Schema.System.Units.Acceleration.MetersPerSecondSquared.StandardName = "M/S2"
Schema.System.Units.Acceleration.FeetPerSecondSquared.Abbreviation = "ft/s sq"
Schema.System.Units.Acceleration.FeetPerSecondSquared.StandardName = "FT/S2"

 
NOTE:
 
The odds of anyone experiencing this problem are low. There's not a single standard device that has Area, Volume, Density, or Acceleration properties. You have to create a custom device that employs them in order to encounter this problem.
 
Back
Top