|
Page 1 of 2
|
[ 29 posts ] |
Go to page: 1, 2 Next |
AD2USB parser? and modify variable based on info?
| Author |
Message |
|
hamw
Joined: Mar 31, 2008 Posts: 739
|
 AD2USB parser? and modify variable based on info?
I am getting an AD2USB ademco alarm interface. It would be good to be able to parse the strings that come from the unit so that one can know if the alarm has been properly set, disarmed, etc.
Unfortunately I know nothing about parsers except in the most general terms. Is there a standard applescript "parser formula" or script that one can just plug in the parameters of the string types that are received and what each specific string should represent?
For implementation I'm thinking, for instance, that if the string representing "alarm set - stay" is received, a trigger would fire changing an "alarm state" variable to "alarm set - stay", which could be displayed on a control page.
any thoughts/help would be appreciated!
|
| Thu Jun 10, 2010 2:11 pm |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 739
|
 Re: AD2USB parser? and modify variable based on info?
Berkinet posted the following on the NuTech forum:
************* The following message is what I see after sending the Arm-Stay sequence to my panel: Code: [010100011000--------],060,[f70000ff106002002c020000000000],"ARMED ***AWAY***May Exit Now 60" Sean's last post should point you towards the information you need to understand this message.
Regarding AppleScript. The issue is not as simple as just writing something in AppleScript, you need to know how to write AppleScripts that can be used by Serial-Bridge. I am sure that the only place you will find that kind of help will be on the Indigo Serial-Bridge forum. In the past there have been several discussions about using Serial-Bridge to parse a wide range of input formats. I have attached the sample script that is distributed with Serial-Bridge.
***************
looking at what is output by the board, the final section is all that is needed. It seems like it should be possible to simply ignore the preceeding comma delimited sections and capture/paste the text to a variable?
|
| Thu Jun 10, 2010 10:20 pm |
|
 |
|
berkinet
Joined: Nov 18, 2008 Posts: 1721 Location: Berkeley, CA
|
 Re: AD2USB parser? and modify variable based on info?
hamw wrote:For implementation I'm thinking, for instance, that if the string representing "alarm set - stay" is received, a trigger would fire changing an "alarm state" variable to "alarm set - stay", which could be displayed on a control page. !
If you only want to know the state of the alarm panel (armed or not) then you need only look at the first three positions in section 1 of the ad2usb message string. These are decoded as: 100 = READY 010 = ARMED AWAY 001 = ARMED HOME
|
| Fri Jun 11, 2010 11:25 am |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 739
|
 Re: AD2USB parser? and modify variable based on info?
Having the text display in a variable field is a lot more useful since WAF is of the essence.
|
| Fri Jun 11, 2010 11:57 am |
|
 |
|
berkinet
Joined: Nov 18, 2008 Posts: 1721 Location: Berkeley, CA
|
 Re: AD2USB parser? and modify variable based on info?
hamw wrote:Having the text display in a variable field is a lot more useful since WAF is of the essence.
I think you are confusing what is displayed on a Control Page with the series of actions that set the display. You want to do the following: 1) In Serial Bridge: Parse a message stream to determine what state your alarm is in. This is most easily done by testing a 3 byte string for 3 values (It is much easier to test a fixed length string with a small set of possible values than a longer string with many possible values). In pseudocode: - Code: Select all
if string is "100" then set an indigo variable to "Ready" elseif string is "010" then set an indigo variable to "Away" elseif string is "001" set an indigo variable to "Stay" else there is an error endif
2) Next, In Indigo (probably an embedded AppleScript) now that you have an Indigo variable which contains the current alarm state you can either display the variable's actual value, or use that value to select another more descriptive message. For example (again in pseudocode): - Code: Select all
if alarm_variable is "Ready" then set the DisplayMessage to "The alarm is disarmed" elseif alarm_variable is "Away" then set the DisplayMessage to "The alarm is ARMED AWAY" elseif etc. etc.
Of course, instead of displaying a text message, you could also display an image that indicated the alarm's state (even higher WAF).
|
| Fri Jun 11, 2010 12:29 pm |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 739
|
 Re: AD2USB parser? Serial Bridge Gurus help?
