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	0020	MACRO_TEMP	"Macro for Individual Thermal Sensor Policy"
A S $(MACRO_ARG0) ST_LOW_CRIT		EMS(EMS_monitor_chassisTemperature_cool, "%s is critical low (%r).")
A S $(MACRO_ARG0) ST_LOW_WARN		EMS(EMS_monitor_chassisTemperature_cool, "%s is warning low (%r).")
A S $(MACRO_ARG0) ST_HIGH_WARN		EMS(EMS_monitor_chassisTemperature_warm, "%s is warning high (%r).")
A S $(MACRO_ARG0) ST_HIGH_CRIT		EMS(EMS_monitor_chassisTemperature_warm, "%s is critical high (%r).")
A S $(MACRO_ARG0) ST_FAILED         EMS(EMS_monitor_temp_unreadable, "%s"), LOG("%s is not readable.")
A S $(MACRO_ARG0) [ST_FAILED|ST_NA] POLL($(MACRO_ARG0),20),120/POLL($(MACRO_ARG0),120)
A S $(MACRO_ARG0) ST_NA             60/SET_STATE($(MACRO_ARG0),ST_FAILED)
END	0020

START   4000    FASRAZM         "Put the description for Razor M 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	"Dblade 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, 4)
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:fd"	      3	      10  -		1*/DEASSERT 2/ASSERT
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:e9"	      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 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 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 DIMM_Temp		"DIMM Temp"		TEMP		3001 "ipmi:20:00:04"	      3       10  pull		- - - - - - - -
S M2_Card_Temp		"M.2_Card_Temp"		TEMP		3001 "ipmi:20:00:03"	      3       10  pull		- - - - - - - -
S PCM_Inlet_Temp		"PCM_Inlet_Temp"		TEMP		3001 "ipmi:20:00:02"	      3       10  pull		- - - - - - - -
S CPU0_Core_Temp	"CPU0 Core Temp"	TEMP		3001 "ipmi:20:00:01"	      3       10  pull		- - - - - - - -
S CPU0_Temp_Margin	"CPU0 Temp Margin"	TEMP		3001 "ipmi:20:00:00"	      3       10  pull		- - - - - - - -

#################################### 3. SES Sensors ##########################################################
# id            devname             type         dev_poll                   sens_poll
C 2001          ses                 SES          300                        60

# id            name                type         cdev_id cdev_adr           retries interval  flags       thresholds/discrete values
# --------------------------------------------------------------------------------------------------------------------------------------------------
S shelf            "Internal Shelf"    DISCRETE     2001 "ses0:shelf"    3       10        hidden      0/NOT_PRESENT 1*/PRESENT

S ambient_temp     "Ambient Temp"      TEMP         2001 "1025"          3       10        pull        - - - - - - - -
S midplane_1_temp  "Midplane 1 Temp"   TEMP         2001 "1033"          3       10        pull        - - - - - - - -
S midplane_2_temp  "Midplane 2 Temp"   TEMP         2001 "1034"          3       10        pull        - - - - - - - -
S midplane_3_temp  "Midplane 3 Temp"   TEMP         2001 "1035"          3       10        pull        - - - - - - - -
S midplane_4_temp  "Midplane 4 Temp"   TEMP         2001 "1036"          3       10        pull        - - - - - - - -
S module_a_temp    "Module A Expander Temp"     TEMP         2001 "1031"          3       10        pull        - - - - - - - -
S module_b_temp    "Module B Expander Temp"     TEMP         2001 "1032"          3       10        pull        - - - - - - - -

S num_fan          "PSU_FAN"           DISCRETE     2001 "768"           3       10        pull        0*/OK 1/FAIL_1 2/FAIL_2 3/FAIL_3 4/FAIL_4

S psu2_hotspot_t   "PSU2 Hotspot Temp" TEMP         2001 "1030"          3       10        pull        - - - - - - - -
S psu2_inlet_t     "PSU2 Inlet Temp"   TEMP         2001 "1029"          3       10        pull        - - - - - - - -
S psu2_fan2        "PSU2 Fan 2"        FAN          2001 "772"           3       10        pull        - - - - - - - -
S psu2_fan1        "PSU2 Fan 1"        FAN          2001 "771"           3       10        pull        - - - - - - - -
S psu2_12amp       "PSU2 12V Curr"     CURRENT      2001 "4868"          3       10        pull        - - - - - - - -
S psu2_5amp        "PSU2 5V Curr"      CURRENT      2001 "4867"          3       10        pull        - - - - - - - -
S psu2_12v         "PSU2 12V"          VOLTAGE      2001 "4612"          3       10        pull        - - - - - - - -
S psu2_5v          "PSU2 5V"           VOLTAGE      2001 "4611"          3       10        pull        - - - - - - - -
S psu2             "PSU2 Present"      DISCRETE     2001 "514"           3       10        pull        0/NOT_PRESENT 1*/PRESENT

