Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sensors #295

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/sonic_ax_impl/mibs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,20 @@ def thermal_info_table(thermal_name):

return "TEMPERATURE_INFO" + TABLE_NAME_SEPARATOR_VBAR + thermal_name

def voltage_sensor_info_table(sensor_name):
"""
:param: sensor_name : Voltage Sensor name
:return: voltage sensor info key
"""
return "VOLTAGE_INFO" + TABLE_NAME_SEPARATOR_VBAR + sensor_name

def current_sensor_info_table(sensor_name):
"""
:param: sensor_name : Current Sensor name
:return: current sensor info key
"""
return "CURRENT_INFO" + TABLE_NAME_SEPARATOR_VBAR + sensor_name

def lldp_entry_table(if_name):
"""
:param if_name: given interface to cast.
Expand Down
18 changes: 18 additions & 0 deletions src/sonic_ax_impl/mibs/ietf/physical_entity_sub_oid_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,21 @@ def get_transceiver_sensor_sub_id(ifindex, offset):

transceiver_oid, = get_transceiver_sub_id(ifindex)
return (transceiver_oid + offset,)

def get_chassis_voltage_sensor_sub_id(position):
"""
Returns sub OID for voltage sensors that belong to chassis. Sub OID is calculated as follows:
sub OID = CHASSIS_MGMT_SUB_ID + DEVICE_TYPE_POWER_MONITOR + position * DEVICE_INDEX_MULTIPLE + SENSOR_TYPE_VOLTAGE,
:param position: voltage sensor position
:return: sub OID of the voltage sensor
"""
return (CHASSIS_MGMT_SUB_ID + DEVICE_TYPE_POWER_MONITOR + position * DEVICE_INDEX_MULTIPLE + SENSOR_TYPE_VOLTAGE, )

def get_chassis_current_sensor_sub_id(position):
"""
Returns sub OID for current sensors that belong to chassis. Sub OID is calculated as follows:
sub OID = CHASSIS_MGMT_SUB_ID + DEVICE_TYPE_POWER_MONITOR + position * DEVICE_INDEX_MULTIPLE + SENSOR_TYPE_CURRENT,
:param position: current sensor position
:return: sub OID of the current sensor
"""
return (CHASSIS_MGMT_SUB_ID + DEVICE_TYPE_POWER_MONITOR + position * DEVICE_INDEX_MULTIPLE + SENSOR_TYPE_CURRENT, )
104 changes: 104 additions & 0 deletions src/sonic_ax_impl/mibs/ietf/rfc2737.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
from .physical_entity_sub_oid_generator import get_psu_sensor_sub_id
from .physical_entity_sub_oid_generator import get_transceiver_sub_id
from .physical_entity_sub_oid_generator import get_transceiver_sensor_sub_id
from .physical_entity_sub_oid_generator import get_chassis_voltage_sensor_sub_id
from .physical_entity_sub_oid_generator import get_chassis_current_sensor_sub_id
from .sensor_data import TransceiverSensorData

@unique
Expand Down Expand Up @@ -111,6 +113,24 @@ class ThermalInfoDB(str, Enum):
REPLACEABLE = 'is_replaceable'


@unique
class VoltageSensorInfoDB(str, Enum):
"""
Voltage sensor info keys
"""
VOLTAGE = 'voltage'
REPLACEABLE = 'is_replaceable'


@unique
class CurrentSensorInfoDB(str, Enum):
"""
Current Sensor info keys
"""
CURRENT = 'current'
REPLACEABLE = 'is_replaceable'


# Map used to generate PSU sensor description
PSU_SENSOR_NAME_MAP = {
'temperature': 'Temperature',
Expand Down Expand Up @@ -1040,6 +1060,90 @@ def _update_entity_cache(self, thermal_name):
else:
self._remove_entity_cache(thermal_name)

@physical_entity_updater()
class VoltageSensorCacheUpdater(PhysicalEntityCacheUpdater):
KEY_PATTERN = mibs.voltage_sensor_info_table("*")

def __init__(self, mib_updater):
super(VoltageSensorCacheUpdater, self).__init__(mib_updater)

def get_key_pattern(self):
return VoltageSensorCacheUpdater.KEY_PATTERN

def _update_entity_cache(self, voltage_sensor_name):
voltage_sensor_info = Namespace.dbs_get_all(self.mib_updater.statedb, mibs.STATE_DB,
mibs.voltage_sensor_info_table(voltage_sensor_name))
if not voltage_sensor_info:
return

voltage, replaceable = get_db_data(voltage_sensor_info, VoltageSensorInfoDB)
if voltage and not is_null_str(voltage):
voltage_sensor_relation_info = self.get_physical_relation_info(voltage_sensor_name)
if not voltage_sensor_relation_info:
return
voltage_sensor_position, voltage_sensor_parent_name = get_db_data(voltage_sensor_relation_info, PhysicalRelationInfoDB)
voltage_sensor_position = int(voltage_sensor_position)

# only process voltage_sensors belonging to chassis here, voltage_sensors belong to other
# physical entity will be processed in other entity updater
if voltage_sensor_parent_name in self.mib_updater.physical_name_to_oid_map and \
self.mib_updater.physical_name_to_oid_map[voltage_sensor_parent_name] == (CHASSIS_SUB_ID,):
voltage_sensor_sub_id = get_chassis_voltage_sensor_sub_id(voltage_sensor_position)
self._add_entity_related_oid(voltage_sensor_name, voltage_sensor_sub_id)

# add voltage_sensor to available OID list
self.mib_updater.add_sub_id(voltage_sensor_sub_id)
self.mib_updater.set_phy_class(voltage_sensor_sub_id, PhysicalClass.SENSOR)
self.mib_updater.set_phy_descr(voltage_sensor_sub_id, voltage_sensor_name)
self.mib_updater.set_phy_name(voltage_sensor_sub_id, voltage_sensor_name)
self.mib_updater.set_phy_parent_relative_pos(voltage_sensor_sub_id, voltage_sensor_position)
self.mib_updater.set_phy_contained_in(voltage_sensor_sub_id, CHASSIS_MGMT_SUB_ID)
self.mib_updater.set_phy_fru(voltage_sensor_sub_id, replaceable)
else:
self._remove_entity_cache(voltage_sensor_name)

@physical_entity_updater()
class CurrentSensorCacheUpdater(PhysicalEntityCacheUpdater):
KEY_PATTERN = mibs.current_sensor_info_table("*")

def __init__(self, mib_updater):
super(CurrentSensorCacheUpdater, self).__init__(mib_updater)

def get_key_pattern(self):
return CurrentSensorCacheUpdater.KEY_PATTERN

def _update_entity_cache(self, current_sensor_name):
current_sensor_info = Namespace.dbs_get_all(self.mib_updater.statedb, mibs.STATE_DB,
mibs.current_sensor_info_table(current_sensor_name))
if not current_sensor_info:
return

current, replaceable = get_db_data(current_sensor_info, CurrentSensorInfoDB)
if current and not is_null_str(current):
current_sensor_relation_info = self.get_physical_relation_info(current_sensor_name)
if not current_sensor_relation_info:
return
current_sensor_position, current_sensor_parent_name = get_db_data(current_sensor_relation_info, PhysicalRelationInfoDB)
current_sensor_position = int(current_sensor_position)

# only process current_sensors belong to chassis here, current_sensors belong to other
# physical entity will be processed in other entity updater
if current_sensor_parent_name in self.mib_updater.physical_name_to_oid_map and \
self.mib_updater.physical_name_to_oid_map[current_sensor_parent_name] == (CHASSIS_SUB_ID,):
current_sensor_sub_id = get_chassis_current_sensor_sub_id(current_sensor_position)
self._add_entity_related_oid(current_sensor_name, current_sensor_sub_id)

# add current_sensor to available OID list
self.mib_updater.add_sub_id(current_sensor_sub_id)
self.mib_updater.set_phy_class(current_sensor_sub_id, PhysicalClass.SENSOR)
self.mib_updater.set_phy_descr(current_sensor_sub_id, current_sensor_name)
self.mib_updater.set_phy_name(current_sensor_sub_id, current_sensor_name)
self.mib_updater.set_phy_parent_relative_pos(current_sensor_sub_id, current_sensor_position)
self.mib_updater.set_phy_contained_in(current_sensor_sub_id, CHASSIS_MGMT_SUB_ID)
self.mib_updater.set_phy_fru(current_sensor_sub_id, replaceable)
else:
self._remove_entity_cache(current_sensor_name)


class PhysicalTableMIB(metaclass=MIBMeta, prefix='.1.3.6.1.2.1.47.1.1.1'):
"""
Expand Down
138 changes: 138 additions & 0 deletions src/sonic_ax_impl/mibs/ietf/rfc3433.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
from .physical_entity_sub_oid_generator import get_psu_sub_id
from .physical_entity_sub_oid_generator import get_psu_sensor_sub_id
from .physical_entity_sub_oid_generator import get_chassis_thermal_sub_id
from .physical_entity_sub_oid_generator import get_chassis_voltage_sensor_sub_id
from .physical_entity_sub_oid_generator import get_chassis_current_sensor_sub_id
from .sensor_data import ThermalSensorData, FANSensorData, PSUSensorData, TransceiverSensorData
from .sensor_data import VoltageSensorData, CurrentSensorData