With a lot of patient help from Berkinet, Sean M and the guys over at the NuTech forum, the AD2USB is functioning correctly and I can now arm and disarm the Ademco from the iPhone. I'm hoping that we can get feedback working so that a variable can be modified to show the state of the alarm. It is my impression that the most basic approach would be to parse the alarm state (the first 3 numbers, 000=alarm off, 010=armed away, 001=armed away) and feed the value into a variable. The changed variable would initiate one of three triggers (alarm off, armed stay, armed away) which would set the iPhone displayed variable to the appropriate state. Could I ask for help from the Serial Bridge Gurus to hopefully put together a parser? Berkinet posted some ideas just above, and here's some info from Sean Matthews at the NuTech site: http://www.nutech.com/index.php?option= ... mitstart=0- Code: Select all
if not armed if ad2usbmessage.Substring(2,1) = '1' Announce "ARMED" armed = true end end
if armed if ad2usbmessage.Substring(2,1) = '0' Announce "DISARMED" armed = false end end
The basic idea is you can determin ARMED home/away etc by just looking at the 0 or 1 in section #1
Section #1 is provided by ad2usb by parsing the data as shown in section #3 or the raw panel data. Section #4 is your "TEXT" data as seen on your alpha keypads. It can vary from panel to panel but most standard messages are the same like a zone fault.
I did start reading up on indigo and Apple Script last night to see what issues exist. Seems like version 5 will solve lots of the extensibility issues with the embedded python scripting.
and some info re the datastream: - Code: Select all
Firmware documentation V1.0f.24
Output Format All lines that start with ! are information All other lines are real panel data or debug ( see @ keyboard command ) Each line ends with a CR LF also known as rn or chr(10),chr(13)
In a normal panel output message the data has 4 sections.
Section #1 the bit fields easy to parse interpretations of the raw panel code. Each bit can be one of three states. 0 = Off 1 = On - = Unknown or float Example: [01010001000---------] Position #1 = READY Position #2 = ARMED AWAY Position #3 = ARMED HOME Position #4 = BACK LIGHT Position #5 = Programming Mode Position #6 = Beep 1-3 ( 3 = beep 3 times ) Position #7 = A ZONE OR ZONES ARE BYPASSED Position #8 = AC Power Position #9 = CHIME MODE Position #10 = ALARM WAS TRIGGERED (Sticky Bit) Position #11 = ALARM BELL Position #12 = BATTERY LOW Position #13 - #20 unused
Section #2 Numeric indicator if message is zone 3 fault this will be 03
Section #3 Raw panel binary message data Example: [f70000000000800c0c020000] This is the raw panel binary message data.
Section #4 Alpha Keypad Message Example: "****DISARMED**** ZONES FAULTED " This is in quotes and is the message that is displayed on an alpha keypad.
Here is a full message from a vista 50p
[01000001000---------],e5,[f707000600e5800c0c020000],"ARMED ***AWAY***** ALL SECURE **" [001000010000--------],10,[f70700060010808c08020000],"ARMED ***STAY** ZONE BYPASSED "
Keyboard Commands = reboot $ oscilloscope watching the DO line #1 @ Diagnostic bit setting #2 % 4800 baud hard switch ^ 2400 baud hard switch ! Configure device
#1 only available on revision 1.5 carrier mod wires can be used to revise a 1.0 board to a 1.5 board but require a very steady hand to wire onto the small chip on the bottom of the board.
#2 Diagnostic bits must be entered as base 10 values 1 Start bit ( will trigger a strobe on PIN C0 when a start bit is detected on the software UART). 2 Stop bit ( will trigger a strobe on PIN C0 when a stop bit is detected on the software UART). 4 Parity bit ( will trigger a strobe on PIN C0 when a parity bit is detected on the software UART). 8 Data bit ( will trigger a strobe on PIN C0 when a data bit is detected on the software UART). 16 Raw RX Data dump will dump raw data as seen by the software uart to the serial port on the DO line of the panel. 32 Raw TX Data dump will dump raw data as seen by the software uart to the serial port on the DI line of the panel. 64 Error bit will strobe PIN C0 when a framing error is detected by the software UART. 128 Will strobe PIN C1 ever time our UART interrupt fires. 256 Will strobe PIN C0 when we detect the DO line has produced a LONG HIGH state as part of the polling window monitoring. 512 Will strobe PIN C0 when we detect our first low state on the DO line. 1024 Will output the size of the polling window to the serial port.
Thanks very much!!
Last edited by hamw on Fri Jul 09, 2010 1:21 pm, edited 1 time in total.
|
| Sat Jun 19, 2010 9:14 am |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 739
|
 Re: AD2USB parser? and modify variable based on info?