S psu1_hotspot_t   "PSU1 Hotspot Temp" TEMP         2001 "1028"          3       10        pull        - - - - - - - -
S psu1_inlet_t     "PSU1 Inlet Temp"   TEMP         2001 "1027"          3       10        pull        - - - - - - - -
S psu1_fan2        "PSU1 Fan 2"        FAN          2001 "770"           3       10        pull        - - - - - - - -
S psu1_fan1        "PSU1 Fan 1"        FAN          2001 "769"           3       10        pull        - - - - - - - -
S psu1_12amp       "PSU1 12V Curr"     CURRENT      2001 "4866"          3       10        pull        - - - - - - - -
S psu1_5amp        "PSU1 5V Curr"      CURRENT      2001 "4865"          3       10        pull        - - - - - - - -
S psu1_12v         "PSU1 12V"          VOLTAGE      2001 "4610"          3       10        pull        - - - - - - - -
S psu1_5v          "PSU1 5V"           VOLTAGE      2001 "4609"          3       10        pull        - - - - - - - -
S psu1             "PSU1 Present"      DISCRETE     2001 "513"           3       10        pull        0/NOT_PRESENT 1*/PRESENT

S partner          "Partner Status"    DISCRETE     2001 "1038"          3       10        pull        0*/A_SIDE_NOT_PRESENT 1*/A_SIDE_PRESENT 2*/B_SIDE_NOT_PRESENT 3*/B_SIDE_PRESENT
# Define the FRU sensors
# id			name		type	cdev_id cdev_adr     fru_id retry_int flags	states
S FRU_PSU2		"PSU2 FRU"	FRU	2001 "ses0:ses_fru_psu2" 0x82 60 hidden,phm	0*/GOOD 1/NOT_PRESENT 2/PSU_FAULT 3/UNDER_VOLT 4/UNDER_CURR 5/FAN_WARN 6/FAN_CRIT 7/OVER_TEMP 8/OVER_CURR 9/OVER_VOLT 10/MULTIFAULT 11/UNDER_TEMP 12/PSU_OFF
S FRU_PSU1		"PSU1 FRU"	FRU	2001 "ses0:ses_fru_psu1" 0x81 60 hidden,phm	0*/GOOD 1/NOT_PRESENT 2/PSU_FAULT 3/UNDER_VOLT 4/UNDER_CURR 5/FAN_WARN 6/FAN_CRIT 7/OVER_TEMP 8/OVER_CURR 9/OVER_VOLT 10/MULTIFAULT 11/UNDER_TEMP 12/PSU_OFF

# 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
F PSU1_INFO FRUINFO	FRU_PSU1
F PSU2_INFO FRUINFO	FRU_PSU2

###############################################################################################################
#                                              Razor-M FRU Policy                                             #
###############################################################################################################
#
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 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 psu1	PRESENT				30/UPDATE_FRU(FRU_PSU1, READ), 30/LOG("PSU1 Present, update fru")
A S psu2	PRESENT				30/UPDATE_FRU(FRU_PSU2, READ), 30/LOG("PSU2 Present, update fru")
A S psu1	[NOT_PRESENT|ST_DISABLED]	UPDATE_FRU(FRU_PSU1, CLEAR)
A S psu2	[NOT_PRESENT|ST_DISABLED]	UPDATE_FRU(FRU_PSU2, CLEAR)

S psu1_on "PSU1 ON"		DISCRETE	- - 0 0	hidden	0*/ON 1/OFF
S psu2_on "PSU2 ON"		DISCRETE	- - 0 0	hidden	0*/ON 1/OFF

G psu1_on_grp psu1_5v, psu1_12v, psu1_5amp, psu1_12amp
G psu2_on_grp psu2_5v, psu2_12v, psu2_5amp, psu2_12amp

# If we are getting readings from PSU sensors, set the status sensor to ON
A G psu1_on_grp ((1,), (1,), (1,), (1,)) {1,4}		SET_VALUE(psu1_on, ON)
A G psu2_on_grp ((1,), (1,), (1,), (1,)) {1,4}		SET_VALUE(psu2_on, ON)

# If a PSU cable is unplugged or switched off, all readings will be 0 and we should set the status sensor to OFF
A G psu1_on_grp ((-1,1), (-1, 1), (-1, 1), (-1,1)) {4,4}		SET_VALUE(psu1_on, OFF)
A G psu2_on_grp ((-1,1), (-1, 1), (-1, 1), (-1,1)) {4,4}		SET_VALUE(psu2_on, OFF)

