WARN_INTERVAL 3600

START	0010	MACRO_POWER	"Macro for Individual Power Sensor Policy"
A S $(MACRO_ARG0) ST_LOW_CRIT		LOG("%s is critical low (%r).")
A S $(MACRO_ARG0) ST_LOW_CRIT		150/EMS(EMS_monitor_chassisPower_degraded, "%s is critical low (%r).")
A S $(MACRO_ARG0) ST_LOW_CRIT		150/SET_VALUE(ctrl_volt_status, BAD)
A S $(MACRO_ARG0) ST_LOW_CRIT		ADD_VALUE(ctrl_volt_bucket, 1)
A S $(MACRO_ARG0) ST_LOW_WARN		LOG("%s is warning low (%r).")
A S $(MACRO_ARG0) ST_HIGH_WARN		LOG("%s is warning high (%r).")
A S $(MACRO_ARG0) ST_HIGH_CRIT		LOG("%s is critical high (%r).")
A S $(MACRO_ARG0) ST_HIGH_CRIT		150/EMS(EMS_monitor_chassisPower_degraded, "%s is critical high (%r).")
A S $(MACRO_ARG0) ST_HIGH_CRIT		150/SET_VALUE(ctrl_volt_status, BAD)
A S $(MACRO_ARG0) ST_HIGH_CRIT		ADD_VALUE(ctrl_volt_bucket, 1)
A S $(MACRO_ARG0) [ST_FAILED|ST_NA]	EMS(EMS_monitor_power_unreadable),SET_VALUE(ctrl_volt_status, BAD)
END	0010

START   4000    FASRAZL		"Put the description for Razor L here"

S init	"init"		DISCRETE	- - 0 0  hidden	0*/INIT

# id    devname		type    dev_poll    sens_poll
C 4001  core		CORE    0           0

S temp_snmp	"Is Board Over Temp"	DISCRETE	4001 "core:temp_snmp"		0 0	hidden	0*/NORMAL_TEMP 1/UNDER_TEMP 2/OVER_TEMP
S db_batt	"Dblade Battery Status"	DISCRETE	4001 "core:bat_snmp"		0 0	hidden	1*/OK 2/PARTIALLY_DISCHARGED 3/FULLY_DISCHARGED 4/NOT_PRESENT 8/OVER_CHARGED 9/FULLY_CHARGED
S batt_charge	"Battery Charge"	DISCRETE	4001 "core:bat_charge"		0 0	hidden	0/BAD 1*/GOOD
S mplink_status	"Mgmt Port Link"	-		4001 "core:link_status"		0 0	hidden	- - - - - - - -
S psu_count	"PSU Count"		COUNTER		4001 "core:psu_count"		0 0	hidden	- - - - - - - -
S fan_count	"Fan Count"		COUNTER		4001 "core:fan_count"		0 0	hidden	- - - - - - - -
S tzone_count	"Thermal Zone Count"	COUNTER		4001 "core:tzone_count"		0 0	hidden	- - - - - - - -
S bat_count	"Bat Count"		COUNTER		4001 "core:bat_count"		0 0	hidden	- - - - - - - -
S mplink_count	"Mgmt Port Count"	COUNTER		4001 "core:linkstatus_count"	0 0	hidden	- - - - - - - -
S nv0_type	"NV0 Type"		DISCRETE	4001 "core:nv0_type"		0 0	hidden	1*/TYPE_NVRAM 2*/TYPE_NVMEM 255/TYPE_UNKNOWN
S nv0_batvolt	"NV0 Battery Voltage"	VOLTAGE		4001 "core:nv0_bat_volt"	0 0	hidden,follow	- - - - - - - -
S nv0_batstate	"NV0 Battery State"	DISCRETE	4001 "core:nv0_bat_st"		0 0	hidden	1*/OK 2/PARTIALLY_DISCHARGED 3/FULLY_DISCHARGED 4/NOT_PRESENT 8/OVER_CHARGED 9/FULLY_CHARGED


# Action initiators
# Action name			min	max	flags
I 4001	update_sen_list		0	0	-
I 4001	splog_get		0	30	payload
I 4001  fail_safe               0       30      -
I 4001	update_snmp		0	256	payload
I 4001  env_halt		0	1	payload
I 4001	check_devfw		0	1	exclusive
I 4001  fruinfo_get             0       5       payload
I 4001	update_fru_state	0	5	payload
I 4001	update_fru_list		0	256	payload
I 4001	prog_nvbat_led		0	255	-


A S init ST_UNINITIALIZED	SET_VALUE(tzone_count, 1)
A S init ST_UNINITIALIZED	SET_VALUE(fan_count, 6)
A S init ST_UNINITIALIZED	SET_VALUE(psu_count, 2)
A S init ST_UNINITIALIZED	SET_VALUE(bat_count, 1)
A S init ST_UNINITIALIZED	SET_VALUE(mplink_count, 1)
A S init ST_INVALID		DO(update_fru_list, 0)

# CONTROLLING DEVICE
# id    devname		type    dev_poll    sens_poll
C 3001  ipmi		IPMI    300         60

# id			name			type	     cdev_id cdev_adr	   retries interval  flags		states
S Attn_Sensor1		"Attention"		DISCRETE	3001 "ipmi:20:00:c8"	      3	      10  -		1*/DEASSERT 2/ASSERT
S Partner_Ctrl_Pre	"Partner Ctrl Pre"	DISCRETE	3001 "ipmi:20:00:6b"	      3       10  -		1*/PRESENT 2*/NOT_PRESENT 128/ERROR
S Wrench_Port_Up	"Wrench Port Up"	DISCRETE	3001 "ipmi:20:00:b7"	      3	      10  hidden	1/DOWN 2*/UP
S Bat_Pack_Invalid	"Bat Pack Invalid"	DISCRETE	3001 "ipmi:20:00:b9"	      3	      10  hidden	1*/OK 2/INVALID
S Bat_Lrn_Active	"Bat Learning Active"	DISCRETE	3001 "ipmi:20:00:ea"	      3       10  hidden	1*/OFF 2*/ON
S Bat_Cycle_Cnt		"Bat Cycle Count"	COUNTER		3001 "ipmi:20:00:e7"	      3       10  pull		- - - - - - - -
S Bat_Charge_FET	"Bat Charge FET"	DISCRETE	3001 "ipmi:20:00:6a"	      3       10  -		1*/ON 2/OFF
S Bat_Dcharge_FET	"Bat Dcharge FET"	DISCRETE	3001 "ipmi:20:00:69"	      3       10  -		1*/ON 2/OFF
S Bat_Power_Fault	"Bat Power Fault"	DISCRETE	3001 "ipmi:20:00:66"	      3       10  -		1*/GOOD 2/BAD
S Bat_Dstg_Cycles	"Bat Dstg Cycles"	COUNTER		3001 "ipmi:20:00:65"	      3       10  pull		- - - - - - - -
S Bat_Initial_Fcc	"Bat Initial FCC"	BATTLIFE	3001 "ipmi:20:00:de"	      3       10  pull		- - - - - - - -
S Bat_Charge_Volt	"Bat Charge Volt"	VOLTAGE		3001 "ipmi:20:00:62"	      3       10  pull		- - - - - - - -
# Pseudo sensor to encapsulate the Bat_Charge_Curr and Bat_Curr
S Bat_Charge_State	"Bat Charging State"	DISCRETE	- -			      0        0  hidden	0*/IDLE 1*/CHARGING 2/WRONG_CHARGE 3/NO_CHARGE
S Bat_Charge_Curr	"Bat Charge Curr"	CURRENT		3001 "ipmi:20:00:61"	      3       10  pull		- - - - - - - -
S Bat_Full_Cap		"Bat Full Cap"		BATTLIFE	3001 "ipmi:20:00:60"	      3       10  pull		- - - - - - - -
S Bat_Rem_Cap		"Bat Rem Cap"		BATTLIFE	3001 "ipmi:20:00:5f"	      3       10  pull		- - - - - - - -
S Bat_Curr		"Bat Curr"		CURRENT		3001 "ipmi:20:00:5e"	      3       10  pull		- - - - - - - -
S Bat_Pct_Cap		"Bat Pct Capacity"	PERCENT		- -			      0        0  hidden	- 39 44 - - - - -
S Bat_Volt		"Bat Volt"		VOLTAGE		3001 "ipmi:20:00:5d"	      3       10  pull		- - - - - - - -
S Bat_Temp		"Bat Temp"		TEMP		3001 "ipmi:20:00:5c"	      3       10  pull		- - - - - - - -
S Bat_Present		"Bat Present"		DISCRETE	- -			      3       10  -		1*/PRESENT 2/NOT_PRESENT
S PSU2_InPwr_Mon	"PSU2 InPwr Monitor"	POWER		3001 "ipmi:20:00:e2"	      3	      10  pull		- - - - - - - -
S PSU2_CrestFactor	"PSU2 Crest Factor"	CURRENT		3001 "ipmi:20:00:e1"	      3	      10  pull		- - - - - - - -
S PSU2_Over_Curr	"PSU2 Over Curr"	DISCRETE	3001 "ipmi:20:00:5b"	      3       10  -		1*/OK 2/OVER_CURR
S PSU2_Over_Volt	"PSU2 Over Volt"	DISCRETE	3001 "ipmi:20:00:5a"	      3       10  -		1*/OK 2/OVER_VOLT
S PSU2_Over_Temp	"PSU2 Over Temp"	DISCRETE	3001 "ipmi:20:00:59"	      3       10  -		1*/OK 2/OVER_TEMP
S PSU2_Input_Type	"PSU2 Input Type"	DISCRETE	3001 "ipmi:20:00:58"	      3       10  hidden	1*/AC_220V 2*/AC_110V
S PSU2_Fault		"PSU2 FAULT"		DISCRETE	3001 "ipmi:20:00:57"	      3       10  -		1*/OK 2/FAULT
S PSU2_Pwr_Out_OK	"PSU2 Pwr Out OK"	DISCRETE	3001 "ipmi:20:00:56"	      3       10  -		1/FAULT 2*/OK
S PSU2_Pwr_In_OK	"PSU2 Pwr In OK"	DISCRETE	3001 "ipmi:20:00:55"	      3       10  -		1/FAULT 2*/OK
S PSU2_Fan2_Fault	"PSU2 Fan2 Fault"	DISCRETE	3001 "ipmi:20:00:53"	      3       10  -		1*/OK 2/FAULT
S PSU2_Fan2_Speed	"PSU2 Fan2 Speed"	FAN		3001 "ipmi:20:00:52"	      3       10  pull		- - - - - - - -
S PSU2_Fan1_Fault	"PSU2 Fan1 Fault"	DISCRETE	3001 "ipmi:20:00:51"	      3       10  -		1*/OK 2/FAULT
S PSU2_Fan1_Speed	"PSU2 Fan1 Speed"	FAN		3001 "ipmi:20:00:50"	      3       10  pull		- - - - - - - -
S PSU2_Curr		"PSU2 Curr"		CURRENT		3001 "ipmi:20:00:4f"	      3       10  pull		- - - - - - - -
S PSU2_Temp		"PSU2 Temp"		TEMP		3001 "ipmi:20:00:4e"	      3       10  pull		- - - - - - - -
S PSU2_Present		"PSU2 Present"		DISCRETE	3001 "ipmi:20:00:4d"	      3       10  -		1*/PRESENT 2/NOT_PRESENT
S PSU1_InPwr_Mon	"PSU1 InPwr Monitor"	POWER		3001 "ipmi:20:00:e0"	      3	      10  pull		- - - - - - - -
S PSU1_CrestFactor	"PSU1 Crest Factor"	CURRENT		3001 "ipmi:20:00:df"	      3	      10  pull		- - - - - - - -
S PSU1_Over_Curr	"PSU1 Over Curr"	DISCRETE	3001 "ipmi:20:00:4c"	      3       10  -		1*/OK 2/OVER_CURR
S PSU1_Over_Volt	"PSU1 Over Volt"	DISCRETE	3001 "ipmi:20:00:4b"	      3       10  -		1*/OK 2/OVER_VOLT
S PSU1_Over_Temp	"PSU1 Over Temp"	DISCRETE	3001 "ipmi:20:00:4a"	      3       10  -		1*/OK 2/OVER_TEMP
S PSU1_Input_Type	"PSU1 Input Type"	DISCRETE	3001 "ipmi:20:00:49"	      3       10  hidden	1*/AC_220V 2*/AC_110V
S PSU1_Fault		"PSU1 FAULT"		DISCRETE	3001 "ipmi:20:00:48"	      3       10  -		1*/OK 2/FAULT
S PSU1_Pwr_Out_OK	"PSU1 Pwr Out OK"	DISCRETE	3001 "ipmi:20:00:47"	      3       10  -		1/FAULT 2*/OK
S PSU1_Pwr_In_OK	"PSU1 Pwr In OK"	DISCRETE	3001 "ipmi:20:00:46"	      3       10  -		1/FAULT 2*/OK
S PSU1_Fan2_Fault	"PSU1 Fan2 Fault"	DISCRETE	3001 "ipmi:20:00:44"	      3       10  -		1*/OK 2/FAULT
S PSU1_Fan2_Speed	"PSU1 Fan2 Speed"	FAN		3001 "ipmi:20:00:43"	      3       10  pull		- - - - - - - -
S PSU1_Fan1_Fault	"PSU1 Fan1 Fault"	DISCRETE	3001 "ipmi:20:00:42"	      3       10  -		1*/OK 2/FAULT
S PSU1_Fan1_Speed	"PSU1 Fan1 Speed"	FAN		3001 "ipmi:20:00:41"	      3       10  pull		- - - - - - - -
S PSU1_Curr		"PSU1 Curr"		CURRENT		3001 "ipmi:20:00:40"	      3       10  pull		- - - - - - - -
S PSU1_Temp		"PSU1 Temp"		TEMP		3001 "ipmi:20:00:3f"	      3       10  pull		- - - - - - - -
S PSU1_Present		"PSU1 Present"		DISCRETE	3001 "ipmi:20:00:3e"	      3       10  -		1*/PRESENT 2/NOT_PRESENT
S Fan_Override		"Fan Override"		DISCRETE	3001 "ipmi:20:00:3d"	      3       10  hidden	1*/NORMAL 2/OVERRIDE
S Sysfan3_F2_Speed	"Sysfan3 F2 Speed"	FAN		3001 "ipmi:20:00:3c"	      3       10  pull		- - - - - - - -
S Sysfan3_F1_Speed	"Sysfan3 F1 Speed"	FAN		3001 "ipmi:20:00:3b"	      3       10  pull		- - - - - - - -
S Sysfan3_Fault		"Sysfan3 Fault"		DISCRETE	3001 "ipmi:20:00:3a"	      3       10  -		1*/OK 2/FAULT
S Sysfan3_Present	"Sysfan3 Present"	DISCRETE	3001 "ipmi:20:00:39"	      3       10  -		1*/PRESENT 2/NOT_PRESENT
S Sysfan2_F2_Speed	"Sysfan2 F2 Speed"	FAN		3001 "ipmi:20:00:38"	      3       10  pull		- - - - - - - -
S Sysfan2_F1_Speed	"Sysfan2 F1 Speed"	FAN		3001 "ipmi:20:00:37"	      3       10  pull		- - - - - - - -
S Sysfan2_Fault		"Sysfan2 Fault"		DISCRETE	3001 "ipmi:20:00:36"	      3       10  -		1*/OK 2/FAULT
S Sysfan2_Present	"Sysfan2 Present"	DISCRETE	3001 "ipmi:20:00:35"	      3       10  -		1*/PRESENT 2/NOT_PRESENT
S Sysfan1_F2_Speed	"Sysfan1 F2 Speed"	FAN		3001 "ipmi:20:00:34"	      3       10  pull		- - - - - - - -
S Sysfan1_F1_Speed	"Sysfan1 F1 Speed"	FAN		3001 "ipmi:20:00:33"	      3       10  pull		- - - - - - - -
S Sysfan1_Fault		"Sysfan1 Fault"		DISCRETE	3001 "ipmi:20:00:32"	      3       10  -		1*/OK 2/FAULT
S Sysfan1_Present	"Sysfan1 Present"	DISCRETE	3001 "ipmi:20:00:31"	      3       10  -		1*/PRESENT 2/NOT_PRESENT
S P12V_STBY_Curr	"P12V STBY Curr"	CURRENT		3001 "ipmi:20:00:d5"	      3	      10  pull		- - - - - - - -
S P12V_STBY		"P12V STBY"		VOLTAGE		3001 "ipmi:20:00:d4"	      3	      10  pull		- - - - - - - -
S P12V_Curr		"P12V Curr"		CURRENT		3001 "ipmi:20:00:d2"	      3	      10  pull		- - - - - - - -
S P12V			"P12V"			VOLTAGE		3001 "ipmi:20:00:d1"	      3	      10  pull		- - - - - - - -
S P3V3_BATT		"P3.3V BATT"		VOLTAGE		3001 "ipmi:20:00:1d"	      3	      10  pull		- - - - - - - -
S PVCCP_CPU0		"PVCCP CPU0"		VOLTAGE		3001 "ipmi:20:00:1b"	      3       10  pull		- - - - - - - -
S PVTT_DDR4_AB		"PVTT DDR4 AB"		VOLTAGE		3001 "ipmi:20:00:1a"	      3       10  pull		- - - - - - - -
S PVDDQ_DDR4_AB		"PVDDQ DDR4 AB"		VOLTAGE		3001 "ipmi:20:00:19"	      3       10  pull		- - - - - - - -
S P3V3			"P3.3V"			VOLTAGE		3001 "ipmi:20:00:18"	      3       10  pull		- - - - - - - -
S P5V			"P5V"			VOLTAGE		3001 "ipmi:20:00:17"	      3       10  pull		- - - - - - - -
S P0V9_STBY		"P0.9V STBY"		VOLTAGE		3001 "ipmi:20:00:16"	      3       10  pull		- - - - - - - -
S P1V2_STBY		"P1.2V STBY"		VOLTAGE		3001 "ipmi:20:00:15"	      3       10  pull		- - - - - - - -
S P1V8_STBY		"P1.8V STBY"		VOLTAGE		3001 "ipmi:20:00:14"	      3       10  pull		- - - - - - - -
S P3V3_STBY		"P3.3V STBY"		VOLTAGE		3001 "ipmi:20:00:13"	      3       10  pull		- - - - - - - -
S P5V_STBY		"P5V STBY"		VOLTAGE		3001 "ipmi:20:00:12"	      3       10  pull		- - - - - - - -
S Ambient_Temp_2	"Ambient Temp 2"	TEMP		3001 "ipmi:20:00:e6"	      3       10  pull		- - - - - - - -
S Ambient_Temp_1	"Ambient Temp 1"	TEMP		3001 "ipmi:20:00:e5"	      3       10  pull		- - - - - - - -
S PCH_Hot		"PCH Hot"		DISCRETE	3001 "ipmi:20:00:11"	      3       10  -		1*/NORMAL 2/HOT
S Memory0_Hot		"Memory0 Hot"		DISCRETE	3001 "ipmi:20:00:09"	      3       10  -		1*/NORMAL 2/HOT
S CPU0_Hot		"CPU0 Hot"		DISCRETE	3001 "ipmi:20:00:08"	      3       10  -		1*/NORMAL 2/HOT
S CPU0_Therm_Trip	"CPU0 Therm Trip"	DISCRETE	3001 "ipmi:20:00:07"	      3       10  -		1*/NORMAL 2/FAULT
S CPU0_Error		"CPU0 Error"		DISCRETE	3001 "ipmi:20:00:06"	      3       10  -		1*/NORMAL 2/ERROR
S Smart_Bat_Temp	"Smart Bat Temp"	TEMP		3001 "ipmi:20:00:05"	      3       10  pull		- - - - - - - -
S PCI_Slot_Temp		"PCI Slot Temp"		TEMP		3001 "ipmi:20:00:04"	      3       10  pull		- - - - - - - -
S Out_Flow_Temp		"Out Flow Temp"		TEMP		3001 "ipmi:20:00:03"	      3       10  pull		- - - - - - - -
S In_Flow_Temp		"In Flow Temp"		TEMP		3001 "ipmi:20:00:02"	      3       10  pull		- - - - - - - -
S CPU0_Temp_Margin	"CPU0 Temp Margin"	TEMP		3001 "ipmi:20:00:00"	      3       10  pull		- - - - - - - -

# Define the FRU sensors
# id			name		type	cdev_id cdev_adr     fru_id retry_int flags	states
S FRU_PSU2		"PSU2"		FRU	3001 "ipmi:82:07:02" 7	60	hidden,phm	0*/GOOD 1/NOT_PRESENT 2/PSU_FAULT 3/PSU_OFF 4/FAN_BAD 5/FAN_WARN 6/FAN_CRIT 7/OVER_TEMP 8/OVER_CURR 9/OVER_VOLT 10/MULTIFAULT
S FRU_PSU1		"PSU1"		FRU	3001 "ipmi:80:06:02" 6	60	hidden,phm	0*/GOOD 1/NOT_PRESENT 2/PSU_FAULT 3/PSU_OFF 4/FAN_BAD 5/FAN_WARN 6/FAN_CRIT 7/OVER_TEMP 8/OVER_CURR 9/OVER_VOLT 10/MULTIFAULT
S FRU_Fan3		"Fan3"		FRU	3001 "ipmi:66:05:02" 5	60	hidden,phm	0*/GOOD 1/NOT_PRESENT 2/FAN1_WARN 3/FAN1_CRIT 4/FAN2_WARN 5/FAN2_CRIT 6/FAN_FAULT 7/MULTIFAULT
S FRU_Fan2		"Fan2"		FRU	3001 "ipmi:66:04:02" 4	60	hidden,phm	0*/GOOD 1/NOT_PRESENT 2/FAN1_WARN 3/FAN1_CRIT 4/FAN2_WARN 5/FAN2_CRIT 6/FAN_FAULT 7/MULTIFAULT
S FRU_Fan1		"Fan1"		FRU	3001 "ipmi:66:03:02" 3	60	hidden,phm	0*/GOOD 1/NOT_PRESENT 2/FAN1_WARN 3/FAN1_CRIT 4/FAN2_WARN 5/FAN2_CRIT 6/FAN_FAULT 7/MULTIFAULT

