First Module Please Help
mncchartier
Posts: 68
I have not yet gone to the training yet and I have some basic programming mainly AutoIt scripts. So I already know I have a system that is coming up that has 10 Leviton ViziaRF switches, this is all they want the system to control, via RS-232. So I am writing a module for this just incase I need it again I can just modify it if I need to go over 10 switches. I will be adding in scenes latter on when I get my hands on the system. So what I did was create 3 arrays for One array is all 10 of the Bright buttons, another for the Dim, and another for an On/Off toggle button. The buttons are numbered xzz, x = function (Bright, Dim, Toggle) zz = zone. Here is where I am at now. I know I probably have the Define Device of the RS-232 module set wrong. Any insight would be great.
Source
Module
I just notice that I get a syntax error when compiling the module, at the Toggle button, so I am looking at that right now
Source
PROGRAM_NAME='Vizia Test' (***********************************************************) DEFINE_DEVICE dvTP = 128:1:0 DEFINE_VARIABLE //Format is 1 = Bright and then the zone (switch) number upto 11 DEVCHAN dcViziaBright[] = { {dvTP, 12}, {dvTP, 13}, {dvTP, 14}, {dvTP, 15}, {dvTP, 16}, {dvTP, 17}, {dvTP, 18}, {dvTP, 19}, {dvTP, 110}, {dvTP, 111} } //Format is 2 = Dim and then the zone (switch) number upto 11 DEVCHAN dcViziaDim[] = { {dvTP, 22}, {dvTP, 23}, {dvTP, 24}, {dvTP, 25}, {dvTP, 26}, {dvTP, 27}, {dvTP, 28}, {dvTP, 29}, {dvTP, 210}, {dvTP, 211} } //Format is 3 = Toggle On/Off and then the zone (switch) number upto 11 DEVCHAN dcViziaToggle[] = { {dvTP, 32}, {dvTP, 33}, {dvTP, 34}, {dvTP, 35}, {dvTP, 36}, {dvTP, 37}, {dvTP, 38}, {dvTP, 39}, {dvTP, 310}, {dvTP, 311} } DEFINE_START DEFINE_MODULE 'ViziaRF' md1ViziaModule(dcViziaBright, dcViziaDim, dcViziaToggle)
Module
MODULE_NAME='ViziaRF' (DEVCHAN dcViziaBright[], DEVCHAN dcViziaDim[], DEVCHAN dcViziaToggle[]) DEFINE_DEVICE dvViziaRF = 1:7:0 DEFINE_VARIABLE INTEGER nSwitch INTEGER nFunc INTEGER nStatus DEFINE_EVENT BUTTON_EVENT[dcViziaBright] { PUSH: IF (BUTTON.INPUT.CHANNEL < 100){ SEND_COMMAND dvViziaRF, "'>N',ITOA(BUTTON.INPUT.CHANNEL-10),'BI'" } ELSE { SEND_COMMAND dvViziaRF, "'>N',ITOA(BUTTON.INPUT.CHANNEL-100),'BI'" } } BUTTON_EVENT[dcViziaDim] { PUSH: IF (BUTTON.INPUT.CHANNEL < 200){ SEND_COMMAND dvViziaRF, "'>N',ITOA(BUTTON.INPUT.CHANNEL-20),'DI'" } ELSE { SEND_COMMAND dvViziaRF, "'>N',ITOA(BUTTON.INPUT.CHANNEL-200),'DI'" } } BUTTON_EVENT[dcViziaToggle] { PUSH: IF (BUTTON.INPUT.CHANNEL < 300) { SEND_COMMAND dvViziaRF, "'>?N',ITOA(BUTTON.INPUT.CHANNEL-30)} = nStatus IF (nStatus <> 0) {SEND_COMMAND dvViziaRF, "'>N',ITOA(BUTTON.INPUT.CHANNEL-30), 'OF'"} ELSE {SEND_COMMAND dvViziaRF, "'>N',ITOA(BUTTON.INPUT.CHANNEL-30), 'ON'"} ELSE { SEND_COMMAND dvViziaRF, "'>N',ITOA(BUTTON.INPUT.CHANNEL-300)} = nStatus IF (nStatus <> 0) {SEND_COMMAND dvViziaRF, "'>N',ITOA(BUTTON.INPUT.CHANNEL-300), 'OF'"} ELSE {SEND_COMMAND dvViziaRF, "'>N',ITOA(BUTTON.INPUT.CHANNEL-300), 'ON'"} }
I just notice that I get a syntax error when compiling the module, at the Toggle button, so I am looking at that right now
0
Comments
That being said, here's your toggle event all bracketed out . . . you should be able to find the problem MUCH easier.
= find the needle = find the haystack
I'm curious, what are you trying to do here?
Get the value of the switch gives the dimmer percentage 0 is off and set the variable to this value. the command to do this is >?N1 would do node (switch) 1
You're making the same mistakes that I made when I first started programming.
SEND_COMMANDs are meant for virtual / AMX devices
SEND_STRINGS are meant for real devices
So, to send the "command" to the device, you'll need to use SEND_STRING instead of SEND_COMMAND.
Next, you'll need to parse the received data. So, you're going to need a whole new section: the DATA_EVENT section. You'll assign nStatus there. But since 99.99% of devices can't respond faster than the processor, you're going to need to wait until you get a response back before proceeding with what to do with the answer.
See if that makes sense....
I understand that now I just looked at some other modules. Now the question that rises up is that I am using the BUTTON.INPUT.CHANNEL to figure out the switch number am I able to set a variable in the BUTTON_EVENT to the zone and pass that to the DATA_EVENT, not sure if I am going about this the right way.
It appears you're parsing the virtual device and not the real device. Is the real device dvViziaRF?
Next..... Without defining the size of each CHAR variable, they'll only be one character long. Need to do something like this: Not sure how big your variables need to be, so increase or decrease them accordingly. And I would use INTEGERs rather than CHARs for nStatus & nNode. See below.
Next... First, the incoming data is already "ASCII", so there's no need to convert it. ITOA is converting an INTEGER to an ASCII (or CHAR) variable. What you'll probably want to do is capture the entire string and manipulate it from there.
You could do something for the manipulation like this (and let's assume cData has the data we need to parse): ATOI will convert the numbers in a string up to the first letter into an INTEGER
Then, make you evaluations Take a look at this tech note, it should help you with parsing incoming data.
http://amx.com/techsupport/techNote.asp?id=616
Also, for Hungarian notation, I generally use this set of rules...
dv - DEVICE, PHYSICAL
vdv - DEVICE, VIRTUAL
dc - DEVICE,CHANNEL
s - CONSTANT LITERAL STRING EXPRESSION
c - 8 BIT CHARACTER
n - 16 BIT NUMERIC
sn - SIGNED 16 BIT NUMERIC
dv_ - DEVICE ARRAY
ch_ - CHANNEL ARRAY
dc_ - DEVICE,CHANNEL ARRAY
c_ - 8 BIT CHARACTER ARRAY
n_ - 16 BIT NUMERIC ARRAY
sn_ - SIGNED 16 BIT NUMERIC ARRAY
Hope this helps!
After that, create a UI Module that integrates the user interface (ie. Button Channels).
You could use commands link: TOGGLE-2 or DIM-5 to control the Comm Module. That is if you want to go this far....
JJames you help is extremely appreciated thank you.
<E000
<X002
<E000
The line that I need is the middle line.
I'd normally have:
if you need to que the commands, the commands would be parsed easiest if they were added to the que with delimiters ($FE,$FF maybe). Pull the next command out by remove_string looking for $FE$FF. Only parse the que if you find $FE$FF in it.
Pretty much want 1 button for each zone that toggles on/off the light and shows the status of the light. I also have another page on the TP for scenes but they are not sure they want to do that yet.
So this is what I have come up with so far.
I appreciate all the help, looks like I will be in school in December.
So, maybe something like this for the evaluation:
and then in the DATA_EVENT:
Or, you can simply do a WAIT...
And don't forget - SEND_COMMANDs are for virtuals or AMX devices - SEND_STRINGS are for REAL devices that you'll communicate with.
Thanks you mentioned this before and it slipped my mind
Example: nLiteStatus would be integers, and their values would be set in the DATA_EVENT when parsing the response. On would be 1, off would be 0; this way, each pass of DEFINE_PROGRAM, it gets updated automatically.
Also, you need brackets around you proposed WAIT_UNTIL if you're going to do an IF/ELSE in it . . . it doesn't fall through.
Another thing, most devices aren't online at DEFINE_START, so you'll probably want to put a WAIT at DEFINE_START before doing anything. Typically, I set variables and trigger an All Off function 15 seconds after startup (DEFINE_START.)
Something I noticed though in the DATA_EVENT.
cTemp will only be one character, and DATA.TEXT is not an integer - no ITOA. There's gotta be more to the parsing, yes? Don't forget to assign cZone or are you doing that in the button press?
Also yes the cZone is being set on the Button Press
Also, since the zone is probably an integer, you may want to prefix it with an "n" and not a "c". Makes me think cZone is a character and not an integer, but know that's not possible when you put it in the array. Now we're getting picky.
Number one goal I feel in programming a system for a client, is to make it work. After that, it's efficiency. Get it to work, then clean up the code.
I was thinking I need a TO or While Statement that sets the zone like this.
Interesting perspective. I tend to go the other way. Making it work is a far bigger challenge when your code is messy and unorganized. Often there isn't a chance to do any cleanup and the code stays that way.
Paul
Seconded. Usually I write something, get it working and implement it, then read something here and learn a better way I could have done it. Going back to "correct" already working code, seems to be more work than its worth. Just have to remember to do it the correct way the next time.
I am use to trying to condense my programs, if i can do in 2 lines what i can do in 10 then do it.
Word to that (or whatever slang for "I agree" is popular nowadays). One day, I would really like to post my very first programming job. I didn't know how to use arrays or anything. I did everything line by line. Really horrible. Then I went to class, joined this forum, and increased my AMX Jedi skills. Still have a long ways to go though. I would love so much to go back to that first job and "fix" it. But it is a conference room in Iraq, so I really doubt they would pay for my plane tickets just to go over there and make it better.
Now that I am thinking about that program, it makes me laugh. Not only did I not use any arrays, but I did not know how to properly manipulate strings. So, I hard coded everything. All of the perceived feedback to the touch panel, was written into the code. Like when they opened the mics on the Tandberg, the TP would indicate the mics were on even if the Tandberg was powered off. And the TP would probably win an award for AMX's worst designed touch panel. It all worked and met their requirements, but now that I am wiser and know better, I am really embarrassed by it.
Anyway, as to the DEFINE_PROGRAM question. If [dvTP,2] is always for lighting zone number 2, and nLiteStatus[2] is updated in the DATA_EVENT then what you had originally will work, no need for the loop.
And, I just looked further into your code . . . okay. cZone looks like it is a character, in which case, you cannot use it to designate a position in an array. A char "1" would be a decimal 49, which is probably too big for the array, so you'd be getting "runtime errors." You need a new variable, like nZone, which would be the equivalent to nButtonIndex, but global so that it could be referenced elsewhere in code. Unless of course, you did a ATOI on cZone every time you needed to get the decimal version of the zone - which, would not be recommended.
I added some error messages the Lighting can kick back but I have not done anything with them yet, I have not decided if I want the error to send a message to the TP or not.