G grp_fru_psu1 psu1_on, psu1, psu1_5v, psu1_12v, psu1_5amp, psu1_12amp, psu1_fan1, psu1_fan2, psu1_inlet_t, psu1_hotspot_t
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} 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],(ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK){8,8}) {2, 2}  SET_VALUE(FRU_PSU1,PSU_FAULT)
A G grp_fru_psu1 (-, [ST_FAILED|ST_NA],(!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK){1,8}) {2, 2} SET_VALUE(FRU_PSU1, MULTIFAULT)
A G grp_fru_psu1 (ON, PRESENT,[ST_LOW_CRIT|ST_LOW_WARN],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,UNDER_VOLT)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,[ST_LOW_CRIT|ST_LOW_WARN],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,UNDER_VOLT)
A G grp_fru_psu1 (ON, PRESENT,[ST_HIGH_CRIT|ST_HIGH_WARN],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,OVER_VOLT)
A G grp_fru_psu1 (ON, PRESENT,[ST_FAILED|ST_NA],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,PSU_FAULT)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,[ST_HIGH_CRIT|ST_HIGH_WARN],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,OVER_VOLT)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,[ST_FAILED|ST_NA],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,PSU_FAULT)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,[ST_LOW_CRIT|ST_LOW_WARN],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,UNDER_CURR)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,[ST_LOW_WARN|ST_LOW_WARN],ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,UNDER_CURR)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,[ST_HIGH_CRIT|ST_HIGH_WARN],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,OVER_CURR)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,[ST_FAILED|ST_NA],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,PSU_FAULT)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,[ST_HIGH_CRIT|ST_HIGH_WARN],ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,OVER_CURR)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,[ST_FAILED|ST_NA],ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,PSU_FAULT)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,[ST_HIGH_WARN|ST_LOW_WARN],ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,FAN_WARN)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_HIGH_WARN|ST_LOW_WARN],ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,FAN_WARN)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,[ST_HIGH_CRIT|ST_LOW_CRIT],ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,FAN_CRIT)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,[ST_FAILED|ST_NA],ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,PSU_FAULT)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_HIGH_CRIT|ST_LOW_CRIT],ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,FAN_CRIT)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_FAILED|ST_NA],ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU1,PSU_FAULT)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_LOW_CRIT|ST_LOW_WARN],ST_OK) {10, 10} SET_VALUE(FRU_PSU1,UNDER_TEMP)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_LOW_CRIT|ST_LOW_WARN]) {10, 10} SET_VALUE(FRU_PSU1,UNDER_TEMP)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_HIGH_CRIT|ST_HIGH_WARN],ST_OK) {10, 10} SET_VALUE(FRU_PSU1,OVER_TEMP)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_FAILED|ST_NA],ST_OK) {10, 10} SET_VALUE(FRU_PSU1,PSU_FAULT)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_HIGH_CRIT|ST_HIGH_WARN]) {10, 10} SET_VALUE(FRU_PSU1,OVER_TEMP)
A G grp_fru_psu1 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_FAILED|ST_NA]) {10, 10} SET_VALUE(FRU_PSU1,PSU_FAULT)
A G grp_fru_psu1 (-, PRESENT,(!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK) {2, 8}) {2, 2} SET_VALUE(FRU_PSU1,MULTIFAULT)

G grp_fru_psu2 psu2_on, psu2, psu2_5v, psu2_12v, psu2_5amp, psu2_12amp, psu2_fan1, psu2_fan2, psu2_inlet_t, psu2_hotspot_t
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} 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],(ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK){8,8}) {2, 2}  SET_VALUE(FRU_PSU2,PSU_FAULT)
A G grp_fru_psu2 (-, [ST_FAILED|ST_NA],(!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK){1,8}) {2, 2} SET_VALUE(FRU_PSU2, MULTIFAULT)
A G grp_fru_psu2 (ON, PRESENT,[ST_LOW_CRIT|ST_LOW_WARN],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,UNDER_VOLT)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,[ST_LOW_CRIT|ST_LOW_WARN],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,UNDER_VOLT)
A G grp_fru_psu2 (ON, PRESENT,[ST_HIGH_CRIT|ST_HIGH_WARN],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,OVER_VOLT)
A G grp_fru_psu2 (ON, PRESENT,[ST_FAILED|ST_NA],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,PSU_FAULT)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,[ST_HIGH_CRIT|ST_HIGH_WARN],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,OVER_VOLT)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,[ST_FAILED|ST_NA],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,PSU_FAULT)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,[ST_LOW_CRIT|ST_LOW_WARN],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,UNDER_CURR)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,[ST_LOW_WARN|ST_LOW_WARN],ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,UNDER_CURR)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,[ST_HIGH_CRIT|ST_HIGH_WARN],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,OVER_CURR)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,[ST_FAILED|ST_NA],ST_OK,ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,PSU_FAULT)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,[ST_HIGH_CRIT|ST_HIGH_WARN],ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,OVER_CURR)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,[ST_FAILED|ST_NA],ST_OK,ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,PSU_FAULT)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,[ST_HIGH_WARN|ST_LOW_WARN],ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,FAN_WARN)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_HIGH_WARN|ST_LOW_WARN],ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,FAN_WARN)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,[ST_HIGH_CRIT|ST_LOW_CRIT],ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,FAN_CRIT)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,[ST_FAILED|ST_NA],ST_OK,ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,PSU_FAULT)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_HIGH_CRIT|ST_LOW_CRIT],ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,FAN_CRIT)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_FAILED|ST_NA],ST_OK,ST_OK) {10, 10} SET_VALUE(FRU_PSU2,PSU_FAULT)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_LOW_CRIT|ST_LOW_WARN],ST_OK) {10, 10} SET_VALUE(FRU_PSU2,UNDER_TEMP)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_LOW_CRIT|ST_LOW_WARN]) {10, 10} SET_VALUE(FRU_PSU2,UNDER_TEMP)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_HIGH_CRIT|ST_HIGH_WARN],ST_OK) {10, 10} SET_VALUE(FRU_PSU2,OVER_TEMP)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_FAILED|ST_NA],ST_OK) {10, 10} SET_VALUE(FRU_PSU2,PSU_FAULT)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_HIGH_CRIT|ST_HIGH_WARN]) {10, 10} SET_VALUE(FRU_PSU2,OVER_TEMP)
A G grp_fru_psu2 (ON, PRESENT,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_FAILED|ST_NA]) {10, 10} SET_VALUE(FRU_PSU2,PSU_FAULT)
A G grp_fru_psu2 (-, PRESENT,(!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK,!ST_OK) {2, 8}) {2, 2} SET_VALUE(FRU_PSU2,MULTIFAULT)