# Corresponding FRU info availability state.  The discrete values are defined as
# sensor_update_fru_follower(action->target_sensor, (rv == ENV_SUCCESS));
# in policy.c:policy_update_fru()
S PSU1_INFO		"PSU1 INFO"	DISCRETE	- - - -	hidden	1*/FRU_AVAIL 0/FRU_NA 2/FAILED
S PSU2_INFO		"PSU1 INFO"	DISCRETE	- - - -	hidden	1*/FRU_AVAIL 0/FRU_NA 2/FAILED
S Fan1_INFO		"Fan1 INFO"	DISCRETE	- - - -	hidden	1*/FRU_AVAIL 0/FRU_NA 2/FAILED
S Fan2_INFO		"Fan2 INFO"	DISCRETE	- - - -	hidden	1*/FRU_AVAIL 0/FRU_NA 2/FAILED
S Fan3_INFO		"Fan3 INFO"	DISCRETE	- - - -	hidden	1*/FRU_AVAIL 0/FRU_NA 2/FAILED
F PSU1_INFO FRUINFO	FRU_PSU1
F PSU2_INFO FRUINFO	FRU_PSU2
F Fan1_INFO FRUINFO	FRU_Fan1
F Fan2_INFO FRUINFO	FRU_Fan2
F Fan3_INFO FRUINFO	FRU_Fan3

###############################################################################################################
#                                              Razor-L FRU Policy                                             #
###############################################################################################################
#
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_fru_info_readable_Fan1)
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_fru_info_readable_Fan2)
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_fru_info_readable_Fan3)
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_fru_info_readable_PSU1)
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_fru_info_readable_PSU2)

#
A S PSU1_INFO	!FRU_AVAIL	300/EMS(EMS_monitor_fru_info_unreadable, "PSU1"), 300/ARM(EMS_monitor_fru_info_readable_PSU1)
A S PSU2_INFO	!FRU_AVAIL	300/EMS(EMS_monitor_fru_info_unreadable, "PSU2"), 300/ARM(EMS_monitor_fru_info_readable_PSU2)
A S Fan1_INFO	!FRU_AVAIL	300/EMS(EMS_monitor_fru_info_unreadable, "Fan1"), 300/ARM(EMS_monitor_fru_info_readable_Fan1)
A S Fan2_INFO	!FRU_AVAIL	300/EMS(EMS_monitor_fru_info_unreadable, "Fan2"), 300/ARM(EMS_monitor_fru_info_readable_Fan2)
A S Fan3_INFO	!FRU_AVAIL	300/EMS(EMS_monitor_fru_info_unreadable, "Fan3"), 300/ARM(EMS_monitor_fru_info_readable_Fan3)
A S PSU1_INFO	FRU_AVAIL	+0/EMS(EMS_monitor_fru_info_readable_PSU1, "PSU1")
A S PSU2_INFO	FRU_AVAIL	+0/EMS(EMS_monitor_fru_info_readable_PSU2, "PSU2")
A S Fan1_INFO	FRU_AVAIL	+0/EMS(EMS_monitor_fru_info_readable_Fan1, "Fan1")
A S Fan2_INFO	FRU_AVAIL	+0/EMS(EMS_monitor_fru_info_readable_Fan2, "Fan2")
A S Fan3_INFO	FRU_AVAIL	+0/EMS(EMS_monitor_fru_info_readable_Fan3, "Fan3")

A S PSU1_Present	PRESENT				30/UPDATE_FRU(FRU_PSU1, READ)
A S PSU2_Present	PRESENT				30/UPDATE_FRU(FRU_PSU2, READ)
A S Sysfan1_Present	PRESENT				30/UPDATE_FRU(FRU_Fan1, READ)
A S Sysfan2_Present	PRESENT				30/UPDATE_FRU(FRU_Fan2, READ)
A S Sysfan3_Present	PRESENT				30/UPDATE_FRU(FRU_Fan3, READ)
A S PSU1_Present	[NOT_PRESENT|ST_DISABLED]	UPDATE_FRU(FRU_PSU1, CLEAR)
A S PSU2_Present	[NOT_PRESENT|ST_DISABLED]	UPDATE_FRU(FRU_PSU2, CLEAR)
A S Sysfan1_Present	[NOT_PRESENT|ST_DISABLED]	UPDATE_FRU(FRU_Fan1, CLEAR)
A S Sysfan2_Present	[NOT_PRESENT|ST_DISABLED]	UPDATE_FRU(FRU_Fan2, CLEAR)
A S Sysfan3_Present	[NOT_PRESENT|ST_DISABLED]	UPDATE_FRU(FRU_Fan3, CLEAR)

# FRU group actions to set FRU states
# PSU1
S fru_psu1_power	"PSU1 FRU Power"	DISCRETE	- -	0 0	hidden	1*/ON 2/OFF 3/FAULT
S fru_psu1_fan		"PSU1 FRU Fan"		DISCRETE	- -	0 0	hidden	1*/OK 2/WARN 3/CRIT 4/BAD 5/MULTIFAULT

A (PSU1_Pwr_In_OK,PSU1_Pwr_Out_OK) (OK,OK) {2,2}				SET_VALUE(fru_psu1_power, ON)
A (PSU1_Pwr_In_OK,PSU1_Pwr_Out_OK) (FAULT,-) {1,1}				SET_VALUE(fru_psu1_power, OFF)
A (PSU1_Pwr_In_OK,PSU1_Pwr_Out_OK) (OK,[!OK|ST_FAILED|ST_NA]){2,2}		SET_VALUE(fru_psu1_power, FAULT)
A (PSU1_Pwr_In_OK,PSU1_Pwr_Out_OK) ([ST_FAILED|ST_NA],-){1,1}			SET_VALUE(fru_psu1_power, FAULT)

A (PSU1_Fan1_Speed,PSU1_Fan2_Speed,PSU1_Fan1_Fault,PSU1_Fan2_Fault) (ST_OK,ST_OK,OK,OK){4,4}				SET_VALUE (fru_psu1_fan, OK)
A (PSU1_Fan1_Speed,PSU1_Fan2_Speed,PSU1_Fan1_Fault,PSU1_Fan2_Fault) ([ST_HIGH_WARN|ST_LOW_WARN],ST_OK,OK,OK){4,4}	SET_VALUE (fru_psu1_fan, WARN)
A (PSU1_Fan1_Speed,PSU1_Fan2_Speed,PSU1_Fan1_Fault,PSU1_Fan2_Fault) (ST_OK,[ST_HIGH_WARN|ST_LOW_WARN],OK,OK){4,4}	SET_VALUE (fru_psu1_fan, WARN)
A (PSU1_Fan1_Speed,PSU1_Fan2_Speed,PSU1_Fan1_Fault,PSU1_Fan2_Fault) ([ST_HIGH_CRIT|ST_LOW_CRIT],ST_OK,OK,OK){4,4}	SET_VALUE (fru_psu1_fan, CRIT)
A (PSU1_Fan1_Speed,PSU1_Fan2_Speed,PSU1_Fan1_Fault,PSU1_Fan2_Fault) (ST_OK,[ST_HIGH_CRIT|ST_LOW_CRIT],OK,OK){4,4}	SET_VALUE (fru_psu1_fan, CRIT)
A (PSU1_Fan1_Speed,PSU1_Fan2_Speed,PSU1_Fan1_Fault,PSU1_Fan2_Fault) ([ST_HIGH_CRIT|ST_LOW_CRIT|ST_HIGH_WARN|ST_LOW_WARN], \
			[ST_HIGH_CRIT|ST_LOW_CRIT|ST_HIGH_WARN|ST_LOW_WARN], OK,OK){4,4}				SET_VALUE (fru_psu1_fan, MULTIFAULT)
A (PSU1_Fan1_Speed,PSU1_Fan2_Speed,PSU1_Fan1_Fault,PSU1_Fan2_Fault) ([ST_FAILED|ST_NA],[ST_FAILED|ST_NA],[!OK|ST_FAILED|ST_NA],[!OK|ST_FAILED|ST_NA]){1,4}	SET_VALUE (fru_psu1_fan, BAD)

G grp_fru_psu1 PSU1_Present,fru_psu1_power,fru_psu1_fan,PSU1_Fault,PSU1_Over_Temp, PSU1_Over_Volt, PSU1_Over_Curr
A G grp_fru_psu1 (PRESENT,ON,OK,OK,OK,OK,OK){7,7}		SET_VALUE(FRU_PSU1, GOOD)
A G grp_fru_psu1 (NOT_PRESENT,-,-,-,-,-,-){1,1}			SET_VALUE(FRU_PSU1, NOT_PRESENT)
A G grp_fru_psu1 ([ST_FAILED|ST_NA],-,-,-,-,-,-){1,1}		SET_VALUE(FRU_PSU1, PSU_FAULT)
A G grp_fru_psu1 (PRESENT,OFF,-,-,-,-,-){2,2}			SET_VALUE(FRU_PSU1, PSU_OFF)
A G grp_fru_psu1 (PRESENT,ON,BAD,OK,OK,OK,OK){7,7}		SET_VALUE(FRU_PSU1, FAN_BAD)
A G grp_fru_psu1 (PRESENT,ON,WARN,OK,OK,OK,OK){7,7}		SET_VALUE(FRU_PSU1, FAN_WARN)
A G grp_fru_psu1 (PRESENT,ON,CRIT,OK,OK,OK,OK){7,7}		SET_VALUE(FRU_PSU1, FAN_CRIT)
A G grp_fru_psu1 (PRESENT,ON,MULTIFAULT,OK,OK,OK,OK){7,7}	SET_VALUE(FRU_PSU1, MULTIFAULT)
A G grp_fru_psu1 (PRESENT,ON,OK,OK,OVER_TEMP,OK,OK){7,7}	SET_VALUE(FRU_PSU1, OVER_TEMP)
A G grp_fru_psu1 (PRESENT,ON,OK,OK,OK,OK,OVER_CURR){7,7}	SET_VALUE(FRU_PSU1, OVER_CURR)
A G grp_fru_psu1 (PRESENT,ON,OK,OK,OK,OVER_VOLT,OK){7,7}	SET_VALUE(FRU_PSU1, OVER_VOLT)
A G grp_fru_psu1 (PRESENT,FAULT,OK,OK,OK,OK,OK){7,7}			SET_VALUE(FRU_PSU1, PSU_FAULT)
A G grp_fru_psu1 (PRESENT,ON,OK,[FAULT|ST_FAILED|ST_NA],OK,OK,OK){7,7}	SET_VALUE(FRU_PSU1, PSU_FAULT)
A G grp_fru_psu1 (PRESENT,ON,OK,OK,[ST_FAILED|ST_NA],OK,OK){7,7}	SET_VALUE(FRU_PSU1, PSU_FAULT)
A G grp_fru_psu1 (PRESENT,ON,OK,OK,OK,[ST_FAILED|ST_NA],OK){7,7}	SET_VALUE(FRU_PSU1, PSU_FAULT)
A G grp_fru_psu1 (PRESENT,ON,OK,OK,OK,OK,[ST_FAILED|ST_NA]){7,7}	SET_VALUE(FRU_PSU1, PSU_FAULT)
A G grp_fru_psu1 (PRESENT,ON,(!OK,[!OK|ST_FAILED|ST_NA],[!OK|ST_FAILED|ST_NA], \
		 [!OK|ST_FAILED|ST_NA],[!OK|ST_FAILED|ST_NA]) {2,5}) {3,3}	SET_VALUE(FRU_PSU1, MULTIFAULT)
A G grp_fru_psu1 (PRESENT,FAULT,(!OK,[!OK|ST_FAILED|ST_NA],[!OK|ST_FAILED|ST_NA], \
		 [!OK|ST_FAILED|ST_NA],[!OK|ST_FAILED|ST_NA]) {1,5}) {3,3}	SET_VALUE(FRU_PSU1, MULTIFAULT)

# PSU2
S fru_psu2_power	"PSU2 FRU Power"	DISCRETE	- -	0 0	hidden	1*/ON 2/OFF 3/FAULT
S fru_psu2_fan		"PSU2 FRU Fan"		DISCRETE	- -	0 0	hidden	1*/OK 2/WARN 3/CRIT 4/BAD 5/MULTIFAULT

A (PSU2_Pwr_In_OK,PSU2_Pwr_Out_OK) (OK,OK) {2,2}				SET_VALUE(fru_psu2_power, ON)
A (PSU2_Pwr_In_OK,PSU2_Pwr_Out_OK) (FAULT,-) {1,1}				SET_VALUE(fru_psu2_power, OFF)
A (PSU2_Pwr_In_OK,PSU2_Pwr_Out_OK) (OK,[!OK|ST_FAILED|ST_NA]){2,2}		SET_VALUE(fru_psu2_power, FAULT)
A (PSU2_Pwr_In_OK,PSU2_Pwr_Out_OK) ([ST_FAILED|ST_NA],-){1,1}			SET_VALUE(fru_psu2_power, FAULT)

A (PSU2_Fan1_Speed,PSU2_Fan2_Speed,PSU2_Fan1_Fault,PSU2_Fan2_Fault) (ST_OK,ST_OK,OK,OK){4,4}				SET_VALUE (fru_psu2_fan, OK)
A (PSU2_Fan1_Speed,PSU2_Fan2_Speed,PSU2_Fan1_Fault,PSU2_Fan2_Fault) ([ST_HIGH_WARN|ST_LOW_WARN],ST_OK,OK,OK){4,4}	SET_VALUE (fru_psu2_fan, WARN)
A (PSU2_Fan1_Speed,PSU2_Fan2_Speed,PSU2_Fan1_Fault,PSU2_Fan2_Fault) (ST_OK,[ST_HIGH_WARN|ST_LOW_WARN],OK,OK){4,4}	SET_VALUE (fru_psu2_fan, WARN)
A (PSU2_Fan1_Speed,PSU2_Fan2_Speed,PSU2_Fan1_Fault,PSU2_Fan2_Fault) ([ST_HIGH_CRIT|ST_LOW_CRIT],ST_OK,OK,OK){4,4}	SET_VALUE (fru_psu2_fan, CRIT)
A (PSU2_Fan1_Speed,PSU2_Fan2_Speed,PSU2_Fan1_Fault,PSU2_Fan2_Fault) (ST_OK,[ST_HIGH_CRIT|ST_LOW_CRIT],OK,OK){4,4}	SET_VALUE (fru_psu2_fan, CRIT)
A (PSU2_Fan1_Speed,PSU2_Fan2_Speed,PSU2_Fan1_Fault,PSU2_Fan2_Fault) ([ST_HIGH_CRIT|ST_LOW_CRIT|ST_HIGH_WARN|ST_LOW_WARN], \
			[ST_HIGH_CRIT|ST_LOW_CRIT|ST_HIGH_WARN|ST_LOW_WARN], OK,OK){4,4}				SET_VALUE (fru_psu2_fan, MULTIFAULT)
A (PSU2_Fan1_Speed,PSU2_Fan2_Speed,PSU2_Fan1_Fault,PSU2_Fan2_Fault) ([ST_FAILED|ST_NA],[ST_FAILED|ST_NA],[!OK|ST_FAILED|ST_NA],[!OK|ST_FAILED|ST_NA]){1,4}	SET_VALUE (fru_psu2_fan, BAD)

G grp_fru_psu2 PSU2_Present,fru_psu2_power,fru_psu2_fan,PSU2_Fault,PSU2_Over_Temp, PSU2_Over_Volt, PSU2_Over_Curr
A G grp_fru_psu2 (PRESENT,ON,OK,OK,OK,OK,OK){7,7}		SET_VALUE(FRU_PSU2, GOOD)
A G grp_fru_psu2 (NOT_PRESENT,-,-,-,-,-,-){1,1}			SET_VALUE(FRU_PSU2, NOT_PRESENT)
A G grp_fru_psu2 ([ST_FAILED|ST_NA],-,-,-,-,-,-){1,1}		SET_VALUE(FRU_PSU2, PSU_FAULT)
A G grp_fru_psu2 (PRESENT,OFF,-,-,-,-,-){2,2}			SET_VALUE(FRU_PSU2, PSU_OFF)
A G grp_fru_psu2 (PRESENT,ON,BAD,OK,OK,OK,OK){7,7}		SET_VALUE(FRU_PSU2, FAN_BAD)
A G grp_fru_psu2 (PRESENT,ON,WARN,OK,OK,OK,OK){7,7}		SET_VALUE(FRU_PSU2, FAN_WARN)
A G grp_fru_psu2 (PRESENT,ON,CRIT,OK,OK,OK,OK){7,7}		SET_VALUE(FRU_PSU2, FAN_CRIT)
A G grp_fru_psu2 (PRESENT,ON,MULTIFAULT,OK,OK,OK,OK){7,7}	SET_VALUE(FRU_PSU2, MULTIFAULT)
A G grp_fru_psu2 (PRESENT,ON,OK,OK,OVER_TEMP,OK,OK){7,7}	SET_VALUE(FRU_PSU2, OVER_TEMP)
A G grp_fru_psu2 (PRESENT,ON,OK,OK,OK,OK,OVER_CURR){7,7}	SET_VALUE(FRU_PSU2, OVER_CURR)
A G grp_fru_psu2 (PRESENT,ON,OK,OK,OK,OVER_VOLT,OK){7,7}	SET_VALUE(FRU_PSU2, OVER_VOLT)
A G grp_fru_psu2 (PRESENT,FAULT,OK,OK,OK,OK,OK){7,7}			SET_VALUE(FRU_PSU2, PSU_FAULT)
A G grp_fru_psu2 (PRESENT,ON,OK,[FAULT|ST_FAILED|ST_NA],OK,OK,OK){7,7}	SET_VALUE(FRU_PSU2, PSU_FAULT)
A G grp_fru_psu2 (PRESENT,ON,OK,OK,[ST_FAILED|ST_NA],OK,OK){7,7}	SET_VALUE(FRU_PSU2, PSU_FAULT)
A G grp_fru_psu2 (PRESENT,ON,OK,OK,OK,[ST_FAILED|ST_NA],OK){7,7}	SET_VALUE(FRU_PSU2, PSU_FAULT)
A G grp_fru_psu2 (PRESENT,ON,OK,OK,OK,OK,[ST_FAILED|ST_NA]){7,7}	SET_VALUE(FRU_PSU2, PSU_FAULT)
A G grp_fru_psu2 (PRESENT,ON,(!OK,[!OK|ST_FAILED|ST_NA],[!OK|ST_FAILED|ST_NA], \
		 [!OK|ST_FAILED|ST_NA],[!OK|ST_FAILED|ST_NA]) {2,5}) {3,3}	SET_VALUE(FRU_PSU2, MULTIFAULT)
A G grp_fru_psu2 (PRESENT,FAULT,(!OK,[!OK|ST_FAILED|ST_NA],[!OK|ST_FAILED|ST_NA], \
		 [!OK|ST_FAILED|ST_NA],[!OK|ST_FAILED|ST_NA]) {1,5}) {3,3}	SET_VALUE(FRU_PSU2, MULTIFAULT)

# Fan1
G grp_fru_sysfan1 Sysfan1_Present, Sysfan1_Fault, Sysfan1_F1_Speed, Sysfan1_F2_Speed
A G grp_fru_sysfan1 (PRESENT, OK, ST_OK, ST_OK){4,4} SET_VALUE(FRU_Fan1,GOOD)
A G grp_fru_sysfan1 (PRESENT, FAULT, ST_OK, ST_OK){4,4} SET_VALUE(FRU_Fan1,FAN_FAULT)
A G grp_fru_sysfan1 (NOT_PRESENT, -, -, -){1,1} SET_VALUE(FRU_Fan1, NOT_PRESENT)
A G grp_fru_sysfan1 (([ST_FAILED|ST_NA],[ST_FAILED|ST_NA]){1,2}, -, -){1,1} SET_VALUE(FRU_Fan1,FAN_FAULT)
A G grp_fru_sysfan1 (PRESENT, -, [ST_HIGH_WARN|ST_LOW_WARN], ST_OK) {3,3} SET_VALUE(FRU_Fan1, FAN1_WARN)
A G grp_fru_sysfan1 (PRESENT, -, [ST_HIGH_CRIT|ST_LOW_CRIT], ST_OK) {3,3} SET_VALUE(FRU_Fan1, FAN1_CRIT)
A G grp_fru_sysfan1 (PRESENT, -, ST_OK, [ST_HIGH_WARN|ST_LOW_WARN]) {3,3} SET_VALUE(FRU_Fan1, FAN2_WARN)
A G grp_fru_sysfan1 (PRESENT, -, ST_OK, [ST_HIGH_CRIT|ST_LOW_CRIT]) {3,3} SET_VALUE(FRU_Fan1, FAN2_CRIT)
A G grp_fru_sysfan1 (PRESENT, -, [ST_NA|ST_FAILED], ST_OK) {3,3} SET_VALUE(FRU_Fan1,FAN_FAULT)
A G grp_fru_sysfan1 (PRESENT, -, ST_OK, [ST_NA|ST_FAILED]) {3,3} SET_VALUE(FRU_Fan1,FAN_FAULT)
A G grp_fru_sysfan1 (PRESENT, -, [ST_HIGH_WARN|ST_LOW_WARN|ST_HIGH_CRIT|ST_LOW_CRIT|ST_NA|ST_FAILED], \
				 [ST_HIGH_WARN|ST_LOW_WARN|ST_HIGH_CRIT|ST_LOW_CRIT|ST_NA|ST_FAILED]) {3,3} SET_VALUE(FRU_Fan1, MULTIFAULT)

