windows-nt/Source/XPSP1/NT/ds/netapi/svcdlls/upssvc/apcsmart/smartups.cxx

1465 lines
41 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*
* cad07Oct93: SU400 changes, added get codes for programming and load sens
* cad12Oct93: Oops, missed one.
* cad02Nov93: name changes
* cad09Nov93: su250/400 fixes
* cad09Nov93: Turn off eeprom access during calibration
* cad11Nov93: Making sure all timers are cancelled on destruction
* cad10Dec93: fix for dip switches changing on the fly
* rct21Dec93: changed determineXferCause() & HandleLineCond...
* cad08Jan94: fixes for sub-sensors, getting ups model from ini file
* ajr15Feb94: fixed TIMED_RUN_TIME_REMAINING case in SmartUps
* pcy04Mar94: fixed overload handling
* cad04Mar94: fixed up eeprom access
* ajr09Mar94: made HandleBatteryConditionEvent check for ErrUNSUPPORTED
* pcy08Apr94: Trim size, use static iterators, dead code removal
* pcy13Apr94: Use automatic variables decrease dynamic mem allocation
* pcy19Apr94: port for SGI
* ajr25Apr94: Some compilers balk at the auto array init....
* ajr24May94: had to explicitly scope dip_sensor->Get for Unixware...
* ajr10Aug94: Could not match with ^\0 in scanf. Had to go with ^# in
* SmartUps::ParseValues
* jps01Oct94: Commented out deepget of boost in reinit: was causing back end to
* miss transitions to/from boost while no comm.
* djs14Mar95: Added OverloadSensor
* ajr03Jun95: Stopped carrying time around in milliseconds
* djs05Feb96: Added firmware rev codes and smarttrim
* cgm29Feb96: Test for Smart mode
* cgm17Apr96: Test return value on GetAllowedValues for a fail
* pcy28Jun96: Added IS_ stuff for menus
* djs12Jul96: Added IS_ stuff for bar graphs
* djs23Sep96: Added check for smart boost off without on battery condition
* djs02Oct96: Added Duet UPS_TEMP check
* jps14Oct96: Changed AUTO_REBOOT_ENABLED ->Get() to ->Set() in Set()
* jps17Oct96: Added low battery event when LOW_BATTERY_DURATION changed to value
* smaller than current run time remaining
* jps15Nov96: Added LIGHTS_TEST test to HandleOverloadConditionEvent(), SIR 4536
* djs19Nov96: Added Battery Calibration Test to Get
* djs01Dec96: Cleaned up processing of Boost/Trim and lost comm
* srt31Jan96: Fixed small bug w/ state test in HandleOverloadCondition.
* srt11Jun97: Added IS_EXT_SLEEP_UPS case
* dma26Nov97: Fixed bug with monitoring a 2G Smart-Ups.
* dma15Dec97: Eliminated Update call in HandleSmartTrimEvent and
* HandleSmartBoostEvent to eliminate duplicate logging
* of SmartTrim/SmartBoost events. Update is now called in our
* new DeepGet
* dma06Jan98: Removed the restraint on UTILITY_LINE_CONDITION case of
* Update which would not allow the battery line condition
* to be updated during a self test.
* clk11Feb98: Changed DeepGet to DeepGetWithoutUpdate in HandleLineCondition
* and added Update to HandleSmartBoost/TrimEvent's
* dma11Feb98: Fixed problem with detecting a battery that needed replacement.
* tjg02Mar98: Added handling for LIGHTS_TEST code to Get
*
* v-stebe 29Jul2000 Fixed PREfix errors (bugs #112610, #112613)
*/
#include "cdefine.h"
#include "_defs.h"
#include <stdlib.h>
extern "C" {
#include <stdio.h>
}
#include "smartups.h"
#include "unssens.h"
#include "smrtsens.h"
#include "simpsens.h"
#include "firmrevs.h"
#include "dcfrmrev.h"
#include "timerman.h"
#include "dispatch.h"
#include "cfgmgr.h"
#include "cfgcodes.h"
_CLASSDEF( DeviceController )
_CLASSDEF( UnsupportedSensor )
PList AllowedValuesList;
SmartUps::SmartUps(PUpdateObj aDeviceController, PCommController aCommController)
: BackUps(aDeviceController, aCommController),
pendingEventTimerId(0)
{
INT err = ErrNO_ERROR;
// Turn on Smart Mode
if((err = theCommController->Set(TURN_ON_SMART_MODE, (CHAR*)NULL)) != ErrNO_ERROR) {
theObjectStatus = ErrSMART_MODE_FAILED;
theFirmwareRevSensor = (PFirmwareRevSensor)NULL;
theDecimalFirmwareRevSensor = (PDecimalFirmwareRevSensor)NULL;
theCopyrightSensor = (PSensor)NULL;
theTripRegisterSensor = (PSensor)NULL;
theLightsTestSensor = (PSensor)NULL;
theBatteryReplacementManager = (PBatteryReplacementManager)NULL;
theBatteryCapacitySensor = (PSensor)NULL;
theSmartBoostSensor = (PSensor)NULL;
theRunTimeRemainingSensor = (PSensor)NULL;
theLowBatteryDurationSensor = (PSensor)NULL;
theShutdownDelaySensor = (PSensor)NULL;
theManufactureDateSensor = (PSensor)NULL;
theUpsSerialNumberSensor = (PSensor)NULL;
theTurnOffWithDelaySensor = (PSensor)NULL;
thePutUpsToSleepSensor = (PSensor)NULL;
}
else {
// NEW CODE
theObjectStatus = ErrNO_ERROR;
theFirmwareRevSensor = new FirmwareRevSensor(this, aCommController);
theDecimalFirmwareRevSensor = new DecimalFirmwareRevSensor(this, aCommController);
// New for CTRL Z processing --- JOD
AllowedValuesList = new List();
err = GetAllAllowedValues(AllowedValuesList);
if (err != ErrNO_ERROR) {
theObjectStatus = ErrSMART_MODE_FAILED;
theUpsModelSensor = (PSensor)NULL;
theNumberBatteryPacksSensor = (PSensor)NULL;
theCopyrightSensor = (PSensor)NULL;
theTripRegisterSensor = (PSensor)NULL;
theLightsTestSensor = (PSensor)NULL;
theBatteryReplacementManager = (PBatteryReplacementManager)NULL;
theBatteryCapacitySensor = (PSensor)NULL;
theSmartBoostSensor = (PSensor)NULL;
theRunTimeRemainingSensor = (PSensor)NULL;
theLowBatteryDurationSensor = (PSensor)NULL;
theShutdownDelaySensor = (PSensor)NULL;
theManufactureDateSensor = (PSensor)NULL;
theUpsSerialNumberSensor = (PSensor)NULL;
theTurnOffWithDelaySensor = (PSensor)NULL;
thePutUpsToSleepSensor = (PSensor)NULL;
}
else
{
theUpsModelSensor = new UpsModelSensor(this, theCommController, theFirmwareRevSensor);
theNumberBatteryPacksSensor = new NumberBatteryPacksSensor(this, aCommController,theFirmwareRevSensor);
MakeCopyrightSensor( theFirmwareRevSensor );
if ((theCopyrightSensor != NULL) && ((err = theCopyrightSensor->GetObjectStatus()) != ErrNO_ERROR)) {
theObjectStatus = ErrCOPYRIGHT_RESP_ERROR;
}
theTripRegisterSensor = new TripRegisterSensor(this, aCommController );
theLightsTestSensor = new LightsTestSensor(this, aCommController );
theBatteryReplacementManager = new BatteryReplacementManager(this, aCommController, theFirmwareRevSensor );
MakeBatteryCapacitySensor( theFirmwareRevSensor );
MakeSmartBoostSensor( theFirmwareRevSensor );
MakeSmartTrimSensor( theFirmwareRevSensor );
MakeRunTimeRemainingSensor( theFirmwareRevSensor );
MakeLowBatteryDurationSensor( theFirmwareRevSensor );
MakeShutdownDelaySensor( theFirmwareRevSensor );
MakeManufactureDateSensor( theFirmwareRevSensor );
MakeUpsSerialNumberSensor( theFirmwareRevSensor );
MakeTurnOffWithDelaySensor( theFirmwareRevSensor );
MakePutUpsToSleepSensor();
CHAR programmable[32];
Get(IS_EEPROM_PROGRAMMABLE, programmable);
setEepromAccess((_strcmpi(programmable, "YES") == 0) ? AREAD_WRITE : AREAD_ONLY);
pendingEvent = (PEvent)NULL;
}
if (AllowedValuesList) {
AllowedValuesList->FlushAll();
delete AllowedValuesList;
AllowedValuesList = (List*)NULL;
}
}
}
SmartUps::~SmartUps()
{
if (pendingEventTimerId) {
_theTimerManager->CancelTimer(pendingEventTimerId);
pendingEventTimerId = 0;
}
delete theNumberBatteryPacksSensor;
theNumberBatteryPacksSensor = NULL;
delete theFirmwareRevSensor;
theFirmwareRevSensor = NULL;
delete theDecimalFirmwareRevSensor;
theDecimalFirmwareRevSensor = NULL;
delete theTripRegisterSensor;
theTripRegisterSensor = NULL;
delete theLightsTestSensor;
theLightsTestSensor = NULL;
delete theBatteryReplacementManager;
theBatteryReplacementManager = NULL;
if (theCopyrightSensor && (theCopyrightSensor != &_theUnsupportedSensor)) {
delete theCopyrightSensor;
theCopyrightSensor = NULL;
}
if (theBatteryCapacitySensor && (theBatteryCapacitySensor != &_theUnsupportedSensor)) {
delete theBatteryCapacitySensor;
theBatteryCapacitySensor = NULL;
}
if (theSmartBoostSensor && (theSmartBoostSensor != &_theUnsupportedSensor)) {
delete theSmartBoostSensor;
theSmartBoostSensor = NULL;
}
if (theSmartTrimSensor && (theSmartTrimSensor != &_theUnsupportedSensor)) {
delete theSmartTrimSensor;
theSmartTrimSensor = NULL;
}
if (theRunTimeRemainingSensor && (theRunTimeRemainingSensor != &_theUnsupportedSensor)) {
delete theRunTimeRemainingSensor;
theRunTimeRemainingSensor = NULL;
}
if (theLowBatteryDurationSensor && (theLowBatteryDurationSensor != &_theUnsupportedSensor)) {
delete theLowBatteryDurationSensor;
theLowBatteryDurationSensor = NULL;
}
if (theShutdownDelaySensor && (theShutdownDelaySensor != &_theUnsupportedSensor)) {
delete theShutdownDelaySensor;
theShutdownDelaySensor = NULL;
}
if (theManufactureDateSensor && (theManufactureDateSensor != &_theUnsupportedSensor)) {
delete theManufactureDateSensor;
theManufactureDateSensor = NULL;
}
if (theUpsSerialNumberSensor && (theUpsSerialNumberSensor != &_theUnsupportedSensor)) {
delete theUpsSerialNumberSensor;
theUpsSerialNumberSensor = NULL;
}
if (theTurnOffWithDelaySensor && (theTurnOffWithDelaySensor != &_theUnsupportedSensor)) {
delete theTurnOffWithDelaySensor;
theTurnOffWithDelaySensor = NULL;
}
if (thePutUpsToSleepSensor && (thePutUpsToSleepSensor != &_theUnsupportedSensor)) {
delete thePutUpsToSleepSensor;
thePutUpsToSleepSensor = NULL;
}
delete theUpsModelSensor;
theUpsModelSensor = NULL;
}
//-------------------------------------------------------------------------
VOID SmartUps::registerForEvents()
{
BackUps::registerForEvents();
theCommController->RegisterEvent(COMMUNICATION_STATE, this);
theSmartBoostSensor->RegisterEvent(SMART_BOOST_STATE, this);
theSmartTrimSensor->RegisterEvent(SMART_TRIM_STATE, this);
theLightsTestSensor->RegisterEvent(LIGHTS_TEST, this);
thePutUpsToSleepSensor->RegisterEvent(UPS_OFF_PENDING, this);
theTurnOffWithDelaySensor->RegisterEvent(UPS_OFF_PENDING, this);
theRunTimeRemainingSensor->RegisterEvent(RUN_TIME_REMAINING, this);
theBatteryReplacementManager->RegisterEvent(BATTERY_REPLACEMENT_CONDITION, this);
}
//-------------------------------------------------------------------------
INT SmartUps::Get(INT code, PCHAR aValue)
{
INT err = ErrNO_ERROR;
switch(code)
{
case UTILITY_LINE_CONDITION:
case BATTERY_CONDITION:
case UPS_STATE:
case MAX_BATTERY_RUN_TIME:
case TIME_ON_BATTERY:
err = BackUps::Get(code, aValue);
break;
case BATTERY_CALIBRATION_TEST:
err = ErrUNSUPPORTED;
break;
case IS_UPS_LOAD:
case IS_UTILITY_VOLTAGE:
case IS_OUTPUT_VOLTAGE:
strcpy(aValue,"Yes");
break;
case IS_ADMIN_SHUTDOWN:
err = theFirmwareRevSensor->Get(code, aValue);
break;
case EXTERNAL_PACKS_CHANGEABLE:
err = theFirmwareRevSensor->Get(code, aValue);
break;
case EXTERNAL_BATTERY_PACKS:
err = theNumberBatteryPacksSensor->Get(code,aValue);
break;
case INTERNAL_BATTERY_PACKS:
err = theNumberBatteryPacksSensor->Get(code,aValue);
break;
case TOTAL_BATTERY_PACKS:
err = theNumberBatteryPacksSensor->Get(code, aValue);
break;
case DECIMAL_FIRMWARE_REV:
err = theDecimalFirmwareRevSensor->Get(DECIMAL_FIRMWARE_REV, aValue);
break;
case LIGHTS_TEST:
err = theLightsTestSensor->Get(code, aValue);
break;
case IS_UPS_TEMPERATURE:
{
err = theDecimalFirmwareRevSensor->Get(DECIMAL_FIRMWARE_REV, aValue);
if (err == ErrNO_ERROR)
{
INT first_segment = atoi(strtok(aValue,"."));
// Duet UPSs (b firmware response 10,11,12,21 and 22) do not support UPS temp
if ((first_segment > 9 && first_segment < 13) ||
(first_segment > 20 && first_segment < 23))
{
strcpy(aValue, "NO");
}
else
{
strcpy(aValue, "YES");
}
}
else
{
strcpy(aValue, "YES");
}
err = ErrNO_ERROR;
}
break;
case SELF_TEST_STATE:
case SELF_TEST_DAY:
case SELF_TEST_TIME:
case SELF_TEST_SETTING:
case SELF_TEST_RESULT:
case SELF_TEST_LAST_DATE:
case SELF_TEST_LAST_TIME:
case SELFTEST_LIST:
err = ErrUNSUPPORTED;
break;
case SMART_BOOST_STATE:
err = theSmartBoostSensor->Get(code, aValue);
break;
case SMART_TRIM_STATE:
err = theSmartTrimSensor->Get(code, aValue);
break;
case BATTERY_VOLTAGE:
case RATED_BATTERY_VOLTAGE :
case LOW_BATTERY_VOLTAGE_THRESHOLD:
case HIGH_BATTERY_VOLTAGE_THRESHOLD:
err = ErrUNSUPPORTED;
break;
case BATTERY_CAPACITY:
err = theBatteryCapacitySensor->Get(code, aValue);
break;
case UPS_TEMPERATURE:
err = ErrUNSUPPORTED;
break;
case LOW_UPS_TEMP_THRESHOLD:
err = ErrUNSUPPORTED;
break;
case HIGH_UPS_TEMP_THRESHOLD:
err = ErrUNSUPPORTED;
break;
case LOW_UPS_TEMP_THRESHOLD_ENABLED:
err = ErrUNSUPPORTED;
break;
case HIGH_UPS_TEMP_THRESHOLD_ENABLED:
err = ErrUNSUPPORTED;
break;
case OUTPUT_FREQUENCY:
err = ErrUNSUPPORTED;
break;
case RATED_OUTPUT_VOLTAGE:
case LINE_VOLTAGE:
case MIN_LINE_VOLTAGE:
case MAX_LINE_VOLTAGE:
case OUTPUT_VOLTAGE:
case HIGH_TRANSFER_VOLTAGE:
case LOW_TRANSFER_VOLTAGE:
case ALLOWED_RATED_OUTPUT_VOLTAGES:
case ALLOWED_HIGH_TRANSFER_VOLTAGES:
case ALLOWED_LOW_TRANSFER_VOLTAGES:
err = ErrUNSUPPORTED;
break;
case UPS_LOAD:
err = ErrUNSUPPORTED;
break;
case LOW_LOAD_THRESHOLD:
err = ErrUNSUPPORTED;
break;
case HIGH_LOAD_THRESHOLD:
err = ErrUNSUPPORTED;
break;
case TRIP_REGISTER:
err = theTripRegisterSensor->Get(code, aValue);
break;
case RUN_TIME_REMAINING:
err = theRunTimeRemainingSensor->Get(code, aValue);
break;
case BATTERY_REPLACEMENT_DATE:
case BATTERY_AGE_LIMIT:
err = theBatteryReplacementManager->Get(code, aValue);
break;
case UPS_ID:
err = ErrUNSUPPORTED;
break;
case UPS_SENSITIVITY:
err = ErrUNSUPPORTED;
break;
case ALLOWED_UPS_SENSITIVITIES:
err = ErrUNSUPPORTED;
break;
case LOW_BATTERY_DURATION:
err = theLowBatteryDurationSensor->Get(code, aValue);
break;
case ALLOWED_LOW_BATTERY_DURATIONS:
err = theLowBatteryDurationSensor->Get(ALLOWED_VALUES, aValue);
break;
case ALARM_DELAY:
err = ErrUNSUPPORTED;
break;
case ALLOWED_ALARM_DELAYS:
err = ErrUNSUPPORTED;
break;
case SHUTDOWN_DELAY:
err = theShutdownDelaySensor->Get(code, aValue);
break;
case ALLOWED_SHUTDOWN_DELAYS:
err = theShutdownDelaySensor->Get(ALLOWED_VALUES, aValue);
break;
case TURN_ON_DELAY:
err = ErrUNSUPPORTED;
break;
case ALLOWED_TURN_ON_DELAYS:
err = ErrUNSUPPORTED;
break;
case MIN_RETURN_CAPACITY:
err = ErrUNSUPPORTED;
break;
case ALLOWED_MIN_RETURN_CAPACITIES:
err = ErrUNSUPPORTED;
break;
case DIP_SWITCH_POSITION :
err = ErrUNSUPPORTED;
break;
case COPYRIGHT :
err = theCopyrightSensor->Get(code, aValue);
break;
case MANUFACTURE_DATE :
err = theManufactureDateSensor->Get(code, aValue);
break;
case UPS_SERIAL_NUMBER :
err = theUpsSerialNumberSensor->Get(code, aValue);
break;
case UPS_MODEL :
err = theUpsModelSensor->Get(UPS_MODEL_NAME, aValue);
break;
case TIMED_RUN_TIME_REMAINING:
if(theRunTimeExpiration)
{
// some compilers balk at auto array initialization
CHAR enabled[64];
memset(enabled,(int)'\0',64);
theDeviceController->Get(IS_LINE_FAIL_RUN_TIME_ENABLED,enabled);
if (_strcmpi(enabled,"NO") == 0)
{
err =theRunTimeRemainingSensor->Get(RUN_TIME_REMAINING,
aValue);
}
else
{
err = ErrUNSUPPORTED;
}
}
else
{
err = ErrNO_VALUE;
}
break;
case BATTERY_CALIBRATION_DAY:
case BATTERY_CALIBRATION_TIME:
case BATTERY_CALIBRATION_ENABLED:
case BATTERY_CALIBRATION_LAST_DATE:
case BATTERY_CALIBRATION_LIST:
err = ErrUNSUPPORTED;
break;
case AUTO_REBOOT_ENABLED:
err = theTurnOffUpsOnBatterySensor->Get(code, aValue);
break;
case IS_LOAD_SENSING_ON:
{
strcpy(aValue,"No");
}
break;
case IS_EEPROM_PROGRAMMABLE:
{
strcpy(aValue, "Yes");
}
break;
case TRANSFER_CAUSE:
{
CHAR buf[32];
_itoa(theLastTransferCause, buf, 10);
strcpy(aValue, buf);
err = ErrNO_ERROR;
}
break;
case NUMBER_OF_INPUT_PHASES:
case NUMBER_OF_OUTPUT_PHASES:
{
CHAR buf[32];
_itoa(1, buf, 10);
strcpy(aValue, buf);
err = ErrNO_ERROR;
}
break;
default:
case IS_THIRD_GEN:
case IS_SECOND_GEN:
case IS_FIRST_GEN:
case IS_BACKUPS:
case MAX_VOLTAGE_RANGE_VALUE:
case MIN_VOLTAGE_RANGE_VALUE:
case IS_SELF_TEST:
case IS_LIGHTS_TEST:
case IS_SIMULATE_POWER_FAIL:
case IS_BATTERY_CALIBRATION:
case IS_BYPASS:
case FIRMWARE_REV:
case IS_EXT_SLEEP_UPS:
err = theFirmwareRevSensor->Get(code, aValue);
break;
}
return err;
}
//-------------------------------------------------------------------------
VOID SmartUps:: GetAllowedValue(INT code, CHAR *aValue)
{
FindAllowedValues(code, aValue, (PFirmwareRevSensor) theFirmwareRevSensor );
}
//-------------------------------------------------------------------------
INT SmartUps::Set(INT code, const PCHAR aValue)
{
INT err = ErrNO_ERROR;
switch(code) {
case UPS_ID:
err = ErrUNSUPPORTED;
break;
case BATTERY_REPLACEMENT_DATE:
case BATTERY_AGE_LIMIT:
err = theBatteryReplacementManager->Set(code, aValue);
break;
case HIGH_TRANSFER_VOLTAGE:
case LOW_TRANSFER_VOLTAGE:
case RATED_OUTPUT_VOLTAGE:
err = ErrUNSUPPORTED;
break;
case LOW_LOAD_THRESHOLD:
err = ErrUNSUPPORTED;
break;
case HIGH_LOAD_THRESHOLD:
err = ErrUNSUPPORTED;
break;
case UPS_SENSITIVITY:
err = ErrUNSUPPORTED;
break;
case LOW_BATTERY_DURATION:
err = theLowBatteryDurationSensor->Set(code, aValue);
// see if new low battery warning time is greater than the
// current run time - if so, generate a low battery event
char run_time_rem[32];
if ((err = Get(RUN_TIME_REMAINING, run_time_rem)) == ErrNO_ERROR)
{
int run_time, low_battery;
run_time = atoi(run_time_rem);
low_battery = atoi(aValue) * 60;
if (run_time <= low_battery)
{
PEvent tmp = new Event(BATTERY_CONDITION, BATTERY_BAD);
Update(tmp);
}
}
break;
case ALARM_DELAY:
err = ErrUNSUPPORTED;
break;
case MIN_RETURN_CAPACITY:
err = ErrUNSUPPORTED;
break;
case SHUTDOWN_DELAY:
err = theShutdownDelaySensor->Set(code, aValue);
break;
case TURN_ON_DELAY:
err = ErrUNSUPPORTED;
break;
case SELF_TEST:
if (isOnBattery()) {
err = ErrBATTERYTEST_NOT_AVAIL;
break;
}
// else drop through
case SELF_TEST_DAY:
case SELF_TEST_TIME:
case SELF_TEST_SETTING:
case RESCHEDULE_SELF_TEST:
case SELFTEST_LIST:
err = ErrUNSUPPORTED;
break;
case TURN_OFF_UPS_ON_BATTERY:
err = theTurnOffUpsOnBatterySensor->Set(code, aValue);
break;
case TURN_OFF_UPS_AFTER_DELAY:
err = theTurnOffWithDelaySensor->Set(code, aValue);
break;
case PUT_UPS_TO_SLEEP:
err = thePutUpsToSleepSensor->Set(code, aValue);
break;
case LIGHTS_TEST:
if (isOnBattery()) {
err = ErrLIGHTSTEST_NOT_AVAIL;
}
else {
err = theLightsTestSensor->Set(code, aValue);
}
break;
case BATTERY_CALIBRATION_TEST:
case BATTERY_CALIBRATION_DAY:
case BATTERY_CALIBRATION_TIME:
case BATTERY_CALIBRATION_ENABLED:
case BATTERY_CALIBRATION_LAST_DATE:
case BATTERY_CALIBRATION_LIST:
err = ErrUNSUPPORTED;
break;
case SIMULATE_POWER_FAIL:
err = ErrSIMULATEPOWERFAILURE_NOT_AVAIL;
break;
case AUTO_REBOOT_ENABLED:
err = theTurnOffUpsOnBatterySensor->Set(code, aValue);
break;
case EXTERNAL_BATTERY_PACKS:
err = theNumberBatteryPacksSensor->Set(code,aValue);
break;
default:
err = BackUps::Set(code, aValue);
break;
}
return err;
}
//-------------------------------------------------------------------------
INT SmartUps::Update(PEvent anEvent)
{
switch(anEvent->GetCode())
{
case UTILITY_LINE_CONDITION:
HandleLineConditionEvent(anEvent);
break;
case BATTERY_CONDITION:
HandleBatteryConditionEvent(anEvent);
break;
case LIGHTS_TEST:
HandleLightsTestEvent(anEvent);
break;
case BATTERY_CALIBRATION_CONDITION:
HandleBatteryCalibrationEvent(anEvent);
break;
case SELF_TEST_STATE:
case SELF_TEST_RESULT:
HandleSelfTestEvent(anEvent);
break;
case SMART_BOOST_STATE:
HandleSmartBoostEvent(anEvent);
break;
case SMART_TRIM_STATE:
HandleSmartTrimEvent(anEvent);
break;
case OVERLOAD_CONDITION:
HandleOverloadConditionEvent(anEvent);
break;
case DIP_SWITCH_POSITION:
setEepromAccess((atoi(anEvent->GetValue()) == 0) ? AREAD_WRITE : AREAD_ONLY);
break;
case SIMULATE_POWER_FAIL:
switch(atoi(anEvent->GetValue())) {
case SIMULATE_POWER_FAIL:
SET_BIT(theUpsState, SIMULATE_POWER_FAIL_BIT);
break;
case SIMULATE_POWER_FAIL_OVER:
CLEAR_BIT(theUpsState, SIMULATE_POWER_FAIL_BIT);
break;
}
UpdateObj::Update(anEvent);
break;
case BATTERY_REPLACEMENT_CONDITION:
switch(atoi(anEvent->GetValue())) {
case BATTERY_NEEDS_REPLACING :
SET_BIT(theUpsState, BATTERY_REPLACEMENT_BIT);
break;
case BATTERY_DOESNT_NEED_REPLACING :
CLEAR_BIT(theUpsState, BATTERY_REPLACEMENT_BIT);
break;
}
UpdateObj::Update(anEvent);
break;
case COMMUNICATION_STATE:
switch(atoi(anEvent->GetValue())) {
case COMMUNICATION_ESTABLISHED:
reinitialize();
break;
}
break;
default:
BackUps::Update(anEvent);
break;
}
return ErrNO_ERROR;
}
VOID SmartUps::reinitialize()
{
theFirmwareRevSensor->DeepGet();
theNumberBatteryPacksSensor->DeepGet();
theCopyrightSensor->DeepGet();
theTripRegisterSensor->DeepGet();
theBatteryReplacementManager->Reinitialize();
theBatteryCapacitySensor->DeepGet();
theRunTimeRemainingSensor->DeepGet();
theLowBatteryDurationSensor->DeepGet();
theShutdownDelaySensor->DeepGet();
theManufactureDateSensor->DeepGet();
theUpsSerialNumberSensor->DeepGet();
theUpsModelSensor->DeepGet();
CHAR programmable[32];
Get(IS_EEPROM_PROGRAMMABLE, programmable);
setEepromAccess((_strcmpi(programmable, "YES") == 0) ? AREAD_WRITE : AREAD_ONLY);
}
//-------------------------------------------------------------------------
// Determine status of line and generate an event with this status
//-------------------------------------------------------------------------
VOID SmartUps::HandleLineConditionEvent(PEvent anEvent)
{
switch(atoi(anEvent->GetValue())) {
case LINE_GOOD:
{
CHAR boost[32] = { NULL };
CHAR trim[32] = { NULL };
// Get status of boost and trim from the UPS and
// determine the previous state of trim and boost
INT err_boost = theSmartBoostSensor->DeepGetWithoutUpdate(boost);
INT err_trim = theSmartTrimSensor->DeepGetWithoutUpdate(trim);
INT we_were_on_trim = (IS_STATE(UPS_STATE_ON_TRIM));
INT we_were_on_boost = (IS_STATE(UPS_STATE_ON_BOOST));
//
// Cancel a pending line fail event
//
if (isLineFailPending()) {
_theTimerManager->CancelTimer(pendingEventTimerId);
pendingEventTimerId = 0;
}
if ((err_boost != ErrUNSUPPORTED) &&
(atoi(boost) == SMART_BOOST_ON)) {
setLineGood();
SET_BIT(theUpsState, SMART_BOOST_BIT);
CLEAR_BIT(theUpsState, SMART_TRIM_BIT);
Event boost_event(SMART_BOOST_STATE, SMART_BOOST_ON);
UpdateObj::Update(&boost_event);
theLastTransferCause = BROWNOUT;
BackUps::HandleLineConditionEvent(anEvent);
}
else if ((err_trim != ErrUNSUPPORTED)
&& (atoi(trim) == SMART_TRIM_ON)) {
setLineGood();
SET_BIT(theUpsState, SMART_TRIM_BIT);
CLEAR_BIT(theUpsState, SMART_BOOST_BIT);
Event trim_event(SMART_TRIM_STATE, SMART_TRIM_ON);
UpdateObj::Update(&trim_event);
theLastTransferCause = HIGH_LINE_VOLTAGE;
BackUps::HandleLineConditionEvent(anEvent);
}
else if (err_boost != ErrUNSUPPORTED && we_were_on_boost) {
CLEAR_BIT(theUpsState, SMART_BOOST_BIT);
BackUps::HandleLineConditionEvent(anEvent);
}
else if (err_trim != ErrUNSUPPORTED && we_were_on_trim) {
CLEAR_BIT(theUpsState, SMART_TRIM_BIT);
BackUps::HandleLineConditionEvent(anEvent);
}
else if (err_boost != ErrUNSUPPORTED) {
if (pendingEvent) {
UpdateObj::Update(pendingEvent);
}
BackUps::HandleLineConditionEvent(anEvent);
}
else {
BackUps::HandleLineConditionEvent(anEvent);
}
// A LINE_GOOD will void all pending events (see comment in LINE_BAD)
delete pendingEvent;
pendingEvent = NULL;
}
break;
case LINE_BAD:
if(!isLineFailPending()) {
// Start a LINE_BAD timer.
// if the timer expires and the UPS status does not change from
// on battery, then the pending event will handled
pendingEvent = new Event(*anEvent);
pendingEventTimerId = _theTimerManager->SetTheTimer((ULONG)5, anEvent, this);
setLineFailPending();
}
else {
delete pendingEvent;
pendingEvent = (PEvent)NULL;
BackUps::HandleLineConditionEvent(anEvent);
}
break;
case ABNORMAL_CONDITION:
BackUps::HandleLineConditionEvent(anEvent);
break;
default:
break;
}
}
//-------------------------------------------------------------------------
VOID SmartUps::HandleBatteryConditionEvent(PEvent anEvent)
{
CHAR value[32];
INT err = theBatteryCapacitySensor->DeepGet(value);
if (err != ErrUNSUPPORTED) {
anEvent->AppendAttribute(BATTERY_CAPACITY, value);
}
BackUps::HandleBatteryConditionEvent(anEvent);
}
//-------------------------------------------------------------------------
VOID SmartUps::HandleLightsTestEvent(PEvent anEvent)
{
switch(atoi(anEvent->GetValue())) {
case LIGHTS_TEST_IN_PROGRESS:
SET_BIT(theUpsState, LIGHTS_TEST_BIT);
break;
case NO_LIGHTS_TEST_IN_PROGRESS:
CLEAR_BIT(theUpsState, LIGHTS_TEST_BIT);
break;
default:
break;
}
UpdateObj::Update(anEvent);
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
VOID SmartUps::HandleSelfTestEvent(PEvent anEvent)
{
switch(atoi(anEvent->GetValue())) {
case SELF_TEST_IN_PROGRESS:
SET_BIT(theUpsState, SELF_TEST_BIT);
break;
case NO_SELF_TEST_IN_PROGRESS:
CLEAR_BIT(theUpsState, SELF_TEST_BIT);
break;
default:
break;
}
UpdateObj::Update(anEvent);
}
//-------------------------------------------------------------------------
VOID SmartUps::HandleBatteryCalibrationEvent(PEvent anEvent)
{
switch(atoi(anEvent->GetValue())) {
case BATTERY_CALIBRATION_IN_PROGRESS:
SET_BIT(theUpsState, BATTERY_CALIBRATION_BIT);
break;
case NO_BATTERY_CALIBRATION_IN_PROGRESS:
case BATTERY_CALIBRATION_CANCELLED:
// printf("Battery Calibration Cancelled/ended\n");
CLEAR_BIT(theUpsState, BATTERY_CALIBRATION_BIT);
break;
default:
break;
}
UpdateObj::Update(anEvent);
}
//-------------------------------------------------------------------------
VOID SmartUps::HandleSmartBoostEvent(PEvent anEvent)
{
switch(atoi(anEvent->GetValue()))
{
case SMART_BOOST_ON:
// If we're not already on boost, Send the event
if (!(IS_STATE(UPS_STATE_ON_BOOST | UPS_STATE_IN_LIGHTS_TEST)))
{
SET_BIT(theUpsState, SMART_BOOST_BIT);
UpdateObj::Update(anEvent);
}
break;
case SMART_BOOST_OFF:
if (IS_STATE(UPS_STATE_ON_BOOST)) {
CLEAR_BIT(theUpsState, SMART_BOOST_BIT);
UpdateObj::Update(anEvent);
}
break;
// THIS WILL BE HANDLED BY THE HandleLineCondition
default:
break;
}
}
//-------------------------------------------------------------------------
VOID SmartUps::HandleSmartTrimEvent(PEvent anEvent)
{
switch(atoi(anEvent->GetValue()))
{
case SMART_TRIM_ON:
// If we're not already on trim, Send the event
if (!(IS_STATE(UPS_STATE_ON_TRIM | UPS_STATE_IN_LIGHTS_TEST)))
{
SET_BIT(theUpsState, SMART_TRIM_BIT);
UpdateObj::Update(anEvent);
}
break;
case SMART_TRIM_OFF:
if (IS_STATE(UPS_STATE_ON_TRIM)) {
CLEAR_BIT(theUpsState, SMART_TRIM_BIT);
UpdateObj::Update(anEvent);
}
default:
break;
}
}
//-------------------------------------------------------------------------
VOID SmartUps::HandleOverloadConditionEvent(PEvent anEvent)
{
switch(atoi(anEvent->GetValue())) {
case UPS_OVERLOAD:
if (!IS_STATE(UPS_STATE_IN_LIGHTS_TEST))
SET_BIT(theUpsState, OVERLOAD_BIT);
break;
case NO_UPS_OVERLOAD:
CLEAR_BIT(theUpsState, OVERLOAD_BIT);
break;
default:
break;
}
UpdateObj::Update(anEvent);
}
//-------------------------------------------------------------------------
INT SmartUps::MakeBatteryCapacitySensor(const PFirmwareRevSensor rev)
{
INT make_sensor = FALSE;
CHAR Battery_Capacity_Capable[32];
rev->Get(IS_BATTERY_CAPACITY,Battery_Capacity_Capable);
if (_strcmpi(Battery_Capacity_Capable,"Yes") == 0)
{
make_sensor = TRUE;
}
if (make_sensor) {
theBatteryCapacitySensor =
new BatteryCapacitySensor(this, theCommController);
}
else {
theBatteryCapacitySensor = &_theUnsupportedSensor;
}
return ErrNO_ERROR;
}
//-------------------------------------------------------------------------
INT SmartUps::MakeSmartBoostSensor(const PFirmwareRevSensor rev)
{
CHAR Smart_Boost_Capable[32];
rev->Get(IS_SMARTBOOST,Smart_Boost_Capable);
if (_strcmpi(Smart_Boost_Capable, "Yes") == 0)
{
theSmartBoostSensor = new SmartBoostSensor(this, theCommController);
}
else
{
theSmartBoostSensor = &_theUnsupportedSensor;
}
return ErrNO_ERROR;
}
//-------------------------------------------------------------------------
INT SmartUps::MakeSmartTrimSensor(const PFirmwareRevSensor rev)
{
CHAR Smart_Trim_Capable[32];
rev->Get(IS_SMARTTRIM,Smart_Trim_Capable);
if (_strcmpi(Smart_Trim_Capable, "Yes") == 0)
{
theSmartTrimSensor = new SmartTrimSensor (this, theCommController);
}
else
{
theSmartTrimSensor = &_theUnsupportedSensor;
}
return ErrNO_ERROR;
}
//-------------------------------------------------------------------------
INT SmartUps::MakeCopyrightSensor(const PFirmwareRevSensor rev)
{
CHAR Copyright_Capable[32];
rev->Get(IS_COPYRIGHT,Copyright_Capable);
if (_strcmpi(Copyright_Capable, "No") == 0)
{
theCopyrightSensor = &_theUnsupportedSensor;
}
else
{
theCopyrightSensor = new CopyrightSensor(this, theCommController);
}
return ErrNO_ERROR;
}
//-------------------------------------------------------------------------
INT SmartUps::MakeRunTimeRemainingSensor(const PFirmwareRevSensor rev)
{
CHAR Run_Time_Capable[32];
rev->Get(IS_RUNTIME_REMAINING,Run_Time_Capable);
if (_strcmpi(Run_Time_Capable, "No") == 0)
{
theRunTimeRemainingSensor = &_theUnsupportedSensor;
}
else
{
theRunTimeRemainingSensor = new RunTimeRemainingSensor(this, theCommController);
}
return ErrNO_ERROR;
}
//-------------------------------------------------------------------------
INT SmartUps::MakeLowBatteryDurationSensor(const PFirmwareRevSensor rev)
{
CHAR Low_Battery_Duration_Capable[32];
rev->Get(IS_LOW_BATTERY_DURATION,Low_Battery_Duration_Capable);
if (_strcmpi(Low_Battery_Duration_Capable, "No") == 0)
{
theLowBatteryDurationSensor = &_theUnsupportedSensor;
}
else
{
theLowBatteryDurationSensor = new LowBatteryDurationSensor(this, theCommController);
}
return ErrNO_ERROR;
}
//-------------------------------------------------------------------------
INT SmartUps::MakeShutdownDelaySensor(const PFirmwareRevSensor rev)
{
CHAR Shutdown_Delay_Capable[32];
rev->Get(IS_SHUTDOWN_DELAY,Shutdown_Delay_Capable);
if (_strcmpi(Shutdown_Delay_Capable, "No") == 0)
{
theShutdownDelaySensor = &_theUnsupportedSensor;
}
else
{
theShutdownDelaySensor = new ShutdownDelaySensor(this, theCommController);
}
return ErrNO_ERROR;
}
//-------------------------------------------------------------------------
INT SmartUps::MakeManufactureDateSensor(const PFirmwareRevSensor rev)
{
CHAR Manufacture_Date_Capable[32];
rev->Get(IS_MANUFACTURE_DATE,Manufacture_Date_Capable);
if (_strcmpi(Manufacture_Date_Capable, "No") == 0)
{
theManufactureDateSensor = &_theUnsupportedSensor;
}
else
{
theManufactureDateSensor = new ManufactureDateSensor(this, theCommController);
}
return ErrNO_ERROR;
}
//-------------------------------------------------------------------------
INT SmartUps::MakeUpsSerialNumberSensor(const PFirmwareRevSensor rev)
{
CHAR Serial_Number_Capable[32];
rev->Get(IS_SERIAL_NUMBER,Serial_Number_Capable);
if (_strcmpi(Serial_Number_Capable, "No") == 0)
{
theUpsSerialNumberSensor = &_theUnsupportedSensor;
}
else
{
theUpsSerialNumberSensor = new UpsSerialNumberSensor(this, theCommController);
}
return ErrNO_ERROR;
}
//-------------------------------------------------------------------------
INT SmartUps::MakeTurnOffWithDelaySensor(const PFirmwareRevSensor rev)
{
CHAR Turn_Off_Delay_Capable[32];
rev->Get(IS_TURN_OFF_WITH_DELAY,Turn_Off_Delay_Capable);
if (_strcmpi(Turn_Off_Delay_Capable, "No") == 0)
{
theTurnOffWithDelaySensor = &_theUnsupportedSensor;
}
else {
theTurnOffWithDelaySensor =
new TurnOffWithDelaySensor(this, theCommController);
}
return ErrNO_ERROR;
}
//-------------------------------------------------------------------------
INT SmartUps::MakePutUpsToSleepSensor()
{
// SU400/370 and SU250 don't support sleep mode if auto-on
// is enabled.
//
CHAR val[32];
Get(IS_LOAD_SENSING_ON, val);
if (_strcmpi(val, "YES") == 0) {
thePutUpsToSleepSensor = &_theUnsupportedSensor;
}
else {
thePutUpsToSleepSensor =
new PutUpsToSleepSensor(this, theCommController);
}
return ErrNO_ERROR;
}
VOID
SmartUps::setEepromAccess(INT anAccessCode)
{
((PEepromChoiceSensor)theCopyrightSensor)->SetEepromAccess(anAccessCode);
((PEepromChoiceSensor)theManufactureDateSensor)->SetEepromAccess(anAccessCode);
((PEepromChoiceSensor)theLowBatteryDurationSensor)->SetEepromAccess(anAccessCode);
((PEepromChoiceSensor)theShutdownDelaySensor)->SetEepromAccess(anAccessCode);
((PEepromChoiceSensor)theUpsSerialNumberSensor)->SetEepromAccess(anAccessCode);
theBatteryReplacementManager->SetEepromAccess(anAccessCode);
}
//-------------------------------------------------------------------------
// This function is only used when the following function
// SmartUps:: AllowedValuesAreGettable returns TRUE. This
// function constructs the EepromAllowedValuesSensor and then
// parses all the information returned from the sensors DeepGet.
//
//-------------------------------------------------------------------------
INT SmartUps:: GetAllAllowedValues(PList ValueList)
{
// Check to see if CTRL Z is an option
INT cCode = ErrNO_ERROR;
if (AllowedValuesAreGettable(theFirmwareRevSensor))
{
// if CTRL Z load CTRL Z values into non Default values.
CHAR value[512];
INT cCode =theCommController->Get(UPS_ALLOWED_VALUES, value);
if (cCode == ErrNO_ERROR)
cCode = ParseValues(value, ValueList);
}
return cCode;
}
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
INT SmartUps:: ParseValues(CHAR* string, PList ValueList)
{
INT Done = FALSE;
CHAR sensorCode[56];
CHAR upsType[10];
CHAR allValues[128];
while (!Done)
{
CHAR value[128];
string = string+1; // skip the first "#" sign
INT valsize = strcspn(string,"#");
strncpy(value,string,valsize);
value[valsize] = 0;
if (sscanf(value, "%[^,],%1c,%[^#]",sensorCode, upsType, allValues) != EOF) {
AllowedValueItem* item = new AllowedValueItem(atoi(sensorCode),
upsType[0],
allValues);
ValueList->Append(item);
}
string = string + valsize;
if (string[1] == 0)
Done = TRUE;
}
return ErrNO_ERROR;
}
//-------------------------------------------------------------------------
// This function checks the firmware revision to determine if the CTRL Z
// command is valid to use on this UPS.
//
//-------------------------------------------------------------------------
INT SmartUps:: AllowedValuesAreGettable(PSensor theFirmwareRevSensor)
{
CHAR CTRL_Z_Capable[32];
theFirmwareRevSensor->Get(IS_CTRL_Z,CTRL_Z_Capable);
if (_strcmpi(CTRL_Z_Capable, "No") == 0)
return FALSE;
else
return TRUE;
}
VOID SmartUps:: FindAllowedValues(INT code, CHAR *aValue, PFirmwareRevSensor aFirmwareSensor )
{
INT Found = FALSE;
aValue[0] = 0;
if (AllowedValuesList)
{
AllowedValueItem* item = (AllowedValueItem*)AllowedValuesList->GetHead();
ListIterator iter((RList)*AllowedValuesList);
while(!Found && item)
{
if (item->GetUpsCode() == code)
{
CHAR Country_Code[32];
aFirmwareSensor->Get(COUNTRY_CODE,Country_Code);
INT cc = atoi(Country_Code);
if ( (item->GetUpsType() == '4') ||
( (INT)item->GetUpsType() == cc) )
{
strcpy(aValue, item->GetValue());
Found = TRUE;
}
}
item = (AllowedValueItem*)iter.Next();
}
}
}
AllowedValueItem :: AllowedValueItem(INT Code,CHAR Type, CHAR* Value) :
theUpsType(0),
theValue((CHAR*)NULL)
{
theCode = Code;
theUpsType = Type;
theValue = _strdup(Value);
}
AllowedValueItem :: ~AllowedValueItem()
{
if (theValue)
free(theValue);
}