|
Page 2 of 2
|
[ 29 posts ] |
Go to page: Previous 1, 2 |
AD2USB parser? and modify variable based on info?
| Author |
Message |
|
hamw
Joined: Mar 31, 2008 Posts: 738
|
 Re: AD2USB parser? and modify variable based on info?
Berkinet, thanks for following the thread and defining the problem. Am hoping we can get some feedback on how to incorporate these ideas into applescript.
|
| Mon Jul 12, 2010 6:04 am |
|
 |
|
matt (support)
Site Admin
Joined: Jan 27, 2003 Posts: 11689 Location: Texas
|
 Re: AD2USB parser? and modify variable based on info?
Your original mod to the DSC script looks more correct to me. Specifically, it should handle the synchronization correctly because it scans until it hits the new line character. So the basic pseudo code is: - Code: Select all
wait indefinitely for an incoming character if character is a new line character, then we know we are done with this line so process it. else add character to our character line buffer for processing later.
It isn't clear to me what exactly was going wrong or where. I think the problem may have been when MyParse doesn't find a match and doesn't return anything, which I believe I've fixed (below) to work better. I've modified the script to include the original new line scanning that was removed, some of your latter changes, a check for string lengths before parsing, and some additional debugging. Try this, and let me know what the Serial Bridge Event Log output is: - Code: Select all
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 log "trying to parse commandString: " & commandString if length of commandString < 4 then log "commandString length too short to parse" else set commandDescription to my MyParse(characters 2 through 4 of commandString as string) if commandDescription is not "" then log "commandString found matching code; setting Indigo variable value" tell application "IndigoServer" set value of variable "alarmstate" to commandDescription end tell else log "commandString no matching code found" end if end if 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 return "" 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: *)
_________________
|
| Mon Jul 12, 2010 8:02 pm |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 738
|
 Re: AD2USB parser? and modify variable based on info?