# Fan2
G grp_fru_sysfan2 Sysfan2_Present, Sysfan2_Fault, Sysfan2_F1_Speed, Sysfan2_F2_Speed
A G grp_fru_sysfan2 (PRESENT, OK, ST_OK, ST_OK){4,4} SET_VALUE(FRU_Fan2,GOOD)
A G grp_fru_sysfan2 (PRESENT, FAULT, ST_OK, ST_OK){4,4} SET_VALUE(FRU_Fan2,FAN_FAULT)
A G grp_fru_sysfan2 (NOT_PRESENT, -, -, -){1,1} SET_VALUE(FRU_Fan2, NOT_PRESENT)
A G grp_fru_sysfan2 (([ST_FAILED|ST_NA],[ST_FAILED|ST_NA]){1,2}, -, -){1,1} SET_VALUE(FRU_Fan2,FAN_FAULT)
A G grp_fru_sysfan2 (PRESENT, -, [ST_HIGH_WARN|ST_LOW_WARN], ST_OK) {3,3} SET_VALUE(FRU_Fan2, FAN1_WARN)
A G grp_fru_sysfan2 (PRESENT, -, [ST_HIGH_CRIT|ST_LOW_CRIT], ST_OK) {3,3} SET_VALUE(FRU_Fan2, FAN1_CRIT)
A G grp_fru_sysfan2 (PRESENT, -, ST_OK, [ST_HIGH_WARN|ST_LOW_WARN]) {3,3} SET_VALUE(FRU_Fan2, FAN2_WARN)
A G grp_fru_sysfan2 (PRESENT, -, ST_OK, [ST_HIGH_CRIT|ST_LOW_CRIT]) {3,3} SET_VALUE(FRU_Fan2, FAN2_CRIT)
A G grp_fru_sysfan2 (PRESENT, -, [ST_NA|ST_FAILED], ST_OK) {3,3} SET_VALUE(FRU_Fan2,FAN_FAULT)
A G grp_fru_sysfan2 (PRESENT, -, ST_OK, [ST_NA|ST_FAILED]) {3,3} SET_VALUE(FRU_Fan2,FAN_FAULT)
A G grp_fru_sysfan2 (PRESENT, -, [ST_HIGH_WARN|ST_LOW_WARN|ST_HIGH_CRIT|ST_LOW_CRIT|ST_NA|ST_FAILED], \
				 [ST_HIGH_WARN|ST_LOW_WARN|ST_HIGH_CRIT|ST_LOW_CRIT|ST_NA|ST_FAILED]) {3,3} SET_VALUE(FRU_Fan2, MULTIFAULT)

# Fan3
G grp_fru_sysfan3 Sysfan3_Present, Sysfan3_Fault, Sysfan3_F1_Speed, Sysfan3_F2_Speed
A G grp_fru_sysfan3 (PRESENT, OK, ST_OK, ST_OK){4,4} SET_VALUE(FRU_Fan3,GOOD)
A G grp_fru_sysfan3 (PRESENT, FAULT, ST_OK, ST_OK){4,4} SET_VALUE(FRU_Fan3,FAN_FAULT)
A G grp_fru_sysfan3 (NOT_PRESENT, -, -, -){1,1} SET_VALUE(FRU_Fan3, NOT_PRESENT)
A G grp_fru_sysfan3 (([ST_FAILED|ST_NA],[ST_FAILED|ST_NA]){1,2}, -, -){1,1} SET_VALUE(FRU_Fan3,FAN_FAULT)
A G grp_fru_sysfan3 (PRESENT, -, [ST_HIGH_WARN|ST_LOW_WARN], ST_OK) {3,3} SET_VALUE(FRU_Fan3, FAN1_WARN)
A G grp_fru_sysfan3 (PRESENT, -, [ST_HIGH_CRIT|ST_LOW_CRIT], ST_OK) {3,3} SET_VALUE(FRU_Fan3, FAN1_CRIT)
A G grp_fru_sysfan3 (PRESENT, -, ST_OK, [ST_HIGH_WARN|ST_LOW_WARN]) {3,3} SET_VALUE(FRU_Fan3, FAN2_WARN)
A G grp_fru_sysfan3 (PRESENT, -, ST_OK, [ST_HIGH_CRIT|ST_LOW_CRIT]) {3,3} SET_VALUE(FRU_Fan3, FAN2_CRIT)
A G grp_fru_sysfan3 (PRESENT, -, [ST_NA|ST_FAILED], ST_OK) {3,3} SET_VALUE(FRU_Fan3,FAN_FAULT)
A G grp_fru_sysfan3 (PRESENT, -, ST_OK, [ST_NA|ST_FAILED]) {3,3} SET_VALUE(FRU_Fan3,FAN_FAULT)
A G grp_fru_sysfan3 (PRESENT, -, [ST_HIGH_WARN|ST_LOW_WARN|ST_HIGH_CRIT|ST_LOW_CRIT|ST_NA|ST_FAILED], \
				 [ST_HIGH_WARN|ST_LOW_WARN|ST_HIGH_CRIT|ST_LOW_CRIT|ST_NA|ST_FAILED]) {3,3} SET_VALUE(FRU_Fan3, MULTIFAULT)

###############################################################################################################
#                                              Razor-L Thermal Policy                                         #
###############################################################################################################
## Controller Temperature

# initially disarm ok ems message
A S init ST_UNINITIALIZED		DISARM(EMS_monitor_chassisTemperature_ok)
A S Attn_Sensor1 ST_UNINITIALIZED       SET_VALUE(Attn_Sensor1, 1)

# Averaging all the temp sensors
S Amb1_Temp_Avg		"Amb1 Temp  Avg"	TEMP		- - 0 0	hidden,follow	- - - - - - - -
S Amb2_Temp_Avg		"Amb2 Temp Avg"		TEMP		- - 0 0	hidden,follow	- - - - - - - -
S Bat_Temp_Avg		"Bat Temp Avg"		TEMP		- - 0 0	hidden,follow	- - - - - - - -
S PCI_Temp_Avg		"PCI Temp Avg"		TEMP		- - 0 0	hidden,follow	- - - - - - - -
S OutFlow_Temp_Avg	"OutFlow Temp Avg"	TEMP		- - 0 0	hidden,follow	- - - - - - - -
S InFlow_Temp_Avg	"InFlow Temp Avg"	TEMP		- - 0 0	hidden,follow	- - - - - - - -
S CPU0_Temp_Avg		"CPU0 Temp Avg"		TEMP		- - 0 0	hidden,follow	- - - - - - - -

F Amb2_Temp_Avg		AVERAGE	5 Ambient_Temp_2
F Amb1_Temp_Avg		AVERAGE	5 Ambient_Temp_1
F Bat_Temp_Avg		AVERAGE	5 Smart_Bat_Temp
F PCI_Temp_Avg		AVERAGE	5 PCI_Slot_Temp
F OutFlow_Temp_Avg	AVERAGE	5 Out_Flow_Temp
F InFlow_Temp_Avg	AVERAGE	5 In_Flow_Temp
F CPU0_Temp_Avg		AVERAGE	5 CPU0_Temp_Margin

# Group all the average sensors and aggregate them to Avg_Temp_High pseudo sensor
S Avg_Temp_High		"Temp Average High"	DISCRETE	- - 0 0 hidden		0*/NO 1/YES
S Avg_Temp_Low		"Temp Average Low"	DISCRETE	- - 0 0 hidden		0*/NO 1/YES

G temp_avg_grp Amb1_Temp_Avg, Amb2_Temp_Avg, Bat_Temp_Avg, PCI_Temp_Avg, OutFlow_Temp_Avg, InFlow_Temp_Avg, CPU0_Temp_Avg
A G temp_avg_grp (ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT) {1,7} \
	SET_VALUE(Avg_Temp_High, YES)
A G temp_avg_grp (!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT) {7,7} \
	SET_VALUE(Avg_Temp_High, NO)
A G temp_avg_grp (ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT) {1,7} \
	SET_VALUE(Avg_Temp_Low, YES)
A G temp_avg_grp (!ST_LOW_CRIT,!ST_LOW_CRIT,!ST_LOW_CRIT,!ST_LOW_CRIT,!ST_LOW_CRIT,!ST_LOW_CRIT,!ST_LOW_CRIT) {7,7} \
	SET_VALUE(Avg_Temp_Low, NO)

# If any temperature sensor is abnormal, arm the OK ems message.
G temp_grp Avg_Temp_High, Avg_Temp_Low, Ambient_Temp_1,Ambient_Temp_2, In_Flow_Temp, PCI_Slot_Temp, Smart_Bat_Temp, Out_Flow_Temp, CPU0_Temp_Margin
A G temp_grp	( -, -, \
		 [ST_LOW_CRIT|ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA], \
		 [ST_LOW_CRIT|ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA], \
		 [ST_LOW_CRIT|ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA], \
		 [ST_LOW_CRIT|ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA], \
		 [ST_LOW_CRIT|ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA], \
		 [ST_LOW_CRIT|ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA], \
		 [ST_LOW_CRIT|ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA]){1,7}	ARM(EMS_monitor_chassisTemperature_ok)

# If all the temperature sensors are normal, send the OK ems message.
A G temp_grp (-,-,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK){7,7}		+0/EMS(EMS_monitor_chassisTemperature_ok)

A G temp_grp	(-,-,[ST_HIGH_WARN|ST_HIGH_CRIT],[ST_HIGH_WARN|ST_HIGH_CRIT], [ST_HIGH_WARN|ST_HIGH_CRIT],[ST_HIGH_WARN|ST_HIGH_CRIT], \
		 [ST_HIGH_WARN|ST_HIGH_CRIT],[ST_HIGH_WARN|ST_HIGH_CRIT],[ST_HIGH_WARN|ST_HIGH_CRIT]){1,7} \
		 EMS(EMS_callhome_chassis_hitemp, "CHASSIS OVER TEMPERATURE")

# individual sensor warnings

A S Ambient_Temp_1 ST_LOW_CRIT		EMS(EMS_monitor_chassisTemperature_cool, "%s is critical low (%r).")
A S Ambient_Temp_1 ST_LOW_WARN		EMS(EMS_monitor_chassisTemperature_cool, "%s is warning low (%r).")
A S Ambient_Temp_1 ST_HIGH_WARN		EMS(EMS_monitor_chassisTemperature_warm, "%s is warning high (%r).")
A S Ambient_Temp_1 ST_HIGH_CRIT		EMS(EMS_monitor_chassisTemperature_warm, "%s is critical high (%r).")
A S Ambient_Temp_1 [ST_FAILED|ST_NA]	EMS(EMS_monitor_temp_unreadable, "%s")

A S Ambient_Temp_2 ST_LOW_CRIT		EMS(EMS_monitor_chassisTemperature_cool, "%s is critical low (%r).")
A S Ambient_Temp_2 ST_LOW_WARN		EMS(EMS_monitor_chassisTemperature_cool, "%s is warning low (%r).")
A S Ambient_Temp_2 ST_HIGH_WARN		EMS(EMS_monitor_chassisTemperature_warm, "%s is warning high (%r).")
A S Ambient_Temp_2 ST_HIGH_CRIT		EMS(EMS_monitor_chassisTemperature_warm, "%s is critical high (%r).")
A S Ambient_Temp_2 [ST_FAILED|ST_NA]	EMS(EMS_monitor_temp_unreadable, "%s")

A S In_Flow_Temp ST_LOW_CRIT		EMS(EMS_monitor_chassisTemperature_cool, "%s is critical low (%r).")
A S In_Flow_Temp ST_LOW_WARN		EMS(EMS_monitor_chassisTemperature_cool, "%s is warning low (%r).")
A S In_Flow_Temp ST_HIGH_WARN		EMS(EMS_monitor_chassisTemperature_warm, "%s is warning high (%r).")
A S In_Flow_Temp ST_HIGH_CRIT		EMS(EMS_monitor_chassisTemperature_warm, "%s is critical high (%r).")
A S In_Flow_Temp [ST_FAILED|ST_NA]	EMS(EMS_monitor_temp_unreadable, "%s")

A S Out_Flow_Temp ST_LOW_CRIT		EMS(EMS_monitor_chassisTemperature_cool, "%s is critical low (%r).")
A S Out_Flow_Temp ST_LOW_WARN		EMS(EMS_monitor_chassisTemperature_cool, "%s is warning low (%r).")
A S Out_Flow_Temp ST_HIGH_WARN		EMS(EMS_monitor_chassisTemperature_warm, "%s is warning high (%r).")
A S Out_Flow_Temp ST_HIGH_CRIT		EMS(EMS_monitor_chassisTemperature_warm, "%s is critical high (%r).")
A S Out_Flow_Temp [ST_FAILED|ST_NA]	EMS(EMS_monitor_temp_unreadable, "%s")

A S Smart_Bat_Temp ST_LOW_CRIT		EMS(EMS_monitor_chassisTemperature_cool, "%s is critical low (%r).")
A S Smart_Bat_Temp ST_LOW_WARN		EMS(EMS_monitor_chassisTemperature_cool, "%s is warning low (%r).")
A S Smart_Bat_Temp ST_HIGH_WARN		EMS(EMS_monitor_chassisTemperature_warm, "%s is warning high (%r).")
A S Smart_Bat_Temp ST_HIGH_CRIT		EMS(EMS_monitor_chassisTemperature_warm, "%s is critical high (%r).")
A S Smart_Bat_Temp [ST_FAILED|ST_NA]	EMS(EMS_monitor_temp_unreadable, "%s")

A S PCI_Slot_Temp ST_LOW_CRIT		EMS(EMS_monitor_chassisTemperature_cool, "%s is critical low (%r).")
A S PCI_Slot_Temp ST_LOW_WARN		EMS(EMS_monitor_chassisTemperature_cool, "%s is warning low (%r).")
A S PCI_Slot_Temp ST_HIGH_WARN		EMS(EMS_monitor_chassisTemperature_warm, "%s is warning high (%r).")
A S PCI_Slot_Temp ST_HIGH_CRIT		EMS(EMS_monitor_chassisTemperature_warm, "%s is critical high (%r).")
A S PCI_Slot_Temp [ST_FAILED|ST_NA]	EMS(EMS_monitor_temp_unreadable, "%s")

A S CPU0_Temp_Margin ST_HIGH_WARN	EMS(EMS_monitor_chassisTemperature_warm, "%s is warning high (%r).")
A S CPU0_Temp_Margin ST_HIGH_CRIT	EMS(EMS_monitor_chassisTemperature_warm, "%s is critical high (%r).")
A S CPU0_Temp_Margin [ST_FAILED|ST_NA]	EMS(EMS_monitor_temp_unreadable, "%s")

# Shutdown Policy
# Define the group of sensors that the primary temp policy depends on.
G chassis_temp_grp Ambient_Temp_1, Ambient_Temp_2, In_Flow_Temp, Out_Flow_Temp, PCI_Slot_Temp, Smart_Bat_Temp, CPU0_Temp_Margin

# Define the dummy shutdown sensor.
S temp_shutdown	"Thermal Shutdown"	DISCRETE	- - 0 0	hidden	0*/UP 1/DOWN
A S temp_shutdown DOWN			120+10/DO(env_halt, 1, "Temperature critical"), ARM(EMS_monitor_shutdown_cancel)
A S temp_shutdown UP			+0/EMS(EMS_monitor_shutdown_cancel)

# Send additional EMS if both Ambient failed and none other temp sensors failed
A G temp_grp    (-,-,ST_FAILED,ST_FAILED,!ST_FAILED,!ST_FAILED,!ST_FAILED,!ST_FAILED,!ST_FAILED){7,7} \
                        EMS(EMS_monitor_chassisTemperature_state_unknown, "Both Ambient temp sensors are unreadable.")

# Shutdown if both Ambient failed and one or more other temp sensors failed
A G temp_grp	(-, -, ST_FAILED, ST_FAILED, (ST_FAILED,ST_FAILED,ST_FAILED,ST_FAILED,ST_FAILED){1,5}){3,3} \
			EMS(EMS_callhome_chassis_overtemp, "CHASSIS OVER TEMPERATURE SHUTDOWN"), \
			EMS(EMS_monitor_chassisTemperature_state_unknown, "Multiple Temp sensors are unreadable. System will be shutdown in 2 minutes"), \
			SET_VALUE(temp_shutdown, DOWN)

# Shutdown if 3 or more (not-ambient)  temp sensors failed
A G temp_grp	(-, -, -, -, ST_FAILED,ST_FAILED,ST_FAILED,ST_FAILED,ST_FAILED){3,5} \
			EMS(EMS_callhome_chassis_overtemp, "CHASSIS OVER TEMPERATURE SHUTDOWN"), \
			EMS(EMS_monitor_chassisTemperature_state_unknown, "Multiple Temp sensors are unreadable. System will be shutdown in 2 minutes"), \
			SET_VALUE(temp_shutdown, DOWN)

# Shutdown if any average sensor is critical high and 2 or more temp sensors are critical high
A G temp_grp	(YES, -, (ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT){2,7}){2,2} \
			EMS(EMS_callhome_chassis_overtemp, "CHASSIS OVER TEMPERATURE SHUTDOWN"), \
			EMS(EMS_monitor_shutdown_chassisOverTemp, "Multiple Temp sensors are critical high. System will be shutdown in 2 minutes"), \
			SET_VALUE(temp_shutdown, DOWN)

# Shutdown if any average sensor is critical low and 2 or more temp sensors are critical low
A G temp_grp	(NO, YES, (ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT){2,7}){3,3} \
			EMS(EMS_callhome_chassis_undertemp, "CHASSIS UNDER TEMPERATURE SHUTDOWN"), \
			EMS(EMS_monitor_shutdown_chassisUnderTemp, "Multiple Temp sensors are critical low. System will be shutdown in 2 minutes"), \
			SET_VALUE(temp_shutdown, DOWN)

# Cancel the shtudown if average is not high, and less than 3 sensors failed
A G temp_grp	(NO, -, (ST_FAILED,ST_FAILED,ST_FAILED,ST_FAILED,ST_FAILED,ST_FAILED,ST_FAILED){0,2}){2,2} SET_VALUE(temp_shutdown, UP)

# Cancel the shtudown if average is high and less than 2 sensors are critical high
A G temp_grp	(YES, -,(ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT){0,1}){2,2} \
			SET_VALUE(temp_shutdown, UP)

# Cancel the shtudown if average is low and less than 2 sensors are critical low
A G temp_grp	(NO, YES,(ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT,ST_LOW_CRIT){0,1}){3,3} \
			SET_VALUE(temp_shutdown, UP)

# Create the pseudo-sensors
S chassis_temp_snmp	"Chassis Thermal Zone"	DISCRETE	- - 0 0	hidden		0*/NORMAL_TEMP 1/UNDER_TEMP 2/OVER_TEMP

# If all sensors are normal, we set the pseudo-sensor to normal
A G chassis_temp_grp (ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK){7,7}	SET_VALUE(chassis_temp_snmp, NORMAL_TEMP)
# If any sensor is high, we set the pseudo-sensor to high
A G chassis_temp_grp		([ST_HIGH_CRIT|ST_HIGH_WARN|ST_FAILED|ST_NA],	\
				 [ST_HIGH_CRIT|ST_HIGH_WARN|ST_FAILED|ST_NA],	\
				 [ST_HIGH_CRIT|ST_HIGH_WARN|ST_FAILED|ST_NA],	\
				 [ST_HIGH_CRIT|ST_HIGH_WARN|ST_FAILED|ST_NA],	\
				 [ST_HIGH_CRIT|ST_HIGH_WARN|ST_FAILED|ST_NA],	\
				 [ST_HIGH_CRIT|ST_HIGH_WARN|ST_FAILED|ST_NA],	\
				 [ST_HIGH_CRIT|ST_HIGH_WARN|ST_FAILED|ST_NA]){1,7}	SET_VALUE(chassis_temp_snmp, OVER_TEMP)
