Adding Thermal resource schema

Adding Thermal resource schema from Redfish API

Change-Id: I40279cfa689632b8e6efa5e8db991224bd02d33e
Story: 2005414
Task: 30431
This commit is contained in:
Riccardo Pittau 2019-04-09 17:54:24 +02:00
parent 9a138d4ec9
commit 87dcc7a139
7 changed files with 303 additions and 0 deletions

View File

@ -0,0 +1,4 @@
---
features:
- |
Adds the Thermal resource to the Library.

View File

@ -0,0 +1,18 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
FAN_READING_UNIT_PERCENTAGE = 'Percentage'
"""Indicates that the fan reading and thresholds are measured in percentage"""
FAN_READING_UNIT_RPM = 'RPM'
"""Indicates that the fan reading and thresholds
are measured in rotations per minute."""

View File

@ -0,0 +1,18 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from sushy.resources.chassis.thermal import constants as the_cons
FAN_READING_UNITS_MAP = {
'Percentage': the_cons.FAN_READING_UNIT_PERCENTAGE,
'RPM': the_cons.FAN_READING_UNIT_RPM,
}

View File

@ -0,0 +1,138 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# This is referred from Redfish standard schema.
# http://redfish.dmtf.org/schemas/v1/Thermal.v1_3_0.json
from sushy.resources import base
from sushy.resources.chassis.thermal import mappings as the_maps
from sushy.resources import common
from sushy.resources import mappings as res_maps
from sushy import utils
class Sensor(base.ListField):
"""The sensor device/s associated with Thermal."""
identity = base.Field('MemberId', required=True)
"""Identifier of the Sensor"""
lower_threshold_critical = base.Field('LowerThresholdCritical',
adapter=utils.int_or_none)
"""Below normal range but not yet fatal"""
lower_threshold_fatal = base.Field('LowerThresholdFatal',
adapter=utils.int_or_none)
"""Below normal range and is fatal"""
lower_threshold_non_critical = base.Field('LowerThresholdNonCritical',
adapter=utils.int_or_none)
"""Below normal range"""
name = base.Field('Name')
"""The name of this sensor"""
physical_context = base.Field('PhysicalContext')
"""Area or device associated with this sensor"""
status = common.StatusField('Status')
"""Status of the sensor"""
upper_threshold_critical = base.Field('UpperThresholdCritical',
adapter=utils.int_or_none)
"""Above normal range but not yet fatal"""
upper_threshold_fatal = base.Field('UpperThresholdFatal',
adapter=utils.int_or_none)
"""Above normal range and is fatal"""
upper_threshold_non_critical = base.Field('UpperThresholdNonCritical',
adapter=utils.int_or_none)
"""Above normal range"""
class FansListField(Sensor):
"""The Fan device/s associated with Thermal."""
indicator_led = base.MappedField('IndicatorLED',
res_maps.INDICATOR_LED_VALUE_MAP)
"""The state of the indicator LED, used to identify the fan"""
manufacturer = base.Field('Manufacturer')
"""This is the manufacturer of this Fan"""
max_reading_range = base.Field('MaxReadingRange',
adapter=utils.int_or_none)
"""Maximum value for Reading"""
min_reading_range = base.Field('MinReadingRange',
adapter=utils.int_or_none)
"""Minimum value for Reading"""
model = base.Field('Model')
"""The model of this Fan"""
part_number = base.Field('PartNumber')
"""Part number of this Fan"""
reading = base.Field('Reading', adapter=utils.int_or_none)
"""Current Fan Speed"""
reading_units = base.MappedField('ReadingUnits',
the_maps.FAN_READING_UNITS_MAP)
"""Units in which the reading and thresholds are measured"""
serial_number = base.Field('SerialNumber')
"""Serial number of this Fan"""
class TemperaturesListField(Sensor):
"""The Temperature device/s associated with Thermal."""
max_allowable_operating_value = base.Field('MaxAllowableOperatingValue',
adapter=utils.int_or_none)
"""Maximum allowable operating temperature for this equipment"""
min_allowable_operating_value = base.Field('MinAllowableOperatingValue',
adapter=utils.int_or_none)
"""Minimum allowable operating temperature for this equipment"""
max_reading_range_temp = base.Field('MaxReadingRangeTemp')
"""Maximum value for ReadingCelsius"""
min_reading_range_temp = base.Field('MinReadingRangeTemp')
"""Minimum value for ReadingCelsius"""
reading_celsius = base.Field('ReadingCelsius')
"""Temperature"""
sensor_number = base.Field('SensorNumber', adapter=utils.int_or_none)
"""A numerical identifier to represent the temperature sensor"""
class Thermal(base.ResourceBase):
"""This class represents a Thermal resource."""
identity = base.Field('Id')
"""Identifier of the resource"""
name = base.Field('Name')
"""The name of the resource"""
status = common.StatusField('Status')
"""Status of the resource"""
fans = FansListField('Fans', default=[])
"""A tuple of Fan identities"""
temperatures = TemperaturesListField('Temperatures', default=[])
"""A tuple of Temperature identities"""

