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
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
0
Comments
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
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 }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
About codes such as "^N" it is possible to look here:
http://en.wikipedia.org/wiki/ASCII
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