# If any sensor is low and no sensor is high, we set the pseudo-sensor to low
A G chassis_temp_grp		( [ST_LOW_CRIT|ST_LOW_WARN],			\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA]){7,7}	SET_VALUE(chassis_temp_snmp, UNDER_TEMP)
A G chassis_temp_grp		(![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				  [ST_LOW_CRIT|ST_LOW_WARN],			\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA]){7,7}	SET_VALUE(chassis_temp_snmp, UNDER_TEMP)
A G chassis_temp_grp		(![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				  [ST_LOW_CRIT|ST_LOW_WARN],			\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA]){7,7}	SET_VALUE(chassis_temp_snmp, UNDER_TEMP)
A G chassis_temp_grp		(![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				  [ST_LOW_CRIT|ST_LOW_WARN],			\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA]){7,7}	SET_VALUE(chassis_temp_snmp, UNDER_TEMP)
A G chassis_temp_grp		(![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				  [ST_LOW_CRIT|ST_LOW_WARN],			\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA]){7,7}	SET_VALUE(chassis_temp_snmp, UNDER_TEMP)
A G chassis_temp_grp		(![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				  [ST_LOW_CRIT|ST_LOW_WARN],			\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA]){7,7}	SET_VALUE(chassis_temp_snmp, UNDER_TEMP)
A G chassis_temp_grp		(![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 ![ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED|ST_NA],	\
				 [ST_LOW_CRIT|ST_LOW_WARN]){7,7}			SET_VALUE(chassis_temp_snmp, UNDER_TEMP)

# Set the SNMP pseudo-sensor to the worst of the chassis.
A S chassis_temp_snmp NORMAL_TEMP	SET_VALUE(temp_snmp, NORMAL_TEMP), DO(update_sen_list, "crit_zone", DEL, chassis_temp_snmp), DO(update_snmp, ENTITY_TEMP)
A S chassis_temp_snmp OVER_TEMP		SET_VALUE(temp_snmp, OVER_TEMP), DO(update_sen_list, "crit_zone", ADD, chassis_temp_snmp), DO(update_snmp, ENTITY_TEMP)
A S chassis_temp_snmp UNDER_TEMP	SET_VALUE(temp_snmp, UNDER_TEMP), DO(update_sen_list, "crit_zone", ADD, chassis_temp_snmp), DO(update_snmp, ENTITY_TEMP)

## Controller Fans

# Dummy sensors used to keep track of the failed fans.
# GOOD: self-explanatory
# WARN: something is wrong with the fan, but not enough to trigger a shutdown
#  BAD: the fan is definitely not working (contributes to the bad fan count used to decide whether to shutdown)
S sysfan11	"Sysfan1 F1"		DISCRETE	- - 0 0	hidden		0*/GOOD 1/WARN 2/BAD
S sysfan12	"Sysfan1 F2"		DISCRETE	- - 0 0	hidden		0*/GOOD 1/WARN 2/BAD
S sysfan21	"Sysfan2 F1"		DISCRETE	- - 0 0	hidden		0*/GOOD 1/WARN 2/BAD
S sysfan22	"Sysfan2 F2"		DISCRETE	- - 0 0	hidden		0*/GOOD 1/WARN 2/BAD
S sysfan31	"Sysfan3 F1"		DISCRETE	- - 0 0	hidden		0*/GOOD 1/WARN 2/BAD
S sysfan32	"Sysfan3 F2"		DISCRETE	- - 0 0	hidden		0*/GOOD 1/WARN 2/BAD

# Sysfan1 Present
A S Sysfan1_Present [NOT_PRESENT|ST_DISABLED]	SET_STATE(Sysfan1_Fault,ST_DISABLED)
A S Sysfan1_Present [NOT_PRESENT|ST_DISABLED]	SET_STATE(Sysfan1_F1_Speed, ST_DISABLED), SET_STATE(Sysfan1_F2_Speed, ST_DISABLED)
A S Sysfan1_Present NOT_PRESENT			EMS(EMS_monitor_chassisFan_removed, "SysFan1")
A S Sysfan1_Present NOT_PRESENT			EMS(EMS_callhome_c_fan_fru_rm, "CHASSIS FAN FRU REMOVED: SysFan1")
A S Sysfan1_Present NOT_PRESENT			ARM(EMS_monitor_chassisFan_ok_Sysfan1)
A (Sysfan1_Present,Sysfan1_Fault) (PRESENT, ST_DISABLED) {2,2}		SET_STATE(Sysfan1_Fault,ST_UNINITIALIZED)
A (Sysfan1_Present,Sysfan1_F1_Speed) (PRESENT, ST_DISABLED) {2,2}	SET_STATE(Sysfan1_F1_Speed, ST_UNINITIALIZED), SET_STATE(Sysfan1_F2_Speed, ST_UNINITIALIZED)
A S Sysfan1_Present PRESENT			+0/EMS(EMS_monitor_chassisFan_ok_Sysfan1)
# Sysfan1 F1 Speed
A S Sysfan1_F1_Speed ST_HIGH_CRIT			30/EMS(EMS_monitor_chassisFan_degraded, "SysFan1 F1 is spinning too fast (%r)")
A S Sysfan1_F1_Speed [ST_HIGH_WARN|ST_LOW_WARN]		30/EMS(EMS_monitor_chassisFan_warning, "SysFan1 F1 (%r)")
A S Sysfan1_F1_Speed [ST_LOW_CRIT|ST_FAILED]		30/EMS(EMS_monitor_chassisFan_stop, "SysFan1 F1 (%r)")
A S Sysfan1_F1_Speed [ST_LOW_CRIT|ST_FAILED]		30/EMS(EMS_callhome_c_fan_fru_fault, "CHASSIS FAN FRU FAILED: SysFan1 F1")
A S Sysfan1_F1_Speed [ST_LOW_CRIT|ST_HIGH_CRIT|ST_FAILED|ST_HIGH_WARN|ST_LOW_WARN] POLL(Sysfan1_F1_Speed, 10),30/POLL(Sysfan1_F1_Speed, 60)
A S Sysfan1_F1_Speed ST_NA				180/SET_STATE(Sysfan1_F1_Speed, ST_FAILED)
A S Sysfan1_F1_Speed ST_NA				POLL(Sysfan1_F1_Speed, 10)
# Sysfan1 F2 Speed
A S Sysfan1_F2_Speed ST_HIGH_CRIT			30/EMS(EMS_monitor_chassisFan_degraded, "SysFan1 F2 is spinning too fast (%r)")
A S Sysfan1_F2_Speed [ST_HIGH_WARN|ST_LOW_WARN]		30/EMS(EMS_monitor_chassisFan_warning, "SysFan1 F2 (%r)")
A S Sysfan1_F2_Speed [ST_LOW_CRIT|ST_FAILED]		30/EMS(EMS_monitor_chassisFan_stop, "SysFan1 F2 (%r)")
A S Sysfan1_F2_Speed [ST_LOW_CRIT|ST_FAILED]		30/EMS(EMS_callhome_c_fan_fru_fault, "CHASSIS FAN FRU FAILED: SysFan1 F2")
A S Sysfan1_F2_Speed [ST_LOW_CRIT|ST_HIGH_CRIT|ST_FAILED|ST_HIGH_WARN|ST_LOW_WARN] POLL(Sysfan1_F2_Speed, 10),30/POLL(Sysfan1_F2_Speed, 60)
A S Sysfan1_F2_Speed ST_NA				180/SET_STATE(Sysfan1_F2_Speed, ST_FAILED)
A S Sysfan1_F2_Speed ST_NA				POLL(Sysfan1_F2_Speed, 10)

# Sysfan2 Present
A S Sysfan2_Present [NOT_PRESENT|ST_DISABLED]	SET_STATE(Sysfan2_Fault,ST_DISABLED)
A S Sysfan2_Present [NOT_PRESENT|ST_DISABLED]	SET_STATE(Sysfan2_F1_Speed, ST_DISABLED), SET_STATE(Sysfan2_F2_Speed, ST_DISABLED)
A S Sysfan2_Present NOT_PRESENT			EMS(EMS_monitor_chassisFan_removed, "SysFan2")
A S Sysfan2_Present NOT_PRESENT			EMS(EMS_callhome_c_fan_fru_rm, "CHASSIS FAN FRU REMOVED: SysFan2")
A S Sysfan2_Present NOT_PRESENT			ARM(EMS_monitor_chassisFan_ok_Sysfan2)
A (Sysfan2_Present,Sysfan2_Fault) (PRESENT, ST_DISABLED) {2,2}		SET_STATE(Sysfan2_Fault,ST_UNINITIALIZED)
A (Sysfan2_Present,Sysfan2_F1_Speed) (PRESENT, ST_DISABLED) {2,2}	SET_STATE(Sysfan2_F1_Speed, ST_UNINITIALIZED), SET_STATE(Sysfan2_F2_Speed, ST_UNINITIALIZED)
A S Sysfan2_Present PRESENT			+0/EMS(EMS_monitor_chassisFan_ok_Sysfan2)
# Sysfan2 F1 Speed
A S Sysfan2_F1_Speed ST_HIGH_CRIT			30/EMS(EMS_monitor_chassisFan_degraded, "SysFan2 F1 is spinning too fast (%r)")
A S Sysfan2_F1_Speed [ST_HIGH_WARN|ST_LOW_WARN]		30/EMS(EMS_monitor_chassisFan_warning, "SysFan2 F1 (%r)")
A S Sysfan2_F1_Speed [ST_LOW_CRIT|ST_FAILED]		30/EMS(EMS_monitor_chassisFan_stop, "SysFan2 F1 (%r)")
A S Sysfan2_F1_Speed [ST_LOW_CRIT|ST_FAILED]		30/EMS(EMS_callhome_c_fan_fru_fault, "CHASSIS FAN FRU FAILED: SysFan2 F1")
A S Sysfan2_F1_Speed [ST_LOW_CRIT|ST_HIGH_CRIT|ST_FAILED|ST_HIGH_WARN|ST_LOW_WARN] POLL(Sysfan2_F1_Speed, 10),30/POLL(Sysfan2_F1_Speed, 60)
A S Sysfan2_F1_Speed ST_NA				180/SET_STATE(Sysfan2_F1_Speed, ST_FAILED)
A S Sysfan2_F1_Speed ST_NA				POLL(Sysfan2_F1_Speed, 10)
# Sysfan2 F2 Speed
A S Sysfan2_F2_Speed ST_HIGH_CRIT			30/EMS(EMS_monitor_chassisFan_degraded, "SysFan2 F2 is spinning too fast (%r)")
A S Sysfan2_F2_Speed [ST_HIGH_WARN|ST_LOW_WARN]		30/EMS(EMS_monitor_chassisFan_warning, "SysFan2 F2 (%r)")
A S Sysfan2_F2_Speed [ST_LOW_CRIT|ST_FAILED]		30/EMS(EMS_monitor_chassisFan_stop, "SysFan2 F2 (%r)")
A S Sysfan2_F2_Speed [ST_LOW_CRIT|ST_FAILED]		30/EMS(EMS_callhome_c_fan_fru_fault, "CHASSIS FAN FRU FAILED: SysFan2 F2")
A S Sysfan2_F2_Speed [ST_LOW_CRIT|ST_HIGH_CRIT|ST_FAILED|ST_HIGH_WARN|ST_LOW_WARN] POLL(Sysfan2_F2_Speed, 10),30/POLL(Sysfan2_F2_Speed, 60)
A S Sysfan2_F2_Speed ST_NA				180/SET_STATE(Sysfan2_F2_Speed, ST_FAILED)
A S Sysfan2_F2_Speed ST_NA				POLL(Sysfan2_F2_Speed, 10)

# Sysfan3 Present
A S Sysfan3_Present [NOT_PRESENT|ST_DISABLED]	SET_STATE(Sysfan3_Fault,ST_DISABLED)
A S Sysfan3_Present [NOT_PRESENT|ST_DISABLED]	SET_STATE(Sysfan3_F1_Speed, ST_DISABLED), SET_STATE(Sysfan3_F2_Speed, ST_DISABLED)
A S Sysfan3_Present NOT_PRESENT			EMS(EMS_monitor_chassisFan_removed, "SysFan3")
A S Sysfan3_Present NOT_PRESENT			EMS(EMS_callhome_c_fan_fru_rm, "CHASSIS FAN FRU REMOVED: SysFan3")
A S Sysfan3_Present NOT_PRESENT			ARM(EMS_monitor_chassisFan_ok_Sysfan3)
A (Sysfan3_Present,Sysfan3_Fault) (PRESENT, ST_DISABLED) {2,2}	SET_STATE(Sysfan3_Fault,ST_UNINITIALIZED)
A (Sysfan3_Present,Sysfan3_F1_Speed) (PRESENT, ST_DISABLED) {2,2}	SET_STATE(Sysfan3_F1_Speed, ST_UNINITIALIZED), SET_STATE(Sysfan3_F2_Speed, ST_UNINITIALIZED)
A S Sysfan3_Present PRESENT			+0/EMS(EMS_monitor_chassisFan_ok_Sysfan3)
# Sysfan3 F1 Speed
A S Sysfan3_F1_Speed ST_HIGH_CRIT			30/EMS(EMS_monitor_chassisFan_degraded, "SysFan3 F1 is spinning too fast (%r)")
A S Sysfan3_F1_Speed [ST_HIGH_WARN|ST_LOW_WARN]		30/EMS(EMS_monitor_chassisFan_warning, "SysFan3 F1 (%r)")
A S Sysfan3_F1_Speed [ST_LOW_CRIT|ST_FAILED]		30/EMS(EMS_monitor_chassisFan_stop, "SysFan3 F1 (%r)")
A S Sysfan3_F1_Speed [ST_LOW_CRIT|ST_FAILED]		30/EMS(EMS_callhome_c_fan_fru_fault, "CHASSIS FAN FRU FAILED: SysFan3 F1")
A S Sysfan3_F1_Speed [ST_LOW_CRIT|ST_HIGH_CRIT|ST_FAILED|ST_HIGH_WARN|ST_LOW_WARN] POLL(Sysfan3_F1_Speed, 10),30/POLL(Sysfan3_F1_Speed, 60)
A S Sysfan3_F1_Speed ST_NA				180/SET_STATE(Sysfan3_F1_Speed, ST_FAILED)
A S Sysfan3_F1_Speed ST_NA				POLL(Sysfan3_F1_Speed, 10)
# Sysfan3 F2 Speed
A S Sysfan3_F2_Speed ST_HIGH_CRIT			30/EMS(EMS_monitor_chassisFan_degraded, "SysFan3 F2 is spinning too fast (%r)")
A S Sysfan3_F2_Speed [ST_HIGH_WARN|ST_LOW_WARN]		30/EMS(EMS_monitor_chassisFan_warning, "SysFan3 F2 (%r)")
A S Sysfan3_F2_Speed [ST_LOW_CRIT|ST_FAILED]		30/EMS(EMS_monitor_chassisFan_stop, "SysFan3 F2 (%r)")
A S Sysfan3_F2_Speed [ST_LOW_CRIT|ST_FAILED]		30/EMS(EMS_callhome_c_fan_fru_fault, "CHASSIS FAN FRU FAILED: SysFan3 F2")
A S Sysfan3_F2_Speed [ST_LOW_CRIT|ST_HIGH_CRIT|ST_FAILED|ST_HIGH_WARN|ST_LOW_WARN] POLL(Sysfan3_F2_Speed, 10),30/POLL(Sysfan3_F2_Speed, 60)
A S Sysfan3_F2_Speed ST_NA				180/SET_STATE(Sysfan3_F2_Speed, ST_FAILED)
A S Sysfan3_F2_Speed ST_NA				POLL(Sysfan3_F2_Speed, 10)

# Failed Fans Policy
# There are three fan FRUs, each with two fans.  For a given fan, if that fan's FRU is not present
# or if that fan's speed is critical low, then we consider that fan to be "failed".
# So, for each fan, we have a pseudo-sensor that represents whether that fan is GOOD or BAD (failed).

# Sysfan1 F1 OK
G fan1_f1_ok Sysfan1_Present, Sysfan1_F1_Speed
A G fan1_f1_ok (PRESENT,ST_OK){2,2}					SET_VALUE(sysfan11, GOOD), DO(update_sen_list, "crit_fan", DEL, sysfan11)
A G fan1_f1_ok (PRESENT,[ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT]){2,2}	30/SET_VALUE(sysfan11, WARN), 30/DO(update_sen_list, "crit_fan", DEL, sysfan11)
A G fan1_f1_ok ([NOT_PRESENT|ST_FAILED],[ST_LOW_CRIT|ST_FAILED]){1,2}	30/SET_VALUE(sysfan11, BAD), 30/DO(update_sen_list, "crit_fan", ADD, sysfan11)

# Sysfan1 F2 OK
G fan1_f2_ok Sysfan1_Present, Sysfan1_F2_Speed
A G fan1_f2_ok (PRESENT,ST_OK){2,2}					SET_VALUE(sysfan12, GOOD), DO(update_sen_list, "crit_fan", DEL, sysfan12)
A G fan1_f2_ok (PRESENT,[ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT]){2,2}	30/SET_VALUE(sysfan12, WARN), 30/DO(update_sen_list, "crit_fan", DEL, sysfan12)
A G fan1_f2_ok ([NOT_PRESENT|ST_FAILED],[ST_LOW_CRIT|ST_FAILED]){1,2}	30/SET_VALUE(sysfan12, BAD), 30/DO(update_sen_list, "crit_fan", ADD, sysfan12)

# Sysfan2 F1 OK
G fan2_f1_ok Sysfan2_Present, Sysfan2_F1_Speed
A G fan2_f1_ok (PRESENT,ST_OK){2,2}					SET_VALUE(sysfan21, GOOD), DO(update_sen_list, "crit_fan", DEL, sysfan21)
A G fan2_f1_ok (PRESENT,[ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT]){2,2}	30/SET_VALUE(sysfan21, WARN), 30/DO(update_sen_list, "crit_fan", DEL, sysfan21)
A G fan2_f1_ok ([NOT_PRESENT|ST_FAILED],[ST_LOW_CRIT|ST_FAILED]){1,2}	30/SET_VALUE(sysfan21, BAD), 30/DO(update_sen_list, "crit_fan", ADD, sysfan21)

# Sysfan2 F2 OK
G fan2_f2_ok Sysfan2_Present, Sysfan2_F2_Speed
A G fan2_f2_ok (PRESENT,ST_OK){2,2}					SET_VALUE(sysfan22, GOOD), DO(update_sen_list, "crit_fan", DEL, sysfan22)
A G fan2_f2_ok (PRESENT,[ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT]){2,2}	30/SET_VALUE(sysfan22, WARN), 30/DO(update_sen_list, "crit_fan", DEL, sysfan22)
A G fan2_f2_ok ([NOT_PRESENT|ST_FAILED],[ST_LOW_CRIT|ST_FAILED]){1,2}	30/SET_VALUE(sysfan22, BAD), 30/DO(update_sen_list, "crit_fan", ADD, sysfan22)

# Sysfan3 F1 OK
G fan3_f1_ok Sysfan3_Present, Sysfan3_F1_Speed
A G fan3_f1_ok (PRESENT,ST_OK){2,2}					SET_VALUE(sysfan31, GOOD), DO(update_sen_list, "crit_fan", DEL, sysfan31)
A G fan3_f1_ok (PRESENT,[ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT]){2,2}	30/SET_VALUE(sysfan31, WARN), 30/DO(update_sen_list, "crit_fan", DEL, sysfan31)
A G fan3_f1_ok ([NOT_PRESENT|ST_FAILED],[ST_LOW_CRIT|ST_FAILED]){1,2}	30/SET_VALUE(sysfan31, BAD), 30/DO(update_sen_list, "crit_fan", ADD, sysfan31)

# Sysfan3 F2 OK
G fan3_f2_ok Sysfan3_Present, Sysfan3_F2_Speed
A G fan3_f2_ok (PRESENT,ST_OK){2,2}					SET_VALUE(sysfan32, GOOD), DO(update_sen_list, "crit_fan", DEL, sysfan32)
A G fan3_f2_ok (PRESENT,[ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT]){2,2}	30/SET_VALUE(sysfan32, WARN), 30/DO(update_sen_list, "crit_fan", DEL, sysfan32)
A G fan3_f2_ok ([NOT_PRESENT|ST_FAILED],[ST_LOW_CRIT|ST_FAILED]){1,2}	30/SET_VALUE(sysfan32, BAD), 30/DO(update_sen_list, "crit_fan", ADD, sysfan32)

# Send an EMS message if the fan returns to good from a bad state.
# The EMS messages will be sent for the fans on a FRU when that FRU is inserted during a hot swap.
# If one of these messages gets armed and then we go on backup policy, the message will still be
# armed, so if we go back to primary policy and the sensors go to good, then we'll get the ok
# ems message, which is good because otherwise the customer will still be concerned that
# something is wrong.
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_chassisFan_ok_Sysfan1)
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_chassisFan_ok_Sysfan1_F1)
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_chassisFan_ok_Sysfan1_F2)
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_chassisFan_ok_Sysfan2)
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_chassisFan_ok_Sysfan2_F1)
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_chassisFan_ok_Sysfan2_F2)
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_chassisFan_ok_Sysfan3)
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_chassisFan_ok_Sysfan3_F1)
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_chassisFan_ok_Sysfan3_F2)
A S sysfan11 GOOD		+0/EMS(EMS_monitor_chassisFan_ok_Sysfan1_F1)
A S sysfan12 GOOD		+0/EMS(EMS_monitor_chassisFan_ok_Sysfan1_F2)
A S sysfan21 GOOD		+0/EMS(EMS_monitor_chassisFan_ok_Sysfan2_F1)
A S sysfan22 GOOD		+0/EMS(EMS_monitor_chassisFan_ok_Sysfan2_F2)
A S sysfan31 GOOD		+0/EMS(EMS_monitor_chassisFan_ok_Sysfan3_F1)
A S sysfan32 GOOD		+0/EMS(EMS_monitor_chassisFan_ok_Sysfan3_F2)
A S sysfan11 [WARN|BAD]		ARM(EMS_monitor_chassisFan_ok_Sysfan1_F1)
A S sysfan12 [WARN|BAD]		ARM(EMS_monitor_chassisFan_ok_Sysfan1_F2)
A S sysfan21 [WARN|BAD]		ARM(EMS_monitor_chassisFan_ok_Sysfan2_F1)
A S sysfan22 [WARN|BAD]		ARM(EMS_monitor_chassisFan_ok_Sysfan2_F2)
A S sysfan31 [WARN|BAD]		ARM(EMS_monitor_chassisFan_ok_Sysfan3_F1)
A S sysfan32 [WARN|BAD]		ARM(EMS_monitor_chassisFan_ok_Sysfan3_F2)

# Total Fans Failed
G ctrl_fans sysfan11, sysfan12, sysfan21, sysfan22, sysfan31, sysfan32
A S init ST_UNINITIALIZED			DISARM(EMS_monitor_shutdown_cancel)

# If 2 or more fans had been failed, but now less than 2
# fans are failed, send the "shutdown cancel" EMS message.
A G ctrl_fans ([GOOD|WARN],[GOOD|WARN],[GOOD|WARN],[GOOD|WARN],[GOOD|WARN],[GOOD|WARN]){5,6}	+0/EMS(EMS_monitor_shutdown_cancel)