Deleted this stuff as it was not the right approach. See next post.
Last edited by hamw on Fri Jul 09, 2010 1:21 pm, edited 2 times in total.
|
| Tue Jul 06, 2010 7:24 pm |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 739
|
 Re: AD2USB parser? and modify variable based on info?
Am slowwwwwly figuring something out. I pinched the following script from the DSC security alarm script ( viewtopic.php?f=6&t=875&start=15) and modded it a little. It actually appears to work a bit, as it updates two variables, alarmstate and alarmserial, but just once and then hangs. The problem is a -2753 error which I think is at the "set value" section--the "value" remains in purple once compiled. What should be there? I tried "state" but that just threw another code. set value of variable "alarmstate" to commandDescription set value of variable "alarmserial" to commandString Also, I'd like to capture the final bits of the description as here: [01000001000---------],e5,[f707000600e5800c0c020000],"ARMED ***AWAY***** ALL SECURE **" that give the state directly, basically char 52 on. I tried "set commandData to (characters 60 through -3 of commandString as string)" but no luck. I think I need to somehow account for the commas? - Code: Select all
----------- --
(* --Serial process script for Serial Bridge --by M. Bendikson --mods by dtich --mods by HFTobeason
--This script reads Hex message data broadcast from a DSC PC4401 serial interface board and logs the parsed value to IndigoServer, repeating until fatal error. *)
property commandString : "" property commandCodes : {"100 Disarmed", "010 Armed Away", "001 Armed Stay"}
on MyProcessSerialData(connectionName) tell application "Serial Bridge" -- this will block until at least 1 byte is available wait for data from source connectionName set byteRead to read byte from source connectionName if byteRead is 13 or byteRead is 10 then -- CR=Hex 0D=ASCII 13 / LF=Hex 0A=ASCII 10 if commandString is not "" then set commandDescription to my MyParse(characters 2 through 4 of commandString as string) set commandData to (characters 60 through -3 of commandString as string) tell application "IndigoServer" -- set value of variable "alarmstate" to commandDescription set value of variable "alarmstate" to commandDescription set value of variable "alarmserial" to commandString -- set value of variable "alarmserial" to commandString end tell set commandString to "" end if else set charRead to ASCII character byteRead set commandString to commandString & charRead end if end tell end MyProcessSerialData
on startCommunication(connectionName) tell application "Serial Bridge" try set bufferDumpStr to (read string from source connectionName) log "dumping rs232 buffer: " & bufferDumpStr end try -- Loop forever: wait for data, read it, process it, and optionally send -- out serial data. -- -- We do not want our script to return or exit since Serial Bridge -- only calls our script on launch (or when the Reload Script button -- is pressed). repeat while true try set maxTimeoutDelay to 8947848 -- 103.56 days (hex 0x00888888) with timeout of maxTimeoutDelay seconds my MyProcessSerialData(connectionName) end timeout on error number errNum if errNum is -1712 then log "timeout waiting for serial data" using type "Error" else if errNum is -1708 then log "AppleEvent not handled" using type "Error" --return -- fatal error; exit script processing else if errNum is -128 then log "connection script aborted" using type "Error" return -- fatal error; exit script processing else log "error " & errNum & " inside MyProcessSerialData()" using type "Error" --return -- maybe fatal error; exit script processing end if end try end repeat end tell end startCommunication
on MyParse(commandString) repeat with x from 1 to count of commandCodes if word 1 of item x of commandCodes is commandString then return (characters 5 through -1 of item x of commandCodes as string) end if end repeat end MyParse (* The above read verbs all have an optional argument, "timeout after", * to specify how long to wait in milliseconds for the data if it is not * currently available. If no timeout argument is present, then a * timeout error will be immediately thrown if there is not enough * data present to fulfill the request. *)
----------------------------------------------------------------------------- (* To send data use the "send to source" verb. You can either send * a single byte, multiple bytes as a list, or a string. To send a single byte: *)
Thanks again for any advice!
|
| Thu Jul 08, 2010 9:04 pm |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 739
|
 Re: AD2USB parser? and modify variable based on info?
