Home AMX User Forum NetLinx Studio

Code Based Notifications

If anyone familiar with a way to have code put a text string in the Notifications of the Output Bar in NetLinx Studio when you are connected to a system.

What I am trying to accomplish is to have a line of code in a DEFINE_CALL that will send just a notification with a custom string to the notifications when connected. Something like "Define_call XYZ was run" so it would have a timestamp for debugging/monitoring/troubleshooting timelines and other events.

The only way I can think of is to SEND_STRING to the master with my custom message or to a fake defined device. There must be a better way though. Suggestions?

Thanks.

Comments

  • ericmedleyericmedley Posts: 4,177
    SEND_STRING 0, 'a message to my bad self' will show up in diagnostics.
  • That is sending a string to the master correct? (Pretty new to Netlinx)

    I wasn't sure if that was the correct way.

    I know there is a #WARN for compile time, couldn't find anything for a run-time notification by code.

    Thanks for the suggestion.
  • the8thstthe8thst Posts: 470
    send_string 0 does exactly what you are requesting. It will send a text message to the notifications (or better yet a telnet session after the command "msg on" is sent), but neither of those logs are saved or stored anywhere. So "send_string 0" is a great tool for real time information.

    Here is a quick function that will do almost the same thing, but will save the message, with date and time stamp, to a text file that can be downloaded from the master with a FTP program.
    //
    	define_function char[60] getFileError (slong slErr)
    	{
    		switch (abs_value(slErr))
    		{
    			case 0: return '(0) Success'
    			case 1: return '(-1) Invalid File Handle'
    			case 2: return '(-2) Invalid File Path or Name'
    			case 3: return '(-3) Invalid Value Supplied for IO Flag'
    			case 4: return '(-4) Invalid Directory Path'
    			case 5: return '(-5) Disk I/O Error'
    			case 6: return '(-6) Invalid Parameter'
    			case 7: return '(-7) File Already Closed'
    			case 8: return '(-8) File Name Already Exists'
    			case 9: return '(-9) End Of File Reached'
    			case 10: return '(-10) size of DirPath buffer too small for dir path name'
    			case 11: return '(-11) Disk Full'
    			case 13: return '(-13) Directory Already Exists'
    			case 14: return '(-14) Max Num Files Already Open (10)'
    			case 15: return '(-15) Invalid File Format'
    			default: return "'(default) slErr[ ',itoa(slErr),' ]'"
    		}
    	}
    	
    	//
    	define_function integer logToFile (char msg[])
    	{
    		stack_var slong slDir
    		stack_var slong slFile
    		stack_var slong slResult
    		stack_var char logMsg[200]
    		
    		slDir = file_createdir('\LOGS\')
    		
    		logMsg = "'',date,' ',time,'--> ',msg,10"
    		
    		if (slDir == 0 || slDir == -13) {
    			slFile = file_open('\LOGS\log.txt',file_rw_append)
    			
    			if (slFile > 0) {
    				slResult = file_write(slFile,logmsg,length_string(logMsg))
    				file_close(slFile)
    			} else {
    				send_string 0, "'<logToFile> Directory OK: File Error[',getFileError(slFile),']'"
    			}
    		} else {
    			send_string 0,"'<logToFile> File Error[',getFileError(slDir),']'"
    		}
    	}
    

    Those two tools should cover both realtime debugging/monitoring and monitoring/logging when you need to troubleshoot a problem that occurs when you are not actively connected and watching the telnet window.
  • Great stuff, thanks for quick responses of suggestions.
  • ROOROO Posts: 46
    Using a Telnet session to capture Debug strings

    When you send a string to the master (ie. Send_string 0, cString; ), you can look at it in the telnet session.

    Open the Telnet session to the master ( o 192.168.1.11), when it connects to the master, type the MSG ON command to the Netlinx. All strings sent to the master are displayed in the Telnet window. I send the strings to a Debug function, that I can enable/disable with a variable. That way I can minimize data I have to look at based on turning on/off various code sections.

    If I want to capture the data going to the telnet session, I turn the Telnet logfile on before I connect to the master.
    "set logfile c:\logfile.txt" - Turns logging on
    "o 192.168.1.11" - Opens the telnet session
    "msg on" - tells the Netlinx to pring it's send_string data to the screen (and therefore the logfile).

    It allows me to capture most of the Netlinx startup data on reboots too, so I don't have to be so fast at enableing the Netlinx notifications.

    ROO
  • ericmedleyericmedley Posts: 4,177
    If I know I'm just doing a quick debug I will also send out strings on the virtual device I'm using in the peice of code I'm working on at that moment. Chances are I'm already watching it in Device Watch anyway.
  • viningvining Posts: 4,368
    Every device in my system has a seperate debug function:
    DEFINE_FUNCTION fnAVSys_DeBug(CHAR iMSG[])
         
         {
         if(nAVSys_DeBug)
    	  {
    	  SEND_STRING 0,"'AV SYSTEM DEBUG: ',iMSG" ;
    	  }
         }
    
    or like this when data I want displayed is over the 180(?) character limit then can be displayed on 1 line.
    
    DEFINE_FUNCTION fnDevMod_DeBug(CHAR iStr[])
    
         {
         if(nSqz_DeBug > DEBUG_AXI_ONLY)
    	  {
    	  STACK_VAR CHAR cCopyStr[MAX_1024] ;
    	  STACK_VAR INTEGER nLineCount ;
    	  
    	  cCopyStr = iStr ;
    	  
    	  nLineCount ++ ;
    	  WHILE(length_string(cCopyStr) > 100)
    	       {
    	       SEND_STRING 0,"'SQZ_BOX MOD-[ ',itoa(sSqzBox.sPlayer.nDev_Instance),' ] DEBUG:[L-',itoa(nLineCount),'], ',get_buffer_string(cCopyStr,100)" ;
    	       nLineCount ++
    	       }
    	  if(length_string(cCopyStr))
    	       {
    	       SEND_STRING 0,"'SQZ_BOX MOD-[ ',itoa(sSqzBox.sPlayer.nDev_Instance),' ] DEBUG:[L-',itoa(nLineCount),'], ',cCopyStr" ;
    	       }
    	  }
         
         RETURN ;
         } 
    

    Then through out a particular device's code where appropriate I use something like this:
    fnAVSYS_DeBug("'WAIT CLEARED, SRC-[ ',itoa(iSrc_Indx),' ], TIME-[ ',itoa(iTime),' ] :DEBUG<',ITOA(__LINE__),'>'") ;
    

    Now if I'm working on a particular device and I want debug info printed to the diagnostic screen I just open up the debug window put in that devices debug variable and set it to 1. Some modules I write I have different debug levels like 1 for just the .axi, 2 for just the .axs (module) or 3 for everything.

    Notice I use the __LINE__ function so when it prints to the screen I know where in the code, what line it originated from. Makes life a little easier.

    I then use "DEBUG: in the printed line so it can be filtered from the daily log that is collected and set out daily to the office. I've been using Dave Hawthorne's DevTermLogger module for that which is available on the forum and he created a filter array just for such purposes. That way I can work on a system with out the daily log getting filled with a bunch of crap from that day's testing or troubleshooting.
Sign In or Register to comment.