# If PSU X is off, set fru state to OFF
A S psu1_on				OFF		30/SET_VALUE(FRU_PSU1, PSU_OFF)
A S psu2_on				OFF		30/SET_VALUE(FRU_PSU2, PSU_OFF)

###############################################################################################################
#                                              Razor-M Shelf Policy                                           #
###############################################################################################################
# When Shelf (dblade) is present/not present, enable/disable PSU present sensor and num of failed fan
# TODO: Enable it when sensor "shelf" is available
#A S shelf	NOT_PRESENT		POLL(shelf, 10),SET_STATE(psu1,ST_DISABLED),SET_STATE(psu2,ST_DISABLED), \
#					SET_STATE(num_fan,ST_DISABLED),SET_STATE(ambient_temp,ST_DISABLED), \
#					SET_STATE(midplane_1_temp,ST_DISABLED), SET_STATE(midplane_2_temp,ST_DISABLED), \
#					SET_STATE(midplane_3_temp,ST_DISABLED), SET_STATE(midplane_4_temp,ST_DISABLED), \
#					SET_STATE(module_a_temp,ST_DISABLED),SET_STATE(module_b_temp,ST_DISABLED)

#A S shelf	PRESENT			POLL(shelf, 300),SET_STATE(psu1,ST_UNINITIALIZED),SET_STATE(psu2,ST_UNINITIALIZED), \
#					SET_STATE(num_fan,ST_UNINITIALIZED),SET_STATE(ambient_temp,ST_UNINITIALIZED), \
#					SET_STATE(midplane_1_temp,ST_UNINITIALIZED), SET_STATE(midplane_2_temp,ST_UNINITIALIZED), \
#					SET_STATE(midplane_3_temp,ST_UNINITIALIZED), SET_STATE(midplane_4_temp,ST_UNINITIALIZED), \
#					SET_STATE(module_a_temp,ST_UNINITIALIZED),SET_STATE(module_b_temp,ST_UNINITIALIZED)

### if SES sensor is at failed state, poll more frequently for 2 mins 
A S psu1_inlet_t		ST_FAILED		POLL(psu1_inlet_t,20),120/POLL(psu1_inlet_t,120)
A S psu1_hotspot_t		ST_FAILED		POLL(psu1_hotspot_t,20),120/POLL(psu1_hotspot_t,120)
A S psu1_fan1			ST_FAILED		POLL(psu1_fan1,20),120/POLL(psu1_fan1,120)
A S psu1_fan2			ST_FAILED		POLL(psu1_fan2,20),120/POLL(psu1_fan2,120)
A S psu1_5v			ST_FAILED		POLL(psu1_5v,20),120/POLL(psu1_5v,120)
A S psu1_12v			ST_FAILED		POLL(psu1_12v,20),120/POLL(psu1_12v,120)
A S psu1_5amp			ST_FAILED		POLL(psu1_5amp,20),120/POLL(psu1_5amp,120)
A S psu1_12amp			ST_FAILED		POLL(psu1_12amp,20),120/POLL(psu1_12amp,120)

A S psu2_inlet_t		ST_FAILED		POLL(psu2_inlet_t,20),120/POLL(psu2_inlet_t,120)
A S psu2_hotspot_t		ST_FAILED		POLL(psu2_hotspot_t,20),120/POLL(psu2_hotspot_t,120)
A S psu2_fan1			ST_FAILED		POLL(psu2_fan1,20),120/POLL(psu2_fan1,120)
A S psu2_fan2			ST_FAILED		POLL(psu2_fan2,20),120/POLL(psu2_fan2,120)
A S psu2_5v			ST_FAILED		POLL(psu2_5v,20),120/POLL(psu2_5v,120)
A S psu2_12v			ST_FAILED		POLL(psu2_12v,20),120/POLL(psu2_12v,120)
A S psu2_5amp			ST_FAILED		POLL(psu2_5amp,20),120/POLL(psu2_5amp,120)
A S psu2_12amp			ST_FAILED		POLL(psu2_12amp,20),120/POLL(psu2_12amp,120)


A S init			ST_UNINITIALIZED	DISARM(EMS_monitor_shutdown_cancel)

A S ambient_temp ST_LOW_CRIT			 	POLL(ambient_temp,10),120/POLL(ambient_temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_callhome_chassis_undertemp, "CHASSIS UNDER TEMPERATURE SHUTDOWN"), \
							20/EMS(EMS_monitor_shutdown_chassisUnderTemp, "System will be shutdown in 2 minutes."), \
							140+10/DO(env_halt,1,"Ambient temperature too low")
A S ambient_temp ST_HIGH_CRIT			 	POLL(ambient_temp,10),120/POLL(ambient_temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_callhome_chassis_overtemp, "CHASSIS OVER TEMPERATURE SHUTDOWN"), \
							20/EMS(EMS_monitor_shutdown_chassisOverTemp, "System will be shutdown in 2 minutes"), \
							140+10/DO(env_halt,1,"Ambient temperature too high")