# If 2 fans are failed, send the "shutting down in 2 minutes" EMS message and ASUP, and shutdown in 2 minutes.
# If the SP goes away, the SP sensors get disabled but these dummy sensors don't, so if this shutdown gets
# triggered and then the SP goes down, the shutdown will still take place (which is what we want).
A G ctrl_fans (BAD,BAD,BAD,BAD,BAD,BAD){2,2}	EMS(EMS_monitor_chassisFanFail_xMinShutdown, "2")
A G ctrl_fans (BAD,BAD,BAD,BAD,BAD,BAD){2,2}	EMS(EMS_callhome_c_fan_fru_shut, "MULTIPLE CHASSIS FAN FAILED: System will shut down in 2 minutes")
# Only do the shutdown if we're on the primary thermal poilicy.
A G ctrl_fans (BAD,BAD,BAD,BAD,BAD,BAD){2,2}	150+10/DO(env_halt,1,"Multiple fans failed")

# If 2 or more fans have failed, arm the "shutdown cancel" EMS message (when on the primary policy).
A G ctrl_fans (BAD,BAD,BAD,BAD,BAD,BAD){2,6}	ARM(EMS_monitor_shutdown_cancel)

# If 3 or more fans have failed, shutdown (when on the primary policy).
A G ctrl_fans (BAD,BAD,BAD,BAD,BAD,BAD){3,6}	EMS(EMS_monitor_shutdown_emergency, "Multiple chassis fans have failed.")
A G ctrl_fans (BAD,BAD,BAD,BAD,BAD,BAD){3,6}	EMS(EMS_callhome_fans_failed, "MULTIPLE FAN FAILURE")
A G ctrl_fans (BAD,BAD,BAD,BAD,BAD,BAD){3,6}	10+10/DO(env_halt,1,"Multiple fans failed")

# Update Critical Fan Count SNMP
# Triggers the update_snmp if the number of BAD fans in the group is changing among 0, 1, 2 and 3.
# Since the policy shuts down the filer right away for 3 or more bad fans, we can ignore the number of failed fans changed
# beyond 3 (without updating the snmp).  If this policy changed, these actions may need to revise.
A G ctrl_fans (BAD,BAD,BAD,BAD,BAD,BAD){0,0}	DO(update_snmp, ENTITY_FAN)
A G ctrl_fans (BAD,BAD,BAD,BAD,BAD,BAD){1,1}	DO(update_snmp, ENTITY_FAN)
A G ctrl_fans (BAD,BAD,BAD,BAD,BAD,BAD){2,2}	DO(update_snmp, ENTITY_FAN)
A G ctrl_fans (BAD,BAD,BAD,BAD,BAD,BAD){3,6}	DO(update_snmp, ENTITY_FAN)

## PSU Sensors

# Disarm OK messages to prevent OK spam during boot
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_chassisPowerSupply_ok_1)
A S init ST_UNINITIALIZED	DISARM(EMS_callhome_chassis_ps_ok_1)
A S init ST_UNINITIALIZED	DISARM(EMS_monitor_chassisPowerSupply_ok_2)
A S init ST_UNINITIALIZED	DISARM(EMS_callhome_chassis_ps_ok_2)
# We only want to trigger the OK EMS message if we have actually triggered a bad EMS message.
# Since the bad messages are being delayed, we need to use a pseudo-sensor to track when to
# trigger the OK message.
S psu1_state "PSU1"		DISCRETE	- - 0 0	hidden	0*/GOOD 1/BAD
S psu2_state "PSU2"		DISCRETE	- - 0 0	hidden	0*/GOOD 1/BAD
# Pseudo sensor to track whether the PSU is failed and need replacement. This condition occurs when
# the input AC_OK  is fine, but output DC_OK is not valid. This condition affects other PSU sensor's state
# and to differentiate this easily, this sensor is introduced.
S psu1_replace "PSU1 need replacement" DISCRETE - - 0 0 hidden 0*/NO 1/YES 2/NOTSURE
S psu2_replace "PSU2 need replacement" DISCRETE - - 0 0 hidden 0*/NO 1/YES 2/NOTSURE
A S psu1_state GOOD	+0/EMS(EMS_monitor_chassisPowerSupply_ok_1)
A S psu1_state GOOD	+0/EMS(EMS_callhome_chassis_ps_ok_1)
A S psu2_state GOOD	+0/EMS(EMS_monitor_chassisPowerSupply_ok_2)
A S psu2_state GOOD	+0/EMS(EMS_callhome_chassis_ps_ok_2)
A S psu1_state BAD	ARM(EMS_monitor_chassisPowerSupply_ok_1)
A S psu1_state BAD	ARM(EMS_callhome_chassis_ps_ok_1)
A S psu1_replace YES ARM(EMS_monitor_chassisPowerSupply_ok_1)
A S psu1_replace YES ARM(EMS_callhome_chassis_ps_ok_1)
A S psu2_state BAD	ARM(EMS_monitor_chassisPowerSupply_ok_2)
A S psu2_state BAD	ARM(EMS_callhome_chassis_ps_ok_2)
A S psu2_replace YES ARM(EMS_monitor_chassisPowerSupply_ok_2)
A S psu2_replace YES ARM(EMS_callhome_chassis_ps_ok_2)
# If a PSU's status is bad, trigger an ASUP.  We only want to do this
# if the PSU is considered present because a not_present PSU will force
# the status to bad but that state has it's own ASUP associated with it.
# Policy for psux_replace sensor
#	AC_OK	DC_OK		PSU_REPLACE
#	OK		FAULT		YES
#	OK		OK			NO
#	OK		FAILED/NA	NOTSURE
#	!OK	-				NOTSURE
#Chassis PS replace ASUP will be generated only when PSU_REPLACE is in YES condition

A (PSU1_Present, psu1_state, psu1_replace) (PRESENT, BAD, !YES){3,3}	EMS(EMS_callhome_chassis_ps_degraded, "CHASSIS POWER SUPPLY DEGRADED: PS 1")
A (PSU2_Present, psu2_state, psu2_replace) (PRESENT, BAD, !YES){3,3}	EMS(EMS_callhome_chassis_ps_degraded, "CHASSIS POWER SUPPLY DEGRADED: PS 2")
A (PSU1_Present, psu1_state, psu1_replace) (PRESENT, -, YES){2,2}	EMS(EMS_callhome_chassis_ps_replace, "CHASSIS POWER SUPPLY NEED TO BE REPLACED: PS 1")
A (PSU2_Present, psu2_state, psu2_replace) (PRESENT, -, YES){2,2}	EMS(EMS_callhome_chassis_ps_replace, "CHASSIS POWER SUPPLY NEED TO BE REPLACED: PS 2")

# if PSU1 gets pulled, disable all the PSU1 sensors
A S PSU1_Present NOT_PRESENT		30/EMS(EMS_monitor_chassisPowerSupply_notPresent,"1")
A S PSU1_Present NOT_PRESENT		30/EMS(EMS_callhome_chassis_ps_rm,"CHASSIS POWER SUPPLY REMOVED: PS 1")
A S PSU1_Present NOT_PRESENT		30/SET_VALUE(psu1_state, BAD)
A S PSU1_Present [NOT_PRESENT|ST_DISABLED]	30/SET_STATE(PSU1_Temp,ST_DISABLED),30/SET_STATE(PSU1_Curr,ST_DISABLED),30/SET_STATE(PSU1_Fan1_Speed,ST_DISABLED)
A S PSU1_Present [NOT_PRESENT|ST_DISABLED]	30/SET_STATE(PSU1_Fan1_Fault,ST_DISABLED),30/SET_STATE(PSU1_Fan2_Speed,ST_DISABLED),30/SET_STATE(PSU1_Fan2_Fault,ST_DISABLED)
A S PSU1_Present [NOT_PRESENT|ST_DISABLED]	30/SET_STATE(PSU1_Pwr_In_OK,ST_DISABLED),30/SET_STATE(PSU1_Pwr_Out_OK,ST_DISABLED),30/SET_STATE(PSU1_InPwr_Mon,ST_DISABLED)
A S PSU1_Present [NOT_PRESENT|ST_DISABLED]	30/SET_STATE(PSU1_Fault,ST_DISABLED),30/SET_STATE(PSU1_Input_Type,ST_DISABLED),30/SET_STATE(PSU1_Over_Temp,ST_DISABLED)
A S PSU1_Present [NOT_PRESENT|ST_DISABLED]	30/SET_STATE(PSU1_Over_Volt,ST_DISABLED),30/SET_STATE(PSU1_Over_Curr,ST_DISABLED),30/SET_STATE(PSU1_CrestFactor,ST_DISABLED)

# if PSU1 gets inserted, enable all the PSU1 sensors
A (PSU1_Present,PSU1_Temp) (PRESENT,ST_DISABLED) {2,2}	\
	30/SET_STATE(PSU1_Temp,ST_UNINITIALIZED),30/SET_STATE(PSU1_Curr,ST_UNINITIALIZED),30/SET_STATE(PSU1_Fan1_Speed,ST_UNINITIALIZED), \
	30/SET_STATE(PSU1_Fan1_Fault,ST_UNINITIALIZED),30/SET_STATE(PSU1_Fan2_Speed,ST_UNINITIALIZED),30/SET_STATE(PSU1_Fan2_Fault,ST_UNINITIALIZED), \
	30/SET_STATE(PSU1_Pwr_In_OK,ST_UNINITIALIZED),30/SET_STATE(PSU1_Pwr_Out_OK,ST_UNINITIALIZED),30/SET_STATE(PSU1_InPwr_Mon,ST_UNINITIALIZED), \
	30/SET_STATE(PSU1_Fault,ST_UNINITIALIZED),30/SET_STATE(PSU1_Input_Type,ST_UNINITIALIZED),30/SET_STATE(PSU1_Over_Temp,ST_UNINITIALIZED), \
	30/SET_STATE(PSU1_Over_Volt,ST_UNINITIALIZED),30/SET_STATE(PSU1_Over_Curr,ST_UNINITIALIZED),30/SET_STATE(PSU1_CrestFactor,ST_UNINITIALIZED)

# if PSU2 gets pulled, disable all the PSU2 sensors
A S PSU2_Present NOT_PRESENT		30/EMS(EMS_monitor_chassisPowerSupply_notPresent,"2")
A S PSU2_Present NOT_PRESENT		30/EMS(EMS_callhome_chassis_ps_rm,"CHASSIS POWER SUPPLY REMOVED: PS 2")
A S PSU2_Present NOT_PRESENT		30/SET_VALUE(psu2_state, BAD)
A S PSU2_Present [NOT_PRESENT|ST_DISABLED]	30/SET_STATE(PSU2_Temp,ST_DISABLED),30/SET_STATE(PSU2_Curr,ST_DISABLED),30/SET_STATE(PSU2_Fan1_Speed,ST_DISABLED)
A S PSU2_Present [NOT_PRESENT|ST_DISABLED]	30/SET_STATE(PSU2_Fan1_Fault,ST_DISABLED),30/SET_STATE(PSU2_Fan2_Speed,ST_DISABLED),30/SET_STATE(PSU2_Fan2_Fault,ST_DISABLED)
A S PSU2_Present [NOT_PRESENT|ST_DISABLED]	30/SET_STATE(PSU2_Pwr_In_OK,ST_DISABLED),30/SET_STATE(PSU2_Pwr_Out_OK,ST_DISABLED),30/SET_STATE(PSU2_InPwr_Mon,ST_DISABLED)
A S PSU2_Present [NOT_PRESENT|ST_DISABLED]	30/SET_STATE(PSU2_Fault,ST_DISABLED),30/SET_STATE(PSU2_Input_Type,ST_DISABLED),30/SET_STATE(PSU2_Over_Temp,ST_DISABLED)
A S PSU2_Present [NOT_PRESENT|ST_DISABLED]	30/SET_STATE(PSU2_Over_Volt,ST_DISABLED),30/SET_STATE(PSU2_Over_Curr,ST_DISABLED),30/SET_STATE(PSU2_CrestFactor,ST_DISABLED)

# if PSU2 gets inserted, enable all the PSU2 sensors
A (PSU2_Present,PSU2_Temp) (PRESENT,ST_DISABLED) {2,2}	\
	30/SET_STATE(PSU2_Temp,ST_UNINITIALIZED),30/SET_STATE(PSU2_Curr,ST_UNINITIALIZED),30/SET_STATE(PSU2_Fan1_Speed,ST_UNINITIALIZED), \
	30/SET_STATE(PSU2_Fan1_Fault,ST_UNINITIALIZED),30/SET_STATE(PSU2_Fan2_Speed,ST_UNINITIALIZED),30/SET_STATE(PSU2_Fan2_Fault,ST_UNINITIALIZED), \
	30/SET_STATE(PSU2_Pwr_In_OK,ST_UNINITIALIZED),30/SET_STATE(PSU2_Pwr_Out_OK,ST_UNINITIALIZED),30/SET_STATE(PSU2_InPwr_Mon,ST_UNINITIALIZED), \
	30/SET_STATE(PSU2_Fault,ST_UNINITIALIZED),30/SET_STATE(PSU2_Input_Type,ST_UNINITIALIZED),30/SET_STATE(PSU2_Over_Temp,ST_UNINITIALIZED), \
	30/SET_STATE(PSU2_Over_Volt,ST_UNINITIALIZED),30/SET_STATE(PSU2_Over_Curr,ST_UNINITIALIZED),30/SET_STATE(PSU2_CrestFactor,ST_UNINITIALIZED)

# if a PSU is turned off, send warning messages
A S PSU1_Pwr_In_OK FAULT		30/EMS(EMS_monitor_chassisPowerSupply_off,"1")
A S PSU1_Pwr_In_OK FAULT		30/EMS(EMS_callhome_chassis_ps_off,"CHASSIS POWER SUPPLY OFF: PS 1")
A S PSU1_Pwr_In_OK FAULT		30/SET_VALUE(psu1_state, BAD)
A S PSU2_Pwr_In_OK FAULT		30/EMS(EMS_monitor_chassisPowerSupply_off,"2")
A S PSU2_Pwr_In_OK FAULT		30/EMS(EMS_callhome_chassis_ps_off,"CHASSIS POWER SUPPLY OFF: PS 2")
A S PSU2_Pwr_In_OK FAULT		30/SET_VALUE(psu2_state, BAD)

# PSU Sensor Groups
G psu1_grp PSU1_Temp, PSU1_Curr, PSU1_Fan1_Speed, PSU1_Fan1_Fault, PSU1_Fan2_Speed, PSU1_Fan2_Fault, \
	   PSU1_Pwr_In_OK, PSU1_Pwr_Out_OK, PSU1_Fault, PSU1_Over_Temp, PSU1_Over_Volt, PSU1_Over_Curr, PSU1_CrestFactor, PSU1_InPwr_Mon
G psu2_grp PSU2_Temp, PSU2_Curr, PSU2_Fan1_Speed, PSU2_Fan1_Fault, PSU2_Fan2_Speed, PSU2_Fan2_Fault, \
	   PSU2_Pwr_In_OK, PSU2_Pwr_Out_OK, PSU2_Fault, PSU2_Over_Temp, PSU2_Over_Volt, PSU2_Over_Curr, PSU2_CrestFactor, PSU2_InPwr_Mon

# If all the PSU1 sensors are good, say so
A G psu1_grp (ST_OK,ST_OK,ST_OK,OK,ST_OK,OK,OK,OK,OK,OK,OK,OK,ST_OK,ST_OK){14,14}	 30/SET_VALUE(psu1_state, GOOD)
A (PSU1_Pwr_In_OK,PSU1_Pwr_Out_OK) (OK,OK) {2,2}     30/SET_VALUE(psu1_replace, NO)

# If all the PSU2 sensors are good, say so
A G psu2_grp (ST_OK,ST_OK,ST_OK,OK,ST_OK,OK,OK,OK,OK,OK,OK,OK,ST_OK,ST_OK){14,14}	 30/SET_VALUE(psu2_state, GOOD)
A (PSU2_Pwr_In_OK,PSU2_Pwr_Out_OK) (OK,OK) {2,2}     30/SET_VALUE(psu2_replace, NO)