NOT_AVAILABLE = 'N/A'
CHASSIS_NAME_SUB_STRING = 'chassis'
Expand Down Expand Up @@ -337,6 +340,33 @@ class ThermalSensor(SensorInterface):
'temperature': ThermalSensor
})

class VoltageSensor(SensorInterface):
"""
Voltage sensor.
"""

TYPE = EntitySensorDataType.VOLTS_DC
SCALE = EntitySensorDataScale.MILLI
PRECISION = 0


VoltageSensorData.bind_sensor_interface({
'voltage': VoltageSensor
})

class CurrentSensor(SensorInterface):
"""
Current sensor.
"""

TYPE = EntitySensorDataType.AMPERES
SCALE = EntitySensorDataScale.MILLI
PRECISION = 0


CurrentSensorData.bind_sensor_interface({
'current': CurrentSensor
})

class PhysicalSensorTableMIBUpdater(MIBUpdater):
"""
Expand All @@ -347,6 +377,8 @@ class PhysicalSensorTableMIBUpdater(MIBUpdater):
PSU_SENSOR_KEY_PATTERN = mibs.psu_info_table("*")
FAN_SENSOR_KEY_PATTERN = mibs.fan_info_table("*")
THERMAL_SENSOR_KEY_PATTERN = mibs.thermal_info_table("*")
VOLTAGE_SENSOR_KEY_PATTERN = mibs.voltage_sensor_info_table("*")
CURRENT_SENSOR_KEY_PATTERN = mibs.current_sensor_info_table("*")

def __init__(self):
"""
Expand All @@ -373,6 +405,8 @@ def __init__(self):
self.psu_sensor = []
self.thermal_sensor = []
self.broken_transceiver_info = []
self.voltage_sensor = []
self.current_sensor = []

