Premise Transmitting UPB Links

Motorola Premise

acalbear

Member
Premise can send UPB links via a Serial UPB PIM. The easiest way to do so is to navigate to the upbSerialInterface device in explorer and type in a command into the "link data" field and hit return. This will immediately transmit the link and if you're lucky the linked devices will respond.

The link data is in this basic format of {nid}{link}{mdid}{data} where

Nid = hex network id;
Link = hex device id;
Mdid = hex command;
Data = optional hex data.

Since "data" is optional I don't use it since I have no idea what it does. :unsure:

What I struggled with is what do all those 3 and 4 letter format definitions translate to. In short, here's an example - C80C21. A total of 6 characters is all that is needed. Here is my newbie translation:

NID (the "C8" in the example)- Pull up any of your UPB devices in Premise explorer and you will find the Network ID number within the object properties. Suppose your ID is 200. Find a decimal to hex converter such as http://www.easycalculation.com/decimal-converter.php and enter in your Network ID and out pops the Hex equivalent of C8. Again, you code heads might have this memorized but for me I sought google for help.

Link (the "0C" in the example)- This is the link you want to transmit. In UpStart, hit Links then Link Names and there are your listed links along with the Link ID which is what you need. Suppose your link ID is 12. Go to your converter and you should get "C". Remember you need two characters for this field so just enter a zero before the C.

Mdid - This basically is the command to transmit the link. Simply use 20 to activate the link and 21 to deactivate the link.

Therefore, in my example - the string will activate link 12 on my network that has a network id of 200.

Lastly, you can include in a script. I have yet to do so but suspect you can can embed the script into a scene or object or bind to a button. Here is a property change script that works. This is a script that runs on a property change.

If sysevent.newVal Then
Devices.upb.upbSerialInterface.upbLinkData = "C80921"
End If

Now, anybody know how to receive a link and parse the data???

Thanks to Sam and George for their help to get me up and running with UPB.

-acb
 
Now, anybody know how to receive a link and parse the data???
-acb

And that's what I'd like to know too. If I had hair, I'd be pulling it out. I have an 8-button switch sitting on my desk right now and cannot figure out how to get Premise to see anything from that switch.

If anyone has any guidance for us, it would be greatly appreciated.
 
... Find a decimal to hex converter ... I sought google for help.

Can't help you with UPB (hope to learn more when I find time) but a decimal/hex converter can be found in the Windows Calculator app.
  1. Open Calculator and select Scientific from the View menu.
  2. Ensure the number system is set to "Dec" (Decimal; Base 10) and enter a number (200).
  3. Change the number system to "Hex" (Hexadecimal; Base 16) and observe the result (C8).
As for "receive a link and parse the data" ... that's the function of a driver ... to listen for incoming data on a port, process it, and update whatever needs to be updated.

The core mechanism to receive data can be found in most of the Module-based drivers posted in the Downloads section. If you want, I can post a 'skeleton driver' that simply takes whatever comes through a port and dumps it to the Windows Debug Console. This is the easy part; the real work is interpreting the incoming UPB data and updating all necessary objects.

The only caveat, and this is if I understand your intentions correctly, is that I never tried to connect two drivers to the same serial port. You'd have the existing UPB driver plus an "adjunct" skeleton driver listening to the same COM port. I don't know if that's possible.
 
There is a way to obtain the data as its built into the UPB driver.

A simple command would be as follows: Devices.upb.upbSerialInterface.upbNetworkData

I tried a simple equation after immediately sending a transmit; something like this:

this.bucket = Devices.upb.upbSerialInterface.upbNetworkData

I received errors as appeared that what was coming through was not a simple data string but something more complex. 123 if you can provide the skeleton driver we hopefully can gain insight into how the data is received and tie that to the documentation. Right now I have no idea whats being and received and when.