Might be part of the issue here. When Terminal is reading the AD2USB with nothing going on, the lines come in very regularly: - Code: Select all
[100000011000--------],0c0,[f704000000c0001c28021f00000000],"****DISARMED**** READY TO ARM " [100000011000--------],018,[f71300000018001c28021f00000000],"****DISARMED**** READY TO ARM " !Sending.done [001100011000--------],018,[f71300000018038c28021f00000000]," ARMED STAY 1 ZONE BYPASSED " [100000011000--------],0c0,[f704000000c0001c28021f00000000],"****DISARMED**** READY TO ARM " [001100011000--------],018,[f71300000018008c28021f00000000]," ARMED STAY 1 ZONE BYPASSED " [100000011000--------],0c0,[f704000000c0001c28021f00000000],"****DISARMED**** READY TO ARM "
However, as soon as the Serial Bridge connection is turned on, the lines go completely out of order, missing characters and running together: - Code: Select all
[100000011000--------],018,[f71300000018001c28021f00000000],"****DISARMED**** READY TO ARM " [100000011000--------],0c0,[f704000000c0001c28021f00000000],"****DISARMED**** READY TO ARM " 000-------],018180000[100000011000--------],0c0,[2802000000],"****DISA" --------],018,[f70000180028021f00" [100000011000--------],0c0,[0000c01f000000],"****DISARMED**** READY TO ARM --------],0181300001800000011000--------],0c0,[f704000000c000281f00000000],"****DISARMED**** READY TO ARM [100000011000018,[f7130000001800],"****DISARMED**** READY TO ARM " 0011000--------],0c0,[f704000000c000021f00],"****DISARMED**** READY TO ARM " [100000011000--------],18,[f71800000000],"****DISARMED**** READY TO ARM --------],0c0,[f70400001c],"****DISARME" --------],0180000128021f],"****DISARMED**** READY TO ARM " 0011000--------],0c0f70000c00000000000],"****DISARMED**** READY TO ARM " [100000011000--------],018,[f71300000018001c28021f00000000],"****DISARMED**** READY TO ARM " [100000011000--------],0c0,[f704000000c0001c28021f00000000],"****DISARMED**** READY TO ARM "
So although the parser does work, perhaps it is not possible to parse this particular data stream given the effects of SB on its format. The parser is looking for specific sequences, and when it sees different sequences because all the characters are out of sequence, it throws an error. If the parser could recognize the pattern when the datastream is giving the panel alphanumeric reading, maybe it could then capture that specific information to put in the variable. It might be suggested that the Terminal connection and the SB connection can't be on at the same time, and that's why the lines are out of whack, but even with the Terminal connection closed the parser hangs shortly after it begins.
|
| Sat Jul 10, 2010 3:55 pm |
|
 |
|
berkinet
Joined: Nov 18, 2008 Posts: 1721 Location: Berkeley, CA
|
 Re: AD2USB parser? and modify variable based on info?