def reinit_connection(self):
Namespace.connect_all_dbs(self.statedb, mibs.STATE_DB)
Expand Down Expand Up @@ -409,6 +443,16 @@ def reinit_data(self):
if thermal_sensor_encoded:
self.thermal_sensor = [entry for entry in thermal_sensor_encoded]

voltage_sensor_encoded = self.statedb[HOST_NAMESPACE_DB_IDX].keys(self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB,
self.VOLTAGE_SENSOR_KEY_PATTERN)
if voltage_sensor_encoded:
self.voltage_sensor = [entry for entry in voltage_sensor_encoded]

current_sensor_encoded = self.statedb[HOST_NAMESPACE_DB_IDX].keys(self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB,
self.CURRENT_SENSOR_KEY_PATTERN)
if current_sensor_encoded:
self.current_sensor = [entry for entry in current_sensor_encoded]

def update_xcvr_dom_data(self):
if not self.transceiver_dom:
return
Expand Down Expand Up @@ -619,6 +663,96 @@ def update_thermal_sensor_data(self):

self.sub_ids.append(sub_id)

def update_voltage_sensor_data(self):
if not self.voltage_sensor:
return

for voltage_sensor_entry in self.voltage_sensor:
voltage_name = voltage_sensor_entry.split(mibs.TABLE_NAME_SEPARATOR_VBAR)[-1]
voltage_relation_info = self.statedb[HOST_NAMESPACE_DB_IDX].get_all(
self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, mibs.physical_entity_info_table(voltage_name))
voltage_position, voltage_parent_name = get_db_data(voltage_relation_info, PhysicalRelationInfoDB)