The driver details that the developer (George) wrote follows. Unfortunatley, I need to see a sample packet then I can try to figure out how do deal with it (i'm a visual learner).

upbNetworkData

This is used by modules to receive data packets from the network. These may be packets from the module’s hardware device, or link packets sent from another device, or from the upbLinkData property. The messages are in a hex formatted string, using two characters per byte, of the form; {messageid}<{type}><{data}>, where messageid is the general message source type, type is the message type used in certain sources, and data is message data that may be present. The source types are as follows:
• Device Message – A message generated by the associated hardware device. The message source type is followed by a type identifying the message as either a Link or Direct message. This is then followed by the data portion in the format of: {nid}{did}{sid}{mdid}<{data}>, where nid is the network identifier, did is the destination identifier (link or direct), sid is the source device identifier, mdid is the message data identifier, and data is the optional message data. This is the same format as a network packet, without the two header bytes.
• Broadcast – A message broadcast on the network to a specific Link identifier which this module contains in its Receive Components. This is the same format as a Device Message.
• Device Response – A message generate in response to a previously sent request. This is the same format as a Device Message.
• Accept – Acceptance of a message sent to the network in the case where no other response would be forthcoming.
• NAK – Rejection of a message sent.
• PIM Busy – The PIM could not handle the message.
• PIM Error – The PIM detected an error with the message.
• PIM Registers – The message is in response to a request for PIM register data, which is not cached as other module registers are. This is of the form: {reg}{data}, where reg is the start register, and data is the list of register contents.
 
Premise can send UPB links via a Serial UPB PIM. The easiest way to do so is to navigate to the upbSerialInterface device in explorer and type in a command into the "link data" field and hit return. This will immediately transmit the link and if you're lucky the linked devices will respond.


Now, anybody know how to receive a link and parse the data???

Thanks to Sam and George for their help to get me up and running with UPB.

-acb


Does the Premise driver listen for incoming messages? If not, then forget it. If so, it should be easy and only a matter of proper configurations. I don't know anything about Premise. sorry. I wrote my own UPB driver for a basic co-processor that interfaces with my controller.
 
I don't know anything about Premise's UPB driver ... uni or bi-directional ... no clue.

I've attached a super-basic driver (Text_Listener.xdo) that simply listens for text-messages on a COM port and dumps them to the Windows Debug Console (you'll need DebugView to see the results).

I now realize that this will be of limited use to you because a UPB packet is binary encoded and is not an ASCII text-string (yeah,I skimmed through the UPB manual). The ELK M1 uses text-based packets and each one ends with a carriage-return and line feed so they're 'human-readable' and very easy to parse.

I haven't worked with binary-coded packets but I've seen examples of how to do it (the Downloads section contains plenty of good reference material). I'll create a Binary_Listener.xdo next week and post it. You'll still have to write code to parse the received packet in order to make any sense of it ... I can add some code for this purpose but, without access to UPB, I can't guarantee it would do the job correctly.

ckindt, would you consider applying you UPB talents to overhauling Premise's UPB driver? I believe its source-code (C++) is available ... or you could write a new one using a .NET based language and have it talk to Premise via its Minibroker interface (a .NET wrapper for a COM object) ... or write one as a Premise Module in VBscript. Just a thought ... :unsure:

BTW
Text_Listener.xdo can be used to observe the messages coming from an M1 (but then so can HyperTerminal or telnet).
 

Attachments

  • Text_Listener.zip
    2.2 KB · Views: 48
I think I may have found a workaround to receive links. Open up a logic block (object diagram) and drag a UPB switch device into the logic block. Don't drag a home object that is bound to the device; drag the actual device object into the block. You should now see all the device object attributes including the infamous upbNetworkData field. It is likely to be filled with the string "SDXXFF048664". XX being the hex equivalent of your Network ID number.

What I have discovered is that this field is dynamic based on buttons that are pushed on your switch including links. Go push a physical button that is on physical device represented by the device object you placed in the logic block. You should see the upbNetworkData field change. What this implies is that by using a simple equal to logic statement you can drive premise functions by UPB button pushes. The upbNetworkData field is bindable so you can link that to an EQ logic block and compare to strings you expect.

For example, if I push a button that transmits the PARTY link I might get the following output in the upbNetworkData field: MLXX0E1020FFFF. I break it down as follows: ML = the type of message being sent which is a link in this case; XX is the hex equivalent of your NID #; 0E is the hex equivalent for the link that is being sent; 10 is the hex equivalent of the device number that is sending the link; 20 is noting that the link is being activated (it would be 21 if the link were being deactivated) and FFFF are just attribute fillers.

Therefore, I THINK if you want to drive other premise functions based on a link then merely bind the upbNetworkData field for the switch that you are monitoring to an Equal logic block such that when it equals MLXX0E1020FFFF (in my example) then it performs your desired tasks.

I havent figured out how to read the upbNetworkData without binding to the specific switch that you want to monitor.

Would like to see if this works for others.

-ACB
 
Well. This seems to work EXCEPT that if you push a button a second time, the EQ block does not react again. It seems to not reset it's state (?). If I push a different button then go back to the original, it retriggers.

The positive here, is that at least I now know that Premise is actually seeing the button push. Obviously the drivers as written are missing something, since the button alone in a logic diagram does nothing.

But you have sent me down a path. I'll keep playing with it.

Thanks
 