The problem you are seeing has to do with synchronization. The alarm messages are of fixed length, but for some reason, a message may not be sent all at once. This results in a single logical message being spread across two physical (\n separated) lines. You need to get the lines back together again. Here is an example, simplified for this discussion, that I wrote in Perl. We start by reading an alarm message into $string, then: - Code: Select all
$inString = $inString . $string; if ($inString =~ /\n/) { @strings = split(/\n/, $inString, 2); $rawData = @strings[0]; $inString = @strings[1]; $inString =~ s/\n//g; }
In English, it does... - Code: Select all
concatenate (join) whatever we have saved in $inString with the message just read ($string) If the message ($inString) contains a newline (\n), then split the message into 2 parts at the newline character call part 1 $rawData call part 2 $inString (replacing the old value of $inString) remove any newlines from $inString Continue processing using the data saved in $rawData and any leftover data ($inString) will be added to the front of the next message read, etc, etc.
You will need to do something like this in AppleScript. I couldn't find a convenient example, maybe someone else on here has one, or can provide you with a few pointers - otherwise I'll see if I can put something together.
Last edited by berkinet on Sun Jul 11, 2010 6:28 pm, edited 1 time in total.
|
| Sat Jul 10, 2010 4:34 pm |
|
 |
|
berkinet
Joined: Nov 18, 2008 Posts: 1721 Location: Berkeley, CA
|
 Re: AD2USB parser? and modify variable based on info?
BTW, You will also need to filter out lines that are generated by the ad2usb alarm interface. These trpically start with "!"
|
| Sat Jul 10, 2010 4:36 pm |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 739
|
 Re: AD2USB parser? and modify variable based on info?
stripping most of the stuff from the connection script as here: - Code: Select all
on MyProcessSerialData(connectionName) tell application "Serial Bridge" wait for data from source connectionName to count 60 set restOfString to read string from source connectionName log "rest of string = " & restOfString using type "Sample" end tell end MyProcessSerialData
yields more organized data, which appears to begin as it should on each line. Even the motion detector triggering did not upset it. I tried to incorporate "sample" instead of byteread into the parsing script but got lots of errors. Characters 2-4, 100 or 010 or 001 following Sample rest of string = "
represent the alarm state which the parser recognizes to update the variable. Capturing characters might help get us on the right track? - Code: Select all
11Jul, 2010 7:39:35 PM Sample rest of string = " [100000011000--------],0c0,[f704000000c0001c28021f00000000],"****DISARMED**** READY TO ARM Sample rest of string = " [100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM
11Jul, 2010 7:39:47 PM Sample rest of string = " [100000011000--------],0c0,[f704000000c0001c28021f00000000],"****DISARMED**** READY TO ARM " [100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM "
Sample rest of string = [100000011000--------],0c0,[f704000000c0001c28021f00000000],"****DISARMED**** READY TO ARM "
11Jul, 2010 7:39:56 PM Sample rest of string = [100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM " [100000011000--------],0c0,[f704000000c0001c28021f00000000],"****DISARMED**** READY TO ARM "
Sample rest of string = [100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM "
11Jul, 2010 7:40:02 PM Sample rest of string = !RFX:0216067,04 [100000011000--------],0c0,[f704000000c0001c28021f00000000
11Jul, 2010 7:40:04 PM Sample rest of string = ],"****DISARMED**** READY TO ARM " [100000011000--------],029,[f71300 Sample rest of string = 000029001c28021f00000000],"****DISARMED**** READY TO ARM "
11Jul, 2010 7:40:09 PM Sample rest of string = [100000011000--------],0c0,[f704000000c0001c28021f00000000],"****DISARMED**** READY TO ARM "
11Jul, 2010 7:40:13 PM Sample rest of string = [100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM " [000000011000--------],029,[f71300000029000028021f00000000],"FAULT 029 2ND FLOOR MOTION "
11Jul, 2010 7:40:16 PM Sample rest of string = [100000011000--------],0c0,[f704000000c0001c28021f00000000],"****DISARMED**** READY TO ARM "
Last edited by hamw on Mon Jul 12, 2010 5:58 am, edited 1 time in total.
|
| Sun Jul 11, 2010 5:49 pm |
|
 |
|
berkinet
Joined: Nov 18, 2008 Posts: 1721 Location: Berkeley, CA
|
 Re: AD2USB parser? and modify variable based on info?
Waiting for the data may seem to help at first, but, the problem you will eventually run into is that message frequency seems to increase linearly with the number of faulted zones. While a system in "Ready to Arm" state may send a message every 6 to 10 seconds, when you have the doors open on a nice day, or for a party, etc. and 4 or 5 zones are faulted, the messages arrive every second or faster. And, don't forget, you will also be getting raw messages like:"!RFX:0670107,80" from the RF sensors.
Unless you add code to track and "repair" the message chunks, or figure out some other way of guaranteeing that you always get complete messages, your system is bound to give un-predictable results.
|
| Sun Jul 11, 2010 6:14 pm |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 739
|
 Re: AD2USB parser? and modify variable based on info?
In copying the DSC script the basics were made a bit more complicated. At a minimum only "alarm state" is needed, so the section: - Code: Select all
if commandString is not "" then set commandDescription to my MyParse(characters 2 through 4 of commandString as string) set commandData to (characters 60 through -3 of commandString as string) tell application "IndigoServer" -- set value of variable "alarmstate" to commandDescription set value of variable "alarmstate" to commandDescription set value of variable "alarmserial" to commandString -- set value of variable "alarmserial" to commandString end tell set commandString to "" end if
can be reduced to: - Code: Select all
if commandString is not "" then set commandDescription to my MyParse(characters 2 through 4 of commandString as string) tell application "IndigoServer" set value of variable "alarmstate" to commandDescription end tell set commandString to "" end if
if that simplifies matters.
|
| Sun Jul 11, 2010 9:33 pm |
|
 |
|
berkinet
Joined: Nov 18, 2008 Posts: 1721 Location: Berkeley, CA
|
 Re: AD2USB parser? and modify variable based on info?
hamw wrote:...if that simplifies matters.
That simplifies the pattern matching to determine the alarm state. However, if the string you are looking for is not in the right position (chars 2-4) in the message string (because the messages are mixed together), then you cannot easily find the information you are looking for.
|
| Sun Jul 11, 2010 9:55 pm |
|
|
|
Page 1 of 2
|
[ 29 posts ] |
Go to page: 1, 2 Next |
Who is online |
Users browsing this forum: Google [Bot] and 0 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|