/* * 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 extern "C" { #include } #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); }