Not sure what you mean by "since the button alone in a logic diagram does nothing" but with this workaround you will have to build logic into a script to decide what to do with the button push.

To reset, I think all you need to do is develop another sub script that re-writes the EQ input from the upbNetworkData such that when the EQ input changes it then immediately writes SDD6FF048600 to the EQ input box to replace the just received upbNetworkData. To avoid an infinite loop you prevent the re-write script from running if the EQ input box is equal to SDD6FF048600.

I havent tried the above but that might work. However, this may not work if you're trying to discover quick sequential pushes of the button but should work for pushes that have some amount of time between them.

Obviously, this is a workaround and isnt the most efficient or effective way to receive data from the buttons.
 
I guess it's time to learn VBScripting. I've had such a huge aversion to learning any kind of coding that it causes me to hit the wall very often in these kinds of situations. I've been a support-side IT person for ages, but never on the programming side.

Time to jump in the pool I guess.
 
Well. This seems to work EXCEPT that if you push a button a second time, the EQ block does not react again. It seems to not reset it's state (?). If I push a different button then go back to the original, it retriggers.

The positive here, is that at least I now know that Premise is actually seeing the button push. Obviously the drivers as written are missing something, since the button alone in a logic diagram does nothing.

But you have sent me down a path. I'll keep playing with it.

Thanks

acalbear is correct about the subscript.
You won't see the same button press twice in the top echelon register since there is no change. You can easily overcome this by coding a timer so the top register is cleared if it doesn't equal "0" or null or something you recognize as a cleared state. Then every time there is a message from UPB the register will equal the message. I just don't know what this is in Premise. It may already be parsed to some degree or might be the unparsed message string. Either way, clear the register after you have done what you want with the data in other scripts. I clear mine after 3 seconds and it works superbly. UPB messages are relatively slow.

SO, starting with a cleared UPB incoming register:

1. New UPB message in
2. Premise displays value in its register
3. You script something in Premise that reacts when the UPB register is not it's default value - move it to another register or act accordingly
4. Clear the non-default value from the incoming UPB register so it's ready to accept another UPB incoming message
...back to number 1.


That's it. It should be somewhat easy - you shouldn't have to screw around with drivers, just the scripting within Premise.
 
Bah! You don't need Binary_Listener.xdo, everything is already exposed by the UPB driver.

As you've already surmised, pushing the button repeatedly writes the same value to the upbNetworkData property. There is no state-change so the EQ block is not re-triggered.

Your proposed solution sounds like it will work. I use something similar when validating a property value. If the Gizmo property is supposed to hold a value from 1-5 and you enter 6 (Gizmo's state just changed), the OnChangeGizmo script will trigger, discover the out-of-range value of 6, and I force it to 1. However, the OnChangeGizmo just changed the value it monitors and that will cause it to run again (i.e. recursion occurs). It will find that Gizmo=1 and leave it be. To avoid re-running the entire OnChangeGizmo script, the first line simply checks the Gizmo value and if it is not 1 (the default) then it does its magic otherwise it will do nothing.
Code:
' if it is NOT the default value then do something with the property value
' otherwise do nothing
if not sysevent.newVal = 1 then
	' script magic goes here
end if

I quickly learned that you can't do this with an OnChange script that toggles a Boolean value! Thankfully, Premise has a recursion limit and won't recurse infinitely! An alert will popup and warn you that your flawed code just hit the recursion limit.

wooops! I see ckindt beat me to the post!
 
Finally solved it thanks to all of you. Here's how it works:

Create an Object Diagram. Drag in the multibutton switch. Then drag in an EQ function block, the scene or device you want affected by the button push, an On Delay block and finally the ChangeText block attached (simple scripts inside). Also see the Object Diagram below.

The logic is, the switch sends whatever message it does for the button pressed. It is captured in the upbNetworkData field. It goes to the EQ block. If it matches the number in the B field, it sets the result to True which triggers the bound device/scene. Then that triggers the On delay timer which triggers the ChangeText block which changes the A field in the EQ block to cleared. Phew.

Remember to change the extension on the Custom Logic Block XDO (remove the .txt)


4-1-08 : Changed image and XDO file. Think I've solved it. Please let me know if you have any issues.
 

Attachments

  • ChangeTextBlock.jpg
    ChangeTextBlock.jpg
    77.3 KB · Views: 50
  • ChangeText.xdo.txt
    2.8 KB · Views: 55
Well....
Just when you think you got it all figured out, something just ain't right. Seems that if I restart the Premise server, the Change Text block I created disappears from the diagram.

Anyone have any clue why that would happen????
 
Back
Top