# Individual PSU sensor EMS messages
A S PSU1_Temp ST_LOW_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Temperature is Critical Low (%r)")
A S PSU1_Temp ST_LOW_CRIT	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Temp ST_LOW_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Temperature is Warning Low (%r)")
A S PSU1_Temp ST_LOW_WARN	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Temp ST_HIGH_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Temperature is Warning High (%r)")
A S PSU1_Temp ST_HIGH_WARN	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Temp ST_HIGH_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Temperature is Critical High (%r)")
A S PSU1_Temp ST_HIGH_CRIT	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Temp [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Temperature is Unreadable")
A S PSU1_Temp [ST_FAILED|ST_NA]	30/SET_VALUE(psu1_state, BAD)

A S PSU1_Curr ST_LOW_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Current is Critical Low (%r)")
A S PSU1_Curr ST_LOW_CRIT	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Curr ST_LOW_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Current is Warning Low (%r)")
A S PSU1_Curr ST_LOW_WARN	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Curr ST_HIGH_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Current is Warning High (%r)")
A S PSU1_Curr ST_HIGH_WARN	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Curr ST_HIGH_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Current is Critical High (%r)")
A S PSU1_Curr ST_HIGH_CRIT	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Curr [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Current is Unreadable")
A S PSU1_Curr [ST_FAILED|ST_NA]	30/SET_VALUE(psu1_state, BAD)

A S PSU1_Fan1_Speed ST_LOW_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan1 Speed is Critical Low (%r)")
A S PSU1_Fan1_Speed ST_LOW_CRIT	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Fan1_Speed ST_LOW_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan1 Speed is Warning Low (%r)")
A S PSU1_Fan1_Speed ST_LOW_WARN	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Fan1_Speed ST_HIGH_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan1 Speed is Warning High (%r)")
A S PSU1_Fan1_Speed ST_HIGH_WARN	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Fan1_Speed ST_HIGH_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan1 Speed is Critical High (%r)")
A S PSU1_Fan1_Speed ST_HIGH_CRIT	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Fan1_Speed [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan1 Speed is Unreadable")
A S PSU1_Fan1_Speed [ST_FAILED|ST_NA]	30/SET_VALUE(psu1_state, BAD)

A S PSU1_Fan1_Fault FAULT		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan1 has failed")
A S PSU1_Fan1_Fault FAULT		30/SET_VALUE(psu1_state, BAD)
A S PSU1_Fan1_Fault [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan1 Fault is Unreadable")
A S PSU1_Fan1_Fault [ST_FAILED|ST_NA]	30/SET_VALUE(psu1_state, BAD)

A S PSU1_Fan2_Speed ST_LOW_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan2 Speed is Critical Low (%r)")
A S PSU1_Fan2_Speed ST_LOW_CRIT	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Fan2_Speed ST_LOW_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan2 Speed is Warning Low (%r)")
A S PSU1_Fan2_Speed ST_LOW_WARN	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Fan2_Speed ST_HIGH_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan2 Speed is Warning High (%r)")
A S PSU1_Fan2_Speed ST_HIGH_WARN	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Fan2_Speed ST_HIGH_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan2 Speed is Critical High (%r)")
A S PSU1_Fan2_Speed ST_HIGH_CRIT	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Fan2_Speed [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan2 Speed is Unreadable")
A S PSU1_Fan2_Speed [ST_FAILED|ST_NA]	30/SET_VALUE(psu1_state, BAD)

A S PSU1_Fan2_Fault FAULT		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan2 has failed")
A S PSU1_Fan2_Fault FAULT		30/SET_VALUE(psu1_state, BAD)
A S PSU1_Fan2_Fault [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fan2 Fault is Unreadable")
A S PSU1_Fan2_Fault [ST_FAILED|ST_NA]	30/SET_VALUE(psu1_state, BAD)

A S PSU1_Pwr_Out_OK FAULT		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Power Output has failed")
A (PSU1_Pwr_In_OK,PSU1_Pwr_Out_OK) (OK,FAULT) {2,2}		30/SET_VALUE(psu1_replace, YES), 30/SET_VALUE(psu1_state, BAD)
A (PSU1_Pwr_In_OK,PSU1_Pwr_Out_OK) (!OK,FAULT){2,2}		30/SET_VALUE(psu1_state, BAD), 30/SET_VALUE(psu1_replace, NOTSURE)
A S PSU1_Pwr_Out_OK [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Pwr Out OK is Unreadable")
A (PSU1_Pwr_In_OK,PSU1_Pwr_Out_OK) (-, [ST_FAILED|ST_NA]) {1,1}	30/SET_VALUE(psu1_replace, NOTSURE), 30/SET_VALUE(psu1_state, BAD)

A S PSU1_Fault FAULT		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 has failed")
A S PSU1_Fault FAULT		30/SET_VALUE(psu1_state, BAD)
A S PSU1_Fault [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Fault is Unreadable")
A S PSU1_Fault [ST_FAILED|ST_NA]	30/SET_VALUE(psu1_state, BAD)

A S PSU1_Over_Temp OVER_TEMP	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 is over temperature")
A S PSU1_Over_Temp OVER_TEMP	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Over_Temp [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Over Temp is Unreadable")
A S PSU1_Over_Temp [ST_FAILED|ST_NA]	30/SET_VALUE(psu1_state, BAD)

A S PSU1_Over_Volt OVER_VOLT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 is over voltage")
A S PSU1_Over_Volt OVER_VOLT	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Over_Volt [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Over Volt is Unreadable")
A S PSU1_Over_Volt [ST_FAILED|ST_NA]	30/SET_VALUE(psu1_state, BAD)

A S PSU1_Over_Curr OVER_CURR	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 is over current")
A S PSU1_Over_Curr OVER_CURR	30/SET_VALUE(psu1_state, BAD)
A S PSU1_Over_Curr [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Over Curr is Unreadable")
A S PSU1_Over_Curr [ST_FAILED|ST_NA]	30/SET_VALUE(psu1_state, BAD)

A S PSU1_CrestFactor ST_LOW_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Crest Factor is Critical Low (%r)")
A S PSU1_CrestFactor ST_LOW_CRIT	30/SET_VALUE(psu1_state, BAD)
A S PSU1_CrestFactor ST_LOW_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Crest Factor is Warning Low (%r)")
A S PSU1_CrestFactor ST_LOW_WARN	30/SET_VALUE(psu1_state, BAD)
A S PSU1_CrestFactor ST_HIGH_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Crest Factor is Warning High (%r)")
A S PSU1_CrestFactor ST_HIGH_WARN	30/SET_VALUE(psu1_state, BAD)
A S PSU1_CrestFactor ST_HIGH_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Crest Factor is Critical High (%r)")
A S PSU1_CrestFactor ST_HIGH_CRIT	30/SET_VALUE(psu1_state, BAD)
A S PSU1_CrestFactor [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 Crest Factor is Unreadable")
A S PSU1_CrestFactor [ST_FAILED|ST_NA]	30/SET_VALUE(psu1_state, BAD)

A S PSU1_InPwr_Mon ST_LOW_CRIT		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 InPower Monitor is Critical Low (%r)")
A S PSU1_InPwr_Mon ST_LOW_CRIT		30/SET_VALUE(psu1_state, BAD)
A S PSU1_InPwr_Mon ST_LOW_WARN		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 InPower Monitor is Warning Low (%r)")
A S PSU1_InPwr_Mon ST_LOW_WARN		30/SET_VALUE(psu1_state, BAD)
A S PSU1_InPwr_Mon ST_HIGH_WARN		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 InPower Monitor is Warning High (%r)")
A S PSU1_InPwr_Mon ST_HIGH_WARN		30/SET_VALUE(psu1_state, BAD)
A S PSU1_InPwr_Mon ST_HIGH_CRIT		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 InPower Monitor is Critical High (%r)")
A S PSU1_InPwr_Mon ST_HIGH_CRIT		30/SET_VALUE(psu1_state, BAD)
A S PSU1_InPwr_Mon [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "1", "PSU1 InPower Monitor is Unreadable")
A S PSU1_InPwr_Mon [ST_FAILED|ST_NA]	30/SET_VALUE(psu1_state, BAD)

A S PSU2_Temp ST_LOW_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Temperature is Critical Low (%r)")
A S PSU2_Temp ST_LOW_CRIT	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Temp ST_LOW_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Temperature is Warning Low (%r)")
A S PSU2_Temp ST_LOW_WARN	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Temp ST_HIGH_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Temperature is Warning High (%r)")
A S PSU2_Temp ST_HIGH_WARN	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Temp ST_HIGH_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Temperature is Critical High (%r)")
A S PSU2_Temp ST_HIGH_CRIT	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Temp [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Temperature is Unreadable")
A S PSU2_Temp [ST_FAILED|ST_NA]	30/SET_VALUE(psu2_state, BAD)

A S PSU2_Curr ST_LOW_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Current is Critical Low (%r)")
A S PSU2_Curr ST_LOW_CRIT	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Curr ST_LOW_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Current is Warning Low (%r)")
A S PSU2_Curr ST_LOW_WARN	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Curr ST_HIGH_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Current is Warning High (%r)")
A S PSU2_Curr ST_HIGH_WARN	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Curr ST_HIGH_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Current is Critical High (%r)")
A S PSU2_Curr ST_HIGH_CRIT	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Curr [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Current is Unreadable")
A S PSU2_Curr [ST_FAILED|ST_NA]	30/SET_VALUE(psu2_state, BAD)

A S PSU2_Fan1_Speed ST_LOW_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan1 Speed is Critical Low (%r)")
A S PSU2_Fan1_Speed ST_LOW_CRIT	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Fan1_Speed ST_LOW_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan1 Speed is Warning Low (%r)")
A S PSU2_Fan1_Speed ST_LOW_WARN	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Fan1_Speed ST_HIGH_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan1 Speed is Warning High (%r)")
A S PSU2_Fan1_Speed ST_HIGH_WARN	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Fan1_Speed ST_HIGH_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan1 Speed is Critical High (%r)")
A S PSU2_Fan1_Speed ST_HIGH_CRIT	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Fan1_Speed [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan1 Speed is Unreadable")
A S PSU2_Fan1_Speed [ST_FAILED|ST_NA]	30/SET_VALUE(psu2_state, BAD)

A S PSU2_Fan1_Fault FAULT		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan1 has failed")
A S PSU2_Fan1_Fault FAULT		30/SET_VALUE(psu2_state, BAD)
A S PSU2_Fan1_Fault [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan1 Fault is Unreadable")
A S PSU2_Fan1_Fault [ST_FAILED|ST_NA]	30/SET_VALUE(psu2_state, BAD)

A S PSU2_Fan2_Speed ST_LOW_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan2 Speed is Critical Low (%r)")
A S PSU2_Fan2_Speed ST_LOW_CRIT	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Fan2_Speed ST_LOW_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan2 Speed is Warning Low (%r)")
A S PSU2_Fan2_Speed ST_LOW_WARN	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Fan2_Speed ST_HIGH_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan2 Speed is Warning High (%r)")
A S PSU2_Fan2_Speed ST_HIGH_WARN	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Fan2_Speed ST_HIGH_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan2 Speed is Critical High (%r)")
A S PSU2_Fan2_Speed ST_HIGH_CRIT	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Fan2_Speed [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan2 Speed is Unreadable")
A S PSU2_Fan2_Speed [ST_FAILED|ST_NA]	30/SET_VALUE(psu2_state, BAD)

A S PSU2_Fan2_Fault FAULT		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan2 has failed")
A S PSU2_Fan2_Fault FAULT		30/SET_VALUE(psu2_state, BAD)
A S PSU2_Fan2_Fault [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fan2 Fault is Unreadable")
A S PSU2_Fan2_Fault [ST_FAILED|ST_NA]	30/SET_VALUE(psu2_state, BAD)

A S PSU2_Pwr_Out_OK FAULT		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Power Output has failed")
A (PSU2_Pwr_In_OK,PSU2_Pwr_Out_OK) (OK,FAULT) {2,2}		30/SET_VALUE(psu2_replace, YES),30/SET_VALUE(psu2_state, BAD)
A (PSU2_Pwr_In_OK,PSU2_Pwr_Out_OK) (!OK,FAULT){2,2}		30/SET_VALUE(psu2_state, BAD), 30/SET_VALUE(psu2_replace, NOTSURE)
A S PSU2_Pwr_Out_OK [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Pwr Out OK is Unreadable")
A (PSU2_Pwr_In_OK,PSU2_Pwr_Out_OK) (-, [ST_FAILED|ST_NA]) {1,1}	30/SET_VALUE(psu2_replace, NOTSURE), 30/SET_VALUE(psu2_state, BAD)

A S PSU2_Fault FAULT		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 has failed")
A S PSU2_Fault FAULT		30/SET_VALUE(psu2_state, BAD)
A S PSU2_Fault [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Fault is Unreadable")
A S PSU2_Fault [ST_FAILED|ST_NA]	30/SET_VALUE(psu2_state, BAD)

A S PSU2_Over_Temp OVER_TEMP	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 is over temperature")
A S PSU2_Over_Temp OVER_TEMP	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Over_Temp [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Over Temp is Unreadable")
A S PSU2_Over_Temp [ST_FAILED|ST_NA]	30/SET_VALUE(psu2_state, BAD)

A S PSU2_Over_Volt OVER_VOLT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 is over voltage")
A S PSU2_Over_Volt OVER_VOLT	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Over_Volt [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Over Volt is Unreadable")
A S PSU2_Over_Volt [ST_FAILED|ST_NA]	30/SET_VALUE(psu2_state, BAD)

A S PSU2_Over_Curr OVER_CURR	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 is over current")
A S PSU2_Over_Curr OVER_CURR	30/SET_VALUE(psu2_state, BAD)
A S PSU2_Over_Curr [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Over Curr is Unreadable")
A S PSU2_Over_Curr [ST_FAILED|ST_NA]	30/SET_VALUE(psu2_state, BAD)

A S PSU2_CrestFactor ST_LOW_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Crest Factor is Critical Low (%r)")
A S PSU2_CrestFactor ST_LOW_CRIT	30/SET_VALUE(psu2_state, BAD)
A S PSU2_CrestFactor ST_LOW_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Crest Factor is Warning Low (%r)")
A S PSU2_CrestFactor ST_LOW_WARN	30/SET_VALUE(psu2_state, BAD)
A S PSU2_CrestFactor ST_HIGH_WARN	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Crest Factor is Warning High (%r)")
A S PSU2_CrestFactor ST_HIGH_WARN	30/SET_VALUE(psu2_state, BAD)
A S PSU2_CrestFactor ST_HIGH_CRIT	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Crest Factor is Critical High (%r)")
A S PSU2_CrestFactor ST_HIGH_CRIT	30/SET_VALUE(psu2_state, BAD)
A S PSU2_CrestFactor [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 Crest Factor is Unreadable")
A S PSU2_CrestFactor [ST_FAILED|ST_NA]	30/SET_VALUE(psu2_state, BAD)

A S PSU2_InPwr_Mon ST_LOW_CRIT		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 InPower Monitor is Critical Low (%r)")
A S PSU2_InPwr_Mon ST_LOW_CRIT		30/SET_VALUE(psu2_state, BAD)
A S PSU2_InPwr_Mon ST_LOW_WARN		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 InPower Monitor is Warning Low (%r)")
A S PSU2_InPwr_Mon ST_LOW_WARN		30/SET_VALUE(psu2_state, BAD)
A S PSU2_InPwr_Mon ST_HIGH_WARN		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 InPower Monitor is Warning High (%r)")
A S PSU2_InPwr_Mon ST_HIGH_WARN		30/SET_VALUE(psu2_state, BAD)
A S PSU2_InPwr_Mon ST_HIGH_CRIT		30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 InPower Monitor is Critical High (%r)")
A S PSU2_InPwr_Mon ST_HIGH_CRIT		30/SET_VALUE(psu2_state, BAD)
A S PSU2_InPwr_Mon [ST_FAILED|ST_NA]	30/EMS(EMS_monitor_chassisPowerSupply_degraded, "2", "PSU2 InPower Monitor is Unreadable")
A S PSU2_InPwr_Mon [ST_FAILED|ST_NA]	30/SET_VALUE(psu2_state, BAD)

# SNMP PSU Count
# To prevent the race condition on the action psus_snmp and update_sen_list, create the pseudo sensor
# psux_bad to make sure the "psus_snmp" action is executed after the "update_sen_list" action.
S psu1_bad "PSU1 Bad"	DISCRETE	- - 0 0	hidden	0*/FALSE 1/TRUE
S psu2_bad "PSU2 Bad"	DISCRETE	- - 0 0	hidden	0*/FALSE 1/TRUE
A S psu1_bad TRUE			DO(update_snmp, ENTITY_PSU)
A S psu2_bad TRUE			DO(update_snmp, ENTITY_PSU)
A S psu1_bad FALSE			DO(update_snmp, ENTITY_PSU)
A S psu2_bad FALSE			DO(update_snmp, ENTITY_PSU)
A S psu1_state GOOD			DO(update_sen_list, "crit_psu", DEL, psu1_state), SET_VALUE(psu1_bad, FALSE)
A S psu2_state GOOD			DO(update_sen_list, "crit_psu", DEL, psu2_state), SET_VALUE(psu2_bad, FALSE)
A S psu1_state BAD			DO(update_sen_list, "crit_psu", ADD, psu1_state), SET_VALUE(psu1_bad, TRUE)
A S psu2_state BAD			DO(update_sen_list, "crit_psu", ADD, psu2_state), SET_VALUE(psu2_bad, TRUE)

###############################################################################################################
#                                            Razor-L Power Policies                                           #
###############################################################################################################

## Controller Voltages
G ctrl_volt	P5V_STBY, P3V3_STBY, P1V8_STBY, P1V2_STBY, P0V9_STBY, P5V, P3V3, PVDDQ_DDR4_AB, PVTT_DDR4_AB, \
		PVCCP_CPU0, P3V3_BATT, P12V, P12V_Curr, P12V_STBY, P12V_STBY_Curr
# Define Psudo sensor to keep track of EMS
S ctrl_volt_status "Voltage Status"	DISCRETE	- - 0 0	hidden	0*/GOOD 1/BAD

A S init ST_UNINITIALIZED		DISARM(EMS_monitor_chassisPower_ok)
A S ctrl_volt_status GOOD	+0/EMS(EMS_monitor_chassisPower_ok)
A S ctrl_volt_status BAD	ARM(EMS_monitor_chassisPower_ok)

# If all voltage sensors are good, send the OK ems message.
A G ctrl_volt (ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK, \
		ST_OK,ST_OK,ST_OK,ST_OK) {15,15}	SET_VALUE(ctrl_volt_status, GOOD)

# We assume brief voltage spikes are more likely to be sensor weirdness than actual
# voltage spikes, mostly evidenced by the fact that the system is still running to
# monitor voltages.  We filter accordingly, but we do want to identify sensors that
# are having more than expected number of problems in order to reject bad sensors.
S ctrl_volt_bucket "Voltage Spike Frequency"	COUNTER	- - 0 0	hidden	-1 - - - 3 - - -
A S init		ST_UNINITIALIZED	SET_VALUE(ctrl_volt_bucket, 0)
A S ctrl_volt_bucket	ST_VALID		+43200/ADD_VALUE(ctrl_volt_bucket, -1, 0, -)
A S ctrl_volt_bucket	ST_HIGH_CRIT		EMS(EMS_monitor_chassisPower_degraded, "Sensor detecting voltage anomalies.")

# Individial voltage sensor EMS messages
INCLUDE MACRO_POWER	(P12V_STBY_Curr)
INCLUDE MACRO_POWER	(P12V_STBY)
INCLUDE MACRO_POWER	(P12V_Curr)
INCLUDE MACRO_POWER	(P12V)
INCLUDE MACRO_POWER	(P3V3_BATT)
INCLUDE MACRO_POWER	(PVCCP_CPU0)
INCLUDE MACRO_POWER	(PVTT_DDR4_AB)
INCLUDE MACRO_POWER	(PVDDQ_DDR4_AB)
INCLUDE MACRO_POWER	(P3V3)
INCLUDE MACRO_POWER	(P5V)
INCLUDE MACRO_POWER	(P0V9_STBY)
INCLUDE MACRO_POWER	(P1V2_STBY)
INCLUDE MACRO_POWER	(P1V8_STBY)
INCLUDE MACRO_POWER	(P3V3_STBY)
INCLUDE MACRO_POWER	(P5V_STBY)

###############################################################################################################
#                                              Razor-L Battery Policy                                         #
###############################################################################################################
#
# Define Pseudo sensors
#
G bat_chrg_grp Bat_Lrn_Active, Bat_Charge_Curr, Bat_Curr
# 'Bat_Charge_State'
# If Larning Active is ON, it is now in learning cycle
A G bat_chrg_grp (ON, -, -) {1,1}			SET_VALUE(Bat_Charge_State, IDLE)
# Charging Current and Battery Current zero means the battery is not charging.
A G bat_chrg_grp (!ON, (-1, 1), (-1, 1)) {3,3}		POLL(Bat_Charge_Curr, -), POLL(Bat_Curr, -), \
							SET_VALUE(Bat_Charge_State, IDLE)
# Charging Current and Battery Current non-zero means the battery is charging.
A G bat_chrg_grp (!ON, !(-1, 1),!(-1, 1) ){3,3}		POLL(Bat_Charge_Curr, -), POLL(Bat_Curr, -), \
							SET_VALUE(Bat_Charge_State, CHARGING)
# Charging Current is zero but Battery Current is non-zero means it's charging without permission.
# Give it 20 seconds because it could take time for the charger to respond (carried from burt424092)
A G bat_chrg_grp (!ON, (-1, 1),!(-1, 1)){3,3}		POLL(Bat_Charge_Curr, 10), POLL(Bat_Curr, 10), \
							30/SET_VALUE(Bat_Charge_State, WRONG_CHARGE)
# Charging Current is non-zero but Battery Current is zero means it's not charging when it should be.
# Give it 5 minutes because it could take time for the charger to respond (carried from burt494480)
A G bat_chrg_grp  (!ON, !(-1, 1),(-1, 1)){3,3}		POLL(Bat_Charge_Curr, 10), POLL(Bat_Curr, 10), \
							300/SET_VALUE(Bat_Charge_State, NO_CHARGE)
# If either Charging Current or Battery Current are failed, we don't know the state, so it's failed
A G bat_chrg_grp  (-, ST_FAILED, ST_FAILED){1,2}	SET_STATE(Bat_Charge_State, ST_FAILED)
# If Learning Active is not readable, we don't know the state, so it's failed
A G bat_chrg_grp ([ST_NA|ST_FAILED],-,-){1,1}		SET_STATE(Bat_Charge_State, ST_FAILED)

# 'Bat_Pct_Cap'
F Bat_Pct_Cap	PERCENT	Bat_Full_Cap Bat_Initial_Fcc

# Set the battery present sesor by checking Bat_Power_Fault and Bat_Pack_Invalid
A (Bat_Power_Fault, Bat_Pack_Invalid)	(BAD, [ST_NA|ST_FAILED|INVALID]){2,2}	SET_VALUE(Bat_Present, NOT_PRESENT)
A (Bat_Power_Fault, Bat_Pack_Invalid)	(GOOD, OK){1,2}			SET_VALUE(Bat_Present, PRESENT)

# if the battery not present, disable all other battery sensors
A S Bat_Present [NOT_PRESENT|ST_DISABLED]	\
			30/SET_STATE(Bat_Charge_FET, ST_DISABLED), 30/SET_STATE(Bat_Dcharge_FET, ST_DISABLED), \
			30/SET_STATE(Bat_Dstg_Cycles, ST_DISABLED), 30/SET_STATE(Bat_Charge_State, ST_DISABLED), \
			30/SET_STATE(Bat_Initial_Fcc, ST_DISABLED), 30/SET_STATE(Bat_Charge_Volt, ST_DISABLED), \
			30/SET_STATE(Bat_Charge_Curr, ST_DISABLED), 30/SET_STATE(Bat_Full_Cap, ST_DISABLED), \
			30/SET_STATE(Bat_Rem_Cap, ST_DISABLED), 30/SET_STATE(Bat_Curr, ST_DISABLED),  \
			30/SET_STATE(Bat_Volt, ST_DISABLED), 30/SET_STATE(Bat_Temp, ST_DISABLED), \
			30/SET_STATE(Bat_Cycle_Cnt, ST_DISABLED), 30/SET_STATE(Bat_Pct_Cap, ST_DISABLED), \
			30/SET_STATE(Bat_Lrn_Active, ST_DISABLED)
# if the battery present, reinit all other battery sensors
A (Bat_Present,Bat_Charge_FET) (PRESENT,ST_DISABLED) {2,2} \
		30/SET_STATE(Bat_Charge_FET, ST_UNINITIALIZED), 30/SET_STATE(Bat_Dcharge_FET, ST_UNINITIALIZED), \
		30/SET_STATE(Bat_Dstg_Cycles, ST_UNINITIALIZED), 30/SET_STATE(Bat_Charge_State, ST_UNINITIALIZED), \
		30/SET_STATE(Bat_Initial_Fcc, ST_UNINITIALIZED), 30/SET_STATE(Bat_Charge_Volt, ST_UNINITIALIZED), \
		30/SET_STATE(Bat_Charge_Curr, ST_UNINITIALIZED), 30/SET_STATE(Bat_Full_Cap, ST_UNINITIALIZED), \
		30/SET_STATE(Bat_Rem_Cap, ST_UNINITIALIZED), 30/SET_STATE(Bat_Curr, ST_UNINITIALIZED), \
		30/SET_STATE(Bat_Volt, ST_UNINITIALIZED), 30/SET_STATE(Bat_Temp, ST_UNINITIALIZED), \
		30/SET_STATE(Bat_Cycle_Cnt, ST_UNINITIALIZED), 30/SET_STATE(Bat_Pct_Cap, ST_UNINITIALIZED), \
		30/SET_STATE(Bat_Lrn_Active, ST_UNINITIALIZED)

#
# Individual battery sensor EMS/ASUP message
#
# Bat Temp
A S init ST_UNINITIALIZED							DISARM(EMS_nvmem_battery_temp_normal)
A S Bat_Temp [ST_LOW_CRIT|ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED]	ARM(EMS_nvmem_battery_temp_normal)
A S Bat_Temp ST_HIGH_CRIT							EMS(EMS_nvmem_battery_tempHigh, "%r", "5")
A S Bat_Temp ST_HIGH_CRIT							EMS(EMS_callhome_battery_failure, "BATTERY (temperature high)")
A S Bat_Temp ST_HIGH_WARN							EMS(EMS_nvmem_battery_temp_high_warn)
A S Bat_Temp ST_HIGH_WARN							+86400/EMS(EMS_callhome_battery_notice, "BATTERY (temperature high)")
A S Bat_Temp ST_OK								+0/EMS(EMS_nvmem_battery_temp_normal)
A S Bat_Temp ST_LOW_WARN							EMS(EMS_nvmem_battery_temp_low_warn)
A S Bat_Temp ST_LOW_WARN							+86400/EMS(EMS_callhome_battery_notice, "BATTERY (temperature low)")
A S Bat_Temp ST_LOW_CRIT							+(,24)/EMS(EMS_nvmem_battery_tempLow, "%r", "%c")
A S Bat_Temp ST_LOW_CRIT							EMS(EMS_callhome_battery_warning, "BATTERY (temperature low)")
A S Bat_Temp [ST_FAILED]							EMS(EMS_nvmem_battery_unread, "%s", "5")
A S Bat_Temp [ST_FAILED]							EMS(EMS_callhome_battery_failure, "BATTERY ('%s' unreadable)")
A S Bat_Temp [ST_NA]								DISARM(EMS_nvmem_battery_temp_normal)
A S Bat_Temp [ST_NA]								30/SET_STATE(Bat_Temp, ST_FAILED), POLL(Bat_Temp, 10)

# Bat Voltage
A S init ST_UNINITIALIZED							DISARM(EMS_nvmem_battery_voltage_normal)
A S Bat_Volt [ST_LOW_CRIT|ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED]	ARM(EMS_nvmem_battery_voltage_normal)
A S Bat_Volt ST_HIGH_CRIT							EMS(EMS_nvmem_battery_voltageHigh, "%r", "5")
A S Bat_Volt ST_HIGH_CRIT							EMS(EMS_callhome_battery_failure, "BATTERY (voltage high)")
A S Bat_Volt ST_HIGH_WARN							+(,24)/EMS(EMS_nvmem_battery_voltageHiWarn, "%r", "%c")
A S Bat_Volt ST_HIGH_WARN							EMS(EMS_callhome_battery_warning, "BATTERY (voltage high)")
A S Bat_Volt ST_OK								+0/EMS(EMS_nvmem_battery_voltage_normal)
A S Bat_Volt ST_LOW_WARN							EMS(EMS_nvmem_battery_voltageLowWarn, "%r")
A S Bat_Volt ST_LOW_WARN							EMS(EMS_callhome_battery_warning, "BATTERY (voltage low)")
A S Bat_Volt ST_LOW_CRIT							EMS(EMS_nvmem_battery_voltageLow, "%r", "5")
A S Bat_Volt ST_LOW_CRIT							EMS(EMS_callhome_battery_failure, "BATTERY (voltage low)")
A S Bat_Volt [ST_FAILED]							EMS(EMS_nvmem_battery_unread, "%s", "5")
A S Bat_Volt [ST_FAILED]							EMS(EMS_callhome_battery_failure, "BATTERY ('%s' unreadable)")
A S Bat_Volt [ST_NA]								DISARM(EMS_nvmem_battery_voltage_normal)
A S Bat_Volt [ST_NA]								30/SET_STATE(Bat_Volt, ST_FAILED), POLL(Bat_Volt, 10)

# Bat Current
A S init ST_UNINITIALIZED							DISARM(EMS_nvmem_battery_current_normal)
A S Bat_Curr [ST_LOW_CRIT|ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED]	ARM(EMS_nvmem_battery_current_normal)
A S Bat_Curr ST_HIGH_CRIT							EMS(EMS_nvmem_battery_currentHigh, "%r", "5")
A S Bat_Curr ST_HIGH_CRIT							EMS(EMS_callhome_battery_failure, "BATTERY (current high)")
A S Bat_Curr ST_HIGH_WARN							+(,24)/EMS(EMS_nvmem_battery_currentHiWarn, "%r", "%c")
A S Bat_Curr ST_HIGH_WARN							EMS(EMS_callhome_battery_warning, "BATTERY (current high)")
A S Bat_Curr ST_OK								+0/EMS(EMS_nvmem_battery_current_normal)
A S Bat_Curr ST_LOW_WARN							+(,24)/EMS(EMS_nvmem_battery_currentLowWarn, "%r", "%c")
A S Bat_Curr ST_LOW_WARN							EMS(EMS_callhome_battery_warning, "BATTERY (current low)")
A S Bat_Curr ST_LOW_CRIT							EMS(EMS_nvmem_battery_currentLow, "%r", "5")
A S Bat_Curr ST_LOW_CRIT							EMS(EMS_callhome_battery_failure, "BATTERY (current low)")
A S Bat_Curr [ST_FAILED]							EMS(EMS_nvmem_battery_unread, "%s", "5")
A S Bat_Curr [ST_FAILED]							EMS(EMS_callhome_battery_failure, "BATTERY ('%s' unreadable)")
A S Bat_Curr [ST_NA]								DISARM(EMS_nvmem_battery_current_normal)
A S Bat_Curr [ST_NA]								30/SET_STATE(Bat_Curr, ST_FAILED), POLL(Bat_Curr, 10)

# Bat Rem. Capacity (Destage)
A S init ST_UNINITIALIZED							DISARM(EMS_nvmem_battery_capNormal)
A S Bat_Dstg_Cycles [ST_LOW_WARN|ST_LOW_CRIT|ST_FAILED]				ARM(EMS_nvmem_battery_capNormal)
A S Bat_Dstg_Cycles ST_OK							+0/EMS(EMS_nvmem_battery_capNormal)
A S Bat_Dstg_Cycles ST_LOW_WARN							EMS(EMS_nvmem_battery_capLowWarn, "%r")
A S Bat_Dstg_Cycles ST_LOW_WARN							+86400/EMS(EMS_callhome_battery_notice, "BATTERY (capacity low)")
A (Bat_Dstg_Cycles,Bat_Dstg_Cycles) (ST_LOW_CRIT,(1,)){2,2}			EMS(EMS_nvmem_battery_capLow, "%r")
A (Bat_Dstg_Cycles,Bat_Dstg_Cycles) (ST_LOW_CRIT,(1,)){2,2}			EMS(EMS_callhome_battery_warning, "BATTERY (capacity low)")
A (Bat_Dstg_Cycles,Bat_Dstg_Cycles) (ST_LOW_CRIT,(,2)){2,2}			EMS(EMS_nvmem_battery_capLowCrit, "%r", "20")
A (Bat_Dstg_Cycles,Bat_Dstg_Cycles) (ST_LOW_CRIT,(,2)){2,2}			EMS(EMS_callhome_battery_failure, "BATTERY (capacity low)")
A S Bat_Dstg_Cycles ST_FAILED							EMS(EMS_nvmem_battery_unread, "%s", "5")
A S Bat_Dstg_Cycles ST_FAILED							EMS(EMS_callhome_battery_failure, "BATTERY ('%s' unreadable)")
A S Bat_Dstg_Cycles [ST_NA]							DISARM(EMS_nvmem_battery_capNormal)
A S Bat_Dstg_Cycles [ST_NA]							30/SET_STATE(Bat_Dstg_Cycles, ST_FAILED), POLL(Bat_Dstg_Cycles, 10)

# Bat Full Capacity
A S init ST_UNINITIALIZED							DISARM(EMS_nvmem_battery_fccNormal)
A S Bat_Pct_Cap [ST_LOW_WARN|ST_LOW_CRIT|ST_FAILED]				ARM(EMS_nvmem_battery_fccNormal)
A S Bat_Pct_Cap ST_OK								+0/EMS(EMS_nvmem_battery_fccNormal)
A S Bat_Pct_Cap ST_LOW_WARN							EMS(EMS_nvmem_battery_fccLowWarn, "%r")
A S Bat_Pct_Cap ST_LOW_WARN							+86400/EMS(EMS_callhome_battery_notice, "BATTERY (full charge capacity low)")
A (Bat_Pct_Cap,Bat_Pct_Cap) (ST_LOW_CRIT,(37,)){2,2}				+(,24)/EMS(EMS_nvmem_battery_fccLow, "%r", "%c")
A (Bat_Pct_Cap,Bat_Pct_Cap) (ST_LOW_CRIT,(37,)){2,2}				EMS(EMS_callhome_battery_warning, "BATTERY (full charge capacity low)")
A (Bat_Pct_Cap,Bat_Pct_Cap) (ST_LOW_CRIT,(,38)){2,2}				EMS(EMS_nvmem_battery_fccLowCrit, "%r", "20")
A (Bat_Pct_Cap,Bat_Pct_Cap) (ST_LOW_CRIT,(,38)){2,2}				EMS(EMS_callhome_battery_failure, "BATTERY (full charge capacity low)")
# We do sensor unreadable for the two real sensors that this pseudo sensor is based on.
A S Bat_Full_Cap [ST_FAILED]							EMS(EMS_nvmem_battery_unread, "%s", "5")
A S Bat_Full_Cap [ST_FAILED]							EMS(EMS_callhome_battery_failure, "BATTERY ('%s' unreadable)")
A S Bat_Full_Cap [ST_NA]							DISARM(EMS_nvmem_battery_fccNormal)
A S Bat_Full_Cap [ST_NA]							30/SET_STATE(Bat_Full_Cap, ST_FAILED), POLL(Bat_Full_Cap, 10)
A S Bat_Initial_Fcc [ST_FAILED]							EMS(EMS_nvmem_battery_unread, "%s", "5")
A S Bat_Initial_Fcc [ST_FAILED]							EMS(EMS_callhome_battery_failure, "BATTERY ('%s' unreadable)")
A S Bat_Initial_Fcc [ST_NA]							DISARM(EMS_nvmem_battery_fccNormal)
A S Bat_Initial_Fcc [ST_NA]							30/SET_STATE(Bat_Initial_Fcc, ST_FAILED), POLL(Bat_Initial_Fcc, 10)

# Bat Charge Current
A S Bat_Charge_Curr [ST_FAILED]							EMS(EMS_nvmem_battery_unread, "%s", "5")
A S Bat_Charge_Curr [ST_FAILED]							EMS(EMS_callhome_battery_failure, "BATTERY ('%s' unreadable)")
A S Bat_Charge_Curr [ST_NA]							DISARM(EMS_nvmem_battery_normalCharge)
A S Bat_Charge_Curr [ST_NA]							30/SET_STATE(Bat_Charge_Curr, ST_FAILED), POLL(Bat_Charge_Curr, 10)

# Bat Charge Volt
A S Bat_Charge_Volt [ST_FAILED]							EMS(EMS_nvmem_battery_unread, "%s", "5")
A S Bat_Charge_Volt [ST_FAILED]							EMS(EMS_callhome_battery_failure, "BATTERY ('%s' unreadable)")
A S Bat_Charge_Volt [ST_FAILED]							ARM(EMS_nvmem_battery_normalCharge)
A S Bat_Charge_Volt [ST_NA]							DISARM(EMS_nvmem_battery_normalCharge)
A S Bat_Charge_Volt [ST_NA]							30/SET_STATE(Bat_Charge_Volt, ST_FAILED), POLL(Bat_Charge_Volt, 10)

# Bat Charging State
A S init ST_UNINITIALIZED							DISARM(EMS_nvmem_battery_normalCharge)
A S Bat_Charge_State [WRONG_CHARGE|NO_CHARGE|ST_FAILED]				ARM(EMS_nvmem_battery_normalCharge)
A (Bat_Charge_State, Bat_Charge_Volt) ([IDLE|CHARGING], !ST_FAILED){2,2}	+0/EMS(EMS_nvmem_battery_normalCharge)
A S Bat_Charge_State WRONG_CHARGE						+(,24)/EMS(EMS_nvmem_battery_wrongCharge, "%c")
A S Bat_Charge_State WRONG_CHARGE						EMS(EMS_callhome_battery_warning, "BATTERY (wrong charge)")
A S Bat_Charge_State NO_CHARGE							EMS(EMS_nvmem_battery_noCharge, "20")
A S Bat_Charge_State NO_CHARGE							EMS(EMS_callhome_battery_failure, "BATTERY (no charge)")
# No sensor unreadable because this is a pseudo sensor based on 'Charging
# Current' and 'Batt Current', which are both already handled above.

# Bat Power Fault
A S init ST_UNINITIALIZED							DISARM(EMS_nvmem_battery_powerNormal)
A S Bat_Power_Fault [BAD|ST_FAILED]						ARM(EMS_nvmem_battery_powerNormal)
A S Bat_Power_Fault GOOD							+0/EMS(EMS_nvmem_battery_powerNormal)
A (Bat_Power_Fault, Bat_Present) (BAD, PRESENT){2,2}				EMS(EMS_nvmem_battery_powerFault, "5")
A (Bat_Power_Fault, Bat_Present) (BAD, PRESENT){2,2}				EMS(EMS_callhome_battery_failure, "BATTERY (power fault)")
A S Bat_Power_Fault [ST_FAILED]							EMS(EMS_nvmem_battery_unread, "%s", "5")
A S Bat_Power_Fault [ST_FAILED]							EMS(EMS_callhome_battery_failure, "BATTERY ('%s' unreadable)")
A S Bat_Power_Fault [ST_NA]							DISARM(EMS_nvmem_battery_powerNormal)
A S Bat_Power_Fault [ST_NA]							30/SET_STATE(Bat_Power_Fault, ST_FAILED), POLL(Bat_Power_Fault, 10)

# Bat Charge FET
A S init ST_UNINITIALIZED							DISARM(EMS_nvmem_battery_FET_normal)
A S Bat_Charge_FET [OFF|ST_FAILED]						ARM(EMS_nvmem_battery_FET_normal)
A S Bat_Charge_FET ON								+0/EMS(EMS_nvmem_battery_FET_normal)
A S Bat_Charge_FET OFF								+(,24)/EMS(EMS_nvmem_battery_FET_off, "%c")
A S Bat_Charge_FET OFF								EMS(EMS_callhome_battery_warning, "BATTERY (charge FET off)")
A S Bat_Charge_FET [ST_FAILED]							EMS(EMS_nvmem_battery_unread, "%s", "5")
A S Bat_Charge_FET [ST_FAILED]							EMS(EMS_callhome_battery_failure, "BATTERY ('%s' unreadable)")
A S Bat_Charge_FET [ST_NA]							DISARM(EMS_nvmem_battery_FET_normal)
A S Bat_Charge_FET [ST_NA]							30/SET_STATE(Bat_Charge_FET, ST_FAILED), POLL(Bat_Charge_FET, 10)

# Bat Dcharge FET
A S init ST_UNINITIALIZED							DISARM(EMS_nvmem_battery_discFET_normal)
A S Bat_Dcharge_FET [OFF|ST_FAILED]						ARM(EMS_nvmem_battery_discFET_normal)
A S Bat_Dcharge_FET ON								+0/EMS(EMS_nvmem_battery_discFET_normal)
A S Bat_Dcharge_FET OFF								EMS(EMS_nvmem_battery_discFET_off, "5")
A S Bat_Dcharge_FET OFF								EMS(EMS_callhome_battery_failure, "BATTERY (discharge FET off)")
A S Bat_Dcharge_FET [ST_FAILED]							EMS(EMS_nvmem_battery_unread, "%s", "5")
A S Bat_Dcharge_FET [ST_FAILED]							EMS(EMS_callhome_battery_failure, "BATTERY ('%s' unreadable)")
A S Bat_Dcharge_FET [ST_NA]							DISARM(EMS_nvmem_battery_discFET_normal)
A S Bat_Dcharge_FET [ST_NA]							30/SET_STATE(Bat_Dcharge_FET, ST_FAILED), POLL(Bat_Dcharge_FET, 10)

# Battery pack invalid policy
A S init ST_UNINITIALIZED							DISARM(EMS_nvmem_battery_packValid)
A (Bat_Pack_Invalid, Bat_Present) ([INVALID|ST_FAILED], PRESENT){2,2}   	ARM(EMS_nvmem_battery_packValid)
A (Bat_Pack_Invalid, Bat_Present) (OK, PRESENT){2,2}				+0/EMS(EMS_nvmem_battery_packValid)
A (Bat_Pack_Invalid, Bat_Present) (INVALID, PRESENT){2,2}			120/EMS(EMS_nvmem_battery_packInvalid, "271-00046", "5")
A (Bat_Pack_Invalid, Bat_Present) (ST_FAILED, PRESENT){2,2}			EMS(EMS_nvmem_battery_unread, "%s", "5")
A (Bat_Pack_Invalid, Bat_Present) (ST_FAILED, PRESENT){2,2}			EMS(EMS_callhome_battery_failure, "BATTERY ('%s' unreadable)")
A (Bat_Pack_Invalid, Bat_Present) (ST_NA, PRESENT){2,2}				DISARM(EMS_nvmem_battery_packValid)
A (Bat_Pack_Invalid, Bat_Present) (ST_NA, PRESENT){2,2}				30/SET_STATE(Bat_Pack_Invalid, ST_FAILED), POLL(Bat_Pack_Invalid, 10)

# Battery presence policy
A S Bat_Present NOT_PRESENT							ARM(EMS_nvmem_battery_packValid)
A S Bat_Present NOT_PRESENT							120/EMS(EMS_nvmem_battery_notPresent, "5")
A S Bat_Present NOT_PRESENT							EMS(EMS_callhome_battery_failure, "BATTERY (not present)")

#
# Shutdown Policy for Battery
# We do a 5 minutes shutdown under any of the following conditions:
#   1. Bat Temp:		crithigh or failed
#   2. Bat Voltage:		critlow, crithigh or failed
#   3. Bat Current:		critlow, crithigh or failed
#   4. Bat Design Capacity:	failed
#   5. Bat Full Capacity:	failed
#   6. Bat Charging Current:	failed
#   7. Bat Charging Voltage:	failed
#   8. Bat Initial FCC:	failed
#   9. Bat Power Fault:		BAD or failed
#  10. Bat Charge FET:		failed
#  11. Bat Discharge FET:	OFF or failed
#  12. Bat Present		not_present - 5 minutes plus 2 mins EMS delay
#  13. Bat Pack Invalid		INVALID - 5 minutes plus 2 mins EMS delay
A S Bat_Temp		[ST_HIGH_CRIT|ST_FAILED]			300+10/DO(env_halt, 1, "Battery temp critical")
A S Bat_Volt		[ST_LOW_CRIT|ST_HIGH_CRIT|ST_FAILED]		300+10/DO(env_halt, 1, "Battery voltage critical")
A S Bat_Curr		[ST_LOW_CRIT|ST_HIGH_CRIT|ST_FAILED]		300+10/DO(env_halt, 1, "Battery current critical")
A S Bat_Dstg_Cycles	[ST_FAILED]					300+10/DO(env_halt, 1, "Battery remain capacity failed")
A S Bat_Full_Cap	[ST_FAILED]					300+10/DO(env_halt, 1, "Battery full capacity failed")
A S Bat_Charge_Curr	[ST_FAILED]					300+10/DO(env_halt, 1, "Battery charging current failed")
A S Bat_Charge_Volt	[ST_FAILED]					300+10/DO(env_halt, 1, "Battery charging voltage failed")
A S Bat_Initial_Fcc	[ST_FAILED]					300+10/DO(env_halt, 1, "Battery initial FCC failed")
A (Bat_Power_Fault, Bat_Present) ([BAD|ST_FAILED], PRESENT){2,2}	300+10/DO(env_halt, 1, "Battery power fault")
A S Bat_Charge_FET	[ST_FAILED]					300+10/DO(env_halt, 1, "Battery charge FET failed")
A S Bat_Dcharge_FET	[OFF|ST_FAILED]					300+10/DO(env_halt, 1, "Battery discharge FET failed")
A S Bat_Present		NOT_PRESENT					420+10/DO(env_halt, 1, "Battery not present")
A (Bat_Pack_Invalid, Bat_Present) ([INVALID|ST_FAILED], PRESENT){2,2}	420+10/DO(env_halt, 1, "Battery pack invalid")

# We do a 20 minutes shutdown under any of the following conditions:
#   1. Destage cycles		< 1
#   2. Bat Pct Capacity:	<38
#   3. Bat Charging State:	NO_CHARGE
A S Bat_Dstg_Cycles	(,1)						1200+10/DO(env_halt, 1, "Battery remain capacity critical")
A S Bat_Pct_Cap		(,38)						1200+10/DO(env_halt, 1, "Battery PCT capacity critical")
A S Bat_Charge_State	NO_CHARGE					1200+10/DO(env_halt, 1, "Battery not charging")

# We do a 24 hour shutdown under any of the following conditions:
#   1. Bat Temp			critlow
#   2. Bat Voltage		warnhigh
#   3. Bat Current		warnlow or warnhigh
#   4. Bat Pct Capacity		critlow
#   5. Bat Charging State	WRONG_CHARGE
#   6. Bat Charge FET		OFF
A S Bat_Temp			ST_LOW_CRIT			86400+10/DO(env_halt, 1, "Battery temp low")
A S Bat_Volt			ST_HIGH_WARN			86400+10/DO(env_halt, 1, "Battery voltage warning")
A S Bat_Curr			[ST_LOW_WARN|ST_HIGH_WARN]	86400+10/DO(env_halt, 1, "Battery current warning")
A S Bat_Pct_Cap				ST_LOW_CRIT			86400+10/DO(env_halt, 1, "Battery PCT capacity low")
A S Bat_Charge_State			WRONG_CHARGE			86400+10/DO(env_halt, 1, "Battery charging current failed")
A S Bat_Charge_FET			OFF				86400+10/DO(env_halt, 1, "Battery charge FET off")

#
# Sensors for ONTAP to reference when it boots up.  The following sensor names should remain no change
# because the ONTAP retrieves the sensor values via the sensor names.
#
# "Battery Charge" - expose to boot_battery_check.
#	BAD: battery is temporarily unfit.  Delay boot until GOOD
#      GOOD: battery is normal, go ahead and boot
# ST_FAILED: something is so wrong that we will probably never transition to GOOD (replace the battery)
#
S batt_boot_msg	"Battery Capacity Message"	DISCRETE	- - 0 0	hidden	0/BAD 1*/GOOD

# Define two more pseudo-sensors to track our intent to set "Battery Charge" to BAD or ST_FAILED.  The
# reason we need this is that we could have conflicting conditions and we don't want them to result in
# a race condition where BAD could win out over ST_FAILED.  So, if a condition wants to set batt_charge
# to BAD, instead it sets batt_charge_bad to TRUE.  If it wants to set batt_charge to ST_FAILED, instead
# it sets batt_charge_failed to TRUE.  Then, we can make sure batt_charge is failed any time batt_charge_failed
# is TRUE regardless of the value of batt_charge_bad.
# The Battery FRU LED (led_num=BBA_LED_BATTERY=4) should be in sync with the batt_charge state
A S init		ST_UNINITIALIZED		SET_VALUE(batt_charge, GOOD)
S batt_charge_bad	"Battery Charge Bad?"		DISCRETE	- - 0 0	hidden	0*/FALSE 1/TRUE
S batt_charge_failed	"Battery Charge Failed?"	DISCRETE	- - 0 0	hidden	0*/FALSE 1/TRUE
A (batt_charge_bad,batt_charge_failed)	(FALSE,FALSE){2,2}	SET_VALUE(batt_charge, GOOD), SET_DESC(batt_charge, -)
A (batt_charge_bad,batt_charge_failed)	(TRUE,FALSE){2,2}	SET_VALUE(batt_charge, BAD), SET_DESC(batt_charge, batt_charge_bad)
A S batt_charge_failed			TRUE			SET_STATE(batt_charge, ST_FAILED), SET_DESC(batt_charge, batt_charge_failed)
# If the battery is in the BAD state for more than an hour, then it's not fixing itself, so mark it failed.
A S batt_charge	BAD							3600/SET_STATE(batt_charge, ST_FAILED)

A (Bat_Present,Bat_Dstg_Cycles,Bat_Dstg_Cycles,Bat_Volt) (PRESENT,((ST_LOW_CRIT,(1,)){2,2},ST_LOW_WARN){1,2}){2,2}      SET_VALUE(nv0_batstate, PARTIALLY_DISCHARGED), DO(update_snmp, ENTITY_BATT)
A (Bat_Present,Bat_Dstg_Cycles,Bat_Volt) (PRESENT,([(,2)|ST_FAILED],[ST_LOW_CRIT|ST_FAILED]){1,2}){2,2}         SET_VALUE(nv0_batstate, FULLY_DISCHARGED), DO(update_snmp, ENTITY_BATT)
A (Bat_Present,Bat_Curr,Bat_Volt) (PRESENT,(ST_HIGH_CRIT,ST_HIGH_CRIT){1,2}){2,2}                               SET_VALUE(nv0_batstate, OVER_CHARGED), DO(update_snmp, ENTITY_BATT)
A (Bat_Present,Bat_Dstg_Cycles,Bat_Curr,Bat_Volt) (PRESENT,ST_OK,ST_OK,ST_OK){4,4}                              SET_VALUE(nv0_batstate, OK), DO(update_snmp, ENTITY_BATT)
A S Bat_Present         NOT_PRESENT                                                                             SET_VALUE(nv0_batstate, NOT_PRESENT), DO(update_snmp, ENTITY_BATT)
A S init	ST_UNINITIALIZED	SET_VALUE(nv0_type, TYPE_NVMEM)
F nv0_batvolt	GENERIC			Bat_Volt

# "Battery RemCap Desc" is a preserved sensor name used to hold the description
# of the battery remain capacity which can be queried by the health condition
# check.  Policy is responsible for set the description of this sensor by correlation
# with other battery sensors status.
S health_nvbat_capdesc "Battery RemCap Desc"    DISCRETE - - 0 0	hidden  0*/READY
A S Bat_Dstg_Cycles               ST_VALID        SET_VALUE(health_nvbat_capdesc, READY)
A S Bat_Dstg_Cycles               ST_VALID        SET_DESC(health_nvbat_capdesc, Bat_Dstg_Cycles)

#Battery SNMP
F db_batt GENERIC			nv0_batstate
A S batt_charge GOOD			DO(update_sen_list, "crit_bat", DEL, nv0_batstate)
A S batt_charge [ST_FAILED|BAD]		DO(update_sen_list, "crit_bat", ADD, nv0_batstate)

# Battery FRU LED Policy
# The Battery FRU LED will be turned on for the following conditions
# 1. Bat Voltage	critlow			turn on when ONTAP shutdown (5 minutes)
# 2. Bat Voltage	crithigh
# 3. Bat Current	warnlow or critlow
# 4. Bat Capacity	critlow			turn on when ONTAP shutdown (20 minutes)
# 5. Bat Pct Capacity	< 38
# 6. Bat Power Fault	FAULT
# 7. Bat Charge FET	OFF
# 8. Bat Discharge FET	OFF
# 9. Bat Pack Invalid	INVALID
#10. Bat Present	NOT_PRESENT
#
S bat_led	"Bat FRU LED"		DISCRETE	- - 0 0	hidden		0*/OFF 1/ON

A S Bat_Volt	ST_LOW_CRIT			300/SET_VALUE(bat_led, ON)
A S Bat_Volt	ST_HIGH_CRIT			SET_VALUE(bat_led, ON)
A S Bat_Curr	[ST_LOW_CRIT|ST_LOW_WARN]	SET_VALUE(bat_led, ON)
A S Bat_Dstg_Cycles (,2)			1200/SET_VALUE(bat_led, ON)
A S Bat_Pct_Cap (,38)				SET_VALUE(bat_led, ON)
A S Bat_Power_Fault	BAD			SET_VALUE(bat_led, ON)
A S Bat_Charge_FET	OFF			SET_VALUE(bat_led, ON)
A S Bat_Dcharge_FET	OFF			SET_VALUE(bat_led, ON)
A S Bat_Pack_Invalid	INVALID			SET_VALUE(bat_led, ON)
#A S Bat_Present		NOT_PRESENT		SET_VALUE(bat_led, ON)
#A (Bat_Volt,Bat_Volt,Bat_Curr,Bat_Curr,Bat_Dstg_Cycles,Bat_Pct_Cap,Bat_Power_Fault,Bat_Charge_FET,Bat_Dcharge_FET,Bat_Pack_Invalid,Bat_Present) \
#  (!ST_LOW_CRIT,!ST_HIGH_CRIT,!ST_LOW_CRIT,!ST_LOW_WARN,(1,),(37,),!BAD,!OFF,!OFF,!INVALID,PRESENT) {11,11} \
A (Bat_Volt,Bat_Volt,Bat_Curr,Bat_Curr,Bat_Dstg_Cycles,Bat_Pct_Cap,Bat_Power_Fault,Bat_Charge_FET,Bat_Dcharge_FET,Bat_Pack_Invalid) \
  (!ST_LOW_CRIT,!ST_HIGH_CRIT,!ST_LOW_CRIT,!ST_LOW_WARN,(1,),(37,),!BAD,!OFF,!OFF,!INVALID) {10,10} \
								SET_VALUE(bat_led, OFF)
A S bat_led ON							DO(prog_nvbat_led, 1, "Environmental Condition by env_mgr")
A S bat_led OFF							DO(prog_nvbat_led, 0, "Environmental Condition by env_mgr")

# We expect the battery to recover from the following scenarios automatically, so we set the sensor to BAD
# Note: We put failed in this category because the sensors could just be temporarily unreadable.  If
#       they can't be read in an hour, then we will transition to the permafail state.
#   1. Bat Temp			critlow
#   2. Bat Voltage		warnlow
#   3. Bat Rem. Capacity	critlow
A S Bat_Temp		ST_LOW_CRIT				SET_VALUE(batt_charge_bad, TRUE)
A S Bat_Volt		ST_LOW_WARN				SET_VALUE(batt_charge_bad, TRUE)
A S Bat_Dstg_Cycles	ST_LOW_CRIT				SET_VALUE(batt_charge_bad, TRUE)
# If the sensors are all valid and none of the above are true, then set the pseudo-sensor to FALSE.
A (Bat_Temp,Bat_Temp,Bat_Volt,Bat_Volt,Bat_Dstg_Cycles,Bat_Dstg_Cycles) (ST_VALID,!ST_LOW_CRIT,ST_VALID,!ST_LOW_WARN,ST_VALID,!ST_LOW_CRIT){6,6} \
								SET_VALUE(batt_charge_bad, FALSE)
# We expect the following conditions to be permanent, so we set the sensor to failed.
#   1. Bat Temp			crithigh or failed
#   2. Bat Voltage		critlow, warnhigh, crithigh or failed
#   3. Bat Current		critlow, warnlow, warnhigh, crithigh or failed
#   4. Bat Rem. Capacity	failed
#   5. Bat Destage Cycles	failed
#   6. Bat Full Capacity	critlow or failed
#   7. Bat Charging Current	failed
#   8. Bat Charging Voltage	failed
#   9. Bat Charging State	WRONG_CHARGE or NO_CHARGE
#  10. Bat Power Fault		BAD or failed
#  11. Bat Charge FET		OFF or failed
#  12. Bat Discharge FET	OFF or failed
#  13. Bat Pack Invalid		INVALID or failed
A S Bat_Temp		[ST_HIGH_CRIT|ST_FAILED]						30/SET_VALUE(batt_charge_failed, TRUE)
A S Bat_Volt		[ST_LOW_CRIT|ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED]			30/SET_VALUE(batt_charge_failed, TRUE)
A S Bat_Curr		[ST_LOW_CRIT|ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT|ST_FAILED]		30/SET_VALUE(batt_charge_failed, TRUE)
A S Bat_Rem_Cap		[ST_FAILED]								30/SET_VALUE(batt_charge_failed, TRUE)
A S Bat_Dstg_Cycles	[ST_FAILED]								30/SET_VALUE(batt_charge_failed, TRUE)
A S Bat_Full_Cap	[ST_LOW_CRIT|ST_FAILED]							30/SET_VALUE(batt_charge_failed, TRUE)
A S Bat_Charge_Curr	[ST_FAILED]								30/SET_VALUE(batt_charge_failed, TRUE)
A S Bat_Charge_Volt	[ST_FAILED]								30/SET_VALUE(batt_charge_failed, TRUE)
A S Bat_Charge_State	[WRONG_CHARGE|NO_CHARGE|ST_FAILED]					30/SET_VALUE(batt_charge_failed, TRUE)
A S Bat_Power_Fault	[BAD|ST_FAILED]								30/SET_VALUE(batt_charge_failed, TRUE)
A S Bat_Charge_FET	[OFF|ST_FAILED]								30/SET_VALUE(batt_charge_failed, TRUE)
A S Bat_Dcharge_FET	[OFF|ST_FAILED]								30/SET_VALUE(batt_charge_failed, TRUE)
A S Bat_Pack_Invalid	[INVALID|ST_FAILED]							30/SET_VALUE(batt_charge_failed, TRUE)
A S Bat_Present		[NOT_PRESENT|ST_FAILED]							30/SET_VALUE(batt_charge_failed, TRUE)

# If the sensors are all valid and none of the above are true, then set the pseudo-sensor to FALSE.
A (Bat_Temp,Bat_Volt,Bat_Curr,Bat_Rem_Cap,Bat_Full_Cap,Bat_Charge_Curr,Bat_Charge_State, \
   Bat_Charge_Volt,Bat_Dstg_Cycles,Bat_Power_Fault,Bat_Charge_FET,Bat_Dcharge_FET,Bat_Pack_Invalid) \
		([ST_LOW_CRIT|ST_LOW_WARN|ST_OK|ST_HIGH_WARN],[ST_LOW_WARN|ST_OK],ST_OK,ST_VALID, \
		 [ST_LOW_WARN|ST_OK|ST_HIGH_WARN|ST_HIGH_CRIT],ST_VALID,[IDLE|CHARGING],ST_VALID, \
		 ST_VALID,GOOD,ON,ON,OK){13,13}				SET_VALUE(batt_charge_failed, FALSE)

#
# Describe the Battery conditions
#
D desc_bat_temp_hi		"Battery temperature is too high"
D desc_bat_temp_failed		"Failed to detect the battery temperature"
D desc_bat_vol_cr		"Battery voltage is in critical state"
D desc_bat_vol_failed		"Failed to detect the battery voltage"
D desc_bat_curr_cr		"Battery current is abnormal"
D desc_bat_curr_failed		"Failed to detect the battery current"
D desc_bat_remcap_failed	"Failed to detect the battery remain capacity"
D desc_bat_fcc_lo		"Battery full charge capacity is too low"
D desc_bat_fcc_failed		"Failed to detect the battery FCC"
D desc_bat_cc_failed		"Failed to detect the battery charge current"
D desc_bat_cv_failed		"Failed to detect the battery charge voltage"
D desc_bat_chg_failed		"Failed to charge the battery"
D desc_bat_power_fault		"Battery power fault"
D desc_bat_fet_off		"Battery charge FET is off"
D desc_bat_fet_failed		"Failed to detect the battery charge FET"
D desc_bat_dfet_off		"Battery discharge FET is off"
D desc_bat_dfet_failed		"Failed to detect the battery discharge FET"
D desc_bat_bat_pack_invalid	"Invalid battery pack is detected"
D desc_bat_bat_pack_failed	"Failed to detect the type of the battery pack"
D desc_bat_temp_lo		"Battery temperature is too low"
D desc_bat_vol_lo		"Battery voltage is abnormally low"
D desc_bat_remcap_lo		"Battery capacity is abnormally low"
D desc_bat_absent               "Battery is not present"
D desc_bat_dstg			"Power outage protection flash de-staging: %r"
D desc_bat_lrn_failed		"Failed to detect the battery learning status"


A S Bat_Dstg_Cycles 	ST_VALID			SET_DESC(Bat_Dstg_Cycles, ADD, desc_bat_dstg)
A S Bat_Dstg_Cycles	!ST_VALID			SET_DESC(Bat_Dstg_Cycles, DEL, desc_bat_dstg)
A S init		ST_UNINITIALIZED		SET_DESC(batt_boot_msg, Bat_Dstg_Cycles)
F batt_boot_msg GENERIC batt_charge

A S Bat_Temp		ST_LOW_CRIT			SET_DESC(batt_charge_bad, ADD, desc_bat_temp_lo)
A S Bat_Temp		!ST_LOW_CRIT			SET_DESC(batt_charge_bad, DEL, desc_bat_temp_lo)

A S Bat_Volt		ST_LOW_WARN			SET_DESC(batt_charge_bad, ADD, desc_bat_vol_lo)
A S Bat_Volt		!ST_LOW_WARN			SET_DESC(batt_charge_bad, DEL, desc_bat_vol_lo)

A S Bat_Dstg_Cycles	ST_LOW_CRIT			SET_DESC(batt_charge_bad, ADD, desc_bat_remcap_lo)
A S Bat_Dstg_Cycles	!ST_LOW_CRIT			SET_DESC(batt_charge_bad, DEL, desc_bat_remcap_lo)

A S Bat_Temp		ST_HIGH_CRIT			SET_DESC(batt_charge_failed, ADD, desc_bat_temp_hi)
A S Bat_Temp		!ST_HIGH_CRIT			SET_DESC(batt_charge_failed, DEL, desc_bat_temp_hi)
A S Bat_Temp		ST_FAILED			SET_DESC(batt_charge_failed, ADD, desc_bat_temp_failed)
A S Bat_Temp		!ST_FAILED			SET_DESC(batt_charge_failed, DEL, desc_bat_temp_failed)

A S Bat_Volt		[ST_LOW_CRIT|ST_HIGH_WARN|ST_HIGH_CRIT]			SET_DESC(batt_charge_failed, ADD, desc_bat_vol_cr)
A (Bat_Volt,Bat_Volt,Bat_Volt) \
			(!ST_LOW_CRIT, !ST_HIGH_WARN, !ST_HIGH_CRIT){3,3}	SET_DESC(batt_charge_failed, DEL, desc_bat_vol_cr)
A S Bat_Volt		ST_FAILED			SET_DESC(batt_charge_failed, ADD, desc_bat_vol_failed)
A S Bat_Volt		!ST_FAILED			SET_DESC(batt_charge_failed, DEL, desc_bat_vol_failed)

A S Bat_Curr		[ST_LOW_CRIT|ST_LOW_WARN|ST_HIGH_WARN|ST_HIGH_CRIT]	SET_DESC(batt_charge_failed, ADD, desc_bat_curr_cr)
A (Bat_Curr,Bat_Curr,Bat_Curr,Bat_Curr) \
			(!ST_LOW_CRIT, !ST_LOW_WARN, !ST_HIGH_WARN, !ST_HIGH_CRIT) {4,4} \
										SET_DESC(batt_charge_failed, DEL, desc_bat_curr_cr)
A S Bat_Curr		ST_FAILED			SET_DESC(batt_charge_failed, ADD, desc_bat_curr_failed)
A S Bat_Curr		!ST_FAILED			SET_DESC(batt_charge_failed, DEL, desc_bat_curr_failed)

A S Bat_Rem_Cap		[ST_FAILED]			SET_DESC(batt_charge_failed, ADD, desc_bat_remcap_failed)
A S Bat_Rem_Cap		!ST_FAILED			SET_DESC(batt_charge_failed, DEL, desc_bat_remcap_failed)

A S Bat_Dstg_Cycles	[ST_FAILED]			SET_DESC(batt_charge_failed, ADD, desc_bat_remcap_failed)
A S Bat_Dstg_Cycles	!ST_FAILED			SET_DESC(batt_charge_failed, DEL, desc_bat_remcap_failed)

A S Bat_Full_Cap	ST_LOW_CRIT			SET_DESC(batt_charge_failed, ADD, desc_bat_fcc_lo)
A S Bat_Full_Cap	!ST_LOW_CRIT			SET_DESC(batt_charge_failed, DEL, desc_bat_fcc_lo)
A S Bat_Full_Cap	ST_FAILED			SET_DESC(batt_charge_failed, ADD, desc_bat_fcc_failed)
A S Bat_Full_Cap	!ST_FAILED			SET_DESC(batt_charge_failed, DEL, desc_bat_fcc_failed)

A S Bat_Charge_Curr	ST_FAILED			SET_DESC(batt_charge_failed, ADD, desc_bat_cc_failed)
A S Bat_Charge_Curr	!ST_FAILED			SET_DESC(batt_charge_failed, DEL, desc_bat_cc_failed)

A S Bat_Charge_Volt	ST_FAILED			SET_DESC(batt_charge_failed, ADD, desc_bat_cv_failed)
A S Bat_Charge_Volt	!ST_FAILED			SET_DESC(batt_charge_failed, DEL, desc_bat_cv_failed)

A S Bat_Charge_State	[WRONG_CHARGE|NO_CHARGE]				SET_DESC(batt_charge_failed, ADD, desc_bat_chg_failed)
A (Bat_Charge_State,Bat_Charge_State)	(!WRONG_CHARGE,!NO_CHARGE) {2,2}	SET_DESC(batt_charge_failed, DEL, desc_bat_chg_failed)

A (Bat_Power_Fault,Bat_Present) ([BAD|ST_FAILED], PRESENT){2,2}			SET_DESC(batt_charge_failed, ADD, desc_bat_power_fault)
A (Bat_Power_Fault,Bat_Power_Fault) (!BAD,!ST_FAILED) {2,2}			SET_DESC(batt_charge_failed, DEL, desc_bat_power_fault)

A S Bat_Charge_FET	OFF				SET_DESC(batt_charge_failed, ADD, desc_bat_fet_off)
A S Bat_Charge_FET	!OFF				SET_DESC(batt_charge_failed, DEL, desc_bat_fet_off)
A S Bat_Charge_FET	ST_FAILED			SET_DESC(batt_charge_failed, ADD, desc_bat_fet_failed)
A S Bat_Charge_FET	!ST_FAILED			SET_DESC(batt_charge_failed, DEL, desc_bat_fet_failed)

A S Bat_Dcharge_FET	OFF				SET_DESC(batt_charge_failed, ADD, desc_bat_dfet_off)
A S Bat_Dcharge_FET	!OFF				SET_DESC(batt_charge_failed, DEL, desc_bat_dfet_off)
A S Bat_Dcharge_FET	ST_FAILED			SET_DESC(batt_charge_failed, ADD, desc_bat_dfet_failed)
A S Bat_Dcharge_FET	!ST_FAILED			SET_DESC(batt_charge_failed, DEL, desc_bat_dfet_failed)

A (Bat_Pack_Invalid,Bat_Present) (INVALID,PRESENT){2,2}	SET_DESC(batt_charge_failed, ADD, desc_bat_bat_pack_invalid)
A (Bat_Pack_Invalid,Bat_Present) (!INVALID,PRESENT){2,2} SET_DESC(batt_charge_failed, DEL, desc_bat_bat_pack_invalid)
A (Bat_Pack_Invalid,Bat_Present) (ST_FAILED,PRESENT){2,2} SET_DESC(batt_charge_failed, ADD, desc_bat_bat_pack_failed)
A (Bat_Pack_Invalid,Bat_Present) (!ST_FAILED,PRESENT){2,2} SET_DESC(batt_charge_failed, DEL, desc_bat_bat_pack_failed)

A S Bat_Lrn_Active	[ST_NA|ST_FAILED]		SET_DESC(batt_charge_failed, ADD, desc_bat_lrn_failed)
A S Bat_Lrn_Active	[ON|OFF]			SET_DESC(batt_charge_failed, DEL, desc_bat_lrn_failed)

A S Bat_Present         NOT_PRESENT                     SET_DESC(batt_charge_failed, ADD, desc_bat_absent), \
                                                        SET_DESC(batt_charge_failed, DEL, desc_bat_power_fault), \
                                                        SET_DESC(batt_charge_failed, DEL, desc_bat_bat_pack_invalid)
A S Bat_Present         !NOT_PRESENT                    SET_DESC(batt_charge_failed, DEL, desc_bat_absent)

END 4000