Matt, that's great! It works! Thank you very much! So check this out- I concatenated the alarm state and the partition state (char 30-31, with 70 representing garage and 71 representing house), and modified the parser values. So, now the variable will cycle between the states of the garage and the house. - Code: Select all
property commandString : "" property commandCodes : {"10071 House Disarmed", "01071 House Armed Away", "00171 House Armed Stay", "10070 Garage Disarmed", "01070 Garage Armed Away", "00170 Garage 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 log "trying to parse commandString: " & commandString if length of commandString < 4 then log "commandString length too short to parse" else set nameofstate to (characters 2 through 4 of commandString as string) set nameofpartition to (characters 30 through 31 of commandString as string) set commandDescription to my MyParse(nameofstate & nameofpartition) if commandDescription is not "" then log "commandString found matching code; setting Indigo variable value" tell application "IndigoServer" set value of variable "alarmstate" to commandDescription end tell else log "commandString no matching code found" end if end if set commandString to "" end if else set charRead to ASCII character byteRead set commandString to commandString & charRead end if end tell end MyProcessSerialData
I would like it to put the house and garage results in separate variables. Tried this but would not get past end tell. Thoughts? - Code: Select all
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 log "trying to parse commandString: " & commandString if length of commandString < 4 then log "commandString length too short to parse" else set nameofstate to (characters 2 through 4 of commandString as string) set nameofpartition to (characters 30 through 31 of commandString as string) set commandDescription to my MyParse(nameofstate & nameofpartition) if commandDescription is not "" then log "commandString found matching code; setting Indigo variable value" tell application "IndigoServer" if nameofpartition is "71" -- (these lines are what I added) set value of variable "housestate" to commandDescription else set value of variable "garagestate" to commandDescription end tell -- (won't go past here) else log "commandString no matching code found" end if end if set commandString to "" end if else set charRead to ASCII character byteRead set commandString to commandString & charRead end if end tell end MyProcessSerialData
Many thanks again!
|
| Mon Jul 12, 2010 9:59 pm |
|
 |
|
matt (support)
Site Admin
Joined: Jan 27, 2003 Posts: 11689 Location: Texas
|
 Re: AD2USB parser? and modify variable based on info?
You were missing an "end if". - Code: Select all
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 log "trying to parse commandString: " & commandString if length of commandString < 4 then log "commandString length too short to parse" else set nameofstate to (characters 2 through 4 of commandString as string) set nameofpartition to (characters 30 through 31 of commandString as string) set commandDescription to my MyParse(nameofstate & nameofpartition) if commandDescription is not "" then log "commandString found matching code; setting Indigo variable value" tell application "IndigoServer" if nameofpartition is "71" -- (these lines are what I added) set value of variable "housestate" to commandDescription else set value of variable "garagestate" to commandDescription end if end tell -- (won't go past here) else log "commandString no matching code found" end if end if set commandString to "" end if else set charRead to ASCII character byteRead set commandString to commandString & charRead end if end tell end MyProcessSerialData
_________________
|
| Tue Jul 13, 2010 10:13 am |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 738
|
 Re: AD2USB parser? and modify variable based on info?
Could not get the above script, which would hopefully put the house alarm and garage alarm states into separate variables, to work. When it starts it is fine except for a -10006 code. But, after setting the alarm the script loses its place and stops updating. - Code: Select all
115Jul, 2010 10:48:33 PM Loaded script "AD2USB/script.scpt"
15Jul, 2010 10:48:36 PM Script trying to parse commandString: [100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM " Script commandString found matching code; setting Indigo variable value Error error -10006 inside MyProcessSerialData() Script trying to parse commandString: [100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM " Script commandString found matching code; setting Indigo variable value Error error -10006 inside MyProcessSerialData()
15Jul, 2010 10:48:43 PM Script trying to parse commandString: [100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM "[100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM " Script commandString found matching code; setting Indigo variable value Error error -10006 inside MyProcessSerialData() Script trying to parse commandString: [100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM "[100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM " Script commandString found matching code; setting Indigo variable value Error error -10006 inside MyProcessSerialData() Script trying to parse commandString: [100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM "[100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM "[100000011000--------],023,[f70400000023001c28021f00000000],"****DISARMED**** READY TO ARM " Script commandString found matching code; setting Indigo variable value Error error -10006 inside MyProcessSerialData() Script trying to parse commandString: [100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM "[100000011000--------],029,[f71300000029001c28021f00000000],"****DISARMED**** READY TO ARM "[100000011000--------],023,[f70400000023001c28021f00000000],"****DISARMED**** READY TO ARM " Script commandString found matching code; setting Indigo variable value Error error -10006 inside MyProcessSerialData()
A workaround script (posted below) will cycle the state of the partitions in a variable, alarmstate, and also cycle the keypad alpha data into another variable, alarmdisplay. That is really really good and we could, if necessary, stop here. The problem is that the data takes a while to update - not to mention some WAF confusion. Would be much better to have separate variables for garage and house that update independently, if that is possible. Could you look at the script above and see if there is an error? - Code: Select all
property commandString : "" property commandCodes : {"10071 House Disarmed", "01071 House Armed Away", "00171 House Armed Stay", "10070 Garage Disarmed", "01070 Garage Armed Away", "00170 Garage Armed Stay", "RFX Command"}
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 log "trying to parse commandString: " & commandString if length of commandString < 25 then log "commandString length too short to parse" else set nameofstate to (characters 2 through 4 of commandString as string) set nameofpartition to (characters 30 through 31 of commandString as string) set commandData to (characters 63 through -1 of commandString as string) set commandDescription to my MyParse(nameofstate & nameofpartition) if commandDescription is not "" then log "commandString found matching code; setting Indigo variable value" tell application "IndigoServer" set value of variable "alarmstate" to commandDescription set value of variable "alarmdisplay" to commandData end tell else log "commandString no matching code found" end if end if 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 7 through -1 of item x of commandCodes as string) end if end repeat return "" 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. *)
one other thing....  any suggestions for how to parse this bit of data representing an RF transmitting sensor with the above script? The identifying numbers for the house vs garage are at positions 30 and 31, beyond the length of the RFX. I tried including a code in "commandcodes" , showing RFX space space then Command to represent receipt of an RFX command. However, eventually I'd like to be able to parse the RFX codes too. Can one have two parsers running at the same time? 15Jul, 2010 11:00:34 PM Script trying to parse commandString: !RFX:0987038,84
|
| Thu Jul 15, 2010 9:00 pm |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 738
|
 Re: AD2USB parser? and modify variable based on info?
OK this script will parse the garage and house states and displays into separate variables. The error in my prior script was in not realizing that commandDescription is the product of myParse. MyParse is the translated codes, so instead of "contains "71" " it should have been "contains "House" " Although I can now see how "if..then...else...end if" can discriminate between two variables. how does one get a third choice, eg the RFX, which is not only too short to parse but has no character at 30 and 31? - Code: Select all
-- Sample connection attachment script for Serial Bridge. -- -- This script, if it is in the same folder as the Serial Bridge database settings -- file (it is by default), will automatically be loaded and launched when Serial -- Bridge is launched. It will be terminated and reloaded whenever any serial -- port settings change for this connection, or if the Reload button is pressed. -- -- MyProcessSerialData() below contains sample code you can modify to -- wait for serial data, read serial data, send serial data, and log information -- to the Serial Bridge log window. -- -- The entry point into this file is startCommunication(). Although -- documentation is provided below for both functions; you will probably -- only need to modify MyProcessSerialData(). -- -- 2005-03-29 Original. (Matt Bendiksen) -- 2005-04-01 Fixed event timeout bugs. (Matt Bendiksen)
----------- --
(* --Serial process script for Serial Bridge --by M. Bendikson --mods by dtich --mods by HFTobeason --mods by hamw for Ademco
--This script reads Hex message data broadcast from an Ademco Vista 128 and logs the parsed value to IndigoServer, repeating until fatal error. The script was initially used to parse the DTC serial board. *) property commandString : "" property commandCodes : {"10071 House Disarmed", "01071 House Armed Away", "00171 House Armed Stay", "10070 Garage Disarmed", "01070 Garage Armed Away", "00170 Garage Armed Stay", "RFX Command"}
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 log "trying to parse commandString: " & commandString if length of commandString < 25 then log "commandString length too short to parse" else set nameofstate to (characters 2 through 4 of commandString as string) set nameofpartition to (characters 30 through 31 of commandString as string) set commandData to (characters 62 through -1 of commandString as string) set commandDescription to my MyParse(nameofstate & nameofpartition) if commandDescription is not "" then log "commandString found matching code; setting Indigo variable value" tell application "IndigoServer" if commandDescription contains "House" then set value of variable "AlarmHouseState" to commandDescription set value of variable "AlarmHouseDisplay" to commandData else set value of variable "AlarmGarageState" to commandDescription set value of variable "AlarmGarageDisplay" to commandData end if end tell else log "commandString no matching code found" end if end if 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 7 through -1 of item x of commandCodes as string) end if end repeat return "" 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: *)
----------- -- Serial Bridge will call the startCommunication() subroutine after it has opened -- the serial port connection for this connection. It is only called after the serial -- port connection has been opened, shortly after Serial Bridge launches or if -- the user presses the Reload Script button. -- -- The argument, connectionName, is a string used to identify this serial port -- connection, and will always be the folder name in which this script (and -- database settings file) resides. This value should be passed to all read, write, -- and wait serial functions to identify which serial port connection the script is -- using. --
|
| Mon Jul 19, 2010 9:31 pm |
|
 |
|
berkinet
Joined: Nov 18, 2008 Posts: 1721 Location: Berkeley, CA
|
 Re: AD2USB parser? and modify variable based on info?
hamw wrote:...Although I can now see how "if..then...else...end if" can discriminate between two variables. how does one get a third choice, eg the RFX, which is not only too short to parse but has no character at 30 and 31?
You will need to start by modifying your parse function. Right now you simply discard any lines that are less than 25 characters. But, if you look at your data, you really have two record types you are interested in: [000000011000--------],024,[f70000ff10240000280200000010f0],"FAULT 24 MAIDS HALL DOOR " = 94 characters !RFX:0576564,24 = 15 characters long So, you might take an approach like (pseudo-code): if we have record type one, then parse a regular alarm message or else, if we have record type 2, then parse an "RFX" message There are a lot of ways to differentiate your record types, text pattern matching would work well. But, to keep things simple, I'd suggest you just use line lengths. Sort of like: if length of commandString = 94 then ... else if length of commandString = 15 then ... else, we have something we don't want. Give that a try and report back how it goes.
|
| Mon Jul 19, 2010 11:05 pm |
|
 |
|
alistair
Joined: Jul 14, 2006 Posts: 88
|
 Re: AD2USB parser? and modify variable based on info?
Guys, I've been following this thread with interest - I'm in the process of moving my HomeSeer system (with AD2USB) over to Indigo.
Any chance you can share your latest script?... I'm happy to contribute back to the group any changes / fixes / improvements I make?
Best, -Alistair
|
| Sun Aug 15, 2010 8:24 pm |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 738
|
 Re: AD2USB parser? and modify variable based on info?
If you don't have a garage or something else on another partition with a different keypad and code, use the second script from the July 15 post above. Set up your variables and it should work, as long as you have communication with the AD2USB via Serial Bridge.
|
| Sun Aug 15, 2010 9:08 pm |
|
 |
|
alistair
Joined: Jul 14, 2006 Posts: 88
|
 Re: AD2USB parser? and modify variable based on info?
Great, thanks  Forgive the dump question but what speed/parity did you configure Serial bridge with for the AD2USB port? (I have the driver working OK, it's the speed settings I'm unsure of) -A
|
| Sun Aug 15, 2010 10:31 pm |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 738
|
 Re: AD2USB parser? and modify variable based on info?
19200, 1, none, none
Set up variables based on the script. Modify those variables (e.g. delete alarmstategarage etc if not using) so the script doesn't throw an error. Not necessary but you can delete the parsing commands you won't use up top - check your output to be sure you whether are getting a 71 or 70 in the AD2USB output and delete others. Make a control page with the variables in it and see what happens.
|
| Mon Aug 16, 2010 6:22 am |
|
 |
|
bbruck
Joined: Oct 05, 2008 Posts: 228
|
 Re: AD2USB parser? and modify variable based on info?
hamw and berkinet -
Thanks for all the hard work you've put in on this.
I have a script working now that pass the alarm display and alarm state to Indigo.
Can anyone assist with two questions?
1. How do I auto-start serial bridge AND open the appropriate connection (which I cleverly named AD2USB)?
2. Can someone point me to how to record the current state of each zone in an Indigo variable??
|
| Sun Apr 17, 2011 7:14 am |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 738
|
 Re: AD2USB parser? and modify variable based on info?
1. To automatically launch SB, go to system preferences/login items. Click the plus sign and add Serial Bridge. It will now auto start on login with the last items you had open. So, if you have your AD2USB folder open and then close SB, the next time you open it, AD2USB will automatically open and connect. So, that also means that if you close AD2USB and then quit SB, the next time you open SB, AD2USB will not open. I also have my SB set to hide after opening.
2. Not sure on the zones. I assume you are not talking about just updating variables with the alarm status?
Glad you found the script useful! Hopefully the instructions were clear otherwise.
|
| Sun Apr 17, 2011 7:26 am |
|
 |
|
hamw
Joined: Mar 31, 2008 Posts: 738
|
 Re: AD2USB parser? and modify variable based on info?
In looking over this thread, I didn't see a link to the write up I did on the AD2USB install. It may also be helpful, and contains the most current code. http://www.perceptiveautomation.com/wiki/doku.php?id=security_script
|
| Sun Apr 17, 2011 7:43 am |
|
|
|
Page 2 of 2
|
[ 29 posts ] |
Go to page: Previous 1, 2 |
Who is online |
Users browsing this forum: No registered users 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
|
|