A S ambient_temp ST_FAILED			 	POLL(ambient_temp,10),120/POLL(ambient_temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_monitor_shutdown_emergency, "Ambient temperature is not readable."), \
							20/EMS(EMS_monitor_shutdown_chassisOverTemp, "System will be shutdown in 2 minutes"), \
							140+10/DO(env_halt,1,"Ambient temperature reading failed")
A S ambient_temp [ST_HIGH_WARN|ST_LOW_WARN|ST_OK] 	+0/EMS(EMS_monitor_shutdown_cancel)


G cpu0_core_grp	shelf,CPU0_Core_Temp
A G cpu0_core_grp (NOT_PRESENT,ST_LOW_CRIT){2,2}	 	POLL(CPU0_Core_Temp,10),120/POLL(CPU0_Core_Temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_callhome_chassis_undertemp, "CHASSIS UNDER TEMPERATURE SHUTDOWN"), \
							20/EMS(EMS_monitor_shutdown_chassisUnderTemp, "System will be shutdown in 2 minutes."), \
							140+10/DO(env_halt,1,"CPU0 core temperature too low")
A G cpu0_core_grp (NOT_PRESENT,ST_HIGH_CRIT){2,2}	 	POLL(CPU0_Core_Temp,10),120/POLL(CPU0_Core_Temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_callhome_chassis_overtemp, "CHASSIS OVER TEMPERATURE SHUTDOWN"), \
							20/EMS(EMS_monitor_shutdown_chassisOverTemp, "System will be shutdown in 2 minutes"), \
							140+10/DO(env_halt,1,"CPU0 core temperature too high")
A G cpu0_core_grp (NOT_PRESENT,ST_FAILED){2,2}	 	POLL(CPU0_Core_Temp,10),120/POLL(CPU0_Core_Temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_monitor_shutdown_emergency, "CPU0 core temperature is not readable."), \
							20/EMS(EMS_monitor_shutdown_chassisOverTemp, "System will be shutdown in 2 minutes"), \
							140+10/DO(env_halt,1,"CPU0 core temperature reading failed")
A G cpu0_core_grp (PRESENT,[ST_HIGH_WARN|ST_LOW_WARN|ST_OK]){1,2} 	+0/EMS(EMS_monitor_shutdown_cancel)


G pcm_inlet_grp	shelf,PCM_Inlet_Temp
A G pcm_inlet_grp (NOT_PRESENT,ST_LOW_CRIT){2,2}	 	POLL(PCM_Inlet_Temp,10),120/POLL(PCM_Inlet_Temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_callhome_chassis_undertemp, "CHASSIS UNDER TEMPERATURE SHUTDOWN"), \
							20/EMS(EMS_monitor_shutdown_chassisUnderTemp, "System will be shutdown in 2 minutes."), \
							140+10/DO(env_halt,1,"PCM inlet temperature too low")
A G pcm_inlet_grp (NOT_PRESENT,ST_HIGH_CRIT){2,2}	 	POLL(PCM_Inlet_Temp,10),120/POLL(PCM_Inlet_Temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_callhome_chassis_overtemp, "CHASSIS OVER TEMPERATURE SHUTDOWN"), \
							20/EMS(EMS_monitor_shutdown_chassisOverTemp, "System will be shutdown in 2 minutes"), \
							140+10/DO(env_halt,1,"PCM inlet temperature too high")
A G pcm_inlet_grp (NOT_PRESENT,ST_FAILED){2,2}	 	POLL(PCM_Inlet_Temp,10),120/POLL(PCM_Inlet_Temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_monitor_shutdown_emergency, "CPU0 core temperature is not readable."), \
							20/EMS(EMS_monitor_shutdown_chassisOverTemp, "System will be shutdown in 2 minutes"), \
							140+10/DO(env_halt,1,"PCM inlet temperature reading failed")
A G pcm_inlet_grp (PRESENT,[ST_HIGH_WARN|ST_LOW_WARN|ST_OK]){1,2} 	+0/EMS(EMS_monitor_shutdown_cancel)


G m2_card_grp	shelf,M2_Card_Temp
A G m2_card_grp (NOT_PRESENT,ST_LOW_CRIT){2,2}	 	POLL(M2_Card_Temp,10),120/POLL(M2_Card_Temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_callhome_chassis_undertemp, "CHASSIS UNDER TEMPERATURE SHUTDOWN"), \
							20/EMS(EMS_monitor_shutdown_chassisUnderTemp, "System will be shutdown in 2 minutes."), \
							140+10/DO(env_halt,1,"M.2 card temperature too low")
A G m2_card_grp (NOT_PRESENT,ST_HIGH_CRIT){2,2}	 	POLL(M2_Card_Temp,10),120/POLL(M2_Card_Temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_callhome_chassis_overtemp, "CHASSIS OVER TEMPERATURE SHUTDOWN"), \
							20/EMS(EMS_monitor_shutdown_chassisOverTemp, "System will be shutdown in 2 minutes"), \
							140+10/DO(env_halt,1,"M.2 card temperature too high")
A G m2_card_grp (NOT_PRESENT,ST_FAILED){2,2}	 	POLL(M2_Card_Temp,10),120/POLL(M2_Card_Temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_monitor_shutdown_emergency, "CPU0 core temperature is not readable."), \
							20/EMS(EMS_monitor_shutdown_chassisOverTemp, "System will be shutdown in 2 minutes"), \
							140+10/DO(env_halt,1,"M.2 card temperature reading failed")