View File

@ -0,0 +1,52 @@
{
"@odata.type": "#Thermal.v1_3_0.Thermal",
"Id": "Thermal",
"Name": "Blade Thermal",
"Temperatures": [
{
"@odata.id": "/redfish/v1/Chassis/Blade1/Thermal#/Temperatures/0",
"MemberId": "0",
"Name": "CPU Temp",
"Status": {
"State": "Enabled",
"Health": "OK"
},
"ReadingCelsius": 62,
"UpperThresholdNonCritical": 75,
"UpperThresholdCritical": 90,
"UpperThresholdFatal": 95,
"MinReadingRangeTemp": 0,
"MaxReadingRangeTemp": 120,
"PhysicalContext": "CPU",
"RelatedItem": [
{
"@odata.id": "/redfish/v1/Systems/529QB9450R6/Processors/CPU"
}
]
}
],
"Fans": [
{
"@odata.id": "/redfish/v1/Chassis/Blade1/Thermal#/Fans/0",
"MemberId": "0",
"Name": "CPU Fan",
"PhysicalContext": "CPU",
"Status": {
"State": "Enabled",
"Health": "OK"
},
"Reading": 6000,
"ReadingUnits": "RPM",
"LowerThresholdFatal": 2000,
"MinReadingRange": 0,
"MaxReadingRange": 10000,
"RelatedItem": [
{
"@odata.id": "/redfish/v1/Systems/529QB9450R6/Processors/CPU"
}
]
}
],
"@odata.context": "/redfish/v1/$metadata#Thermal.Thermal",
"@odata.id": "/redfish/v1/Chassis/Blade1/Thermal"
}

View File

@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import mock
from sushy.resources.chassis.thermal import thermal
from sushy.tests.unit import base
class ThermalTestCase(base.TestCase):
def setUp(self):
super(ThermalTestCase, self).setUp()
self.conn = mock.Mock()
with open('sushy/tests/unit/json_samples/thermal.json') as f:
self.conn.get.return_value.json.return_value = json.load(f)
self.thermal = thermal.Thermal(
self.conn, '/redfish/v1/Chassis/Blade1/Thermal',
redfish_version='1.5.0')
def test__parse_attributes(self):
self.thermal._parse_attributes()
self.assertEqual('1.5.0', self.thermal.redfish_version)
self.assertEqual('Thermal', self.thermal.identity)
self.assertEqual('Blade Thermal', self.thermal.name)
self.assertEqual('0', self.thermal.fans[0].identity)
self.assertEqual('CPU Fan', self.thermal.fans[0].name)
self.assertEqual('CPU', self.thermal.fans[0].physical_context)
self.assertEqual('enabled', self.thermal.fans[0].status.state)
self.assertEqual('ok', self.thermal.fans[0].status.health)
self.assertEqual(6000, self.thermal.fans[0].reading)
self.assertEqual('RPM', self.thermal.fans[0].reading_units)
self.assertEqual(2000, self.thermal.fans[0].lower_threshold_fatal)
self.assertEqual(0, self.thermal.fans[0].min_reading_range)
self.assertEqual(10000, self.thermal.fans[0].max_reading_range)
self.assertEqual('0', self.thermal.temperatures[0].identity)
self.assertEqual('CPU Temp', self.thermal.temperatures[0].name)
self.assertEqual('enabled', self.thermal.temperatures[0].status.state)
self.assertEqual('ok', self.thermal.temperatures[0].status.health)
self.assertEqual(62, self.thermal.temperatures[0].reading_celsius)
self.assertEqual(
75,
self.thermal.temperatures[0].upper_threshold_non_critical
)
self.assertEqual(
90,
self.thermal.temperatures[0].upper_threshold_critical
)
self.assertEqual(
95,
self.thermal.temperatures[0].upper_threshold_fatal
)
self.assertEqual(0,
self.thermal.temperatures[0].min_reading_range_temp)
self.assertEqual(120,
self.thermal.temperatures[0].max_reading_range_temp)
self.assertEqual('CPU', self.thermal.temperatures[0].physical_context)