Home AMX User Forum AMX Technical Discussion

SMARTUPS rs232

I am trying to build a module to monitor/control a APC SmartUPS SC420 from an NI2000 rs232. Anybody been down this road yet?

Document Reference:

http://sibbald.com/apcupsd/3.8manual/upsbible.html

for example the string it says to send is "^N" or several different commands prefixed with ^

from hyperterminal the caret is not accepted, response=NA, however <ctrl>N ellicits the desired response

WHat would i use as an escape character so the the string "^N" is sent or do i have to send it as HEX, all the other commands are ASCII

also this is my first attempt at intelligent RS232 communication(query/response vs blindly sending strings)

what is the best way to parse the response? anyone have code snippets?

Thanks In advance
Paul

Comments

  • Joe HebertJoe Hebert Posts: 2,159
    Hi Paul,

    I don?t think ^N is meant to be sent as a 2 character string. I think it?s looking for SO (shift out) which is $0E in the ASCII chart. ^A = $01 and ^Z = $1A So?.

    SEND_STRING dvUPS, ?$0E? should turn the UPS on.

    HTH
    WHat would i use as an escape character so the the string "^N" is sent or do i have to send it as HEX, all the other commands are ASCII
  • YuriyYuriy Posts: 20
    It traces only some rresponses from APC UPS
    Code for parse of the response:
    DEFINE_CALL 'Parse Buffer' (char Buf[200])
    {
      LOCAL_VAR char cJunk[20], cByte
      LOCAL_VAR integer nPos
      
      IF ((LENGTH_STRING(Buf)) > 1)
        cJunk = REMOVE_STRING (Buf,"$0A",1)
      ELSE 
        cJunk = Buf 
      SELECT
      {
        ACTIVE (FIND_STRING(cJunk,'!',1)):
        {
          OFF[vdvDEV,2]  // Line fail
        }
        ACTIVE (FIND_STRING(cJunk,'$',1)):
        {
          ON[vdvDEV,2]   // Line restory
        }
        ACTIVE (FIND_STRING(cJunk,'%',1)):
        {
          ON[vdvDEV,3] // Low battery
        }
        ACTIVE (FIND_STRING(cJunk,'+',1)):
        {
          OFF[vdvDEV,3] // Battery >= (25%)
        }
        ACTIVE (FIND_STRING(cJunk,'#',1)):
        {
          ON[vdvDEV,6] // Replace battery 
        }
        ACTIVE (FIND_STRING(cJunk,'SM',1)):
        {
          ON[vdvDEV,10] // Smart mode
        }
        ACTIVE (FIND_STRING(cJunk,'?',1)):
        {
          ON[vdvDEV,11]  // Abnormal condition
          OFF[vdvDEV,10] // Smart mode
          CALL 'Add to Queue' ('Y') 
          CANCEL_WAIT 'ABNORM'
          WAIT ABNORMAL_CONDITION_TIMEOUT 'ABNORM'
          {
            OFF[vdvDEV,11]  // Abnormal condition 
    	CALL 'Add to Queue' ('Y')
          }	
        }
        ACTIVE (FIND_STRING(cJunk,'=',1)):
        {
          OFF[vdvDEV,11] // Return from abnormal condition 
          CANCEL_WAIT 'ABNORM'
        }
      }
      SELECT
      { 
        ACTIVE (cLastCmd = 'Q'):  // Status
        {
          cJunk = "cJunk[1],cJunk[2]"
          cByte = HEXTOI(cJunk)
          [vdvDEV,1] = NOT(cByte = $00) // power
          [vdvDEV,2] = (cByte BAND $08) // on line
          [vdvDEV,3] = (cByte BAND $40) // battery low
          [vdvDEV,4] = (cByte BAND $10) // on battery
          [vdvDEV,5] = (cByte BAND $20) // overloaded output
          [vdvDEV,6] = (cByte BAND $80) // replace battery      
        }
        ACTIVE (cLastCmd = 'F'):  // Line frequency, Hz
        {
          IF (LENGTH_STRING(cJunk) > 0)
          {
            SEND_LEVEL vdvDEV, LINE_F_LEVEL, ATOF(cJunk)  
          }	
        }
        ACTIVE (cLastCmd = 'C'):  // Internal temperature
        {
          IF (LENGTH_STRING(cJunk) > 0)
          {
            SEND_LEVEL vdvDEV, TEMP_LEVEL, ATOF(cJunk)
          }	
        }
        ACTIVE (cLastCmd = 'L'):  // Input line voltage
        {
          IF (LENGTH_STRING(cJunk) > 0)
          {
            SEND_LEVEL vdvDEV, LINE_U_LEVEL, ATOF(cJunk)
          }	
        }
        ACTIVE (cLastCmd = 'M'):  // Maximum line voltage
        {
          IF (LENGTH_STRING(cJunk) > 0)
          {
            SEND_LEVEL vdvDEV, LINE_MAX_LEVEL, ATOF(cJunk)
          }	
        }
        ACTIVE (cLastCmd = 'N'):  // Minimum line voltage
        {
          IF (LENGTH_STRING(cJunk) > 0)
          {
            SEND_LEVEL vdvDEV, LINE_MIN_LEVEL, ATOF(cJunk)
          }	
        }
        ACTIVE (cLastCmd = 'O'):  // Output voltage
        {
          IF (LENGTH_STRING(cJunk) > 0)
          {
            SEND_LEVEL vdvDEV, OUTPUT_LEVEL, ATOF(cJunk)
          }	
        }
        ACTIVE (cLastCmd = 'P'):  // Power load % 
        {
          IF (LENGTH_STRING(cJunk) > 0)
          {
            SEND_LEVEL vdvDEV, LOAD_LEVEL, ATOF(cJunk)
          }	
        }
        ACTIVE (cLastCmd = 'f'):  // Battery level 
        {
          IF (LENGTH_STRING(cJunk) > 0)
          {
            SEND_LEVEL vdvDEV, BAT_LEVEL, ATOF(cJunk)
          }	
        }
        ACTIVE (1):
        {
          cLastCmd = ''
        }
      }
      CLEAR_BUFFER Buf
    }
    
  • APC SMARTUPS-rs232

    Joe & Yuriy
    Thanks for the input, I worked out part of it own my own, but i will try your suggestions and let you know how it works out..
    Cheers,
    Paul
  • YuriyYuriy Posts: 20
    Good luck, Paul!
    About codes such as "^N" it is possible to look here:
    http://en.wikipedia.org/wiki/ASCII
  • APC SmartUPS SC 420 is now monitored/Controlled , MAX now gracefully shuts down

    Ok after alot of investigation, I have come up with this

    
    DATA_EVENT[dvSMARTUPS_RS232]
    {
     COMMAND:
     {
      // COMMAND event handler
     }
     STRING:
     {
      // STRING event handler
      SEND_STRING 0,"'string: SMARTUPS=',Data.Text"
      
      if (nLastCommandSent==1)
      {
         IF (FIND_STRING(Data.Text,'50',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 50%'"
        }
        IF (FIND_STRING(Data.Text,'49',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 49%'"
        }
        IF (FIND_STRING(Data.Text,'48',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 48%'"
        }
        IF (FIND_STRING(Data.Text,'47',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 47%'"
        }
        IF (FIND_STRING(Data.Text,'46',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 46%'"
        }
        IF (FIND_STRING(Data.Text,'45',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 45%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'44',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 44%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'43',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 43%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'42',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 42%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'41',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 41%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'40',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 40%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'39',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 39%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'38',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 38%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'37',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 37%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'36',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 36%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'35',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 35%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'34',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 34%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'33',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 33%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'32',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 32%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'31',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 31%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
        IF (FIND_STRING(Data.Text,'30',1))
        {
    	SEND_STRING 0,"'SMARTUPS Battery at 30%'"
    	DO_PUSH(dvMAXMODERO,8)
    	SEND_STRING 0,"'Shutting Down MAX'"
    	wait 700
    	SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	nLastCommandSent = 3 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
        }
      }
      IF (FIND_STRING(Data.Text,'!',1))
      {
       nLowBatteryCounter++
       SEND_STRING 0,"'SMARTUPS Now IN BATTERY MODE'"
       SEND_STRING dvSMARTUPS_RS232,"'f'" //query battery level
       nLastCommandSent = 1 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
    
    
      }
      
      else IF (FIND_STRING(Data.Text,'$',1))
      {
         SEND_STRING 0,"'SMARTUPS Back on A/C Line POWER'"
         SEND_COMMAND dvSMARTUPS_RS232,"'SET BAUD 2400,N,8,1'"
         wait 10
         SEND_STRING dvSMARTUPS_RS232,"'Y'" //turn on smart mode(feedback)
         nLastCommandSent = 2 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
    
    
      }
        
      else IF (FIND_STRING(Data.Text,'FF',1))
      {
         SEND_STRING 0,"'Line POWER quality ok'"
        
         SEND_STRING dvSMARTUPS_RS232,"'Y'" //turn on smart mode(feedback)
         nLastCommandSent = 2 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
    
    
      }
      else IF (FIND_STRING(Data.Text,'%',1))
      {
         SEND_STRING 0,"'SMARTUPS LOW BATTERY ALERT'"
         	//shut down max
    	//DO_PUSH(dvMAXMODERO,8)
    	//wait 700
    	//SEND_STRING dvSMARTUPS_RS232,"'S'"//soft shutdown ups after p(60 secs)
    	
    	
      }
      else IF (FIND_STRING(Data.Text,'#',1))
      {
         SEND_STRING 0,"'REPLACE BATTERY ALERT'"
      }
      else IF (FIND_STRING(Data.Text,'+',1))
      {
         SEND_STRING 0,"'SMARTUPS return to threshold From Low Battery'"
      }
       else IF (FIND_STRING(Data.Text,'?',1))
      {
         SEND_STRING 0,"'Abnormal condition'"
         SEND_STRING dvSMARTUPS_RS232,"'Y'" //turn on smart mode(feedback)
         nLastCommandSent = 2 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
    
    
      }
      
     }
     ONLINE:
     {
      // ONLINE event handler
         SEND_COMMAND dvSMARTUPS_RS232,"'SET BAUD 2400,N,8,1'"
         SEND_STRING 0,"'SMARTUPS Now Online @ 2400bps'"
         SEND_STRING dvSMARTUPS_RS232,"'Y'" //turn on smart mode(feedback)
         SEND_STRING 0,"'SMARTUPS Now in SMARTMODE- feedback enabled'"
         nLastCommandSent = 2 //o for cleared, 1 for BatteryQuery, 2 for SmartModeEnable,3 softpowerdown
    
    
     }
    
     OFFLINE:
     {
      // OFFLINE event handler
           SEND_STRING 0,"'SMARTUPS Now Offline'"
    
     }
    
     ONERROR:
     {
      // ONERROR event handler
           SEND_STRING 0,"'SMARTUPS some error occurred'"
    
     }
    }
    

    I know it is not extremely elegant code but it is functional..
    on low power it shuts down the Max and SoftSwitches the SmartUPS off untill the battery charges to 90%.(UPS return threshold set by 'e')

    Anybody has comments suggestions i would be happy to hear them.

    Cheers,
    Paul
Sign In or Register to comment.