A G m2_card_grp (PRESENT,[ST_HIGH_WARN|ST_LOW_WARN|ST_OK]){1,2} 	+0/EMS(EMS_monitor_shutdown_cancel)


G dimm_grp	shelf,DIMM_Temp
A G dimm_grp (NOT_PRESENT,ST_LOW_CRIT){2,2}	 	POLL(DIMM_Temp,10),120/POLL(DIMM_Temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_callhome_chassis_undertemp, "CHASSIS UNDER TEMPERATURE SHUTDOWN"), \
							20/EMS(EMS_monitor_shutdown_chassisUnderTemp, "System will be shutdown in 2 minutes."), \
							140+10/DO(env_halt,1,"DIMM temperature too low")
A G dimm_grp (NOT_PRESENT,ST_HIGH_CRIT){2,2}	 	POLL(DIMM_Temp,10),120/POLL(DIMM_Temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_callhome_chassis_overtemp, "CHASSIS OVER TEMPERATURE SHUTDOWN"), \
							20/EMS(EMS_monitor_shutdown_chassisOverTemp, "System will be shutdown in 2 minutes"), \
							140+10/DO(env_halt,1,"DIMM temperature too high")
A G dimm_grp (NOT_PRESENT,ST_FAILED){2,2}	 	POLL(DIMM_Temp,10),120/POLL(DIMM_Temp,120), \
							20/ARM(EMS_monitor_shutdown_cancel), \
							20/EMS(EMS_monitor_shutdown_emergency, "CPU0 core temperature is not readable."), \
							20/EMS(EMS_monitor_shutdown_chassisOverTemp, "System will be shutdown in 2 minutes"), \
							140+10/DO(env_halt,1,"DIMM temperature reading failed")
A G dimm_grp (PRESENT,[ST_HIGH_WARN|ST_LOW_WARN|ST_OK]){1,2} 	+0/EMS(EMS_monitor_shutdown_cancel)

###############################################################################################################
#                                              Razor-M PSU Policy                                             #
###############################################################################################################
# 
# PSU is removed/pulled,   enable/disable all PSU sensors (EMS/ASUP will be sent by SES code)
# 
A S psu1		NOT_PRESENT	SET_STATE(psu1_inlet_t,ST_DISABLED),SET_STATE(psu1_hotspot_t,ST_DISABLED), \
					SET_STATE(psu1_fan1,ST_DISABLED),SET_STATE(psu1_fan2,ST_DISABLED), \
					SET_STATE(psu1_5v,ST_DISABLED),SET_STATE(psu1_12v,ST_DISABLED), \
					SET_STATE(psu1_5amp,ST_DISABLED),SET_STATE(psu1_12amp,ST_DISABLED)

A S psu1		PRESENT		SET_STATE(psu1_inlet_t,ST_UNINITIALIZED),SET_STATE(psu1_hotspot_t,ST_UNINITIALIZED), \
					SET_STATE(psu1_fan1,ST_UNINITIALIZED),SET_STATE(psu1_fan2,ST_UNINITIALIZED), \
					SET_STATE(psu1_5v,ST_UNINITIALIZED),SET_STATE(psu1_12v,ST_UNINITIALIZED), \
					SET_STATE(psu1_5amp,ST_UNINITIALIZED),SET_STATE(psu1_12amp,ST_UNINITIALIZED)

A S psu2		NOT_PRESENT	SET_STATE(psu2_inlet_t,ST_DISABLED),SET_STATE(psu2_hotspot_t,ST_DISABLED), \
					SET_STATE(psu2_fan1,ST_DISABLED),SET_STATE(psu2_fan2,ST_DISABLED), \
					SET_STATE(psu2_5v,ST_DISABLED),SET_STATE(psu2_12v,ST_DISABLED), \
					SET_STATE(psu2_5amp,ST_DISABLED),SET_STATE(psu2_12amp,ST_DISABLED)

A S psu2		PRESENT		SET_STATE(psu2_inlet_t,ST_UNINITIALIZED),SET_STATE(psu2_hotspot_t,ST_UNINITIALIZED), \
					SET_STATE(psu2_fan1,ST_UNINITIALIZED),SET_STATE(psu2_fan2,ST_UNINITIALIZED), \
					SET_STATE(psu2_5v,ST_UNINITIALIZED),SET_STATE(psu2_12v,ST_UNINITIALIZED), \
					SET_STATE(psu2_5amp,ST_UNINITIALIZED),SET_STATE(psu2_12amp,ST_UNINITIALIZED)

# PSU Sensor Groups and psudo sensors
S psu1_state "PSU1"		DISCRETE	- - 0 0	hidden	0*/GOOD 1/BAD
S psu2_state "PSU2"		DISCRETE	- - 0 0	hidden	0*/GOOD 1/BAD

G psu1_grp psu1_on, psu1_inlet_t, psu1_hotspot_t, psu1_5v, psu1_12v, psu1_5amp, psu1_12amp,psu1_fan1, psu1_fan2
G psu2_grp psu2_on, psu2_inlet_t, psu2_hotspot_t, psu2_5v, psu2_12v, psu2_5amp, psu2_12amp,psu2_fan1, psu2_fan2

