Home AMX User Forum NetLinx Modules & Duet Modules

First Module Please Help

2

Comments

  • There's a better way to write you feedback.

    for (x =1;x<41;x++)
    {
      [dvTP,nTPbuttons[x]] = nLiteStatus[nTPbuttons[x]]
    }
    

    and the case statements can be stacked...
    switch (message))
    {
      case 'E001':
      case 'E002':
      case 'E003':
      case 'E004':
      case 'E005':
      case 'E006':
      case 'E007':
      case 'E008':
      case 'E009':
      case 'E010':
      {
         on[dvDevice,nReady]
      }
    }
    

    Also I would use channels on the Virtual or Actual device as much as possible. This give access to what is going on with this control system to other AMC control systems. If your just changing a variable from 0 to 1, that information is only accessible by the local controller.
  • ericmedleyericmedley Posts: 4,177
    kbeattyAMX wrote: »
    switch (message))
    {
      case 'E001':
      case 'E002':
      case 'E003':
      case 'E004':
      case 'E005':
      case 'E006':
      case 'E007':
      case 'E008':
      case 'E009':
      case 'E010':
      {
         on[dvDevice,nReady]
      }
    }
    

    Also I would use channels on the Virtual or Actual device as much as possible. This give access to what is going on with this control system to other AMC control systems. If your just changing a variable from 0 to 1, that information is only accessible by the local controller.

    wouldn't it be great if you could do some kind of array for a stacked case...

    switch (message))
    {
      case cCase_Array:
      {
         on[dvDevice,nReady]
      }
    }
    
  • jjamesjjames Posts: 2,908
    Why not just do this?
    [dvDevice,nReady] = (ATOI(message)>=1 && ATOI(message) <= 10)
    

    Also, be careful using a FOR loop in DEFINE_PROGRAM, it's a huge process hog. If you wind up seeing a performance hit, you can easily let the load off by surrounding your FOR loop with a WAIT 2 . . . your eye is not going to notice a 2/10 of a second delay in updating feedback.
  • viningvining Posts: 4,368
    I'd like to see you get rid of the WAIT_UNTILs in the button_events and put that code in the string_event handler under a switch case for cType or cLstCmdSent or something.

    You then might consider creating a queue so you only send commands after a response from the previous command is received. Put in a time out period via a wait in case a valid response isn't received in a resonable amount of time so you can send the next string in queue. The way the code is now you could possible keep pushing buttons and sending strings before getting any replies back and being nReady. Some devices don't like that. You could also block further button pushes if nReady isn't ready but that might piss off the user so you're better off using a queue.
  • jjames wrote: »
    Why not just do this?
    [dvDevice,nReady] = (ATOI(message)>=1 && ATOI(message) <= 10)
    

    Also, be careful using a FOR loop in DEFINE_PROGRAM, it's a huge process hog. If you wind up seeing a performance hit, you can easily let the load off by surrounding your FOR loop with a WAIT 2 . . . your eye is not going to notice a 2/10 of a second delay in updating feedback.

    Not too sure if there is that much difference in processing. Everytime mainline is processed 40 loops of the FOR loop is processed with 1 line of feedback per loop. OR 40 lines of Feedback in each loop of mainline. Seems like a wash to me... Just a lot of less typing with the FOR loop. Also virtual devices start at 33001.
  • Ok so here is what I am thinking if I add ",UP" to the end of the command I will get the status of the light as shown below
    >N8OF,UP - Turn light node 8 Off, and requests an update.
    <E000 - Acknowledges the command
    <X000 - RF Transmission was sent successfully (X002 means unsuccessfully)
    <N008L000 - Returns the status of the light node

    If I do not put the ",UP" on the command I would only get this:
    >N8OF,UP - Turn light node 8 Off, and requests an update.
    <E000 - Acknowledges the command
    <X000 - RF Transmission was sent successfully

    I also found out that the "X000 or X002" means that I can send another command so that is where I should set the nReady state and not on the other feedback messages.
    kbeattyAMX
    and the case statements can be stacked...
    Not too sure if there is that much difference in processing. Everytime mainline is processed 40 loops of the FOR loop is processed with 1 line of feedback per loop. OR 40 lines of Feedback in each loop of mainline. Seems like a wash to me... Just a lot of less typing with the FOR loop. Also virtual devices start at 33001
    I have not done anything with the Error codes yet not sure if I will do anything with them or not
    I have them defined the virtual devices but have not used them yet I may get rid of them and I corrected the addressing for now.
    ericmedley
    wouldn't it be great if you could do some kind of array for a stacked case...
    Not sure if you are being sarcastic or not but yest that would be great, is this allowed?
    jjames
    [dvDevice,nReady] = (ATOI(message)>=1 && ATOI(message) <= 10)
    Not a 100% what this is actually performing. nReady is just a flag that I am using to make sure that the device is ready to receive another command.
    vining
    I'd like to see you get rid of the WAIT_UNTILs in the button_events and put that code in the string_event handler under a switch case for cType or cLstCmdSent or something
    I would love to use a buffer to send the commands I just need to figure out how.

    Also if there is a change of status to any light that is done by the light switch itself the level info would be sent to the Netlinx so would I really need the feedback in the DEFINE_PROGRAM section?
  • jjamesjjames Posts: 2,908
    kbeattyAMX wrote: »
    Not too sure if there is that much difference in processing. Everytime mainline is processed 40 loops of the FOR loop is processed with 1 line of feedback per loop. OR 40 lines of Feedback in each loop of mainline. Seems like a wash to me... Just a lot of less typing with the FOR loop. Also virtual devices start at 33001.

    Hey - don't get me wrong, it's helpful and yes - I do FOR loops in DEFINE_PROGRAM. I've a couple of programs where the FOR loop crippled the system . . . breaking it up with a WAIT or removing some of it and doing direct feedback helped. And I should mention, these were larger systems (18 touch panels in one job, with lighting feedback.)

    I'm not much of a benchmark guy, but if anyone has any numbers that'd be great. I heard numbers before in Programmer 3 - but to be honest, forgot them.
  • For feedback, I typically run a repeating timeline_event at a 1/10 of a second and if feedback is sequential arrays of stuff, I'd condense it down to a for loop. Less critical feedback would run in a repeating timeline_event at 1/2 to 1/3 of a second. I normally don't put stuff like this in mainline but if it is a small program like a typical conference room, its easy just to do feedback there.
  • Ok I made some changes, I am trying the command queue and also the For loop that was mentioned. In the queue portion I put the nReady change in the DATA_EVENT because the lights will reject a command until I receive a X000, X002, or an Exxx error code. I hope I did the queue correctly. Also when I compile this code I get several of these warnings:
    C10571: Converting type [string] to [CHAR] - should I be worried about these, is there a way to correct the problem? I saw a tech note on how to disable the warnings but do they affect anything?

    PROGRAM_NAME='Client XXX'
    (***********************************************************)
    (***********************************************************)
    (*  FILE_LAST_MODIFIED_ON: 11/07/2008  AT: 10:07:19        *)
    (***********************************************************)
    (* System Type : NetLinx                                   *)
    (***********************************************************)
    (* REV HISTORY:                                            *)
    (***********************************************************)
    (*
        $History: $
    *)
    (***********************************************************)
    (*          DEVICE NUMBER DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_DEVICE
    
    dvTP = 128:1:0
    dvViziaRF = 5001:1:0
    	(*  Buad = 9600
    	    data bits = 8
    	    stop bit  = 1
                parity    = no parity
                Handshaking = off *)
    vdvTP = 33001:1:0
    vdvViziaRF = 33002:1:0
    
    (***********************************************************)
    (*               CONSTANT DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_CONSTANT
    
    INTEGER nTPButtons[] =
        {
    	// Individual Nodes
    	101,	//Node 1
    	102,	//Node 2
    	103,	//Node 3
    	104,	//Node 4
    	105,	//Node 5
    	106,	//Node 6
    	107,	//Node 7
    	108,	//Node 8
    	109,	//Node 9
    	110,	//Node 10
    	111,	//Node 11
    	112,	//Node 12
    	113,	//Node 13
    	114,	//Node 14
    	115,	//Node 15
    	116,	//Node 16
    	117,	//Node 17
    	118,	//Node 18
    	119,	//Node 19
    	120,	//Node 20
    	// Groups - A set of switches/Dimmers to behave as one node
    	201,	//Group 1
    	202,	//Group 2
    	203,	//Group 3
    	204,	//Group 4
    	205,	//Group 5
    	206,	//Group 6
    	207,	//Group 7
    	208,	//Group 8
    	209,	//Group 9
    	210,	//Group 10
    	//Scenes 
    	301,	//Scene 1
    	302,	//Scene 2
    	303,	//Scene 3
    	304,	//Scene 4
    	305,	//Scene 5
    	306,	//Scene 6
    	307,	//Scene 7
    	308,	//Scene 8
    	309,	//Scene 9
    	310	//Scene 10
        }
    
    (***********************************************************)
    (*               VARIABLE DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_VARIABLE
    
    VOLATILE CHAR cType				//Stores Selected Node Type
    VOLATILE CHAR cTypeData 			//Stores the type of device on feedback
    VOLATILE CHAR cNode				//Stores Selected Light Node
    VOLATILE CHAR cGroup				//Stores Selected Light Group
    VOLATILE CHAR cScene				//Stores Selected Light Scene
    VOLATILE CHAR cStatus				//Stores Status of Selected Light Zone
    VOLATILE CHAR cMessage				//Stores Light Node/Group/Scene Level error information
    Char cViziaRFQue[255]
    INTEGER nReady					//Flag for waiting for response from Lights
    INTEGER nLiteStatus[400] 			//Stores Light Status for feedback on TP
    INTEGER nNode					//Stores Selected Light Node for Array position
    INTEGER nGroup					//Stores Selected Light Group for Array position
    INTEGER nScene					//Stores Selected Light Scene for Array position
    INTEGER nType					//Stores Selected Light Type for Array Position
    INTEGER x 					//COunt in For Loop for feedback
    
    (***********************************************************)
    (*		Function/Calls Code Goes Here		   *)
    (***********************************************************)
    
    Define_Function SendViziaRFQue ()
    {
        Local_Var Char cCmd[50]
        If(![dvViziaRF,nReady] && Length_String(cViziaRFQue))
        {
            cCmd = Remove_String(cViziaRFQue,"13",1)
            Send_String dvViziaRF,"cCmd"
            Send_String 0,"'Sent Leviton Command: ',cCmd"
        }
    }
     
    Define_Function AddtoViziaRFQue (Char cCmd[50])
    {
        cViziaRFQue = "cViziaRFQue,cCmd,13"
        Send_String 0,"'Added Leviton Command: ',cCmd"
    }
    
    (***********************************************************)
    (*                STARTUP CODE GOES BELOW                  *)
    (***********************************************************)
    DEFINE_START
    
    (***********************************************************)
    (*                THE EVENTS GO BELOW                      *)
    (***********************************************************)
    DEFINE_EVENT
    BUTTON_EVENT [dvTP, nTPButtons]
    {
        PUSH:
        {
    	STACK_VAR INTEGER nButtonIndex
    	
    	nButtonIndex = GET_LAST(nTPButtons)
    	nType = nButtonIndex
    	IF (nType < 200)
    	{
    	    cType = 'Node'
    	    Send_String 0,"cType"					
    	    cNode = ITOA(nButtonIndex)
    	    AddtoViziaRFQue ("'>?N',cNode") 				//gets the status of the Light Zone
    	    IF (cStatus = 'OF')
    	    {
    		AddtoViziaRFQue ("'>N',cNode,'ON,UP'")			//Turn Light Zone On
    	    }
    	    ELSE
    	    {
    		AddtoViziaRFQue ("'>N',cNode,'OF,UP'")			//Turn Light Zone Off
    	    }
    	}
    	ELSE IF (nType < 300)
    	{
    	    cType = 'Group'
    	    Send_String 0,"cType"
    	    cGroup = ITOA(nButtonIndex)
    	    AddtoViziaRFQue ("'>?GR',cGroup")			//Gets the status of the Light Group
    	    IF (cStatus = 'OF')
    	    {
    		AddtoViziaRFQue ("'>GR',cGroup,'ON,UP'")		//Turn Group On
    	    }
    	    ELSE
    	    {
    		AddtoViziaRFQue ("'>GR',cGroup,'OF,UP'")		//Turn Group Off
    	    }
    	}
    	ELSE IF (nType < 400)
    	{
    	    cType = 'Scene'
    	    Send_String 0,"cType"
    	    cScene = ITOA(nButtonIndex)
    	    AddtoViziaRFQue ("'>?S',cScene")			//Gets the status of the Light Scene
    	    IF (cStatus = 'OF')
    	    {
    		AddtoViziaRFQue ("'>S',cScene,'ON,UP'")		//Turn Scene On
    	    }
    	    ELSE
    		AddtoViziaRFQue ("'>S',cScene,'OF,UP'")		//Turn Scene Off
    	    }
    	}
        }
    
    DATA_EVENT [dvViziaRF]
    {
        ONLINE:
        {
    	SEND_STRING dvViziaRF , 'SET BAUD 9600,N,8,1'
        }
        STRING:
        {
    	STACK_VAR CHAR cTemp[17]				// Max 17 characters in the received data from Vizia RS232 module
    	cTemp = (DATA.TEXT)
    	IF (length_string(cTemp) == 5)				//If data is 5 characters it is an error or infomation
    	{
    	    cTypeData = 'Info'
    	    cMessage = MID_STRING(cTemp, 2, 4)
    	}
    	ELSE IF (length_string(cTemp) == 9)			//If data is 9 characters it is a level or status
    	{
    	    cTypeData = 'Status'
    	    cMessage = MID_STRING(cTemp, 6, 4)
    	    IF (find_string(cTemp, 'N', 1) == 1)		//If this is a switch or dimmer
    	    {
    		cNode = "'1', MID_STRING(cTemp, 4, 2)"		//Strip the >N0 and add 1 to the beginning for TP Node Button Number
    		nNode = ATOI(cNode)
    	    }
    	    ELSE IF (find_string(cTemp, 'G', 1) == 1)
    	    {
    		cNode = "'2', MID_STRING(cTemp, 4, 2)"		//Strip the >G0 and add 2 to the beginning for TP Group Button Number
    		nNode = ATOI(cNode)
    	    }
    	    ELSE IF (find_string(cTemp, 'S', 1) == 1)
    	    {
    		cNode = "'3', MID_STRING(cTemp, 4, 2)"		//Strip the >S0 and add 1 to the beginning for TP Scene Button Number
    		nNode = ATOI(cNode)
    	    }
    	}
    	SWITCH(cMessage)
    	{
    	    CASE 'L255':
    	    {
    		cStatus = 'ON'
    		nLiteStatus[nNode] = 1
    	    }
    	    CASE 'L000':
    	    {
    		cStatus = 'OF'
    		nLiteStatus[nNode] = 0
    	    }
    	    // RF Transmission Messages
    	    CASE 'X000':					//No RF Transmission Error
    	    {
    		ON[nReady]
    	    }
    	    CASE 'X002':					//RF Transmission Error
    	    {
    		ON[nReady]
    	    }
    	    // Errors sent from the Vizia RS-232 Module
    	    CASE 'E001':					//wrong start of the string symbol
    	    CASE 'E002':					//Input buffer overflow.
    	    CASE 'E003':					//Can not start RF transmission. All buffers are taken.
    	    CASE 'E004':					//Can not start RF transmission because previous one has not finished.
    	    CASE 'E005':					//Unrecognized command
    	    CASE 'E006':					//Attempt to send the new buffer over RS232 before previous one had been processed.
    	    CASE 'E007':					//The send Message does not have data fields specified.
    	    CASE 'E008':					//Can not stop SUC mode. Node is SUC.
    	    CASE 'E009':					//EERPOM is busy, can&#8217;t store group information
    	    CASE 'E010':					//No devices with specified properties have been found
    	    {
    		ON[nReady]
    	    }
    	}
        }
    }
    
    (***********************************************************)
    (*            THE ACTUAL PROGRAM GOES BELOW                *)
    (***********************************************************)
    DEFINE_PROGRAM
    
    SendViziaRFQue()
    
    for (x =1;x<41;x++)
    {
      [dvTP,nTPbuttons[x]] = nLiteStatus[nTPbuttons[x]]
    }
    (***********************************************************)
    (*                     END OF PROGRAM                      *)
    (*        DO NOT PUT ANY CODE BELOW THIS COMMENT           *)
    (***********************************************************)
    
  • Don't let the command que back up to much. It looks real goofy then the communications are ready and the system spits out 2 minutes of commands because the que was backed up. O yeah, If you don't define the size/length of the CHAR variables you get this warning.
    C10571: Converting type [string] to [CHAR] - should I be worried about these, is there a way to correct the problem? I saw a tech note on how to disable the warnings but do they affect anything?
  • kbeattyAMX wrote: »
    Don't let the command que back up to much. It looks real goofy then the communications are ready and the system spits out 2 minutes of commands because the que was backed up. O yeah, If you don't define the size/length of the CHAR variables you get this warning.

    Thanks that fixed the warnings, what kind of advice can you offer on how to keep the queue from backing up? I do know that I need to see one of the Xyyy or Eyyy events returned from the lighting interface before I can send the next command that is why I put the nReady change in the data_event after those strings.
  • Add to the front of the que and limit the size of the que. This would push old commands out of the que leaving the most recent commands to be executed. Like FILO First in last out. Not FIFO.
  • Sort of like this?
    Char cViziaRFQue[60]
    
    (***********************************************************)
    (*		Function/Calls Code Goes Here		   *)
    (***********************************************************)
    
    Define_Function SendViziaRFQue ()
    {
        Local_Var Char cCmd[20]
        If(![dvViziaRF,nReady] && Length_String(cViziaRFQue))
        {
            cCmd = Remove_String(cViziaRFQue,"13",1)
            Send_String dvViziaRF,"cCmd"
            Send_String 0,"'Sent Leviton Command: ',cCmd"
        }
    }
     
    Define_Function AddtoViziaRFQue (Char cCmd[20])
    {
        cViziaRFQue = "cCmd,cViziaRFQue,13"
        Send_String 0,"'Added Leviton Command: ',cCmd"
    }
    
  • Define_Function AddtoViziaRFQue (Char cCmd[20])
    {
        cViziaRFQue = "cCmd,cViziaRFQue,13"
        Send_String 0,"'Added Leviton Command: ',cCmd"
    }
    


    more like this...
    Define_Function AddtoViziaRFQue (Char cCmd[20])
    {
        cViziaRFQue = "cCmd,13,cViziaRFQue"
        Send_String 0,"'Added Leviton Command: ',cCmd"
    }
    
  • Got it, much appreciated. Thanx
  • AMXJeffAMXJeff Posts: 450
    kbeattyAMX wrote: »
    Define_Function AddtoViziaRFQue (Char cCmd[20])
    {
        cViziaRFQue = "cCmd,cViziaRFQue,13"
        Send_String 0,"'Added Leviton Command: ',cCmd"
    }
    


    more like this...
    Define_Function AddtoViziaRFQue (Char cCmd[20])
    {
        cViziaRFQue = "cCmd,13,cViziaRFQue"
        Send_String 0,"'Added Leviton Command: ',cCmd"
    }
    

    Actually the function as coded above acts as a stack (Last In First Out) vs a Queue (First In First Out).
    // Queue is this...
    Define_Function AddtoViziaRFQue (Char cCmd[20])
    {
        cViziaRFQue = "cViziaRFQue, cCmd,13"
        Send_String 0,"'Added Leviton Command: ',cCmd"
    }
    
  • Yes! but the problem exists, if the lighting system is not ready for a command and someone is pressing the buttons repeatedly the que becomes backlogged with commands Then when it is finally ready, the que parses sending the lighting system tons of old commands before it gets to the current command. There needs to be a limit of commands stored in the que and the most recent command should be processed first. I figured just stacking them in FILO and limiting the size of the que would solve this delimma,

    I personally would not que commands for a lighting system. Just send the last command when it's ready.
  • viningvining Posts: 4,368
    Normally most equipment responds fast enough so that you don't fill the queue that much unless you really push alot and fast, with the exception of hold and repeats for raise/lower lighting levels. It's more often used for timing. Send command, receive response and check queue for more commands and if the queue holds any send the next command type of thing. Keeps you from stepping on your previous command or sending when the device is still processing the previous command. Unless the Leviton device is a real dog I would stick with a FIFO type buffer (queue) since your 1st push may be to turn on the light and the next may be to increase its intensity doing that in reverse order will likely accomplish nothing.
  • Everything is going ok with this. The one thing I am having an issue with is updating the text on some of the TP buttons.
    Example
    send_string dvTP, "'^TXT-301,0,',cSunset"
    

    cSunset is a string and also button 301 is programmed as a general button and right now address code 301, I have also tried it with 301 as a channel code on the button. I see it in the NS2 diagnostics window as being sent with the appropriate information but it is not updating. Could someone inform me as to what stupid thing I am doing wrong. Thanks
  • Send_Command not Send_String. I miss that all of the time when I'm coding.
  • Joe HebertJoe Hebert Posts: 2,159
    Everything is going ok with this. The one thing I am having an issue with is updating the text on some of the TP buttons.
    Example
    send_string dvTP, "'^TXT-301,0,',cSunset"
    

    cSunset is a string and also button 301 is programmed as a general button and right now address code 301, I have also tried it with 301 as a channel code on the button. I see it in the NS2 diagnostics window as being sent with the appropriate information but it is not updating. Could someone inform me as to what stupid thing I am doing wrong. Thanks
    You need to use SEND_COMMAND not SEND_STRING to send variable text to button.
  • Joe Hebert wrote: »
    You need to use SEND_COMMAND not SEND_STRING to send variable text to button.

    So then I would need to create a virtual device for the TP, seeing the SEND_COMMAND is for virtual device correct?
  • Joe HebertJoe Hebert Posts: 2,159
    So then I would need to create a virtual device for the TP, seeing the SEND_COMMAND is for virtual device correct?
    Nope, SEND_COMMAND is valid for real devices also.
  • Ok thanx for the quick replies
  • Ok, I actually installed the equipment today. I am having an issue with the send_strings and what I am receiving. I verified that I can communicate to the ViziaRF module with hyperterm and was able to send the commands and receive the feedback with no problem. When send the commands from the processor it looks like it is HEX when I need it to be ASCI and the same thing in the feedback repsonses, is this normal? Does the processor take everything back in as HEX? If so then I need to fix my STRING processing in my programming. So here is what I am talking about. Also I tried to receiving the commands from the process into hyperterm but just got garbage due to the HEX (I beleive)
    Diagnostics
    Line 85 (10:20:03):: Added Leviton Command: >?N4
    Line 86 (10:20:03):: Added Leviton Command: >N4ON
    Line 87 (10:20:03):: Added Leviton Command: >?N4
    Line 88 (10:20:03):: Sent Leviton Command: >?N4$0D
    Line 89 (10:20:03):: Sent Leviton Command: >N4ON$0D
    Line 90 (10:20:03):: Sent Leviton Command: >?N4$0D
    Line 91 (10:20:03):: 0
    Line 92 (10:20:22):: Exiting UDP SNMP Read thread - closing this socket for local port 3
    Line 93 (10:20:22):: CIpEvent::OffLine 0:3:1
    Line 94 (10:20:47):: 0
    Line 95 (10:20:47):: 120
    Line 96 (10:20:51):: 0
    Line 97 (10:20:51):: 128

    Notification
    Line 14 (10:20:03):: Input Status:Pushed [10001:1:1] - Channel 104
    Line 15 (10:20:03):: String To [5001:1:1]-[>?N4$0D]
    Line 16 (10:20:03):: String To [5001:1:1]-[>N4ON$0D]
    Line 17 (10:20:03):: String To [5001:1:1]-[>?N4$0D]
    Line 18 (10:20:03):: String From [5001:1:1]-[$00$80x$00x$80$00$80$80$80$80x$00$80x]
    Line 19 (10:20:03):: Input Status:Released [10001:1:1] - Channel 104
    Line 20 (10:20:47):: String From [5001:1:1]-[$00$80$80$80x$80$00$80x$80$80$F8$80x$80$00$F8$80x$F8$80$00x$00$80$00$80$00$80$00x$00$80$80$80$80x$80$00x$00$80x$80$80$80$80$00x$00$80$00$80$F8$80$80$00x$00$80$00$80x$80]
    Line 21 (10:20:47):: String From [5001:1:1]-[x$00$80x]
    Line 22 (10:20:51):: String From [5001:1:1]-[$00$80$80$80x$80$00$80x$80$80$F8$80x$80$00$F8$80x$F8$80$00x$00$80$00$80$00$80$00x$00$80$80$80$80x$80$00x$00$80x$80$80$80$80$00x$00$80$00$80$F8$80$80$00x$00$80$00$80$80$80]
    Line 23 (10:20:51):: String From [5001:1:1]-[$80x$00$80x]

    Here is my code
    PROGRAM_NAME='ClientXXX'
    (***********************************************************)
    (***********************************************************)
    (*  FILE_LAST_MODIFIED_ON: 11/26/2008  AT: 14:01:38        *)
    (***********************************************************)
    (* System Type : NetLinx                                   *)
    (***********************************************************)
    (* REV HISTORY:                                            *)
    (***********************************************************)
    (*
        $History: $
    *)
    (***********************************************************)
    (*          DEVICE NUMBER DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_DEVICE
    
    dvTP = 10001:1:0
    dvViziaRF = 5001:1:0
    	(*  Buad = 9600
    	    data bits = 8
    	    stop bit  = 1
                parity    = no parity
                Handshaking = off *)
    vdvViziaRF = 33002:1:0
    vdvSchEvents = 33003:1:0
    dvTmTimeSync  = 0:3:0
    
    (***********************************************************)
    (*               CONSTANT DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_CONSTANT
    
    INTEGER nTPLiteButtons[] =
        {
    	//Lighting Nodes - Individual Switches/Dimmers
    	101,	//Light Node Button  1 - VRCPG Controller
    	102,	//Light Node Button  2 - RS-232 Module
    	103,	//Light Node Button  3 - Driveway
    	104,	//Light Node Button  4 - Garage
    	105,	//Light Node Button  5 - Brick Left
    	106,	//Light Node Button  6 - Brick Right
    	107,	//Light Node Button  7 - Front Island
    	108,	//Light Node Button  8 - Front Accent Right
    	109,	//Light Node Button  9 - Front Accent Left
    	110,	//Light Node Button  10 - Rear Accent
    	111,	//Light Node Button  11 - Pool Accent
    	112,	//Light Node Button  12 - Cabana External
    	113,	//Light Node Button  13 - Cabana Sofit
    	114	//Light Node Button  14 - Doghouse
        }
    
    INTEGER nTPGroupButtons[] =
        {
    	//Lighting Groups - A set of switches/Dimmers to behave as one node
    	201,	//Light Group Button 1
    	202,	//Light Group Button  2
    	203,	//Light Group Button  3
    	204,	//Light Group Button  4
    	205,	//Light Group Button  5
    	206,	//Light Group Button  6
    	207,	//Light Group Button  7
    	208,	//Light Group Button  8
    	209,	//Light Group Button  9
    	210	//Light Group Button  10
        }
    
    (* Timeserver protocols *)
    nProtoNone        = 0
    nProtoDaytime     = 1
    nProtoTime        = 2
    nProtoSNTP        = 3
    nProtoSNTPBCast   = 4
    (***********************************************************)
    (*               VARIABLE DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_VARIABLE
    
    VOLATILE CHAR cLastcCmd[20]			//Stores last sent command
    VOLATILE CHAR cType[5]				//Stores Selected Node Type
    VOLATILE CHAR cTypeData[6] 			//Stores the type of device on feedback
    VOLATILE CHAR cNode[3]				//Stores Selected Light Node
    VOLATILE CHAR cGroup[3]				//Stores Selected Light Group
    VOLATILE CHAR cScene[3]				//Stores Selected Light Scene
    VOLATILE CHAR cStatus[3]			//Stores Status of Selected Light Zone
    VOLATILE CHAR cMessage[255]			//Stores Light Node/Group/Scene Level error information
    VOLATILE CHAR cCable[3]
    Char cViziaRFQue[60]				//ViziaRF Que
    VOLATILE CHAR cSunrise[30]
    VOLATILE CHAR cSunset[30]
    VOLATILE CHAR cLocation[100]
    VOLATILE CHAR cPrevSunrise[30]
    VOLATILE CHAR cPrevSunset[30]
    VOLATILE CHAR cPrevLocation[100]
    VOLATILE CHAR cReady				//Flag for waiting for response from Lights
    INTEGER nLiteStatus[21]				//Stores Light Status for feedback on TP
    INTEGER nGroupStatus[11]			//Stores Group Status for feedback
    INTEGER nNode					//Stores Selected Light Node for Array position
    INTEGER nStatus
    INTEGER nGroup					//Stores Selected Light Group for Array position
    INTEGER nScene					//Stores Selected Light Scene for Array position
    INTEGER nType					//Stores Selected Light Type for Array Position
    INTEGER nTPOnline
    x 						//Count in For Loop for lite feedback
    y						//Count in For Loop for Group feedback
    
    (* Timezone *)
    CHAR    dTmTzName[100]
    CHAR    dTmTzDesc[10]
    DOUBLE  dTmTzGmtOffset
    CHAR    strTmTzDstRules[1000]
    
    (* Location *)
    CHAR    strTmLocName[100]
    DOUBLE  dTmLocLong
    DOUBLE  dTmLocLat
    
    (* Timeserver *)
    INTEGER nTmTsProtocol
    INTEGER nTmTsCheckTime
    CHAR    strTmTsServer[100]
    
    (***********************************************************)
    (*		Define Device Combining Here		   *)
    (***********************************************************)
    DEFINE_COMBINE
    
    (***********************************************************)
    (*		Function/Calls Code Goes Here		   *)
    (***********************************************************)
    
    Define_Function SendViziaRFQue ()
    {
        Local_Var Char cCmd[20]
        If(![dvViziaRF,cReady] && Length_String(cViziaRFQue))
        {
            cCmd = Remove_String(cViziaRFQue,"13",1)
    	cLastcCmd = cCmd
            Send_String dvViziaRF,"cCmd"
            Send_String 0,"'Sent Leviton Command: ',cCmd"
    	OFF[cReady]
        }
    }
     
    Define_Function AddtoViziaRFQue (Char cCmd[20])
    {
        cViziaRFQue = "cViziaRFQue,cCmd,13"
        Send_String 0,"'Added Leviton Command: ',cCmd"
    }
    
    (***********************************************************)
    (*                STARTUP CODE GOES BELOW                  *)
    (***********************************************************)
    DEFINE_START
    dTmTzName     = 'Eastern'
    dTmTzDesc     = 'E&#37;sT'
    dTmTzGmtOffset = -5.0
    strTmTzDstRules = 'US'
    strTmLocName   = 'Rehoboth, MA 02769'
    dTmLocLong = -71.25
    dTmLocLat = 41.84
    nTmTsProtocol   = nProtoSNTP
    nTmTsCheckTime  = 0
    strTmTsServer   = ''
    cReady = '0'
    
    (***********************************************************)
    (*                THE EVENTS GO BELOW                      *)
    (***********************************************************)
    DEFINE_EVENT
    BUTTON_EVENT [dvTP, nTPLiteButtons]
    {
        PUSH:
        {
    	STACK_VAR INTEGER nLiteButtonsIndex
    	
    	nLiteButtonsIndex = GET_LAST(nTPLiteButtons)					
    	cNode = ITOA(nLiteButtonsIndex)
    	AddtoViziaRFQue ("'>?N',cNode") 				//gets the status of the Light Zone
    	IF (nLiteStatus[nLiteButtonsIndex] = 0)
    	{
    	    AddtoViziaRFQue ("'>N',cNode,'ON'")
    	    AddtoViziaRFQue ("'>?N',cNode")
    	}
    	ELSE
    	{
    	    AddtoViziaRFQue ("'>N',cNode,'OFF'")			//Turn Light Zone Off
    	    AddtoViziaRFQue ("'>?N',cNode")
    	}
        }
    }
    BUTTON_EVENT [dvTP, nTPGroupButtons]
    {
        PUSH:
        {
    	STACK_VAR INTEGER nGrouButtonsIndex
    	
    	nGrouButtonsIndex = GET_LAST(nTPGroupButtons)				
    	cGroup = ITOA(nGrouButtonsIndex)
    	AddtoViziaRFQue ("'>?GR',cGroup")			//Gets the status of the Light Group
    	IF (nGroupStatus[nGrouButtonsIndex] = 0)
    	{
    	    AddtoViziaRFQue ("'>GR',cGroup,'ON'")		//Turn Group On
    	    AddtoViziaRFQue ("'>?G',cGroup")
    	}
    	ELSE
    	{
    	    AddtoViziaRFQue ("'>GR',cGroup,'OFF'")		//Turn Group Off
    	    AddtoViziaRFQue ("'>?G',cGroup")
    	}
        }
    }
    
    BUTTON_EVENT[vdvSchEvents,1]						//Group 1 On/Off
    {
        PUSH:
        {
    	AddtoViziaRFQue ('>G1ON')
        }
        RELEASE:
        {
    	AddtoViziaRFQue ('>GR1OFF')
        }
    }
    
    DATA_EVENT [dvViziaRF]
    {
        ONLINE:
        {
    	SEND_STRING dvViziaRF , 'SET BAUD 9600,N,8,1,OFF'
    	AddtoViziaRFQue ('>?N')
    	AddtoViziaRFQue ('>N7,8,9GS1')			//Landscape Light Group
    	//AddtoViziaRFQue ('>N8,9,10,11,7GS2')
        }
        STRING:
        {
        	STACK_VAR CHAR cTemp[17]				// Max 17 characters in the received data from Vizia RS232 module
    	cTemp = itoa(DATA.TEXT)
    	send_string 0, "cTemp"
    	SELECT
    	{
    	    ACTIVE (FIND_STRING(cTemp,'<N',1)):			//Looks to see if it is a Node Level Status
    	    {
    		REMOVE_STRING (cTemp,'<',1)			//Makes the message NxxxLyyy
    		SEND_STRING 0,"'Node',cTemp"
    		cNode = MID_STRING(cTemp,2,3)
    		nNode = ATOI(cNode)
    		cStatus = MID_STRING(cTemp,6,3)
    		nStatus = ATOI(cStatus)
    		IF (cStatus == '000')
    		{
    		    nLiteStatus[nNode] = 0
    		}
    		ELSE IF (cStatus == '255')
    		{
    		    nLiteStatus[nNode] = 1
    		}
    	    }
    	    ACTIVE (FIND_STRING(cTemp, '<G',1)):		//Looks to see if it is a Group Level Status
    	    {
    		REMOVE_STRING (cTemp,'<',1)			//cTemp is now GxxxLyyy
    		SEND_STRING 0,"'Group',cTemp"
    	    }
    	    ACTIVE (FIND_STRING(cTemp, '<X',1)):		//Looks to see if it is a RF Transmission Status
    	    {
    		REMOVE_STRING (cTemp,'<',1)			//cTemp is now Xxxx
    		SEND_STRING 0, "'RF Trans', cTemp"
    		cReady = '0'					//ViziaRF is ready to receive a command
    		IF (cTemp == 'X002')
    		{
    		    AddtoViziaRFQue(cLastcCmd)
    		}
    	    }
    	    ACTIVE (FIND_STRING(cTemp, '<E',1)):		//Looks to see if it is an Error Message
    	    {
    		REMOVE_STRING (cTemp,'<',1)			//cTemp is now Exxx
    		SEND_STRING 0, "'Error', cTemp"
    		ON[cReady]
    	    }
    	    ACTIVE (FIND_STRING(cTemp, '<F',1)):		//Found new node message
    	    {
    		REMOVE_STRING (cTemp,'<',1)			//cTemp is now Fxxx
    		SEND_STRING 0, "'Found Node', cTemp"
    	    }
    	    ACTIVE (FIND_STRING(cTemp, '$00',1)):
    	    {
    		ON[cReady]
    	    }
    	}
        }
    }
    
    DATA_EVENT[vdvSchEvents]
    {
      STRING:
      {
        STACK_VAR
        CHAR strUpper[30]
        CHAR strTemp[30]
        CHAR strTrash[30]
    
        strUpper = UPPER_STRING(DATA.TEXT)
        strTemp = DATA.TEXT
        strTrash = REMOVE_STRING(strTemp,'-',1)
        SELECT
        {
    	(* SUNRISE *)
    	ACTIVE (FIND_STRING(strUpper,'SUNRISE-',1)):
            {
    	    SEND_STRING 0,"'Sunrise Time=',strTemp"
    	    cSunrise = strTemp
    	}
    	(* SUNSET *)
    	ACTIVE (FIND_STRING(strUpper,'SUNSET-',1)):
    	{
    	    SEND_STRING 0,"'Sunset Time=',strTemp"
    	    cSunset = strTemp
    	}
    	(* TIME ZONE NAME *)
    	ACTIVE (FIND_STRING(strUpper,'TIMEZONE-',1)):
    	    SEND_STRING 0,"'Timezone=',strTemp"
    	(* TIME DESCRPTION *)
    	ACTIVE (FIND_STRING(strUpper,'TIMEDESC-',1)):
    	    SEND_STRING 0,"'Time Description=',strTemp"
    	(* LOCATION *)
    	ACTIVE (FIND_STRING(strUpper,'LOCATION-',1)):
    	{
    	    SEND_STRING 0,"'Location=',strTemp"
    	    cLocation = strTemp
    	}
        }
      }
      ONLINE:
      {
        (* Debug *)
        //ON[vdvSchEvents,250]
    
        (* Setup events *)
        (* Group 1 On - start at 7:00 PM and end at 10:00 PM Daily *)
        SEND_COMMAND vdvSchEvents,"'SET EVENT-1,Group 1,Daily,18:00,22:00'"
    
       // (* Group 2 On - start at 7:00 PM and end at 10:30 PM Daily *)
       // SEND_COMMAND vdvSchEvents,"'SET EVENT-2,Group 2,Daily,19:30,22:30'"
      }
    }
    
    DEFINE_MODULE 'i!-ScheduleEngineMod' mdlSch(vdvSchEvents,
                                                dvTmTimeSync,
                                                (* Timezone *)
                                                dTmTzName,
                                                dTmTzDesc,
                                                dTmTzGmtOffset,
                                                strTmTzDstRules,
                                                (* Location *)
                                                strTmLocName,
                                                dTmLocLong,
                                                dTmLocLat,
                                                (* Timeserver *)
                                                nTmTsProtocol,
                                                nTmTsCheckTime,
                                                strTmTsServer)
    (***********************************************************)
    (*            THE ACTUAL PROGRAM GOES BELOW                *)
    (***********************************************************)
    DEFINE_PROGRAM
    
    SendViziaRFQue()
    
    for (x =3;x<13;x++)
    {
      [dvTP,nTPLiteButtons[x]] = nLiteStatus[x]
    }
    
    For (y =1;y<11;y++)
    {
        [dvTP,nTPGroupButtons[y]] = nGroupStatus[y]
    }
    (***********************************************************)
    (*                     END OF PROGRAM                      *)
    (*        DO NOT PUT ANY CODE BELOW THIS COMMENT           *)
    (***********************************************************)
    
  • ericmedleyericmedley Posts: 4,177
    I saw this in the code:
    DATA_EVENT [dvViziaRF]
    {
        ONLINE:
        {
    	SEND_STRING dvViziaRF , 'SET BAUD 9600,N,8,1,OFF'
    	AddtoViziaRFQue ('>?N')
    	AddtoViziaRFQue ('>N7,8,9GS1')			//Landscape Light Group
    	//AddtoViziaRFQue ('>N8,9,10,11,7GS2')
        }
    
    

    It should be:
    SEND_COMMAND dvViziaRF , 'SET BAUD 9600,N,8,1,OFF'
    
  • Looks like the Baud rate is off. Yea SEND_COMMAND not SEND_STRING for the SET BAUD.
  • Thank you kbeatty I got. I remembered someone saying that SEND_COMMAND was for virtual devices and SEND_STRING was for real devices. So I will change that and try again.
  • glr-ftiglr-fti Posts: 286
    Send_Command is sending a command TO the device. Send_String is sending a command THROUGH a device.
  • glr-fti wrote: »
    Send_Command is sending a command TO the device. Send_String is sending a command THROUGH a device.

    Thank you for the clarification on that.

    So I should change these to SEND_COMMAND?
    Define_Function SendViziaRFQue ()
    {
        Local_Var Char cCmd[20]
        If(![dvViziaRF,cReady] && Length_String(cViziaRFQue))
        {
            cCmd = Remove_String(cViziaRFQue,"13",1)
    	cLastcCmd = cCmd
            Send_String dvViziaRF,"cCmd"
            Send_String 0,"'Sent Leviton Command: ',cCmd"
    	OFF[cReady]
        }
    }
    
Sign In or Register to comment.