if is_null_empty_str(voltage_parent_name) or is_null_empty_str(voltage_parent_name) or \
CHASSIS_NAME_SUB_STRING not in voltage_parent_name.lower():
continue

voltage_position = int(voltage_position)

voltage_sensor_entry_data = self.statedb[HOST_NAMESPACE_DB_IDX].get_all(
self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, voltage_sensor_entry)

if not voltage_sensor_entry_data:
continue

sensor_data_list = VoltageSensorData.create_sensor_data(voltage_sensor_entry_data)
for sensor_data in sensor_data_list:
raw_sensor_value = sensor_data.get_raw_value()
if is_null_empty_str(raw_sensor_value):
continue
sensor = sensor_data.get_sensor_interface()
sub_id = get_chassis_voltage_sensor_sub_id(voltage_position)

try:
mib_values = sensor.mib_values(raw_sensor_value)
except (ValueError, ArithmeticError):
mibs.logger.error("Exception occurred when converting"
"value for sensor {} : {}".format(sensor, voltage_name))
continue
else:
self.ent_phy_sensor_type_map[sub_id], \
self.ent_phy_sensor_scale_map[sub_id], \
self.ent_phy_sensor_precision_map[sub_id], \
self.ent_phy_sensor_value_map[sub_id], \
self.ent_phy_sensor_oper_state_map[sub_id] = mib_values

self.sub_ids.append(sub_id)

def update_current_sensor_data(self):
if not self.current_sensor:
return

for current_sensor_entry in self.current_sensor:
current_name = current_sensor_entry.split(mibs.TABLE_NAME_SEPARATOR_VBAR)[-1]
current_relation_info = self.statedb[HOST_NAMESPACE_DB_IDX].get_all(
self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, mibs.physical_entity_info_table(current_name))
current_position, current_parent_name = get_db_data(current_relation_info, PhysicalRelationInfoDB)

if is_null_empty_str(current_parent_name) or is_null_empty_str(current_parent_name) or \
CHASSIS_NAME_SUB_STRING not in current_parent_name.lower():
continue

current_position = int(current_position)

current_sensor_entry_data = self.statedb[HOST_NAMESPACE_DB_IDX].get_all(
self.statedb[HOST_NAMESPACE_DB_IDX].STATE_DB, current_sensor_entry)

if not current_sensor_entry_data:
continue

sensor_data_list = CurrentSensorData.create_sensor_data(current_sensor_entry_data)
for sensor_data in sensor_data_list:
raw_sensor_value = sensor_data.get_raw_value()
if is_null_empty_str(raw_sensor_value):
continue
sensor = sensor_data.get_sensor_interface()
sub_id = get_chassis_current_sensor_sub_id(current_position)

try:
mib_values = sensor.mib_values(raw_sensor_value)
except (ValueError, ArithmeticError):
mibs.logger.error("Exception occurred when converting"
"value for sensor {} : {}".format(sensor, current_name))
continue
else:
self.ent_phy_sensor_type_map[sub_id], \
self.ent_phy_sensor_scale_map[sub_id], \
self.ent_phy_sensor_precision_map[sub_id], \
self.ent_phy_sensor_value_map[sub_id], \
self.ent_phy_sensor_oper_state_map[sub_id] = mib_values

self.sub_ids.append(sub_id)

def update_data(self):
"""
Update sensors cache.
Expand All @@ -634,6 +768,10 @@ def update_data(self):

self.update_thermal_sensor_data()

self.update_voltage_sensor_data()

self.update_current_sensor_data()

self.sub_ids.sort()

def get_next(self, sub_id):
Expand Down
Loading
Loading