# If all the PSU sensors are good, set the status sensor to GOOD
A G psu1_grp (ON,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK){9,9}	30/SET_VALUE(psu1_state, GOOD)
A G psu2_grp (ON,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK){9,9}	30/SET_VALUE(psu2_state, GOOD)

# If PSU X is off, set state to BAD
A S psu1_on				OFF		30/SET_VALUE(psu1_state, BAD)
A S psu2_on				OFF		30/SET_VALUE(psu2_state, BAD)

# If PSU is not present, set psu_status to be BAD
A S psu1				NOT_PRESENT		30/SET_VALUE(psu1_state, BAD)
A S psu2				NOT_PRESENT		30/SET_VALUE(psu2_state, BAD)

# If PSU is off, set status to BAD
A (psu1, psu1_12v)    (ST_FAILED, ST_FAILED){2,2}		30/SET_VALUE(psu1_state, BAD)
A (psu2, psu2_12v)    (ST_FAILED, ST_FAILED){2,2}		30/SET_VALUE(psu2_state, BAD)

# If Any PSU sensor are crit condition, set the status sensor to BAD
A G psu1_grp	(ON,[ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN],[ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN], \
		 [ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN],[ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN], \
		 [ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN],[ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN], \
		 [ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN],[ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN]){2,9}	30/SET_VALUE(psu1_state, BAD)
A G psu2_grp	(ON,[ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN],[ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN], \
		 [ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN],[ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN], \
		 [ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN],[ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN], \
		 [ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN],[ST_LOW_CRIT|ST_HIGH_CRIT|ST_LOW_WARN|ST_HIGH_WARN]){2,9}	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-M Partner Status Policy                                  #
###############################################################################################################
A S partner A_SIDE_NOT_PRESENT   SET_STATE(module_a_temp,ST_DISABLED)
A S partner A_SIDE_PRESENT       SET_STATE(module_a_temp,ST_UNINITIALIZED)
A S partner B_SIDE_NOT_PRESENT   SET_STATE(module_b_temp,ST_DISABLED)
A S partner B_SIDE_PRESENT       SET_STATE(module_b_temp,ST_UNINITIALIZED)

###############################################################################################################
#                                              Razor-M 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)

# If any temperature sensor is abnormal, arm the OK ems message.
G temp_grp CPU0_Core_Temp,CPU0_Temp_Margin,PCM_Inlet_Temp, M2_Card_Temp, DIMM_Temp, ambient_temp, midplane_1_temp, midplane_2_temp, midplane_3_temp, midplane_4_temp, module_a_temp, module_b_temp, psu2_hotspot_t, psu2_inlet_t, psu1_hotspot_t, psu1_inlet_t

 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], \
		 [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,12}	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,ST_OK,ST_OK,ST_OK,[ST_OK|ST_DISABLED],[ST_OK|ST_DISABLED],-,-,-,-){12,12}		+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], [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,12}		EMS(EMS_callhome_chassis_hitemp, "CHASSIS OVER TEMPERATURE")

# individual sensor warnings
INCLUDE MACRO_TEMP	(CPU0_Core_Temp)
INCLUDE MACRO_TEMP	(CPU0_Temp_Margin)
INCLUDE MACRO_TEMP	(PCM_Inlet_Temp)
INCLUDE MACRO_TEMP	(M2_Card_Temp)
INCLUDE MACRO_TEMP	(DIMM_Temp)
INCLUDE MACRO_TEMP	(ambient_temp)
INCLUDE MACRO_TEMP	(midplane_1_temp)
INCLUDE MACRO_TEMP	(midplane_2_temp)
INCLUDE MACRO_TEMP	(midplane_3_temp)
INCLUDE MACRO_TEMP	(midplane_4_temp)
INCLUDE MACRO_TEMP	(module_a_temp)
INCLUDE MACRO_TEMP	(module_b_temp)

# Report Temp SNMP
# Create the temp pseudo sensors
S chassis_is_overtemp   "Chassis is Over Temp"  DISCRETE        - - 0 0 hidden          0*/NO 1/YES
S chassis_is_undertemp  "Chassis is Under Temp" DISCRETE        - - 0 0 hidden          0*/NO 1/YES

# If all sensors are normal, we set the pseudo-sensor to normal
A G temp_grp (ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,ST_OK,[ST_OK|ST_DISABLED],[ST_OK|ST_DISABLED],-,-,-,-){12,12}		SET_VALUE(chassis_is_overtemp, NO), SET_VALUE(chassis_is_undertemp, NO)
# If any sensor is high or failed, flag it as temp high
A G 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],	\
			 [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,12}	SET_VALUE(chassis_is_overtemp, YES)

# If any sensor is low, flag it as temp low
A G temp_grp		([ST_LOW_CRIT|ST_LOW_WARN],	\
			 [ST_LOW_CRIT|ST_LOW_WARN],	\
			 [ST_LOW_CRIT|ST_LOW_WARN],	\
			 [ST_LOW_CRIT|ST_LOW_WARN],	\
			 [ST_LOW_CRIT|ST_LOW_WARN],	\
			 [ST_LOW_CRIT|ST_LOW_WARN],	\
			 [ST_LOW_CRIT|ST_LOW_WARN],	\
			 [ST_LOW_CRIT|ST_LOW_WARN],	\
			 [ST_LOW_CRIT|ST_LOW_WARN],	\
			 [ST_LOW_CRIT|ST_LOW_WARN],	\
			 [ST_LOW_CRIT|ST_LOW_WARN],	\
			 [ST_LOW_CRIT|ST_LOW_WARN],	\
			 -,-,-,-){1,12}	SET_VALUE(chassis_is_undertemp, YES)

A (chassis_is_overtemp,chassis_is_undertemp)    (YES, -){1,1}           SET_VALUE(temp_snmp, OVER_TEMP), DO(update_sen_list, "crit_zone", ADD, temp_snmp), DO(update_snmp, ENTITY_TEMP)
A (chassis_is_overtemp,chassis_is_undertemp)    (!YES, YES){2,2}        SET_VALUE(temp_snmp, UNDER_TEMP), DO(update_sen_list, "crit_zone", ADD, temp_snmp), DO(update_snmp, ENTITY_TEMP)
A (chassis_is_overtemp,chassis_is_undertemp)    (!YES, !YES){2,2}       SET_VALUE(temp_snmp, NORMAL_TEMP), DO(update_sen_list, "crit_zone", DEL, temp_snmp), DO(update_snmp, ENTITY_TEMP)				 


S any_temp_crit_high 	"Any Temp Crit High?"		DISCRETE	- - 0 0	hidden		0*/NO 1/YES

A G temp_grp	(ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT,ST_HIGH_CRIT) {1,16} SET_VALUE(any_temp_crit_high,YES)
A G temp_grp	(!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT,!ST_HIGH_CRIT) {16,16} SET_VALUE(any_temp_crit_high,NO)

# Fan Count SNMP
S snmp_badfan			"SNMP Bad Fan Count"		DISCRETE	- - 0 0	hidden		0*/OK 1/ONE_FAILED 2/MULTI_FAILED
A S num_fan [ST_NA|ST_FAILED]				POLL(num_fan, 10), 60/SET_VALUE(snmp_badfan, MULTI_FAILED), 90/EMS(EMS_monitor_shutdown_emergency,"Status of fans is unknown for 90 seconds. Shutting down now."), \
								90/EMS(EMS_callhome_fans_failed,"MULTIPLE FAN FAILURE"), 90/DO(env_halt,1,"Multiple fans failed"), ARM(EMS_monitor_shutdown_cancel)
A S num_fan	[FAIL_1|FAIL_2|FAIL_3|FAIL_4]	POLL(num_fan, 30)
A S num_fan	OK					SET_VALUE(snmp_badfan, OK)
A S num_fan	FAIL_1				SET_VALUE(snmp_badfan, ONE_FAILED)
A S num_fan	[OK|FAIL_1]			+0/EMS(EMS_monitor_shutdown_cancel)
A S num_fan	[FAIL_2]			EMS(EMS_monitor_fan_critical,"2 fans have failed. Replace them to avoid overheating. If not corrected, system will shutdown in 2 minutes."), \
								SET_VALUE(snmp_badfan, MULTI_FAILED),20/EMS(EMS_callhome_fans_failed,"MULTIPLE FAN FAILURE"), 140/DO(env_halt,1,"Multiple fans failed"),20/ARM(EMS_monitor_shutdown_cancel)
A S num_fan	[FAIL_3|FAIL_4]		SET_VALUE(snmp_badfan, MULTI_FAILED), 30/EMS(EMS_monitor_shutdown_emergency,"Number of failed fans more than tolerable limit. Shutting down now."), \
								30/EMS(EMS_callhome_fans_failed,"MULTIPLE FAN FAILURE"), 30/DO(env_halt,1,"Multiple fans failed")

A (num_fan,any_temp_crit_high) ([ST_NA|ST_FAILED],YES){2,2}					SET_VALUE(snmp_badfan, MULTI_FAILED), 30/EMS(EMS_monitor_shutdown_emergency,"Fans in unknown state and at least one temperature sensor is Critical High"), \
																			30/EMS(EMS_callhome_fans_failed,"MULTIPLE FAN FAILURE"), 30/DO(env_halt,1,"Multiple fans failed")

A S snmp_badfan	OK				DO(update_sen_list, "crit_fan", READ, snmp_badfan), DO(update_snmp, ENTITY_FAN)
A S snmp_badfan	ONE_FAILED			DO(update_sen_list, "crit_fan", READ, snmp_badfan), DO(update_snmp, ENTITY_FAN)
A S snmp_badfan	MULTI_FAILED			DO(update_sen_list, "crit_fan", READ, snmp_badfan), DO(update_snmp, ENTITY_FAN)

###############################################################################################################
#                                            Razor-M 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-M 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}			30/EMS(EMS_nvmem_battery_capLow, "%r")
A (Bat_Dstg_Cycles,Bat_Dstg_Cycles) (ST_LOW_CRIT,(1,)){2,2}			30/EMS(EMS_callhome_battery_warning, "BATTERY (capacity low)")
A (Bat_Dstg_Cycles,Bat_Dstg_Cycles) (ST_LOW_CRIT,(,2)){2,2}			30/EMS(EMS_nvmem_battery_capLowCrit, "%r", "20")
A (Bat_Dstg_Cycles,Bat_Dstg_Cycles) (ST_LOW_CRIT,(,2)){2,2}			30/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 Voltage
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-00045", "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
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 S init		ST_UNINITIALIZED	SET_VALUE(batt_charge, GOOD)
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

