From 46f3b1c02c4fefb30e00b3ddbc01ca4ca280178e Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Sat, 11 Jun 2022 21:35:10 -0700 Subject: [PATCH 1/7] fix using linter. --- .../@treo/services/config/config.service.ts | 14 +- .../src/app/core/config/app.config.ts | 14 +- .../src/app/data/mock/device/details/sda.ts | 450 +-- .../src/app/data/mock/device/details/sdb.ts | 3516 ++++++++--------- .../src/app/data/mock/device/details/sdc.ts | 3100 +++++++-------- .../src/app/data/mock/device/details/sdd.ts | 378 +- .../src/app/data/mock/device/details/sde.ts | 378 +- .../src/app/data/mock/device/details/sdf.ts | 50 +- .../src/app/data/mock/summary/data.ts | 924 ++--- ...ashboard-device-delete-dialog.component.ts | 4 +- .../dashboard-device-delete-dialog.module.ts | 24 +- .../dashboard-device.component.ts | 42 +- .../dashboard-device.module.ts | 28 +- .../dashboard-settings.component.ts | 4 +- .../dashboard-settings.module.ts | 12 +- .../detail-settings/detail-settings.module.ts | 12 +- .../src/app/layout/layout.component.ts | 2 +- .../modules/dashboard/dashboard.component.ts | 62 +- .../app/modules/dashboard/dashboard.module.ts | 4 +- .../modules/dashboard/dashboard.routing.ts | 2 +- .../modules/dashboard/dashboard.service.ts | 4 +- .../app/modules/detail/detail.component.ts | 119 +- .../src/app/modules/detail/detail.module.ts | 2 +- .../src/app/modules/detail/detail.routing.ts | 2 +- .../src/app/shared/device-sort.pipe.ts | 18 +- .../src/app/shared/temperature.pipe.ts | 2 +- 26 files changed, 4583 insertions(+), 4584 deletions(-) diff --git a/webapp/frontend/src/@treo/services/config/config.service.ts b/webapp/frontend/src/@treo/services/config/config.service.ts index d526e66..563fc85 100644 --- a/webapp/frontend/src/@treo/services/config/config.service.ts +++ b/webapp/frontend/src/@treo/services/config/config.service.ts @@ -21,10 +21,10 @@ export class TreoConfigService { let currentScrutinyConfig = defaultConfig - let localConfigStr = localStorage.getItem(SCRUTINY_CONFIG_LOCAL_STORAGE_KEY) + const localConfigStr = localStorage.getItem(SCRUTINY_CONFIG_LOCAL_STORAGE_KEY) if (localConfigStr){ - //check localstorage for a value - let localConfig = JSON.parse(localConfigStr) + // check localstorage for a value + const localConfig = JSON.parse(localConfigStr) currentScrutinyConfig = Object.assign({}, currentScrutinyConfig, localConfig) // make sure defaults are available if missing from localStorage. } // Set the private defaults @@ -38,20 +38,20 @@ export class TreoConfigService /** * Setter and getter for config */ - //Setter + // Setter set config(value: any) { // Merge the new config over to the current config - let config = _.merge({}, this._config.getValue(), value); + const config = _.merge({}, this._config.getValue(), value); - //Store the config in localstorage + // Store the config in localstorage localStorage.setItem(SCRUTINY_CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config)); // Execute the observable this._config.next(config); } - //Getter + // Getter get config$(): Observable { return this._config.asObservable(); diff --git a/webapp/frontend/src/app/core/config/app.config.ts b/webapp/frontend/src/app/core/config/app.config.ts index ba39423..e98a6c8 100644 --- a/webapp/frontend/src/app/core/config/app.config.ts +++ b/webapp/frontend/src/app/core/config/app.config.ts @@ -1,7 +1,7 @@ -import { Layout } from "app/layout/layout.types"; +import { Layout } from 'app/layout/layout.types'; // Theme type -export type Theme = "light" | "dark" | "system"; +export type Theme = 'light' | 'dark' | 'system'; /** * AppConfig interface. Update this interface to strictly type your config @@ -28,12 +28,12 @@ export interface AppConfig * "ConfigService". */ export const appConfig: AppConfig = { - theme : "light", - layout: "material", + theme : 'light', + layout: 'material', - dashboardDisplay: "name", - dashboardSort: "status", + dashboardDisplay: 'name', + dashboardSort: 'status', - temperatureUnit: "celsius", + temperatureUnit: 'celsius', }; diff --git a/webapp/frontend/src/app/data/mock/device/details/sda.ts b/webapp/frontend/src/app/data/mock/device/details/sda.ts index 16b2d97..6406e5a 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sda.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sda.ts @@ -1,264 +1,264 @@ export const sda = { - "data": { - "device": { - "CreatedAt": "2021-06-24T21:17:31.301226-07:00", - "UpdatedAt": "2021-10-24T16:37:56.981833-07:00", - "DeletedAt": null, - "wwn": "0x5002538e40a22954", - "device_name": "sda", - "manufacturer": "ATA", - "model_name": "Samsung_SSD_860_EVO_500GB", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "S3YZNB0KBXXXXXX", - "firmware": "002C", - "rotational_speed": 0, - "capacity": 500107862016, - "form_factor": "", - "smart_support": false, - "device_protocol": "NVMe", - "device_type": "", - "label": "", - "host_id": "", - "device_status": 0 + 'data': { + 'device': { + 'CreatedAt': '2021-06-24T21:17:31.301226-07:00', + 'UpdatedAt': '2021-10-24T16:37:56.981833-07:00', + 'DeletedAt': null, + 'wwn': '0x5002538e40a22954', + 'device_name': 'sda', + 'manufacturer': 'ATA', + 'model_name': 'Samsung_SSD_860_EVO_500GB', + 'interface_type': 'SCSI', + 'interface_speed': '', + 'serial_number': 'S3YZNB0KBXXXXXX', + 'firmware': '002C', + 'rotational_speed': 0, + 'capacity': 500107862016, + 'form_factor': '', + 'smart_support': false, + 'device_protocol': 'NVMe', + 'device_type': '', + 'label': '', + 'host_id': '', + 'device_status': 0 }, - "smart_results": [{ - "date": "2021-10-24T23:20:44Z", - "device_wwn": "0x5002538e40a22954", - "device_protocol": "NVMe", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "attrs": { - "available_spare": { - "attribute_id": "available_spare", - "value": 100, - "thresh": 10, - "transformed_value": 0, - "status": 0 + 'smart_results': [{ + 'date': '2021-10-24T23:20:44Z', + 'device_wwn': '0x5002538e40a22954', + 'device_protocol': 'NVMe', + 'temp': 36, + 'power_on_hours': 2401, + 'power_cycle_count': 266, + 'attrs': { + 'available_spare': { + 'attribute_id': 'available_spare', + 'value': 100, + 'thresh': 10, + 'transformed_value': 0, + 'status': 0 }, - "controller_busy_time": { - "attribute_id": "controller_busy_time", - "value": 3060, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'controller_busy_time': { + 'attribute_id': 'controller_busy_time', + 'value': 3060, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "critical_comp_time": { - "attribute_id": "critical_comp_time", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'critical_comp_time': { + 'attribute_id': 'critical_comp_time', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "critical_warning": { - "attribute_id": "critical_warning", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": 0 + 'critical_warning': { + 'attribute_id': 'critical_warning', + 'value': 0, + 'thresh': 0, + 'transformed_value': 0, + 'status': 0 }, - "data_units_read": { - "attribute_id": "data_units_read", - "value": 9511859, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'data_units_read': { + 'attribute_id': 'data_units_read', + 'value': 9511859, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "data_units_written": { - "attribute_id": "data_units_written", - "value": 7773431, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'data_units_written': { + 'attribute_id': 'data_units_written', + 'value': 7773431, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "host_reads": { - "attribute_id": "host_reads", - "value": 111303174, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'host_reads': { + 'attribute_id': 'host_reads', + 'value': 111303174, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "host_writes": { - "attribute_id": "host_writes", - "value": 83170961, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'host_writes': { + 'attribute_id': 'host_writes', + 'value': 83170961, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "media_errors": { - "attribute_id": "media_errors", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": 0 + 'media_errors': { + 'attribute_id': 'media_errors', + 'value': 0, + 'thresh': 0, + 'transformed_value': 0, + 'status': 0 }, - "num_err_log_entries": { - "attribute_id": "num_err_log_entries", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": 0 + 'num_err_log_entries': { + 'attribute_id': 'num_err_log_entries', + 'value': 0, + 'thresh': 0, + 'transformed_value': 0, + 'status': 0 }, - "percentage_used": { - "attribute_id": "percentage_used", - "value": 0, - "thresh": 100, - "transformed_value": 0, - "status": 0 + 'percentage_used': { + 'attribute_id': 'percentage_used', + 'value': 0, + 'thresh': 100, + 'transformed_value': 0, + 'status': 0 }, - "power_cycles": { - "attribute_id": "power_cycles", - "value": 266, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'power_cycles': { + 'attribute_id': 'power_cycles', + 'value': 266, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "power_on_hours": { - "attribute_id": "power_on_hours", - "value": 2401, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'power_on_hours': { + 'attribute_id': 'power_on_hours', + 'value': 2401, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "temperature": { - "attribute_id": "temperature", - "value": 36, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'temperature': { + 'attribute_id': 'temperature', + 'value': 36, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "unsafe_shutdowns": { - "attribute_id": "unsafe_shutdowns", - "value": 43, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'unsafe_shutdowns': { + 'attribute_id': 'unsafe_shutdowns', + 'value': 43, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "warning_temp_time": { - "attribute_id": "warning_temp_time", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'warning_temp_time': { + 'attribute_id': 'warning_temp_time', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 } }, - "Status": 0 + 'Status': 0 }] }, - "metadata": { - "available_spare": { - "display_name": "Available Spare", - "ideal": "high", - "critical": true, - "description": "Contains a normalized percentage (0 to 100%) of the remaining spare capacity available.", - "display_type": "" + 'metadata': { + 'available_spare': { + 'display_name': 'Available Spare', + 'ideal': 'high', + 'critical': true, + 'description': 'Contains a normalized percentage (0 to 100%) of the remaining spare capacity available.', + 'display_type': '' }, - "controller_busy_time": { - "display_name": "Controller Busy Time", - "ideal": "", - "critical": false, - "description": "Contains the amount of time the controller is busy with I/O commands. The controller is busy when there is a command outstanding to an I/O Queue (specifically, a command was issued via an I/O Submission Queue Tail doorbell write and the corresponding completion queue entry has not been posted yet to the associated I/O Completion Queue). This value is reported in minutes.", - "display_type": "" + 'controller_busy_time': { + 'display_name': 'Controller Busy Time', + 'ideal': '', + 'critical': false, + 'description': 'Contains the amount of time the controller is busy with I/O commands. The controller is busy when there is a command outstanding to an I/O Queue (specifically, a command was issued via an I/O Submission Queue Tail doorbell write and the corresponding completion queue entry has not been posted yet to the associated I/O Completion Queue). This value is reported in minutes.', + 'display_type': '' }, - "critical_comp_time": { - "display_name": "Critical CompTime", - "ideal": "", - "critical": false, - "description": "Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater the Critical Composite Temperature Threshold (CCTEMP) field in the Identify Controller data structure.", - "display_type": "" + 'critical_comp_time': { + 'display_name': 'Critical CompTime', + 'ideal': '', + 'critical': false, + 'description': 'Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater the Critical Composite Temperature Threshold (CCTEMP) field in the Identify Controller data structure.', + 'display_type': '' }, - "critical_warning": { - "display_name": "Critical Warning", - "ideal": "low", - "critical": true, - "description": "This field indicates critical warnings for the state of the controller. Each bit corresponds to a critical warning type; multiple bits may be set. If a bit is cleared to ‘0’, then that critical warning does not apply. Critical warnings may result in an asynchronous event notification to the host. Bits in this field represent the current associated state and are not persistent.", - "display_type": "" + 'critical_warning': { + 'display_name': 'Critical Warning', + 'ideal': 'low', + 'critical': true, + 'description': 'This field indicates critical warnings for the state of the controller. Each bit corresponds to a critical warning type; multiple bits may be set. If a bit is cleared to ‘0’, then that critical warning does not apply. Critical warnings may result in an asynchronous event notification to the host. Bits in this field represent the current associated state and are not persistent.', + 'display_type': '' }, - "data_units_read": { - "display_name": "Data Units Read", - "ideal": "", - "critical": false, - "description": "Contains the number of 512 byte data units the host has read from the controller; this value does not include metadata. This value is reported in thousands (i.e., a value of 1 corresponds to 1000 units of 512 bytes read) and is rounded up. When the LBA size is a value other than 512 bytes, the controller shall convert the amount of data read to 512 byte units.", - "display_type": "" + 'data_units_read': { + 'display_name': 'Data Units Read', + 'ideal': '', + 'critical': false, + 'description': 'Contains the number of 512 byte data units the host has read from the controller; this value does not include metadata. This value is reported in thousands (i.e., a value of 1 corresponds to 1000 units of 512 bytes read) and is rounded up. When the LBA size is a value other than 512 bytes, the controller shall convert the amount of data read to 512 byte units.', + 'display_type': '' }, - "data_units_written": { - "display_name": "Data Units Written", - "ideal": "", - "critical": false, - "description": "Contains the number of 512 byte data units the host has written to the controller; this value does not include metadata. This value is reported in thousands (i.e., a value of 1 corresponds to 1000 units of 512 bytes written) and is rounded up. When the LBA size is a value other than 512 bytes, the controller shall convert the amount of data written to 512 byte units.", - "display_type": "" + 'data_units_written': { + 'display_name': 'Data Units Written', + 'ideal': '', + 'critical': false, + 'description': 'Contains the number of 512 byte data units the host has written to the controller; this value does not include metadata. This value is reported in thousands (i.e., a value of 1 corresponds to 1000 units of 512 bytes written) and is rounded up. When the LBA size is a value other than 512 bytes, the controller shall convert the amount of data written to 512 byte units.', + 'display_type': '' }, - "host_reads": { - "display_name": "Host Reads", - "ideal": "", - "critical": false, - "description": "Contains the number of read commands completed by the controller", - "display_type": "" + 'host_reads': { + 'display_name': 'Host Reads', + 'ideal': '', + 'critical': false, + 'description': 'Contains the number of read commands completed by the controller', + 'display_type': '' }, - "host_writes": { - "display_name": "Host Writes", - "ideal": "", - "critical": false, - "description": "Contains the number of write commands completed by the controller", - "display_type": "" + 'host_writes': { + 'display_name': 'Host Writes', + 'ideal': '', + 'critical': false, + 'description': 'Contains the number of write commands completed by the controller', + 'display_type': '' }, - "media_errors": { - "display_name": "Media Errors", - "ideal": "low", - "critical": true, - "description": "Contains the number of occurrences where the controller detected an unrecovered data integrity error. Errors such as uncorrectable ECC, CRC checksum failure, or LBA tag mismatch are included in this field.", - "display_type": "" + 'media_errors': { + 'display_name': 'Media Errors', + 'ideal': 'low', + 'critical': true, + 'description': 'Contains the number of occurrences where the controller detected an unrecovered data integrity error. Errors such as uncorrectable ECC, CRC checksum failure, or LBA tag mismatch are included in this field.', + 'display_type': '' }, - "num_err_log_entries": { - "display_name": "Numb Err Log Entries", - "ideal": "low", - "critical": true, - "description": "Contains the number of Error Information log entries over the life of the controller.", - "display_type": "" + 'num_err_log_entries': { + 'display_name': 'Numb Err Log Entries', + 'ideal': 'low', + 'critical': true, + 'description': 'Contains the number of Error Information log entries over the life of the controller.', + 'display_type': '' }, - "percentage_used": { - "display_name": "Percentage Used", - "ideal": "low", - "critical": true, - "description": "Contains a vendor specific estimate of the percentage of NVM subsystem life used based on the actual usage and the manufacturer’s prediction of NVM life. A value of 100 indicates that the estimated endurance of the NVM in the NVM subsystem has been consumed, but may not indicate an NVM subsystem failure. The value is allowed to exceed 100. Percentages greater than 254 shall be represented as 255. This value shall be updated once per power-on hour (when the controller is not in a sleep state).", - "display_type": "" + 'percentage_used': { + 'display_name': 'Percentage Used', + 'ideal': 'low', + 'critical': true, + 'description': 'Contains a vendor specific estimate of the percentage of NVM subsystem life used based on the actual usage and the manufacturer’s prediction of NVM life. A value of 100 indicates that the estimated endurance of the NVM in the NVM subsystem has been consumed, but may not indicate an NVM subsystem failure. The value is allowed to exceed 100. Percentages greater than 254 shall be represented as 255. This value shall be updated once per power-on hour (when the controller is not in a sleep state).', + 'display_type': '' }, - "power_cycles": { - "display_name": "Power Cycles", - "ideal": "", - "critical": false, - "description": "Contains the number of power cycles.", - "display_type": "" + 'power_cycles': { + 'display_name': 'Power Cycles', + 'ideal': '', + 'critical': false, + 'description': 'Contains the number of power cycles.', + 'display_type': '' }, - "power_on_hours": { - "display_name": "Power on Hours", - "ideal": "", - "critical": false, - "description": "Contains the number of power-on hours. Power on hours is always logging, even when in low power mode.", - "display_type": "" + 'power_on_hours': { + 'display_name': 'Power on Hours', + 'ideal': '', + 'critical': false, + 'description': 'Contains the number of power-on hours. Power on hours is always logging, even when in low power mode.', + 'display_type': '' }, - "temperature": { - "display_name": "Temperature", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'temperature': { + 'display_name': 'Temperature', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "unsafe_shutdowns": { - "display_name": "Unsafe Shutdowns", - "ideal": "", - "critical": false, - "description": "Contains the number of unsafe shutdowns. This count is incremented when a shutdown notification (CC.SHN) is not received prior to loss of power.", - "display_type": "" + 'unsafe_shutdowns': { + 'display_name': 'Unsafe Shutdowns', + 'ideal': '', + 'critical': false, + 'description': 'Contains the number of unsafe shutdowns. This count is incremented when a shutdown notification (CC.SHN) is not received prior to loss of power.', + 'display_type': '' }, - "warning_temp_time": { - "display_name": "Warning Temp Time", - "ideal": "", - "critical": false, - "description": "Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater than or equal to the Warning Composite Temperature Threshold (WCTEMP) field and less than the Critical Composite Temperature Threshold (CCTEMP) field in the Identify Controller data structure.", - "display_type": "" + 'warning_temp_time': { + 'display_name': 'Warning Temp Time', + 'ideal': '', + 'critical': false, + 'description': 'Contains the amount of time in minutes that the controller is operational and the Composite Temperature is greater than or equal to the Warning Composite Temperature Threshold (WCTEMP) field and less than the Critical Composite Temperature Threshold (CCTEMP) field in the Identify Controller data structure.', + 'display_type': '' } }, - "success": true + 'success': true } diff --git a/webapp/frontend/src/app/data/mock/device/details/sdb.ts b/webapp/frontend/src/app/data/mock/device/details/sdb.ts index 5e817bd..232fee5 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sdb.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sdb.ts @@ -1,1822 +1,1822 @@ export const sdb = { - "data": { - "device": { - "CreatedAt": "2021-06-24T21:17:31.302191-07:00", - "UpdatedAt": "2021-10-24T17:06:39.436996-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264eb01d7", - "device_name": "sdb", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "9RK1XXXXX", - "firmware": "81.00A81", - "rotational_speed": 0, - "capacity": 14000519643136, - "form_factor": "", - "smart_support": false, - "device_protocol": "ATA", - "device_type": "", - "label": "", - "host_id": "", - "device_status": 2 - }, - "smart_results": [{ - "date": "2021-10-24T20:34:04Z", - "device_wwn": "0x5000cca264eb01d7", - "device_protocol": "ATA", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "attrs": { - "1": { - "attribute_id": 1, - "value": 100, - "thresh": 1, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.034155719633986996 + 'data': { + 'device': { + 'CreatedAt': '2021-06-24T21:17:31.302191-07:00', + 'UpdatedAt': '2021-10-24T17:06:39.436996-07:00', + 'DeletedAt': null, + 'wwn': '0x5000cca264eb01d7', + 'device_name': 'sdb', + 'manufacturer': 'ATA', + 'model_name': 'WDC_WD140EDFZ-11A0VA0', + 'interface_type': 'SCSI', + 'interface_speed': '', + 'serial_number': '9RK1XXXXX', + 'firmware': '81.00A81', + 'rotational_speed': 0, + 'capacity': 14000519643136, + 'form_factor': '', + 'smart_support': false, + 'device_protocol': 'ATA', + 'device_type': '', + 'label': '', + 'host_id': '', + 'device_status': 2 + }, + 'smart_results': [{ + 'date': '2021-10-24T20:34:04Z', + 'device_wwn': '0x5000cca264eb01d7', + 'device_protocol': 'ATA', + 'temp': 32, + 'power_on_hours': 1730, + 'power_cycle_count': 9, + 'attrs': { + '1': { + 'attribute_id': 1, + 'value': 100, + 'thresh': 1, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.034155719633986996 }, - "10": { - "attribute_id": 10, - "value": 100, - "thresh": 1, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.05459827163896099 + '10': { + 'attribute_id': 10, + 'value': 100, + 'thresh': 1, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.05459827163896099 }, - "12": { - "attribute_id": 12, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.019835987118930823 + '12': { + 'attribute_id': 12, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 9, + 'raw_string': '9', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.019835987118930823 }, - "192": { - "attribute_id": 192, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.01634692899031039 + '192': { + 'attribute_id': 192, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 329, + 'raw_string': '329', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.01634692899031039 }, - "193": { - "attribute_id": 193, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '193': { + 'attribute_id': 193, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 329, + 'raw_string': '329', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "194": { - "attribute_id": 194, - "value": 51, - "thresh": 0, - "worst": 51, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32, - "status": 0 + '194': { + 'attribute_id': 194, + 'value': 51, + 'thresh': 0, + 'worst': 51, + 'raw_value': 163210330144, + 'raw_string': '32 (Min/Max 24/38)', + 'when_failed': '', + 'transformed_value': 32, + 'status': 0 }, - "196": { - "attribute_id": 196, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.007389855800729792 + '196': { + 'attribute_id': 196, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.007389855800729792 }, - "197": { - "attribute_id": 197, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.025540791394761345 + '197': { + 'attribute_id': 197, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.025540791394761345 }, - "198": { - "attribute_id": 198, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.028675322159886437 + '198': { + 'attribute_id': 198, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.028675322159886437 }, - "199": { - "attribute_id": 199, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '199': { + 'attribute_id': 199, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "2": { - "attribute_id": 2, - "value": 135, - "thresh": 54, - "worst": 135, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '2': { + 'attribute_id': 2, + 'value': 135, + 'thresh': 54, + 'worst': 135, + 'raw_value': 108, + 'raw_string': '108', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "22": { - "attribute_id": 22, - "value": 100, - "thresh": 25, - "worst": 100, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '22': { + 'attribute_id': 22, + 'value': 100, + 'thresh': 25, + 'worst': 100, + 'raw_value': 100, + 'raw_string': '100', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "3": { - "attribute_id": 3, - "value": 81, - "thresh": 1, - "worst": 81, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0, - "status": 2, - "status_reason": "Observed Failure Rate for Attribute is greater than 10%", - "failure_rate": 0.11452195377351217 + '3': { + 'attribute_id': 3, + 'value': 81, + 'thresh': 1, + 'worst': 81, + 'raw_value': 30089675132, + 'raw_string': '380 (Average 380)', + 'when_failed': '', + 'transformed_value': 0, + 'status': 2, + 'status_reason': 'Observed Failure Rate for Attribute is greater than 10%', + 'failure_rate': 0.11452195377351217 }, - "4": { - "attribute_id": 4, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.01989335424860646 + '4': { + 'attribute_id': 4, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 9, + 'raw_string': '9', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.01989335424860646 }, - "5": { - "attribute_id": 5, - "value": 100, - "thresh": 1, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.025169175350572493 + '5': { + 'attribute_id': 5, + 'value': 100, + 'thresh': 1, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.025169175350572493 }, - "7": { - "attribute_id": 7, - "value": 100, - "thresh": 1, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.01087335627722523 + '7': { + 'attribute_id': 7, + 'value': 100, + 'thresh': 1, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.01087335627722523 }, - "8": { - "attribute_id": 8, - "value": 133, - "thresh": 20, - "worst": 133, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '8': { + 'attribute_id': 8, + 'value': 133, + 'thresh': 20, + 'worst': 133, + 'raw_value': 18, + 'raw_string': '18', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "9": { - "attribute_id": 9, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '9': { + 'attribute_id': 9, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 1730, + 'raw_string': '1730', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 } }, - "Status": 0 + 'Status': 0 }, { - "date": "2021-10-24T23:20:44Z", - "device_wwn": "0x5000cca264eb01d7", - "device_protocol": "ATA", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "attrs": { - "1": { - "attribute_id": 1, - "value": 100, - "thresh": 1, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.034155719633986996 + 'date': '2021-10-24T23:20:44Z', + 'device_wwn': '0x5000cca264eb01d7', + 'device_protocol': 'ATA', + 'temp': 32, + 'power_on_hours': 1730, + 'power_cycle_count': 9, + 'attrs': { + '1': { + 'attribute_id': 1, + 'value': 100, + 'thresh': 1, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.034155719633986996 }, - "10": { - "attribute_id": 10, - "value": 100, - "thresh": 1, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.05459827163896099 + '10': { + 'attribute_id': 10, + 'value': 100, + 'thresh': 1, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.05459827163896099 }, - "12": { - "attribute_id": 12, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.019835987118930823 + '12': { + 'attribute_id': 12, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 9, + 'raw_string': '9', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.019835987118930823 }, - "192": { - "attribute_id": 192, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.01634692899031039 + '192': { + 'attribute_id': 192, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 329, + 'raw_string': '329', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.01634692899031039 }, - "193": { - "attribute_id": 193, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '193': { + 'attribute_id': 193, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 329, + 'raw_string': '329', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "194": { - "attribute_id": 194, - "value": 51, - "thresh": 0, - "worst": 51, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32, - "status": 0 + '194': { + 'attribute_id': 194, + 'value': 51, + 'thresh': 0, + 'worst': 51, + 'raw_value': 163210330144, + 'raw_string': '32 (Min/Max 24/38)', + 'when_failed': '', + 'transformed_value': 32, + 'status': 0 }, - "196": { - "attribute_id": 196, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.007389855800729792 + '196': { + 'attribute_id': 196, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.007389855800729792 }, - "197": { - "attribute_id": 197, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.025540791394761345 + '197': { + 'attribute_id': 197, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.025540791394761345 }, - "198": { - "attribute_id": 198, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.028675322159886437 + '198': { + 'attribute_id': 198, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.028675322159886437 }, - "199": { - "attribute_id": 199, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '199': { + 'attribute_id': 199, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "2": { - "attribute_id": 2, - "value": 135, - "thresh": 54, - "worst": 135, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '2': { + 'attribute_id': 2, + 'value': 135, + 'thresh': 54, + 'worst': 135, + 'raw_value': 108, + 'raw_string': '108', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "22": { - "attribute_id": 22, - "value": 100, - "thresh": 25, - "worst": 100, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '22': { + 'attribute_id': 22, + 'value': 100, + 'thresh': 25, + 'worst': 100, + 'raw_value': 100, + 'raw_string': '100', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "3": { - "attribute_id": 3, - "value": 81, - "thresh": 1, - "worst": 81, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0, - "status": 2, - "status_reason": "Observed Failure Rate for Attribute is greater than 10%", - "failure_rate": 0.11452195377351217 + '3': { + 'attribute_id': 3, + 'value': 81, + 'thresh': 1, + 'worst': 81, + 'raw_value': 30089675132, + 'raw_string': '380 (Average 380)', + 'when_failed': '', + 'transformed_value': 0, + 'status': 2, + 'status_reason': 'Observed Failure Rate for Attribute is greater than 10%', + 'failure_rate': 0.11452195377351217 }, - "4": { - "attribute_id": 4, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.01989335424860646 + '4': { + 'attribute_id': 4, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 9, + 'raw_string': '9', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.01989335424860646 }, - "5": { - "attribute_id": 5, - "value": 100, - "thresh": 1, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.025169175350572493 + '5': { + 'attribute_id': 5, + 'value': 100, + 'thresh': 1, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.025169175350572493 }, - "7": { - "attribute_id": 7, - "value": 100, - "thresh": 1, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.01087335627722523 + '7': { + 'attribute_id': 7, + 'value': 100, + 'thresh': 1, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.01087335627722523 }, - "8": { - "attribute_id": 8, - "value": 133, - "thresh": 20, - "worst": 133, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '8': { + 'attribute_id': 8, + 'value': 133, + 'thresh': 20, + 'worst': 133, + 'raw_value': 18, + 'raw_string': '18', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "9": { - "attribute_id": 9, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '9': { + 'attribute_id': 9, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 1730, + 'raw_string': '1730', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 } }, - "Status": 0 + 'Status': 0 }] }, - "metadata": { - "1": { - "display_name": "Read Error Rate", - "ideal": "low", - "critical": false, - "description": "(Vendor specific raw value.) Stores data related to the rate of hardware read errors that occurred when reading data from a disk surface. The raw value has different structure for different vendors and is often not meaningful as a decimal number.", - "observed_thresholds": [{ - "low": 80, - "high": 95, - "annual_failure_rate": 0.8879749768303985, - "error_interval": [0.682344353388663, 1.136105732920724] - }, { - "low": 95, - "high": 110, - "annual_failure_rate": 0.034155719633986996, - "error_interval": [0.030188482024981093, 0.038499386872354435] - }, { - "low": 110, - "high": 125, - "annual_failure_rate": 0.06390002135229157, - "error_interval": [0.05852004676110847, 0.06964160930553712] - }, { - "low": 125, - "high": 140, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 140, - "high": 155, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 155, - "high": 170, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 170, - "high": 185, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 185, - "high": 200, - "annual_failure_rate": 0.044823775021490854, - "error_interval": [0.032022762038723306, 0.06103725943096589] + 'metadata': { + '1': { + 'display_name': 'Read Error Rate', + 'ideal': 'low', + 'critical': false, + 'description': '(Vendor specific raw value.) Stores data related to the rate of hardware read errors that occurred when reading data from a disk surface. The raw value has different structure for different vendors and is often not meaningful as a decimal number.', + 'observed_thresholds': [{ + 'low': 80, + 'high': 95, + 'annual_failure_rate': 0.8879749768303985, + 'error_interval': [0.682344353388663, 1.136105732920724] + }, { + 'low': 95, + 'high': 110, + 'annual_failure_rate': 0.034155719633986996, + 'error_interval': [0.030188482024981093, 0.038499386872354435] + }, { + 'low': 110, + 'high': 125, + 'annual_failure_rate': 0.06390002135229157, + 'error_interval': [0.05852004676110847, 0.06964160930553712] + }, { + 'low': 125, + 'high': 140, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 140, + 'high': 155, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 155, + 'high': 170, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 170, + 'high': 185, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 185, + 'high': 200, + 'annual_failure_rate': 0.044823775021490854, + 'error_interval': [0.032022762038723306, 0.06103725943096589] }], - "display_type": "normalized" - }, - "10": { - "display_name": "Spin Retry Count", - "ideal": "low", - "critical": true, - "description": "Count of retry of spin start attempts. This attribute stores a total count of the spin start attempts to reach the fully operational speed (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.05459827163896099, - "error_interval": [0.05113785787727033, 0.05823122757702782] - }, { - "low": 0, - "high": 80, - "annual_failure_rate": 0.5555555555555556, - "error_interval": [0.014065448880161053, 3.095357439410498] + 'display_type': 'normalized' + }, + '10': { + 'display_name': 'Spin Retry Count', + 'ideal': 'low', + 'critical': true, + 'description': 'Count of retry of spin start attempts. This attribute stores a total count of the spin start attempts to reach the fully operational speed (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.05459827163896099, + 'error_interval': [0.05113785787727033, 0.05823122757702782] + }, { + 'low': 0, + 'high': 80, + 'annual_failure_rate': 0.5555555555555556, + 'error_interval': [0.014065448880161053, 3.095357439410498] }], - "display_type": "raw" - }, - "11": { - "display_name": "Recalibration Retries or Calibration Retry Count", - "ideal": "low", - "critical": false, - "description": "This attribute indicates the count that recalibration was requested (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.04658866433672694, - "error_interval": [0.03357701137320878, 0.06297433993055492] - }, { - "low": 0, - "high": 80, - "annual_failure_rate": 0.5555555555555556, - "error_interval": [0.014065448880161053, 3.095357439410498] - }, { - "low": 80, - "high": 160, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 160, - "high": 240, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 240, - "high": 320, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 320, - "high": 400, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 400, - "high": 480, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 480, - "high": 560, - "annual_failure_rate": 0, - "error_interval": [0, 0] + 'display_type': 'raw' + }, + '11': { + 'display_name': 'Recalibration Retries or Calibration Retry Count', + 'ideal': 'low', + 'critical': false, + 'description': 'This attribute indicates the count that recalibration was requested (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.04658866433672694, + 'error_interval': [0.03357701137320878, 0.06297433993055492] + }, { + 'low': 0, + 'high': 80, + 'annual_failure_rate': 0.5555555555555556, + 'error_interval': [0.014065448880161053, 3.095357439410498] + }, { + 'low': 80, + 'high': 160, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 160, + 'high': 240, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 240, + 'high': 320, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 320, + 'high': 400, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 400, + 'high': 480, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 480, + 'high': 560, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] }], - "display_type": "raw" - }, - "12": { - "display_name": "Power Cycle Count", - "ideal": "low", - "critical": false, - "description": "This attribute indicates the count of full hard disk power on/off cycles.", - "observed_thresholds": [{ - "low": 0, - "high": 13, - "annual_failure_rate": 0.019835987118930823, - "error_interval": [0.016560870164523494, 0.023569242386797896] - }, { - "low": 13, - "high": 26, - "annual_failure_rate": 0.038210930067894826, - "error_interval": [0.03353859179329295, 0.0433520775718649] - }, { - "low": 26, - "high": 39, - "annual_failure_rate": 0.11053528307302571, - "error_interval": [0.09671061589521368, 0.1257816678419765] - }, { - "low": 39, - "high": 52, - "annual_failure_rate": 0.16831189443375036, - "error_interval": [0.1440976510675928, 0.19543066007594895] - }, { - "low": 52, - "high": 65, - "annual_failure_rate": 0.20630344262550107, - "error_interval": [0.1693965932069108, 0.2488633537247856] - }, { - "low": 65, - "high": 78, - "annual_failure_rate": 0.1030972634140512, - "error_interval": [0.06734655535304743, 0.15106137807407605] - }, { - "low": 78, - "high": 91, - "annual_failure_rate": 0.12354840389522469, - "error_interval": [0.06578432170016109, 0.21127153335749593] + 'display_type': 'raw' + }, + '12': { + 'display_name': 'Power Cycle Count', + 'ideal': 'low', + 'critical': false, + 'description': 'This attribute indicates the count of full hard disk power on/off cycles.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 13, + 'annual_failure_rate': 0.019835987118930823, + 'error_interval': [0.016560870164523494, 0.023569242386797896] + }, { + 'low': 13, + 'high': 26, + 'annual_failure_rate': 0.038210930067894826, + 'error_interval': [0.03353859179329295, 0.0433520775718649] + }, { + 'low': 26, + 'high': 39, + 'annual_failure_rate': 0.11053528307302571, + 'error_interval': [0.09671061589521368, 0.1257816678419765] + }, { + 'low': 39, + 'high': 52, + 'annual_failure_rate': 0.16831189443375036, + 'error_interval': [0.1440976510675928, 0.19543066007594895] + }, { + 'low': 52, + 'high': 65, + 'annual_failure_rate': 0.20630344262550107, + 'error_interval': [0.1693965932069108, 0.2488633537247856] + }, { + 'low': 65, + 'high': 78, + 'annual_failure_rate': 0.1030972634140512, + 'error_interval': [0.06734655535304743, 0.15106137807407605] + }, { + 'low': 78, + 'high': 91, + 'annual_failure_rate': 0.12354840389522469, + 'error_interval': [0.06578432170016109, 0.21127153335749593] }], - "display_type": "raw" - }, - "13": { - "display_name": "Soft Read Error Rate", - "ideal": "low", - "critical": false, - "description": "Uncorrected read errors reported to the operating system.", - "display_type": "normalized" - }, - "170": { - "display_name": "Available Reserved Space", - "ideal": "", - "critical": false, - "description": "See attribute E8.", - "display_type": "normalized" - }, - "171": { - "display_name": "SSD Program Fail Count", - "ideal": "", - "critical": false, - "description": "(Kingston) The total number of flash program operation failures since the drive was deployed.[33] Identical to attribute 181.", - "display_type": "normalized" - }, - "172": { - "display_name": "SSD Erase Fail Count", - "ideal": "", - "critical": false, - "description": "(Kingston) Counts the number of flash erase failures. This attribute returns the total number of Flash erase operation failures since the drive was deployed. This attribute is identical to attribute 182.", - "display_type": "normalized" - }, - "173": { - "display_name": "SSD Wear Leveling Count", - "ideal": "", - "critical": false, - "description": "Counts the maximum worst erase count on any block.", - "display_type": "normalized" - }, - "174": { - "display_name": "Unexpected Power Loss Count", - "ideal": "", - "critical": false, - "description": "Also known as \"Power-off Retract Count\" per conventional HDD terminology. Raw value reports the number of unclean shutdowns, cumulative over the life of an SSD, where an \"unclean shutdown\" is the removal of power without STANDBY IMMEDIATE as the last command (regardless of PLI activity using capacitor power). Normalized value is always 100.", - "display_type": "" - }, - "175": { - "display_name": "Power Loss Protection Failure", - "ideal": "", - "critical": false, - "description": "Last test result as microseconds to discharge cap, saturated at its maximum value. Also logs minutes since last test and lifetime number of tests. Raw value contains the following data: Bytes 0-1: Last test result as microseconds to discharge cap, saturates at max value. Test result expected in range 25 \u003c= result \u003c= 5000000, lower indicates specific error code. Bytes 2-3: Minutes since last test, saturates at max value.Bytes 4-5: Lifetime number of tests, not incremented on power cycle, saturates at max value. Normalized value is set to one on test failure or 11 if the capacitor has been tested in an excessive temperature condition, otherwise 100.", - "display_type": "normalized" - }, - "176": { - "display_name": "Erase Fail Count", - "ideal": "", - "critical": false, - "description": "S.M.A.R.T. parameter indicates a number of flash erase command failures.", - "display_type": "normalized" - }, - "177": { - "display_name": "Wear Range Delta", - "ideal": "", - "critical": false, - "description": "Delta between most-worn and least-worn Flash blocks. It describes how good/bad the wearleveling of the SSD works on a more technical way. ", - "display_type": "normalized" - }, - "179": { - "display_name": "Used Reserved Block Count Total", - "ideal": "", - "critical": false, - "description": "Pre-Fail attribute used at least in Samsung devices.", - "display_type": "normalized" - }, - "180": { - "display_name": "Unused Reserved Block Count Total", - "ideal": "", - "critical": false, - "description": "\"Pre-Fail\" attribute used at least in HP devices. ", - "display_type": "normalized" - }, - "181": { - "display_name": "Program Fail Count Total", - "ideal": "", - "critical": false, - "description": "Total number of Flash program operation failures since the drive was deployed.", - "display_type": "normalized" - }, - "182": { - "display_name": "Erase Fail Count", - "ideal": "", - "critical": false, - "description": "\"Pre-Fail\" Attribute used at least in Samsung devices.", - "display_type": "normalized" - }, - "183": { - "display_name": "SATA Downshift Error Count or Runtime Bad Block", - "ideal": "low", - "critical": false, - "description": "Western Digital, Samsung or Seagate attribute: Either the number of downshifts of link speed (e.g. from 6Gbit/s to 3Gbit/s) or the total number of data blocks with detected, uncorrectable errors encountered during normal operation. Although degradation of this parameter can be an indicator of drive aging and/or potential electromechanical problems, it does not directly indicate imminent drive failure.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.09084549203210031, - "error_interval": [0.08344373475686712, 0.09872777224842152] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.05756065656498585, - "error_interval": [0.04657000847949464, 0.07036491775108872] - }, { - "low": 2, - "high": 4, - "annual_failure_rate": 0.6193088626208925, - "error_interval": [0.41784508895529787, 0.8841019099092139] - }, { - "low": 4, - "high": 8, - "annual_failure_rate": 0.5533447034299792, - "error_interval": [0.31628430884775033, 0.8985971312402635] - }, { - "low": 8, - "high": 16, - "annual_failure_rate": 0.3882388694727245, - "error_interval": [0.21225380267814295, 0.6513988534774338] - }, { - "low": 16, - "high": 35, - "annual_failure_rate": 0.37116708385481856, - "error_interval": [0.19763084005134446, 0.6347070173754686] - }, { - "low": 35, - "high": 70, - "annual_failure_rate": 0.2561146752205292, - "error_interval": [0.10297138269895259, 0.5276941165819332] - }, { - "low": 70, - "high": 130, - "annual_failure_rate": 0.40299684542586756, - "error_interval": [0.16202563309223209, 0.8303275247667772] - }, { - "low": 130, - "high": 260, - "annual_failure_rate": 0, - "error_interval": [0, 0] + 'display_type': 'raw' + }, + '13': { + 'display_name': 'Soft Read Error Rate', + 'ideal': 'low', + 'critical': false, + 'description': 'Uncorrected read errors reported to the operating system.', + 'display_type': 'normalized' + }, + '170': { + 'display_name': 'Available Reserved Space', + 'ideal': '', + 'critical': false, + 'description': 'See attribute E8.', + 'display_type': 'normalized' + }, + '171': { + 'display_name': 'SSD Program Fail Count', + 'ideal': '', + 'critical': false, + 'description': '(Kingston) The total number of flash program operation failures since the drive was deployed.[33] Identical to attribute 181.', + 'display_type': 'normalized' + }, + '172': { + 'display_name': 'SSD Erase Fail Count', + 'ideal': '', + 'critical': false, + 'description': '(Kingston) Counts the number of flash erase failures. This attribute returns the total number of Flash erase operation failures since the drive was deployed. This attribute is identical to attribute 182.', + 'display_type': 'normalized' + }, + '173': { + 'display_name': 'SSD Wear Leveling Count', + 'ideal': '', + 'critical': false, + 'description': 'Counts the maximum worst erase count on any block.', + 'display_type': 'normalized' + }, + '174': { + 'display_name': 'Unexpected Power Loss Count', + 'ideal': '', + 'critical': false, + 'description': 'Also known as "Power-off Retract Count" per conventional HDD terminology. Raw value reports the number of unclean shutdowns, cumulative over the life of an SSD, where an "unclean shutdown" is the removal of power without STANDBY IMMEDIATE as the last command (regardless of PLI activity using capacitor power). Normalized value is always 100.', + 'display_type': '' + }, + '175': { + 'display_name': 'Power Loss Protection Failure', + 'ideal': '', + 'critical': false, + 'description': 'Last test result as microseconds to discharge cap, saturated at its maximum value. Also logs minutes since last test and lifetime number of tests. Raw value contains the following data: Bytes 0-1: Last test result as microseconds to discharge cap, saturates at max value. Test result expected in range 25 \u003c= result \u003c= 5000000, lower indicates specific error code. Bytes 2-3: Minutes since last test, saturates at max value.Bytes 4-5: Lifetime number of tests, not incremented on power cycle, saturates at max value. Normalized value is set to one on test failure or 11 if the capacitor has been tested in an excessive temperature condition, otherwise 100.', + 'display_type': 'normalized' + }, + '176': { + 'display_name': 'Erase Fail Count', + 'ideal': '', + 'critical': false, + 'description': 'S.M.A.R.T. parameter indicates a number of flash erase command failures.', + 'display_type': 'normalized' + }, + '177': { + 'display_name': 'Wear Range Delta', + 'ideal': '', + 'critical': false, + 'description': 'Delta between most-worn and least-worn Flash blocks. It describes how good/bad the wearleveling of the SSD works on a more technical way. ', + 'display_type': 'normalized' + }, + '179': { + 'display_name': 'Used Reserved Block Count Total', + 'ideal': '', + 'critical': false, + 'description': 'Pre-Fail attribute used at least in Samsung devices.', + 'display_type': 'normalized' + }, + '180': { + 'display_name': 'Unused Reserved Block Count Total', + 'ideal': '', + 'critical': false, + 'description': '"Pre-Fail" attribute used at least in HP devices. ', + 'display_type': 'normalized' + }, + '181': { + 'display_name': 'Program Fail Count Total', + 'ideal': '', + 'critical': false, + 'description': 'Total number of Flash program operation failures since the drive was deployed.', + 'display_type': 'normalized' + }, + '182': { + 'display_name': 'Erase Fail Count', + 'ideal': '', + 'critical': false, + 'description': '"Pre-Fail" Attribute used at least in Samsung devices.', + 'display_type': 'normalized' + }, + '183': { + 'display_name': 'SATA Downshift Error Count or Runtime Bad Block', + 'ideal': 'low', + 'critical': false, + 'description': 'Western Digital, Samsung or Seagate attribute: Either the number of downshifts of link speed (e.g. from 6Gbit/s to 3Gbit/s) or the total number of data blocks with detected, uncorrectable errors encountered during normal operation. Although degradation of this parameter can be an indicator of drive aging and/or potential electromechanical problems, it does not directly indicate imminent drive failure.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.09084549203210031, + 'error_interval': [0.08344373475686712, 0.09872777224842152] + }, { + 'low': 1, + 'high': 2, + 'annual_failure_rate': 0.05756065656498585, + 'error_interval': [0.04657000847949464, 0.07036491775108872] + }, { + 'low': 2, + 'high': 4, + 'annual_failure_rate': 0.6193088626208925, + 'error_interval': [0.41784508895529787, 0.8841019099092139] + }, { + 'low': 4, + 'high': 8, + 'annual_failure_rate': 0.5533447034299792, + 'error_interval': [0.31628430884775033, 0.8985971312402635] + }, { + 'low': 8, + 'high': 16, + 'annual_failure_rate': 0.3882388694727245, + 'error_interval': [0.21225380267814295, 0.6513988534774338] + }, { + 'low': 16, + 'high': 35, + 'annual_failure_rate': 0.37116708385481856, + 'error_interval': [0.19763084005134446, 0.6347070173754686] + }, { + 'low': 35, + 'high': 70, + 'annual_failure_rate': 0.2561146752205292, + 'error_interval': [0.10297138269895259, 0.5276941165819332] + }, { + 'low': 70, + 'high': 130, + 'annual_failure_rate': 0.40299684542586756, + 'error_interval': [0.16202563309223209, 0.8303275247667772] + }, { + 'low': 130, + 'high': 260, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] }], - "display_type": "raw" - }, - "184": { - "display_name": "End-to-End error", - "ideal": "low", - "critical": true, - "description": "This attribute is a part of Hewlett-Packard\"s SMART IV technology, as well as part of other vendors\" IO Error Detection and Correction schemas, and it contains a count of parity errors which occur in the data path to the media via the drive\"s cache RAM", - "observed_thresholds": [{ - "low": 93, - "high": 94, - "annual_failure_rate": 1.631212012870933, - "error_interval": [1.055634407303844, 2.407990716767714] - }, { - "low": 94, - "high": 95, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 95, - "high": 96, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 96, - "high": 97, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 97, - "high": 97, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 97, - "high": 98, - "annual_failure_rate": 1.8069306930693072, - "error_interval": [0.04574752432804858, 10.067573453924245] - }, { - "low": 98, - "high": 99, - "annual_failure_rate": 0.8371559633027523, - "error_interval": [0.10138347095016888, 3.0240951820174824] - }, { - "low": 99, - "high": 100, - "annual_failure_rate": 0.09334816849865138, - "error_interval": [0.08689499010435861, 0.10015372448181788] + 'display_type': 'raw' + }, + '184': { + 'display_name': 'End-to-End error', + 'ideal': 'low', + 'critical': true, + 'description': 'This attribute is a part of Hewlett-Packard"s SMART IV technology, as well as part of other vendors" IO Error Detection and Correction schemas, and it contains a count of parity errors which occur in the data path to the media via the drive"s cache RAM', + 'observed_thresholds': [{ + 'low': 93, + 'high': 94, + 'annual_failure_rate': 1.631212012870933, + 'error_interval': [1.055634407303844, 2.407990716767714] + }, { + 'low': 94, + 'high': 95, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 95, + 'high': 96, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 96, + 'high': 97, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 97, + 'high': 97, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 97, + 'high': 98, + 'annual_failure_rate': 1.8069306930693072, + 'error_interval': [0.04574752432804858, 10.067573453924245] + }, { + 'low': 98, + 'high': 99, + 'annual_failure_rate': 0.8371559633027523, + 'error_interval': [0.10138347095016888, 3.0240951820174824] + }, { + 'low': 99, + 'high': 100, + 'annual_failure_rate': 0.09334816849865138, + 'error_interval': [0.08689499010435861, 0.10015372448181788] }], - "display_type": "normalized" - }, - "185": { - "display_name": "Head Stability", - "ideal": "", - "critical": false, - "description": "Western Digital attribute.", - "display_type": "normalized" - }, - "186": { - "display_name": "Induced Op-Vibration Detection", - "ideal": "", - "critical": false, - "description": "Western Digital attribute.", - "display_type": "normalized" - }, - "187": { - "display_name": "Reported Uncorrectable Errors", - "ideal": "low", - "critical": true, - "description": "The count of errors that could not be recovered using hardware ECC (see attribute 195).", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.028130798308190524, - "error_interval": [0.024487830609364304, 0.032162944988161336] - }, { - "low": 1, - "high": 1, - "annual_failure_rate": 0.33877621175661743, - "error_interval": [0.22325565823630591, 0.4929016016666955] - }, { - "low": 1, - "high": 3, - "annual_failure_rate": 0.24064820598237213, - "error_interval": [0.14488594021076606, 0.3758019832614595] - }, { - "low": 3, - "high": 6, - "annual_failure_rate": 0.5014425058387142, - "error_interval": [0.3062941096766342, 0.7744372808405151] - }, { - "low": 6, - "high": 11, - "annual_failure_rate": 0.38007108544136836, - "error_interval": [0.2989500188963677, 0.4764223967570595] - }, { - "low": 11, - "high": 20, - "annual_failure_rate": 0.5346094598348444, - "error_interval": [0.40595137663302483, 0.6911066985735377] - }, { - "low": 20, - "high": 35, - "annual_failure_rate": 0.8428063943161636, - "error_interval": [0.6504601819243522, 1.0742259350903411] - }, { - "low": 35, - "high": 65, - "annual_failure_rate": 1.4429071005017484, - "error_interval": [1.1405581860945952, 1.8008133631629157] - }, { - "low": 65, - "high": 120, - "annual_failure_rate": 1.6190935390549661, - "error_interval": [1.0263664163011208, 2.4294352761068576] + 'display_type': 'normalized' + }, + '185': { + 'display_name': 'Head Stability', + 'ideal': '', + 'critical': false, + 'description': 'Western Digital attribute.', + 'display_type': 'normalized' + }, + '186': { + 'display_name': 'Induced Op-Vibration Detection', + 'ideal': '', + 'critical': false, + 'description': 'Western Digital attribute.', + 'display_type': 'normalized' + }, + '187': { + 'display_name': 'Reported Uncorrectable Errors', + 'ideal': 'low', + 'critical': true, + 'description': 'The count of errors that could not be recovered using hardware ECC (see attribute 195).', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.028130798308190524, + 'error_interval': [0.024487830609364304, 0.032162944988161336] + }, { + 'low': 1, + 'high': 1, + 'annual_failure_rate': 0.33877621175661743, + 'error_interval': [0.22325565823630591, 0.4929016016666955] + }, { + 'low': 1, + 'high': 3, + 'annual_failure_rate': 0.24064820598237213, + 'error_interval': [0.14488594021076606, 0.3758019832614595] + }, { + 'low': 3, + 'high': 6, + 'annual_failure_rate': 0.5014425058387142, + 'error_interval': [0.3062941096766342, 0.7744372808405151] + }, { + 'low': 6, + 'high': 11, + 'annual_failure_rate': 0.38007108544136836, + 'error_interval': [0.2989500188963677, 0.4764223967570595] + }, { + 'low': 11, + 'high': 20, + 'annual_failure_rate': 0.5346094598348444, + 'error_interval': [0.40595137663302483, 0.6911066985735377] + }, { + 'low': 20, + 'high': 35, + 'annual_failure_rate': 0.8428063943161636, + 'error_interval': [0.6504601819243522, 1.0742259350903411] + }, { + 'low': 35, + 'high': 65, + 'annual_failure_rate': 1.4429071005017484, + 'error_interval': [1.1405581860945952, 1.8008133631629157] + }, { + 'low': 65, + 'high': 120, + 'annual_failure_rate': 1.6190935390549661, + 'error_interval': [1.0263664163011208, 2.4294352761068576] }], - "display_type": "raw" - }, - "188": { - "display_name": "Command Timeout", - "ideal": "low", - "critical": true, - "description": "The count of aborted operations due to HDD timeout. Normally this attribute value should be equal to zero.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.024893587674442153, - "error_interval": [0.020857343769186413, 0.0294830350167543] - }, { - "low": 0, - "high": 13, - "annual_failure_rate": 0.10044174089362015, - "error_interval": [0.0812633664077498, 0.1227848196758574] - }, { - "low": 13, - "high": 26, - "annual_failure_rate": 0.334030592234279, - "error_interval": [0.2523231196342665, 0.4337665082489293] - }, { - "low": 26, - "high": 39, - "annual_failure_rate": 0.36724705400842445, - "error_interval": [0.30398009356575617, 0.4397986538328568] - }, { - "low": 39, - "high": 52, - "annual_failure_rate": 0.29848155926978354, - "error_interval": [0.2509254838615984, 0.35242890006477073] - }, { - "low": 52, - "high": 65, - "annual_failure_rate": 0.2203079701535098, - "error_interval": [0.18366082845676174, 0.26212468677179274] - }, { - "low": 65, - "high": 78, - "annual_failure_rate": 0.3018169948863018, - "error_interval": [0.23779746376787655, 0.37776897542831006] - }, { - "low": 78, - "high": 91, - "annual_failure_rate": 0.32854928239235887, - "error_interval": [0.2301118782147336, 0.4548506948185028] - }, { - "low": 91, - "high": 104, - "annual_failure_rate": 0.28488916640649387, - "error_interval": [0.1366154288236293, 0.5239213202729072] + 'display_type': 'raw' + }, + '188': { + 'display_name': 'Command Timeout', + 'ideal': 'low', + 'critical': true, + 'description': 'The count of aborted operations due to HDD timeout. Normally this attribute value should be equal to zero.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.024893587674442153, + 'error_interval': [0.020857343769186413, 0.0294830350167543] + }, { + 'low': 0, + 'high': 13, + 'annual_failure_rate': 0.10044174089362015, + 'error_interval': [0.0812633664077498, 0.1227848196758574] + }, { + 'low': 13, + 'high': 26, + 'annual_failure_rate': 0.334030592234279, + 'error_interval': [0.2523231196342665, 0.4337665082489293] + }, { + 'low': 26, + 'high': 39, + 'annual_failure_rate': 0.36724705400842445, + 'error_interval': [0.30398009356575617, 0.4397986538328568] + }, { + 'low': 39, + 'high': 52, + 'annual_failure_rate': 0.29848155926978354, + 'error_interval': [0.2509254838615984, 0.35242890006477073] + }, { + 'low': 52, + 'high': 65, + 'annual_failure_rate': 0.2203079701535098, + 'error_interval': [0.18366082845676174, 0.26212468677179274] + }, { + 'low': 65, + 'high': 78, + 'annual_failure_rate': 0.3018169948863018, + 'error_interval': [0.23779746376787655, 0.37776897542831006] + }, { + 'low': 78, + 'high': 91, + 'annual_failure_rate': 0.32854928239235887, + 'error_interval': [0.2301118782147336, 0.4548506948185028] + }, { + 'low': 91, + 'high': 104, + 'annual_failure_rate': 0.28488916640649387, + 'error_interval': [0.1366154288236293, 0.5239213202729072] }], - "display_type": "raw" - }, - "189": { - "display_name": "High Fly Writes", - "ideal": "low", - "critical": false, - "description": "HDD manufacturers implement a flying height sensor that attempts to provide additional protections for write operations by detecting when a recording head is flying outside its normal operating range. If an unsafe fly height condition is encountered, the write process is stopped, and the information is rewritten or reallocated to a safe region of the hard drive. This attribute indicates the count of these errors detected over the lifetime of the drive.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.09070551401946862, - "error_interval": [0.08018892683853401, 0.10221801211956287] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.0844336097370013, - "error_interval": [0.07299813695315267, 0.09715235540340669] - }, { - "low": 2, - "high": 5, - "annual_failure_rate": 0.07943219628781906, - "error_interval": [0.06552176680630226, 0.09542233189887633] - }, { - "low": 5, - "high": 13, - "annual_failure_rate": 0.09208847603893404, - "error_interval": [0.07385765060838133, 0.11345557807163456] - }, { - "low": 13, - "high": 30, - "annual_failure_rate": 0.18161161650924224, - "error_interval": [0.13858879602902988, 0.23377015012749933] - }, { - "low": 30, - "high": 70, - "annual_failure_rate": 0.2678117886102384, - "error_interval": [0.19044036194841887, 0.36610753129699186] - }, { - "low": 70, - "high": 150, - "annual_failure_rate": 0.26126480798826107, - "error_interval": [0.15958733218826962, 0.4035023060905559] - }, { - "low": 150, - "high": 350, - "annual_failure_rate": 0.11337164155924832, - "error_interval": [0.030889956621649995, 0.2902764300762812] + 'display_type': 'raw' + }, + '189': { + 'display_name': 'High Fly Writes', + 'ideal': 'low', + 'critical': false, + 'description': 'HDD manufacturers implement a flying height sensor that attempts to provide additional protections for write operations by detecting when a recording head is flying outside its normal operating range. If an unsafe fly height condition is encountered, the write process is stopped, and the information is rewritten or reallocated to a safe region of the hard drive. This attribute indicates the count of these errors detected over the lifetime of the drive.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.09070551401946862, + 'error_interval': [0.08018892683853401, 0.10221801211956287] + }, { + 'low': 1, + 'high': 2, + 'annual_failure_rate': 0.0844336097370013, + 'error_interval': [0.07299813695315267, 0.09715235540340669] + }, { + 'low': 2, + 'high': 5, + 'annual_failure_rate': 0.07943219628781906, + 'error_interval': [0.06552176680630226, 0.09542233189887633] + }, { + 'low': 5, + 'high': 13, + 'annual_failure_rate': 0.09208847603893404, + 'error_interval': [0.07385765060838133, 0.11345557807163456] + }, { + 'low': 13, + 'high': 30, + 'annual_failure_rate': 0.18161161650924224, + 'error_interval': [0.13858879602902988, 0.23377015012749933] + }, { + 'low': 30, + 'high': 70, + 'annual_failure_rate': 0.2678117886102384, + 'error_interval': [0.19044036194841887, 0.36610753129699186] + }, { + 'low': 70, + 'high': 150, + 'annual_failure_rate': 0.26126480798826107, + 'error_interval': [0.15958733218826962, 0.4035023060905559] + }, { + 'low': 150, + 'high': 350, + 'annual_failure_rate': 0.11337164155924832, + 'error_interval': [0.030889956621649995, 0.2902764300762812] }], - "display_type": "raw" - }, - "190": { - "display_name": "Temperature Difference", - "ideal": "", - "critical": false, - "description": "Value is equal to (100-temp. °C), allowing manufacturer to set a minimum threshold which corresponds to a maximum temperature. This also follows the convention of 100 being a best-case value and lower values being undesirable. However, some older drives may instead report raw Temperature (identical to 0xC2) or Temperature minus 50 here.", - "display_type": "normalized" - }, - "191": { - "display_name": "G-sense Error Rate", - "ideal": "low", - "critical": false, - "description": "The count of errors resulting from externally induced shock and vibration. ", - "display_type": "normalized" - }, - "192": { - "display_name": "Power-off Retract Count", - "ideal": "low", - "critical": false, - "description": "Number of power-off or emergency retract cycles.", - "observed_thresholds": [{ - "low": 1, - "high": 2, - "annual_failure_rate": 0.02861098445412803, - "error_interval": [0.022345416230915037, 0.036088863823297186] - }, { - "low": 2, - "high": 6, - "annual_failure_rate": 0.0738571777154862, - "error_interval": [0.06406927746420421, 0.0847175264009771] - }, { - "low": 6, - "high": 16, - "annual_failure_rate": 0.11970378206823593, - "error_interval": [0.10830059875098269, 0.13198105985656441] - }, { - "low": 16, - "high": 40, - "annual_failure_rate": 0.027266868552620425, - "error_interval": [0.021131448605713823, 0.03462795920968522] - }, { - "low": 40, - "high": 100, - "annual_failure_rate": 0.011741682974559688, - "error_interval": [0.00430899071133239, 0.025556700631152028] - }, { - "low": 100, - "high": 250, - "annual_failure_rate": 0.012659940134091309, - "error_interval": [0.00607093338127348, 0.023282080653656938] - }, { - "low": 250, - "high": 650, - "annual_failure_rate": 0.01634692899031039, - "error_interval": [0.009522688540043157, 0.026173016865409605] - }, { - "low": 650, - "high": 1600, - "annual_failure_rate": 0.005190074354440066, - "error_interval": [0.0025908664180103293, 0.009286476666453648] + 'display_type': 'raw' + }, + '190': { + 'display_name': 'Temperature Difference', + 'ideal': '', + 'critical': false, + 'description': 'Value is equal to (100-temp. °C), allowing manufacturer to set a minimum threshold which corresponds to a maximum temperature. This also follows the convention of 100 being a best-case value and lower values being undesirable. However, some older drives may instead report raw Temperature (identical to 0xC2) or Temperature minus 50 here.', + 'display_type': 'normalized' + }, + '191': { + 'display_name': 'G-sense Error Rate', + 'ideal': 'low', + 'critical': false, + 'description': 'The count of errors resulting from externally induced shock and vibration. ', + 'display_type': 'normalized' + }, + '192': { + 'display_name': 'Power-off Retract Count', + 'ideal': 'low', + 'critical': false, + 'description': 'Number of power-off or emergency retract cycles.', + 'observed_thresholds': [{ + 'low': 1, + 'high': 2, + 'annual_failure_rate': 0.02861098445412803, + 'error_interval': [0.022345416230915037, 0.036088863823297186] + }, { + 'low': 2, + 'high': 6, + 'annual_failure_rate': 0.0738571777154862, + 'error_interval': [0.06406927746420421, 0.0847175264009771] + }, { + 'low': 6, + 'high': 16, + 'annual_failure_rate': 0.11970378206823593, + 'error_interval': [0.10830059875098269, 0.13198105985656441] + }, { + 'low': 16, + 'high': 40, + 'annual_failure_rate': 0.027266868552620425, + 'error_interval': [0.021131448605713823, 0.03462795920968522] + }, { + 'low': 40, + 'high': 100, + 'annual_failure_rate': 0.011741682974559688, + 'error_interval': [0.00430899071133239, 0.025556700631152028] + }, { + 'low': 100, + 'high': 250, + 'annual_failure_rate': 0.012659940134091309, + 'error_interval': [0.00607093338127348, 0.023282080653656938] + }, { + 'low': 250, + 'high': 650, + 'annual_failure_rate': 0.01634692899031039, + 'error_interval': [0.009522688540043157, 0.026173016865409605] + }, { + 'low': 650, + 'high': 1600, + 'annual_failure_rate': 0.005190074354440066, + 'error_interval': [0.0025908664180103293, 0.009286476666453648] }], - "display_type": "raw" - }, - "193": { - "display_name": "Load Cycle Count", - "ideal": "low", - "critical": false, - "description": "Count of load/unload cycles into head landing zone position.[45] Some drives use 225 (0xE1) for Load Cycle Count instead.", - "display_type": "normalized" - }, - "194": { - "display_name": "Temperature", - "ideal": "low", - "critical": false, - "description": "Indicates the device temperature, if the appropriate sensor is fitted. Lowest byte of the raw value contains the exact temperature value (Celsius degrees).", - "transform_value_unit": "°C", - "display_type": "transformed" - }, - "195": { - "display_name": "Hardware ECC Recovered", - "ideal": "", - "critical": false, - "description": "(Vendor-specific raw value.) The raw value has different structure for different vendors and is often not meaningful as a decimal number.", - "observed_thresholds": [{ - "low": 12, - "high": 24, - "annual_failure_rate": 0.31472916829975706, - "error_interval": [0.15711166685282174, 0.5631374192486645] - }, { - "low": 24, - "high": 36, - "annual_failure_rate": 0.15250310197260136, - "error_interval": [0.10497611828070175, 0.21417105521823687] - }, { - "low": 36, - "high": 48, - "annual_failure_rate": 0.2193119102723874, - "error_interval": [0.16475385681835103, 0.28615447006525274] - }, { - "low": 48, - "high": 60, - "annual_failure_rate": 0.05672658497265746, - "error_interval": [0.043182904776447234, 0.07317316161437043] - }, { - "low": 60, - "high": 72, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 72, - "high": 84, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 84, - "high": 96, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 96, - "high": 108, - "annual_failure_rate": 0.04074570216566197, - "error_interval": [0.001031591863615295, 0.22702052218047528] + 'display_type': 'raw' + }, + '193': { + 'display_name': 'Load Cycle Count', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of load/unload cycles into head landing zone position.[45] Some drives use 225 (0xE1) for Load Cycle Count instead.', + 'display_type': 'normalized' + }, + '194': { + 'display_name': 'Temperature', + 'ideal': 'low', + 'critical': false, + 'description': 'Indicates the device temperature, if the appropriate sensor is fitted. Lowest byte of the raw value contains the exact temperature value (Celsius degrees).', + 'transform_value_unit': '°C', + 'display_type': 'transformed' + }, + '195': { + 'display_name': 'Hardware ECC Recovered', + 'ideal': '', + 'critical': false, + 'description': '(Vendor-specific raw value.) The raw value has different structure for different vendors and is often not meaningful as a decimal number.', + 'observed_thresholds': [{ + 'low': 12, + 'high': 24, + 'annual_failure_rate': 0.31472916829975706, + 'error_interval': [0.15711166685282174, 0.5631374192486645] + }, { + 'low': 24, + 'high': 36, + 'annual_failure_rate': 0.15250310197260136, + 'error_interval': [0.10497611828070175, 0.21417105521823687] + }, { + 'low': 36, + 'high': 48, + 'annual_failure_rate': 0.2193119102723874, + 'error_interval': [0.16475385681835103, 0.28615447006525274] + }, { + 'low': 48, + 'high': 60, + 'annual_failure_rate': 0.05672658497265746, + 'error_interval': [0.043182904776447234, 0.07317316161437043] + }, { + 'low': 60, + 'high': 72, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 72, + 'high': 84, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 84, + 'high': 96, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 96, + 'high': 108, + 'annual_failure_rate': 0.04074570216566197, + 'error_interval': [0.001031591863615295, 0.22702052218047528] }], - "display_type": "normalized" - }, - "196": { - "display_name": "Reallocation Event Count", - "ideal": "low", - "critical": true, - "description": "Count of remap operations. The raw value of this attribute shows the total count of attempts to transfer data from reallocated sectors to a spare area. Both successful and unsuccessful attempts are counted.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.007389855800729792, - "error_interval": [0.005652654139732716, 0.009492578928212054] - }, { - "low": 1, - "high": 1, - "annual_failure_rate": 0.026558331312151347, - "error_interval": [0.005476966404484466, 0.07761471429677293] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.02471894893674658, - "error_interval": [0.0006258296027540169, 0.13772516847438018] - }, { - "low": 2, - "high": 4, - "annual_failure_rate": 0.03200912040691046, - "error_interval": [0.0008104007642081744, 0.17834340416493005] - }, { - "low": 4, - "high": 7, - "annual_failure_rate": 0.043078012510326925, - "error_interval": [0.001090640849081295, 0.24001532369794615] - }, { - "low": 7, - "high": 11, - "annual_failure_rate": 0.033843300880853036, - "error_interval": [0.0008568381932559863, 0.18856280368036135] - }, { - "low": 11, - "high": 17, - "annual_failure_rate": 0.16979376647542252, - "error_interval": [0.035015556653263225, 0.49620943874336304] - }, { - "low": 17, - "high": 27, - "annual_failure_rate": 0.059042381106438044, - "error_interval": [0.0014948236677880642, 0.32896309247698113] - }, { - "low": 27, - "high": 45, - "annual_failure_rate": 0.24701105346266636, - "error_interval": [0.050939617608142244, 0.721871118983972] + 'display_type': 'normalized' + }, + '196': { + 'display_name': 'Reallocation Event Count', + 'ideal': 'low', + 'critical': true, + 'description': 'Count of remap operations. The raw value of this attribute shows the total count of attempts to transfer data from reallocated sectors to a spare area. Both successful and unsuccessful attempts are counted.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.007389855800729792, + 'error_interval': [0.005652654139732716, 0.009492578928212054] + }, { + 'low': 1, + 'high': 1, + 'annual_failure_rate': 0.026558331312151347, + 'error_interval': [0.005476966404484466, 0.07761471429677293] + }, { + 'low': 1, + 'high': 2, + 'annual_failure_rate': 0.02471894893674658, + 'error_interval': [0.0006258296027540169, 0.13772516847438018] + }, { + 'low': 2, + 'high': 4, + 'annual_failure_rate': 0.03200912040691046, + 'error_interval': [0.0008104007642081744, 0.17834340416493005] + }, { + 'low': 4, + 'high': 7, + 'annual_failure_rate': 0.043078012510326925, + 'error_interval': [0.001090640849081295, 0.24001532369794615] + }, { + 'low': 7, + 'high': 11, + 'annual_failure_rate': 0.033843300880853036, + 'error_interval': [0.0008568381932559863, 0.18856280368036135] + }, { + 'low': 11, + 'high': 17, + 'annual_failure_rate': 0.16979376647542252, + 'error_interval': [0.035015556653263225, 0.49620943874336304] + }, { + 'low': 17, + 'high': 27, + 'annual_failure_rate': 0.059042381106438044, + 'error_interval': [0.0014948236677880642, 0.32896309247698113] + }, { + 'low': 27, + 'high': 45, + 'annual_failure_rate': 0.24701105346266636, + 'error_interval': [0.050939617608142244, 0.721871118983972] }], - "display_type": "raw" - }, - "197": { - "display_name": "Current Pending Sector Count", - "ideal": "low", - "critical": true, - "description": "Count of \"unstable\" sectors (waiting to be remapped, because of unrecoverable read errors). If an unstable sector is subsequently read successfully, the sector is remapped and this value is decreased. Read errors on a sector will not remap the sector immediately (since the correct value cannot be read and so the value to remap is not known, and also it might become readable later); instead, the drive firmware remembers that the sector needs to be remapped, and will remap it the next time it\"s written.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.025540791394761345, - "error_interval": [0.023161777231213983, 0.02809784482748174] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.34196613799103254, - "error_interval": [0.22723401523750225, 0.4942362818474496] - }, { - "low": 2, - "high": 6, - "annual_failure_rate": 0.6823772508117681, - "error_interval": [0.41083568090070416, 1.0656166047061635] - }, { - "low": 6, - "high": 16, - "annual_failure_rate": 0.6108100007493069, - "error_interval": [0.47336936083368364, 0.7757071095273286] - }, { - "low": 16, - "high": 40, - "annual_failure_rate": 0.9564879341127684, - "error_interval": [0.7701044196378299, 1.174355230793638] - }, { - "low": 40, - "high": 100, - "annual_failure_rate": 1.6519989942167461, - "error_interval": [1.328402276482456, 2.0305872327541317] - }, { - "low": 100, - "high": 250, - "annual_failure_rate": 2.5137741046831956, - "error_interval": [1.9772427971560862, 3.1510376077891613] - }, { - "low": 250, - "high": 650, - "annual_failure_rate": 3.3203378817413904, - "error_interval": [2.5883662702274406, 4.195047163573006] - }, { - "low": 650, - "high": 1600, - "annual_failure_rate": 3.133047210300429, - "error_interval": [1.1497731080460096, 6.819324775707182] + 'display_type': 'raw' + }, + '197': { + 'display_name': 'Current Pending Sector Count', + 'ideal': 'low', + 'critical': true, + 'description': 'Count of "unstable" sectors (waiting to be remapped, because of unrecoverable read errors). If an unstable sector is subsequently read successfully, the sector is remapped and this value is decreased. Read errors on a sector will not remap the sector immediately (since the correct value cannot be read and so the value to remap is not known, and also it might become readable later); instead, the drive firmware remembers that the sector needs to be remapped, and will remap it the next time it"s written.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.025540791394761345, + 'error_interval': [0.023161777231213983, 0.02809784482748174] + }, { + 'low': 1, + 'high': 2, + 'annual_failure_rate': 0.34196613799103254, + 'error_interval': [0.22723401523750225, 0.4942362818474496] + }, { + 'low': 2, + 'high': 6, + 'annual_failure_rate': 0.6823772508117681, + 'error_interval': [0.41083568090070416, 1.0656166047061635] + }, { + 'low': 6, + 'high': 16, + 'annual_failure_rate': 0.6108100007493069, + 'error_interval': [0.47336936083368364, 0.7757071095273286] + }, { + 'low': 16, + 'high': 40, + 'annual_failure_rate': 0.9564879341127684, + 'error_interval': [0.7701044196378299, 1.174355230793638] + }, { + 'low': 40, + 'high': 100, + 'annual_failure_rate': 1.6519989942167461, + 'error_interval': [1.328402276482456, 2.0305872327541317] + }, { + 'low': 100, + 'high': 250, + 'annual_failure_rate': 2.5137741046831956, + 'error_interval': [1.9772427971560862, 3.1510376077891613] + }, { + 'low': 250, + 'high': 650, + 'annual_failure_rate': 3.3203378817413904, + 'error_interval': [2.5883662702274406, 4.195047163573006] + }, { + 'low': 650, + 'high': 1600, + 'annual_failure_rate': 3.133047210300429, + 'error_interval': [1.1497731080460096, 6.819324775707182] }], - "display_type": "raw" - }, - "198": { - "display_name": "(Offline) Uncorrectable Sector Count", - "ideal": "low", - "critical": true, - "description": "The total count of uncorrectable errors when reading/writing a sector. A rise in the value of this attribute indicates defects of the disk surface and/or problems in the mechanical subsystem.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.028675322159886437, - "error_interval": [0.026159385510707116, 0.03136793218577656] - }, { - "low": 0, - "high": 2, - "annual_failure_rate": 0.8135764944275583, - "error_interval": [0.40613445471964466, 1.4557130815309443] - }, { - "low": 2, - "high": 4, - "annual_failure_rate": 1.1173469387755102, - "error_interval": [0.5773494680315332, 1.9517802404552516] - }, { - "low": 4, - "high": 6, - "annual_failure_rate": 1.3558692421991083, - "error_interval": [0.4402470522980859, 3.1641465148237544] - }, { - "low": 6, - "high": 8, - "annual_failure_rate": 0.7324414715719062, - "error_interval": [0.15104704003805655, 2.140504796291604] - }, { - "low": 8, - "high": 10, - "annual_failure_rate": 0.5777213677766163, - "error_interval": [0.43275294849366835, 0.7556737733062419] - }, { - "low": 10, - "high": 12, - "annual_failure_rate": 1.7464114832535886, - "error_interval": [0.47583835092536914, 4.471507017371231] - }, { - "low": 12, - "high": 14, - "annual_failure_rate": 2.6449275362318843, - "error_interval": [0.3203129951758959, 9.554387676519005] - }, { - "low": 14, - "high": 16, - "annual_failure_rate": 0.796943231441048, - "error_interval": [0.5519063550198366, 1.113648286331181] + 'display_type': 'raw' + }, + '198': { + 'display_name': '(Offline) Uncorrectable Sector Count', + 'ideal': 'low', + 'critical': true, + 'description': 'The total count of uncorrectable errors when reading/writing a sector. A rise in the value of this attribute indicates defects of the disk surface and/or problems in the mechanical subsystem.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.028675322159886437, + 'error_interval': [0.026159385510707116, 0.03136793218577656] + }, { + 'low': 0, + 'high': 2, + 'annual_failure_rate': 0.8135764944275583, + 'error_interval': [0.40613445471964466, 1.4557130815309443] + }, { + 'low': 2, + 'high': 4, + 'annual_failure_rate': 1.1173469387755102, + 'error_interval': [0.5773494680315332, 1.9517802404552516] + }, { + 'low': 4, + 'high': 6, + 'annual_failure_rate': 1.3558692421991083, + 'error_interval': [0.4402470522980859, 3.1641465148237544] + }, { + 'low': 6, + 'high': 8, + 'annual_failure_rate': 0.7324414715719062, + 'error_interval': [0.15104704003805655, 2.140504796291604] + }, { + 'low': 8, + 'high': 10, + 'annual_failure_rate': 0.5777213677766163, + 'error_interval': [0.43275294849366835, 0.7556737733062419] + }, { + 'low': 10, + 'high': 12, + 'annual_failure_rate': 1.7464114832535886, + 'error_interval': [0.47583835092536914, 4.471507017371231] + }, { + 'low': 12, + 'high': 14, + 'annual_failure_rate': 2.6449275362318843, + 'error_interval': [0.3203129951758959, 9.554387676519005] + }, { + 'low': 14, + 'high': 16, + 'annual_failure_rate': 0.796943231441048, + 'error_interval': [0.5519063550198366, 1.113648286331181] }], - "display_type": "raw" - }, - "199": { - "display_name": "UltraDMA CRC Error Count", - "ideal": "low", - "critical": false, - "description": "The count of errors in data transfer via the interface cable as determined by ICRC (Interface Cyclic Redundancy Check).", - "observed_thresholds": [{ - "low": 0, - "high": 1, - "annual_failure_rate": 0.04068379316116366, - "error_interval": [0.037534031558106425, 0.04402730201866553] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.1513481259734218, - "error_interval": [0.12037165605991791, 0.18786293065527596] - }, { - "low": 2, - "high": 4, - "annual_failure_rate": 0.16849758722418978, - "error_interval": [0.12976367397863445, 0.2151676572000481] - }, { - "low": 4, - "high": 8, - "annual_failure_rate": 0.15385127340491614, - "error_interval": [0.10887431782430312, 0.21117289306426648] - }, { - "low": 8, - "high": 16, - "annual_failure_rate": 0.14882894050104387, - "error_interval": [0.09631424312463635, 0.2197008753522735] - }, { - "low": 16, - "high": 35, - "annual_failure_rate": 0.20878219917249793, - "error_interval": [0.14086447304552446, 0.29804957135975] - }, { - "low": 35, - "high": 70, - "annual_failure_rate": 0.13742940270409038, - "error_interval": [0.06860426267470295, 0.24589916335290812] - }, { - "low": 70, - "high": 130, - "annual_failure_rate": 0.22336578581363, - "error_interval": [0.11150339549604707, 0.39966309081252904] - }, { - "low": 130, - "high": 260, - "annual_failure_rate": 0.18277416124186283, - "error_interval": [0.07890890989692058, 0.3601379610272007] + 'display_type': 'raw' + }, + '199': { + 'display_name': 'UltraDMA CRC Error Count', + 'ideal': 'low', + 'critical': false, + 'description': 'The count of errors in data transfer via the interface cable as determined by ICRC (Interface Cyclic Redundancy Check).', + 'observed_thresholds': [{ + 'low': 0, + 'high': 1, + 'annual_failure_rate': 0.04068379316116366, + 'error_interval': [0.037534031558106425, 0.04402730201866553] + }, { + 'low': 1, + 'high': 2, + 'annual_failure_rate': 0.1513481259734218, + 'error_interval': [0.12037165605991791, 0.18786293065527596] + }, { + 'low': 2, + 'high': 4, + 'annual_failure_rate': 0.16849758722418978, + 'error_interval': [0.12976367397863445, 0.2151676572000481] + }, { + 'low': 4, + 'high': 8, + 'annual_failure_rate': 0.15385127340491614, + 'error_interval': [0.10887431782430312, 0.21117289306426648] + }, { + 'low': 8, + 'high': 16, + 'annual_failure_rate': 0.14882894050104387, + 'error_interval': [0.09631424312463635, 0.2197008753522735] + }, { + 'low': 16, + 'high': 35, + 'annual_failure_rate': 0.20878219917249793, + 'error_interval': [0.14086447304552446, 0.29804957135975] + }, { + 'low': 35, + 'high': 70, + 'annual_failure_rate': 0.13742940270409038, + 'error_interval': [0.06860426267470295, 0.24589916335290812] + }, { + 'low': 70, + 'high': 130, + 'annual_failure_rate': 0.22336578581363, + 'error_interval': [0.11150339549604707, 0.39966309081252904] + }, { + 'low': 130, + 'high': 260, + 'annual_failure_rate': 0.18277416124186283, + 'error_interval': [0.07890890989692058, 0.3601379610272007] }], - "display_type": "raw" - }, - "2": { - "display_name": "Throughput Performance", - "ideal": "high", - "critical": false, - "description": "Overall (general) throughput performance of a hard disk drive. If the value of this attribute is decreasing there is a high probability that there is a problem with the disk.", - "display_type": "normalized" - }, - "200": { - "display_name": "Multi-Zone Error Rate", - "ideal": "low", - "critical": false, - "description": "The count of errors found when writing a sector. The higher the value, the worse the disk\"s mechanical condition is.", - "display_type": "normalized" - }, - "201": { - "display_name": "Soft Read Error Rate", - "ideal": "low", - "critical": true, - "description": "Count indicates the number of uncorrectable software read errors.", - "display_type": "normalized" - }, - "202": { - "display_name": "Data Address Mark errors", - "ideal": "low", - "critical": false, - "description": "Count of Data Address Mark errors (or vendor-specific).", - "display_type": "normalized" - }, - "203": { - "display_name": "Run Out Cancel", - "ideal": "low", - "critical": false, - "description": "The number of errors caused by incorrect checksum during the error correction.", - "display_type": "normalized" - }, - "204": { - "display_name": "Soft ECC Correction", - "ideal": "low", - "critical": false, - "description": "Count of errors corrected by the internal error correction software.", - "display_type": "" - }, - "205": { - "display_name": "Thermal Asperity Rate", - "ideal": "low", - "critical": false, - "description": "Count of errors due to high temperature.", - "display_type": "normalized" - }, - "206": { - "display_name": "Flying Height", - "ideal": "", - "critical": false, - "description": "Height of heads above the disk surface. If too low, head crash is more likely; if too high, read/write errors are more likely.", - "display_type": "normalized" - }, - "207": { - "display_name": "Spin High Current", - "ideal": "low", - "critical": false, - "description": "Amount of surge current used to spin up the drive.", - "display_type": "normalized" - }, - "208": { - "display_name": "Spin Buzz", - "ideal": "", - "critical": false, - "description": "Count of buzz routines needed to spin up the drive due to insufficient power.", - "display_type": "normalized" - }, - "209": { - "display_name": "Offline Seek Performance", - "ideal": "", - "critical": false, - "description": "Drive\"s seek performance during its internal tests.", - "display_type": "normalized" - }, - "210": { - "display_name": "Vibration During Write", - "ideal": "", - "critical": false, - "description": "Found in Maxtor 6B200M0 200GB and Maxtor 2R015H1 15GB disks.", - "display_type": "normalized" - }, - "211": { - "display_name": "Vibration During Write", - "ideal": "", - "critical": false, - "description": "A recording of a vibration encountered during write operations.", - "display_type": "normalized" - }, - "212": { - "display_name": "Shock During Write", - "ideal": "", - "critical": false, - "description": "A recording of shock encountered during write operations.", - "display_type": "normalized" - }, - "22": { - "display_name": "Current Helium Level", - "ideal": "high", - "critical": false, - "description": "Specific to He8 drives from HGST. This value measures the helium inside of the drive specific to this manufacturer. It is a pre-fail attribute that trips once the drive detects that the internal environment is out of specification.", - "display_type": "normalized" - }, - "220": { - "display_name": "Disk Shift", - "ideal": "low", - "critical": false, - "description": "Distance the disk has shifted relative to the spindle (usually due to shock or temperature). Unit of measure is unknown.", - "display_type": "normalized" - }, - "221": { - "display_name": "G-Sense Error Rate", - "ideal": "low", - "critical": false, - "description": "The count of errors resulting from externally induced shock and vibration.", - "display_type": "normalized" - }, - "222": { - "display_name": "Loaded Hours", - "ideal": "", - "critical": false, - "description": "Time spent operating under data load (movement of magnetic head armature).", - "display_type": "normalized" - }, - "223": { - "display_name": "Load/Unload Retry Count", - "ideal": "", - "critical": false, - "description": "Count of times head changes position.", - "display_type": "normalized" - }, - "224": { - "display_name": "Load Friction", - "ideal": "low", - "critical": false, - "description": "Resistance caused by friction in mechanical parts while operating.", - "display_type": "normalized" - }, - "225": { - "display_name": "Load/Unload Cycle Count", - "ideal": "low", - "critical": false, - "description": "Total count of load cycles Some drives use 193 (0xC1) for Load Cycle Count instead. See Description for 193 for significance of this number. ", - "display_type": "normalized" - }, - "226": { - "display_name": "Load \"In\"-time", - "ideal": "", - "critical": false, - "description": "Total time of loading on the magnetic heads actuator (time not spent in parking area).", - "display_type": "normalized" - }, - "227": { - "display_name": "Torque Amplification Count", - "ideal": "low", - "critical": false, - "description": "Count of attempts to compensate for platter speed variations.[66]", - "display_type": "" - }, - "228": { - "display_name": "Power-Off Retract Cycle", - "ideal": "low", - "critical": false, - "description": "The number of power-off cycles which are counted whenever there is a \"retract event\" and the heads are loaded off of the media such as when the machine is powered down, put to sleep, or is idle.", - "display_type": "" - }, - "230": { - "display_name": "GMR Head Amplitude ", - "ideal": "", - "critical": false, - "description": "Amplitude of \"thrashing\" (repetitive head moving motions between operations).", - "display_type": "normalized" - }, - "231": { - "display_name": "Life Left", - "ideal": "", - "critical": false, - "description": "Indicates the approximate SSD life left, in terms of program/erase cycles or available reserved blocks. A normalized value of 100 represents a new drive, with a threshold value at 10 indicating a need for replacement. A value of 0 may mean that the drive is operating in read-only mode to allow data recovery.", - "display_type": "normalized" - }, - "232": { - "display_name": "Endurance Remaining", - "ideal": "", - "critical": false, - "description": "Number of physical erase cycles completed on the SSD as a percentage of the maximum physical erase cycles the drive is designed to endure.", - "display_type": "normalized" - }, - "233": { - "display_name": "Media Wearout Indicator", - "ideal": "", - "critical": false, - "description": "Intel SSDs report a normalized value from 100, a new drive, to a minimum of 1. It decreases while the NAND erase cycles increase from 0 to the maximum-rated cycles.", - "display_type": "normalized" - }, - "234": { - "display_name": "Average erase count", - "ideal": "", - "critical": false, - "description": "Decoded as: byte 0-1-2 = average erase count (big endian) and byte 3-4-5 = max erase count (big endian).", - "display_type": "normalized" - }, - "235": { - "display_name": "Good Block Count", - "ideal": "", - "critical": false, - "description": "Decoded as: byte 0-1-2 = good block count (big endian) and byte 3-4 = system (free) block count.", - "display_type": "normalized" - }, - "240": { - "display_name": "Head Flying Hours", - "ideal": "", - "critical": false, - "description": "Time spent during the positioning of the drive heads.[15][71] Some Fujitsu drives report the count of link resets during a data transfer.", - "display_type": "normalized" - }, - "241": { - "display_name": "Total LBAs Written", - "ideal": "", - "critical": false, - "description": "Total count of LBAs written.", - "display_type": "normalized" - }, - "242": { - "display_name": "Total LBAs Read", - "ideal": "", - "critical": false, - "description": "Total count of LBAs read.Some S.M.A.R.T. utilities will report a negative number for the raw value since in reality it has 48 bits rather than 32.", - "display_type": "normalized" - }, - "243": { - "display_name": "Total LBAs Written Expanded", - "ideal": "", - "critical": false, - "description": "The upper 5 bytes of the 12-byte total number of LBAs written to the device. The lower 7 byte value is located at attribute 0xF1.", - "display_type": "normalized" - }, - "244": { - "display_name": "Total LBAs Read Expanded", - "ideal": "", - "critical": false, - "description": "The upper 5 bytes of the 12-byte total number of LBAs read from the device. The lower 7 byte value is located at attribute 0xF2.", - "display_type": "normalized" - }, - "249": { - "display_name": "NAND Writes (1GiB)", - "ideal": "", - "critical": false, - "description": "Total NAND Writes. Raw value reports the number of writes to NAND in 1 GB increments.", - "display_type": "normalized" - }, - "250": { - "display_name": "Read Error Retry Rate", - "ideal": "low", - "critical": false, - "description": "Count of errors while reading from a disk.", - "display_type": "normalized" - }, - "251": { - "display_name": "Minimum Spares Remaining", - "ideal": "", - "critical": false, - "description": "The Minimum Spares Remaining attribute indicates the number of remaining spare blocks as a percentage of the total number of spare blocks available.", - "display_type": "normalized" - }, - "252": { - "display_name": "Newly Added Bad Flash Block", - "ideal": "", - "critical": false, - "description": "The Newly Added Bad Flash Block attribute indicates the total number of bad flash blocks the drive detected since it was first initialized in manufacturing.", - "display_type": "normalized" - }, - "254": { - "display_name": "Free Fall Protection", - "ideal": "low", - "critical": false, - "description": "Count of \"Free Fall Events\" detected.", - "display_type": "normalized" - }, - "3": { - "display_name": "Spin-Up Time", - "ideal": "low", - "critical": false, - "description": "Average time of spindle spin up (from zero RPM to fully operational [milliseconds]).", - "observed_thresholds": [{ - "low": 78, - "high": 96, - "annual_failure_rate": 0.11452195377351217, - "error_interval": [0.10591837762295722, 0.12363823501915781] - }, { - "low": 96, - "high": 114, - "annual_failure_rate": 0.040274562840558074, - "error_interval": [0.03465055611002801, 0.046551312468303144] - }, { - "low": 114, - "high": 132, - "annual_failure_rate": 0.009100406705780476, - "error_interval": [0.006530608971356785, 0.012345729280075591] - }, { - "low": 132, - "high": 150, - "annual_failure_rate": 0.008561351734020232, - "error_interval": [0.004273795939256936, 0.015318623141355509] - }, { - "low": 150, - "high": 168, - "annual_failure_rate": 0.015780508262068848, - "error_interval": [0.005123888078524015, 0.03682644215646287] - }, { - "low": 168, - "high": 186, - "annual_failure_rate": 0.05262688124794024, - "error_interval": [0.0325768689524594, 0.08044577830285578] - }, { - "low": 186, - "high": 204, - "annual_failure_rate": 0.01957419424036038, - "error_interval": [0.0023705257325185624, 0.0707087198669825] - }, { - "low": 204, - "high": 222, - "annual_failure_rate": 0.026050959960031404, - "error_interval": [0.0006595532020744994, 0.1451466588889228] + 'display_type': 'raw' + }, + '2': { + 'display_name': 'Throughput Performance', + 'ideal': 'high', + 'critical': false, + 'description': 'Overall (general) throughput performance of a hard disk drive. If the value of this attribute is decreasing there is a high probability that there is a problem with the disk.', + 'display_type': 'normalized' + }, + '200': { + 'display_name': 'Multi-Zone Error Rate', + 'ideal': 'low', + 'critical': false, + 'description': 'The count of errors found when writing a sector. The higher the value, the worse the disk"s mechanical condition is.', + 'display_type': 'normalized' + }, + '201': { + 'display_name': 'Soft Read Error Rate', + 'ideal': 'low', + 'critical': true, + 'description': 'Count indicates the number of uncorrectable software read errors.', + 'display_type': 'normalized' + }, + '202': { + 'display_name': 'Data Address Mark errors', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of Data Address Mark errors (or vendor-specific).', + 'display_type': 'normalized' + }, + '203': { + 'display_name': 'Run Out Cancel', + 'ideal': 'low', + 'critical': false, + 'description': 'The number of errors caused by incorrect checksum during the error correction.', + 'display_type': 'normalized' + }, + '204': { + 'display_name': 'Soft ECC Correction', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of errors corrected by the internal error correction software.', + 'display_type': '' + }, + '205': { + 'display_name': 'Thermal Asperity Rate', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of errors due to high temperature.', + 'display_type': 'normalized' + }, + '206': { + 'display_name': 'Flying Height', + 'ideal': '', + 'critical': false, + 'description': 'Height of heads above the disk surface. If too low, head crash is more likely; if too high, read/write errors are more likely.', + 'display_type': 'normalized' + }, + '207': { + 'display_name': 'Spin High Current', + 'ideal': 'low', + 'critical': false, + 'description': 'Amount of surge current used to spin up the drive.', + 'display_type': 'normalized' + }, + '208': { + 'display_name': 'Spin Buzz', + 'ideal': '', + 'critical': false, + 'description': 'Count of buzz routines needed to spin up the drive due to insufficient power.', + 'display_type': 'normalized' + }, + '209': { + 'display_name': 'Offline Seek Performance', + 'ideal': '', + 'critical': false, + 'description': 'Drive"s seek performance during its internal tests.', + 'display_type': 'normalized' + }, + '210': { + 'display_name': 'Vibration During Write', + 'ideal': '', + 'critical': false, + 'description': 'Found in Maxtor 6B200M0 200GB and Maxtor 2R015H1 15GB disks.', + 'display_type': 'normalized' + }, + '211': { + 'display_name': 'Vibration During Write', + 'ideal': '', + 'critical': false, + 'description': 'A recording of a vibration encountered during write operations.', + 'display_type': 'normalized' + }, + '212': { + 'display_name': 'Shock During Write', + 'ideal': '', + 'critical': false, + 'description': 'A recording of shock encountered during write operations.', + 'display_type': 'normalized' + }, + '22': { + 'display_name': 'Current Helium Level', + 'ideal': 'high', + 'critical': false, + 'description': 'Specific to He8 drives from HGST. This value measures the helium inside of the drive specific to this manufacturer. It is a pre-fail attribute that trips once the drive detects that the internal environment is out of specification.', + 'display_type': 'normalized' + }, + '220': { + 'display_name': 'Disk Shift', + 'ideal': 'low', + 'critical': false, + 'description': 'Distance the disk has shifted relative to the spindle (usually due to shock or temperature). Unit of measure is unknown.', + 'display_type': 'normalized' + }, + '221': { + 'display_name': 'G-Sense Error Rate', + 'ideal': 'low', + 'critical': false, + 'description': 'The count of errors resulting from externally induced shock and vibration.', + 'display_type': 'normalized' + }, + '222': { + 'display_name': 'Loaded Hours', + 'ideal': '', + 'critical': false, + 'description': 'Time spent operating under data load (movement of magnetic head armature).', + 'display_type': 'normalized' + }, + '223': { + 'display_name': 'Load/Unload Retry Count', + 'ideal': '', + 'critical': false, + 'description': 'Count of times head changes position.', + 'display_type': 'normalized' + }, + '224': { + 'display_name': 'Load Friction', + 'ideal': 'low', + 'critical': false, + 'description': 'Resistance caused by friction in mechanical parts while operating.', + 'display_type': 'normalized' + }, + '225': { + 'display_name': 'Load/Unload Cycle Count', + 'ideal': 'low', + 'critical': false, + 'description': 'Total count of load cycles Some drives use 193 (0xC1) for Load Cycle Count instead. See Description for 193 for significance of this number. ', + 'display_type': 'normalized' + }, + '226': { + 'display_name': 'Load "In"-time', + 'ideal': '', + 'critical': false, + 'description': 'Total time of loading on the magnetic heads actuator (time not spent in parking area).', + 'display_type': 'normalized' + }, + '227': { + 'display_name': 'Torque Amplification Count', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of attempts to compensate for platter speed variations.[66]', + 'display_type': '' + }, + '228': { + 'display_name': 'Power-Off Retract Cycle', + 'ideal': 'low', + 'critical': false, + 'description': 'The number of power-off cycles which are counted whenever there is a "retract event" and the heads are loaded off of the media such as when the machine is powered down, put to sleep, or is idle.', + 'display_type': '' + }, + '230': { + 'display_name': 'GMR Head Amplitude ', + 'ideal': '', + 'critical': false, + 'description': 'Amplitude of "thrashing" (repetitive head moving motions between operations).', + 'display_type': 'normalized' + }, + '231': { + 'display_name': 'Life Left', + 'ideal': '', + 'critical': false, + 'description': 'Indicates the approximate SSD life left, in terms of program/erase cycles or available reserved blocks. A normalized value of 100 represents a new drive, with a threshold value at 10 indicating a need for replacement. A value of 0 may mean that the drive is operating in read-only mode to allow data recovery.', + 'display_type': 'normalized' + }, + '232': { + 'display_name': 'Endurance Remaining', + 'ideal': '', + 'critical': false, + 'description': 'Number of physical erase cycles completed on the SSD as a percentage of the maximum physical erase cycles the drive is designed to endure.', + 'display_type': 'normalized' + }, + '233': { + 'display_name': 'Media Wearout Indicator', + 'ideal': '', + 'critical': false, + 'description': 'Intel SSDs report a normalized value from 100, a new drive, to a minimum of 1. It decreases while the NAND erase cycles increase from 0 to the maximum-rated cycles.', + 'display_type': 'normalized' + }, + '234': { + 'display_name': 'Average erase count', + 'ideal': '', + 'critical': false, + 'description': 'Decoded as: byte 0-1-2 = average erase count (big endian) and byte 3-4-5 = max erase count (big endian).', + 'display_type': 'normalized' + }, + '235': { + 'display_name': 'Good Block Count', + 'ideal': '', + 'critical': false, + 'description': 'Decoded as: byte 0-1-2 = good block count (big endian) and byte 3-4 = system (free) block count.', + 'display_type': 'normalized' + }, + '240': { + 'display_name': 'Head Flying Hours', + 'ideal': '', + 'critical': false, + 'description': 'Time spent during the positioning of the drive heads.[15][71] Some Fujitsu drives report the count of link resets during a data transfer.', + 'display_type': 'normalized' + }, + '241': { + 'display_name': 'Total LBAs Written', + 'ideal': '', + 'critical': false, + 'description': 'Total count of LBAs written.', + 'display_type': 'normalized' + }, + '242': { + 'display_name': 'Total LBAs Read', + 'ideal': '', + 'critical': false, + 'description': 'Total count of LBAs read.Some S.M.A.R.T. utilities will report a negative number for the raw value since in reality it has 48 bits rather than 32.', + 'display_type': 'normalized' + }, + '243': { + 'display_name': 'Total LBAs Written Expanded', + 'ideal': '', + 'critical': false, + 'description': 'The upper 5 bytes of the 12-byte total number of LBAs written to the device. The lower 7 byte value is located at attribute 0xF1.', + 'display_type': 'normalized' + }, + '244': { + 'display_name': 'Total LBAs Read Expanded', + 'ideal': '', + 'critical': false, + 'description': 'The upper 5 bytes of the 12-byte total number of LBAs read from the device. The lower 7 byte value is located at attribute 0xF2.', + 'display_type': 'normalized' + }, + '249': { + 'display_name': 'NAND Writes (1GiB)', + 'ideal': '', + 'critical': false, + 'description': 'Total NAND Writes. Raw value reports the number of writes to NAND in 1 GB increments.', + 'display_type': 'normalized' + }, + '250': { + 'display_name': 'Read Error Retry Rate', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of errors while reading from a disk.', + 'display_type': 'normalized' + }, + '251': { + 'display_name': 'Minimum Spares Remaining', + 'ideal': '', + 'critical': false, + 'description': 'The Minimum Spares Remaining attribute indicates the number of remaining spare blocks as a percentage of the total number of spare blocks available.', + 'display_type': 'normalized' + }, + '252': { + 'display_name': 'Newly Added Bad Flash Block', + 'ideal': '', + 'critical': false, + 'description': 'The Newly Added Bad Flash Block attribute indicates the total number of bad flash blocks the drive detected since it was first initialized in manufacturing.', + 'display_type': 'normalized' + }, + '254': { + 'display_name': 'Free Fall Protection', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of "Free Fall Events" detected.', + 'display_type': 'normalized' + }, + '3': { + 'display_name': 'Spin-Up Time', + 'ideal': 'low', + 'critical': false, + 'description': 'Average time of spindle spin up (from zero RPM to fully operational [milliseconds]).', + 'observed_thresholds': [{ + 'low': 78, + 'high': 96, + 'annual_failure_rate': 0.11452195377351217, + 'error_interval': [0.10591837762295722, 0.12363823501915781] + }, { + 'low': 96, + 'high': 114, + 'annual_failure_rate': 0.040274562840558074, + 'error_interval': [0.03465055611002801, 0.046551312468303144] + }, { + 'low': 114, + 'high': 132, + 'annual_failure_rate': 0.009100406705780476, + 'error_interval': [0.006530608971356785, 0.012345729280075591] + }, { + 'low': 132, + 'high': 150, + 'annual_failure_rate': 0.008561351734020232, + 'error_interval': [0.004273795939256936, 0.015318623141355509] + }, { + 'low': 150, + 'high': 168, + 'annual_failure_rate': 0.015780508262068848, + 'error_interval': [0.005123888078524015, 0.03682644215646287] + }, { + 'low': 168, + 'high': 186, + 'annual_failure_rate': 0.05262688124794024, + 'error_interval': [0.0325768689524594, 0.08044577830285578] + }, { + 'low': 186, + 'high': 204, + 'annual_failure_rate': 0.01957419424036038, + 'error_interval': [0.0023705257325185624, 0.0707087198669825] + }, { + 'low': 204, + 'high': 222, + 'annual_failure_rate': 0.026050959960031404, + 'error_interval': [0.0006595532020744994, 0.1451466588889228] }], - "display_type": "normalized" - }, - "4": { - "display_name": "Start/Stop Count", - "ideal": "", - "critical": false, - "description": "A tally of spindle start/stop cycles. The spindle turns on, and hence the count is increased, both when the hard disk is turned on after having before been turned entirely off (disconnected from power source) and when the hard disk returns from having previously been put to sleep mode.", - "observed_thresholds": [{ - "low": 0, - "high": 13, - "annual_failure_rate": 0.01989335424860646, - "error_interval": [0.016596548909440657, 0.023653263230617408] - }, { - "low": 13, - "high": 26, - "annual_failure_rate": 0.03776935438256488, - "error_interval": [0.03310396052098642, 0.04290806173460437] - }, { - "low": 26, - "high": 39, - "annual_failure_rate": 0.11022223828187004, - "error_interval": [0.09655110535164119, 0.12528657238811672] - }, { - "low": 39, - "high": 52, - "annual_failure_rate": 0.16289995457762474, - "error_interval": [0.13926541653588131, 0.18939614504497515] - }, { - "low": 52, - "high": 65, - "annual_failure_rate": 0.19358212432279714, - "error_interval": [0.15864522253849073, 0.23392418181765526] - }, { - "low": 65, - "high": 78, - "annual_failure_rate": 0.1157094940074447, - "error_interval": [0.07861898732346269, 0.16424039052527728] - }, { - "low": 78, - "high": 91, - "annual_failure_rate": 0.12262136155304391, - "error_interval": [0.0670382394080032, 0.20573780888032978] - }, { - "low": 91, - "high": 104, - "annual_failure_rate": 0, - "error_interval": [0, 0] + 'display_type': 'normalized' + }, + '4': { + 'display_name': 'Start/Stop Count', + 'ideal': '', + 'critical': false, + 'description': 'A tally of spindle start/stop cycles. The spindle turns on, and hence the count is increased, both when the hard disk is turned on after having before been turned entirely off (disconnected from power source) and when the hard disk returns from having previously been put to sleep mode.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 13, + 'annual_failure_rate': 0.01989335424860646, + 'error_interval': [0.016596548909440657, 0.023653263230617408] + }, { + 'low': 13, + 'high': 26, + 'annual_failure_rate': 0.03776935438256488, + 'error_interval': [0.03310396052098642, 0.04290806173460437] + }, { + 'low': 26, + 'high': 39, + 'annual_failure_rate': 0.11022223828187004, + 'error_interval': [0.09655110535164119, 0.12528657238811672] + }, { + 'low': 39, + 'high': 52, + 'annual_failure_rate': 0.16289995457762474, + 'error_interval': [0.13926541653588131, 0.18939614504497515] + }, { + 'low': 52, + 'high': 65, + 'annual_failure_rate': 0.19358212432279714, + 'error_interval': [0.15864522253849073, 0.23392418181765526] + }, { + 'low': 65, + 'high': 78, + 'annual_failure_rate': 0.1157094940074447, + 'error_interval': [0.07861898732346269, 0.16424039052527728] + }, { + 'low': 78, + 'high': 91, + 'annual_failure_rate': 0.12262136155304391, + 'error_interval': [0.0670382394080032, 0.20573780888032978] + }, { + 'low': 91, + 'high': 104, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] }], - "display_type": "raw" - }, - "5": { - "display_name": "Reallocated Sectors Count", - "ideal": "low", - "critical": true, - "description": "Count of reallocated sectors. The raw value represents a count of the bad sectors that have been found and remapped.Thus, the higher the attribute value, the more sectors the drive has had to reallocate. This value is primarily used as a metric of the life expectancy of the drive; a drive which has had any reallocations at all is significantly more likely to fail in the immediate months.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.025169175350572493, - "error_interval": [0.022768612038746357, 0.027753988579272894] - }, { - "low": 1, - "high": 4, - "annual_failure_rate": 0.027432608477803388, - "error_interval": [0.010067283827589948, 0.05970923963096652] - }, { - "low": 4, - "high": 16, - "annual_failure_rate": 0.07501976284584981, - "error_interval": [0.039944864177334186, 0.12828607921150972] - }, { - "low": 16, - "high": 70, - "annual_failure_rate": 0.23589260654405794, - "error_interval": [0.1643078435800227, 0.32806951196017664] - }, { - "low": 70, - "high": 260, - "annual_failure_rate": 0.36193219378600433, - "error_interval": [0.2608488901774093, 0.4892271827875412] - }, { - "low": 260, - "high": 1100, - "annual_failure_rate": 0.5676621428968173, - "error_interval": [0.4527895568499355, 0.702804359408436] - }, { - "low": 1100, - "high": 4500, - "annual_failure_rate": 1.5028253400346423, - "error_interval": [1.2681757596263297, 1.768305221795894] - }, { - "low": 4500, - "high": 17000, - "annual_failure_rate": 2.0659987547404763, - "error_interval": [1.6809790460512237, 2.512808045182302] - }, { - "low": 17000, - "high": 70000, - "annual_failure_rate": 1.7755385684503124, - "error_interval": [1.2796520259849835, 2.400012341226441] + 'display_type': 'raw' + }, + '5': { + 'display_name': 'Reallocated Sectors Count', + 'ideal': 'low', + 'critical': true, + 'description': 'Count of reallocated sectors. The raw value represents a count of the bad sectors that have been found and remapped.Thus, the higher the attribute value, the more sectors the drive has had to reallocate. This value is primarily used as a metric of the life expectancy of the drive; a drive which has had any reallocations at all is significantly more likely to fail in the immediate months.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.025169175350572493, + 'error_interval': [0.022768612038746357, 0.027753988579272894] + }, { + 'low': 1, + 'high': 4, + 'annual_failure_rate': 0.027432608477803388, + 'error_interval': [0.010067283827589948, 0.05970923963096652] + }, { + 'low': 4, + 'high': 16, + 'annual_failure_rate': 0.07501976284584981, + 'error_interval': [0.039944864177334186, 0.12828607921150972] + }, { + 'low': 16, + 'high': 70, + 'annual_failure_rate': 0.23589260654405794, + 'error_interval': [0.1643078435800227, 0.32806951196017664] + }, { + 'low': 70, + 'high': 260, + 'annual_failure_rate': 0.36193219378600433, + 'error_interval': [0.2608488901774093, 0.4892271827875412] + }, { + 'low': 260, + 'high': 1100, + 'annual_failure_rate': 0.5676621428968173, + 'error_interval': [0.4527895568499355, 0.702804359408436] + }, { + 'low': 1100, + 'high': 4500, + 'annual_failure_rate': 1.5028253400346423, + 'error_interval': [1.2681757596263297, 1.768305221795894] + }, { + 'low': 4500, + 'high': 17000, + 'annual_failure_rate': 2.0659987547404763, + 'error_interval': [1.6809790460512237, 2.512808045182302] + }, { + 'low': 17000, + 'high': 70000, + 'annual_failure_rate': 1.7755385684503124, + 'error_interval': [1.2796520259849835, 2.400012341226441] }], - "display_type": "raw" - }, - "6": { - "display_name": "Read Channel Margin", - "ideal": "", - "critical": false, - "description": "Margin of a channel while reading data. The function of this attribute is not specified.", - "display_type": "normalized" - }, - "7": { - "display_name": "Seek Error Rate", - "ideal": "", - "critical": false, - "description": "(Vendor specific raw value.) Rate of seek errors of the magnetic heads. If there is a partial failure in the mechanical positioning system, then seek errors will arise. Such a failure may be due to numerous factors, such as damage to a servo, or thermal widening of the hard disk. The raw value has different structure for different vendors and is often not meaningful as a decimal number.", - "observed_thresholds": [{ - "low": 58, - "high": 76, - "annual_failure_rate": 0.2040131025936549, - "error_interval": [0.17032852883286412, 0.2424096283327138] - }, { - "low": 76, - "high": 94, - "annual_failure_rate": 0.08725919610118257, - "error_interval": [0.08077138510999876, 0.09412943212007528] - }, { - "low": 94, - "high": 112, - "annual_failure_rate": 0.01087335627722523, - "error_interval": [0.008732197944943352, 0.013380600544561905] - }, { - "low": 112, - "high": 130, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 130, - "high": 148, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 148, - "high": 166, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 166, - "high": 184, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 184, - "high": 202, - "annual_failure_rate": 0.05316285755900475, - "error_interval": [0.03370069132942804, 0.07977038905848267] + 'display_type': 'raw' + }, + '6': { + 'display_name': 'Read Channel Margin', + 'ideal': '', + 'critical': false, + 'description': 'Margin of a channel while reading data. The function of this attribute is not specified.', + 'display_type': 'normalized' + }, + '7': { + 'display_name': 'Seek Error Rate', + 'ideal': '', + 'critical': false, + 'description': '(Vendor specific raw value.) Rate of seek errors of the magnetic heads. If there is a partial failure in the mechanical positioning system, then seek errors will arise. Such a failure may be due to numerous factors, such as damage to a servo, or thermal widening of the hard disk. The raw value has different structure for different vendors and is often not meaningful as a decimal number.', + 'observed_thresholds': [{ + 'low': 58, + 'high': 76, + 'annual_failure_rate': 0.2040131025936549, + 'error_interval': [0.17032852883286412, 0.2424096283327138] + }, { + 'low': 76, + 'high': 94, + 'annual_failure_rate': 0.08725919610118257, + 'error_interval': [0.08077138510999876, 0.09412943212007528] + }, { + 'low': 94, + 'high': 112, + 'annual_failure_rate': 0.01087335627722523, + 'error_interval': [0.008732197944943352, 0.013380600544561905] + }, { + 'low': 112, + 'high': 130, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 130, + 'high': 148, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 148, + 'high': 166, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 166, + 'high': 184, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 184, + 'high': 202, + 'annual_failure_rate': 0.05316285755900475, + 'error_interval': [0.03370069132942804, 0.07977038905848267] }], - "display_type": "normalized" - }, - "8": { - "display_name": "Seek Time Performance", - "ideal": "high", - "critical": false, - "description": "Average performance of seek operations of the magnetic heads. If this attribute is decreasing, it is a sign of problems in the mechanical subsystem.", - "display_type": "normalized" - }, - "9": { - "display_name": "Power-On Hours", - "ideal": "", - "critical": false, - "description": "Count of hours in power-on state. The raw value of this attribute shows total count of hours (or minutes, or seconds, depending on manufacturer) in power-on state. By default, the total expected lifetime of a hard disk in perfect condition is defined as 5 years (running every day and night on all days). This is equal to 1825 days in 24/7 mode or 43800 hours. On some pre-2005 drives, this raw value may advance erratically and/or \"wrap around\" (reset to zero periodically).", - "display_type": "normalized" + 'display_type': 'normalized' + }, + '8': { + 'display_name': 'Seek Time Performance', + 'ideal': 'high', + 'critical': false, + 'description': 'Average performance of seek operations of the magnetic heads. If this attribute is decreasing, it is a sign of problems in the mechanical subsystem.', + 'display_type': 'normalized' + }, + '9': { + 'display_name': 'Power-On Hours', + 'ideal': '', + 'critical': false, + 'description': 'Count of hours in power-on state. The raw value of this attribute shows total count of hours (or minutes, or seconds, depending on manufacturer) in power-on state. By default, the total expected lifetime of a hard disk in perfect condition is defined as 5 years (running every day and night on all days). This is equal to 1825 days in 24/7 mode or 43800 hours. On some pre-2005 drives, this raw value may advance erratically and/or "wrap around" (reset to zero periodically).', + 'display_type': 'normalized' } }, - "success": true + 'success': true } diff --git a/webapp/frontend/src/app/data/mock/device/details/sdc.ts b/webapp/frontend/src/app/data/mock/device/details/sdc.ts index 66fa65d..a647ec0 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sdc.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sdc.ts @@ -1,1593 +1,1593 @@ export const sdc = { - "data": { - "device": { - "CreatedAt": "2021-06-24T21:17:31.303033-07:00", - "UpdatedAt": "2021-10-24T16:37:56.74865-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264ec3183", - "device_name": "sdc", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "9RK4XXXXX", - "firmware": "MS1OA650", - "rotational_speed": 0, - "capacity": 14000519643136, - "form_factor": "", - "smart_support": false, - "device_protocol": "ATA", - "device_type": "", - "label": "", - "host_id": "", - "device_status": 3 - }, - "smart_results": [{ - "date": "2021-10-24T23:20:44Z", - "device_wwn": "0x5000cca264ec3183", - "device_protocol": "ATA", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "attrs": { - "1": { - "attribute_id": 1, - "value": 100, - "thresh": 16, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.034155719633986996 + 'data': { + 'device': { + 'CreatedAt': '2021-06-24T21:17:31.303033-07:00', + 'UpdatedAt': '2021-10-24T16:37:56.74865-07:00', + 'DeletedAt': null, + 'wwn': '0x5000cca264ec3183', + 'device_name': 'sdc', + 'manufacturer': 'ATA', + 'model_name': 'WDC_WD140EDFZ-11A0VA0', + 'interface_type': 'SCSI', + 'interface_speed': '', + 'serial_number': '9RK4XXXXX', + 'firmware': 'MS1OA650', + 'rotational_speed': 0, + 'capacity': 14000519643136, + 'form_factor': '', + 'smart_support': false, + 'device_protocol': 'ATA', + 'device_type': '', + 'label': '', + 'host_id': '', + 'device_status': 3 + }, + 'smart_results': [{ + 'date': '2021-10-24T23:20:44Z', + 'device_wwn': '0x5000cca264ec3183', + 'device_protocol': 'ATA', + 'temp': 25, + 'power_on_hours': 65592, + 'power_cycle_count': 86, + 'attrs': { + '1': { + 'attribute_id': 1, + 'value': 100, + 'thresh': 16, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.034155719633986996 }, - "10": { - "attribute_id": 10, - "value": 100, - "thresh": 60, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.05459827163896099 + '10': { + 'attribute_id': 10, + 'value': 100, + 'thresh': 60, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.05459827163896099 }, - "12": { - "attribute_id": 12, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0, - "status": 2, - "status_reason": "Observed Failure Rate for Attribute is greater than 10%", - "failure_rate": 0.12354840389522469 + '12': { + 'attribute_id': 12, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 86, + 'raw_string': '86', + 'when_failed': '', + 'transformed_value': 0, + 'status': 2, + 'status_reason': 'Observed Failure Rate for Attribute is greater than 10%', + 'failure_rate': 0.12354840389522469 }, - "192": { - "attribute_id": 192, - "value": 95, - "thresh": 0, - "worst": 95, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '192': { + 'attribute_id': 192, + 'value': 95, + 'thresh': 0, + 'worst': 95, + 'raw_value': 6244, + 'raw_string': '6244', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "193": { - "attribute_id": 193, - "value": 95, - "thresh": 0, - "worst": 95, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '193': { + 'attribute_id': 193, + 'value': 95, + 'thresh': 0, + 'worst': 95, + 'raw_value': 6244, + 'raw_string': '6244', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "194": { - "attribute_id": 194, - "value": 240, - "thresh": 0, - "worst": 240, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25, - "status": 0 + '194': { + 'attribute_id': 194, + 'value': 240, + 'thresh': 0, + 'worst': 240, + 'raw_value': 167504969753, + 'raw_string': '25 (Min/Max 19/39)', + 'when_failed': '', + 'transformed_value': 25, + 'status': 0 }, - "196": { - "attribute_id": 196, - "value": 1, - "thresh": 0, - "worst": 1, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0, - "status": 2, - "status_reason": "Could not determine Observed Failure Rate for Critical Attribute" + '196': { + 'attribute_id': 196, + 'value': 1, + 'thresh': 0, + 'worst': 1, + 'raw_value': 3831, + 'raw_string': '3831', + 'when_failed': '', + 'transformed_value': 0, + 'status': 2, + 'status_reason': 'Could not determine Observed Failure Rate for Critical Attribute' }, - "197": { - "attribute_id": 197, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 8, - "raw_string": "8", - "when_failed": "", - "transformed_value": 0, - "status": 1, - "status_reason": "Observed Failure Rate for Critical Attribute is greater than 10%", - "failure_rate": 0.6108100007493069 + '197': { + 'attribute_id': 197, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 8, + 'raw_string': '8', + 'when_failed': '', + 'transformed_value': 0, + 'status': 1, + 'status_reason': 'Observed Failure Rate for Critical Attribute is greater than 10%', + 'failure_rate': 0.6108100007493069 }, - "198": { - "attribute_id": 198, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.028675322159886437 + '198': { + 'attribute_id': 198, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.028675322159886437 }, - "199": { - "attribute_id": 199, - "value": 200, - "thresh": 0, - "worst": 200, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '199': { + 'attribute_id': 199, + 'value': 200, + 'thresh': 0, + 'worst': 200, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "2": { - "attribute_id": 2, - "value": 136, - "thresh": 54, - "worst": 136, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '2': { + 'attribute_id': 2, + 'value': 136, + 'thresh': 54, + 'worst': 136, + 'raw_value': 91, + 'raw_string': '91', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "3": { - "attribute_id": 3, - "value": 125, - "thresh": 24, - "worst": 125, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.009100406705780476 + '3': { + 'attribute_id': 3, + 'value': 125, + 'thresh': 24, + 'worst': 125, + 'raw_value': 17192124596, + 'raw_string': '180 (Average 187)', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.009100406705780476 }, - "4": { - "attribute_id": 4, - "value": 100, - "thresh": 0, - "worst": 100, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0, - "status": 2, - "status_reason": "Observed Failure Rate for Attribute is greater than 10%", - "failure_rate": 0.12262136155304391 + '4': { + 'attribute_id': 4, + 'value': 100, + 'thresh': 0, + 'worst': 100, + 'raw_value': 86, + 'raw_string': '86', + 'when_failed': '', + 'transformed_value': 0, + 'status': 2, + 'status_reason': 'Observed Failure Rate for Attribute is greater than 10%', + 'failure_rate': 0.12262136155304391 }, - "5": { - "attribute_id": 5, - "value": 1, - "thresh": 5, - "worst": 1, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0, - "status": 1, - "status_reason": "Observed Failure Rate for Critical Attribute is greater than 10%", - "failure_rate": 1.5028253400346423 + '5': { + 'attribute_id': 5, + 'value': 1, + 'thresh': 5, + 'worst': 1, + 'raw_value': 1975, + 'raw_string': '1975', + 'when_failed': 'now', + 'transformed_value': 0, + 'status': 1, + 'status_reason': 'Observed Failure Rate for Critical Attribute is greater than 10%', + 'failure_rate': 1.5028253400346423 }, - "7": { - "attribute_id": 7, - "value": 100, - "thresh": 67, - "worst": 100, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": 0, - "failure_rate": 0.01087335627722523 + '7': { + 'attribute_id': 7, + 'value': 100, + 'thresh': 67, + 'worst': 100, + 'raw_value': 0, + 'raw_string': '0', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0, + 'failure_rate': 0.01087335627722523 }, - "8": { - "attribute_id": 8, - "value": 118, - "thresh": 20, - "worst": 118, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '8': { + 'attribute_id': 8, + 'value': 118, + 'thresh': 20, + 'worst': 118, + 'raw_value': 33, + 'raw_string': '33', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 }, - "9": { - "attribute_id": 9, - "value": 91, - "thresh": 0, - "worst": 91, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0, - "status": 0 + '9': { + 'attribute_id': 9, + 'value': 91, + 'thresh': 0, + 'worst': 91, + 'raw_value': 65592, + 'raw_string': '65592', + 'when_failed': '', + 'transformed_value': 0, + 'status': 0 } }, - "Status": 0 + 'Status': 0 }] }, - "metadata": { - "1": { - "display_name": "Read Error Rate", - "ideal": "low", - "critical": false, - "description": "(Vendor specific raw value.) Stores data related to the rate of hardware read errors that occurred when reading data from a disk surface. The raw value has different structure for different vendors and is often not meaningful as a decimal number.", - "observed_thresholds": [{ - "low": 80, - "high": 95, - "annual_failure_rate": 0.8879749768303985, - "error_interval": [0.682344353388663, 1.136105732920724] - }, { - "low": 95, - "high": 110, - "annual_failure_rate": 0.034155719633986996, - "error_interval": [0.030188482024981093, 0.038499386872354435] - }, { - "low": 110, - "high": 125, - "annual_failure_rate": 0.06390002135229157, - "error_interval": [0.05852004676110847, 0.06964160930553712] - }, { - "low": 125, - "high": 140, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 140, - "high": 155, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 155, - "high": 170, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 170, - "high": 185, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 185, - "high": 200, - "annual_failure_rate": 0.044823775021490854, - "error_interval": [0.032022762038723306, 0.06103725943096589] + 'metadata': { + '1': { + 'display_name': 'Read Error Rate', + 'ideal': 'low', + 'critical': false, + 'description': '(Vendor specific raw value.) Stores data related to the rate of hardware read errors that occurred when reading data from a disk surface. The raw value has different structure for different vendors and is often not meaningful as a decimal number.', + 'observed_thresholds': [{ + 'low': 80, + 'high': 95, + 'annual_failure_rate': 0.8879749768303985, + 'error_interval': [0.682344353388663, 1.136105732920724] + }, { + 'low': 95, + 'high': 110, + 'annual_failure_rate': 0.034155719633986996, + 'error_interval': [0.030188482024981093, 0.038499386872354435] + }, { + 'low': 110, + 'high': 125, + 'annual_failure_rate': 0.06390002135229157, + 'error_interval': [0.05852004676110847, 0.06964160930553712] + }, { + 'low': 125, + 'high': 140, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 140, + 'high': 155, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 155, + 'high': 170, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 170, + 'high': 185, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 185, + 'high': 200, + 'annual_failure_rate': 0.044823775021490854, + 'error_interval': [0.032022762038723306, 0.06103725943096589] }], - "display_type": "normalized" - }, - "10": { - "display_name": "Spin Retry Count", - "ideal": "low", - "critical": true, - "description": "Count of retry of spin start attempts. This attribute stores a total count of the spin start attempts to reach the fully operational speed (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.05459827163896099, - "error_interval": [0.05113785787727033, 0.05823122757702782] - }, { - "low": 0, - "high": 80, - "annual_failure_rate": 0.5555555555555556, - "error_interval": [0.014065448880161053, 3.095357439410498] + 'display_type': 'normalized' + }, + '10': { + 'display_name': 'Spin Retry Count', + 'ideal': 'low', + 'critical': true, + 'description': 'Count of retry of spin start attempts. This attribute stores a total count of the spin start attempts to reach the fully operational speed (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.05459827163896099, + 'error_interval': [0.05113785787727033, 0.05823122757702782] + }, { + 'low': 0, + 'high': 80, + 'annual_failure_rate': 0.5555555555555556, + 'error_interval': [0.014065448880161053, 3.095357439410498] }], - "display_type": "raw" - }, - "11": { - "display_name": "Recalibration Retries or Calibration Retry Count", - "ideal": "low", - "critical": false, - "description": "This attribute indicates the count that recalibration was requested (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.04658866433672694, - "error_interval": [0.03357701137320878, 0.06297433993055492] - }, { - "low": 0, - "high": 80, - "annual_failure_rate": 0.5555555555555556, - "error_interval": [0.014065448880161053, 3.095357439410498] - }, { - "low": 80, - "high": 160, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 160, - "high": 240, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 240, - "high": 320, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 320, - "high": 400, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 400, - "high": 480, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 480, - "high": 560, - "annual_failure_rate": 0, - "error_interval": [0, 0] + 'display_type': 'raw' + }, + '11': { + 'display_name': 'Recalibration Retries or Calibration Retry Count', + 'ideal': 'low', + 'critical': false, + 'description': 'This attribute indicates the count that recalibration was requested (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.04658866433672694, + 'error_interval': [0.03357701137320878, 0.06297433993055492] + }, { + 'low': 0, + 'high': 80, + 'annual_failure_rate': 0.5555555555555556, + 'error_interval': [0.014065448880161053, 3.095357439410498] + }, { + 'low': 80, + 'high': 160, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 160, + 'high': 240, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 240, + 'high': 320, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 320, + 'high': 400, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 400, + 'high': 480, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 480, + 'high': 560, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] }], - "display_type": "raw" - }, - "12": { - "display_name": "Power Cycle Count", - "ideal": "low", - "critical": false, - "description": "This attribute indicates the count of full hard disk power on/off cycles.", - "observed_thresholds": [{ - "low": 0, - "high": 13, - "annual_failure_rate": 0.019835987118930823, - "error_interval": [0.016560870164523494, 0.023569242386797896] - }, { - "low": 13, - "high": 26, - "annual_failure_rate": 0.038210930067894826, - "error_interval": [0.03353859179329295, 0.0433520775718649] - }, { - "low": 26, - "high": 39, - "annual_failure_rate": 0.11053528307302571, - "error_interval": [0.09671061589521368, 0.1257816678419765] - }, { - "low": 39, - "high": 52, - "annual_failure_rate": 0.16831189443375036, - "error_interval": [0.1440976510675928, 0.19543066007594895] - }, { - "low": 52, - "high": 65, - "annual_failure_rate": 0.20630344262550107, - "error_interval": [0.1693965932069108, 0.2488633537247856] - }, { - "low": 65, - "high": 78, - "annual_failure_rate": 0.1030972634140512, - "error_interval": [0.06734655535304743, 0.15106137807407605] - }, { - "low": 78, - "high": 91, - "annual_failure_rate": 0.12354840389522469, - "error_interval": [0.06578432170016109, 0.21127153335749593] + 'display_type': 'raw' + }, + '12': { + 'display_name': 'Power Cycle Count', + 'ideal': 'low', + 'critical': false, + 'description': 'This attribute indicates the count of full hard disk power on/off cycles.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 13, + 'annual_failure_rate': 0.019835987118930823, + 'error_interval': [0.016560870164523494, 0.023569242386797896] + }, { + 'low': 13, + 'high': 26, + 'annual_failure_rate': 0.038210930067894826, + 'error_interval': [0.03353859179329295, 0.0433520775718649] + }, { + 'low': 26, + 'high': 39, + 'annual_failure_rate': 0.11053528307302571, + 'error_interval': [0.09671061589521368, 0.1257816678419765] + }, { + 'low': 39, + 'high': 52, + 'annual_failure_rate': 0.16831189443375036, + 'error_interval': [0.1440976510675928, 0.19543066007594895] + }, { + 'low': 52, + 'high': 65, + 'annual_failure_rate': 0.20630344262550107, + 'error_interval': [0.1693965932069108, 0.2488633537247856] + }, { + 'low': 65, + 'high': 78, + 'annual_failure_rate': 0.1030972634140512, + 'error_interval': [0.06734655535304743, 0.15106137807407605] + }, { + 'low': 78, + 'high': 91, + 'annual_failure_rate': 0.12354840389522469, + 'error_interval': [0.06578432170016109, 0.21127153335749593] }], - "display_type": "raw" - }, - "13": { - "display_name": "Soft Read Error Rate", - "ideal": "low", - "critical": false, - "description": "Uncorrected read errors reported to the operating system.", - "display_type": "normalized" - }, - "170": { - "display_name": "Available Reserved Space", - "ideal": "", - "critical": false, - "description": "See attribute E8.", - "display_type": "normalized" - }, - "171": { - "display_name": "SSD Program Fail Count", - "ideal": "", - "critical": false, - "description": "(Kingston) The total number of flash program operation failures since the drive was deployed.[33] Identical to attribute 181.", - "display_type": "normalized" - }, - "172": { - "display_name": "SSD Erase Fail Count", - "ideal": "", - "critical": false, - "description": "(Kingston) Counts the number of flash erase failures. This attribute returns the total number of Flash erase operation failures since the drive was deployed. This attribute is identical to attribute 182.", - "display_type": "normalized" - }, - "173": { - "display_name": "SSD Wear Leveling Count", - "ideal": "", - "critical": false, - "description": "Counts the maximum worst erase count on any block.", - "display_type": "normalized" - }, - "174": { - "display_name": "Unexpected Power Loss Count", - "ideal": "", - "critical": false, - "description": "Also known as \"Power-off Retract Count\" per conventional HDD terminology. Raw value reports the number of unclean shutdowns, cumulative over the life of an SSD, where an \"unclean shutdown\" is the removal of power without STANDBY IMMEDIATE as the last command (regardless of PLI activity using capacitor power). Normalized value is always 100.", - "display_type": "" - }, - "175": { - "display_name": "Power Loss Protection Failure", - "ideal": "", - "critical": false, - "description": "Last test result as microseconds to discharge cap, saturated at its maximum value. Also logs minutes since last test and lifetime number of tests. Raw value contains the following data: Bytes 0-1: Last test result as microseconds to discharge cap, saturates at max value. Test result expected in range 25 \u003c= result \u003c= 5000000, lower indicates specific error code. Bytes 2-3: Minutes since last test, saturates at max value.Bytes 4-5: Lifetime number of tests, not incremented on power cycle, saturates at max value. Normalized value is set to one on test failure or 11 if the capacitor has been tested in an excessive temperature condition, otherwise 100.", - "display_type": "normalized" - }, - "176": { - "display_name": "Erase Fail Count", - "ideal": "", - "critical": false, - "description": "S.M.A.R.T. parameter indicates a number of flash erase command failures.", - "display_type": "normalized" - }, - "177": { - "display_name": "Wear Range Delta", - "ideal": "", - "critical": false, - "description": "Delta between most-worn and least-worn Flash blocks. It describes how good/bad the wearleveling of the SSD works on a more technical way. ", - "display_type": "normalized" - }, - "179": { - "display_name": "Used Reserved Block Count Total", - "ideal": "", - "critical": false, - "description": "Pre-Fail attribute used at least in Samsung devices.", - "display_type": "normalized" - }, - "180": { - "display_name": "Unused Reserved Block Count Total", - "ideal": "", - "critical": false, - "description": "\"Pre-Fail\" attribute used at least in HP devices. ", - "display_type": "normalized" - }, - "181": { - "display_name": "Program Fail Count Total", - "ideal": "", - "critical": false, - "description": "Total number of Flash program operation failures since the drive was deployed.", - "display_type": "normalized" - }, - "182": { - "display_name": "Erase Fail Count", - "ideal": "", - "critical": false, - "description": "\"Pre-Fail\" Attribute used at least in Samsung devices.", - "display_type": "normalized" - }, - "183": { - "display_name": "SATA Downshift Error Count or Runtime Bad Block", - "ideal": "low", - "critical": false, - "description": "Western Digital, Samsung or Seagate attribute: Either the number of downshifts of link speed (e.g. from 6Gbit/s to 3Gbit/s) or the total number of data blocks with detected, uncorrectable errors encountered during normal operation. Although degradation of this parameter can be an indicator of drive aging and/or potential electromechanical problems, it does not directly indicate imminent drive failure.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.09084549203210031, - "error_interval": [0.08344373475686712, 0.09872777224842152] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.05756065656498585, - "error_interval": [0.04657000847949464, 0.07036491775108872] - }, { - "low": 2, - "high": 4, - "annual_failure_rate": 0.6193088626208925, - "error_interval": [0.41784508895529787, 0.8841019099092139] - }, { - "low": 4, - "high": 8, - "annual_failure_rate": 0.5533447034299792, - "error_interval": [0.31628430884775033, 0.8985971312402635] - }, { - "low": 8, - "high": 16, - "annual_failure_rate": 0.3882388694727245, - "error_interval": [0.21225380267814295, 0.6513988534774338] - }, { - "low": 16, - "high": 35, - "annual_failure_rate": 0.37116708385481856, - "error_interval": [0.19763084005134446, 0.6347070173754686] - }, { - "low": 35, - "high": 70, - "annual_failure_rate": 0.2561146752205292, - "error_interval": [0.10297138269895259, 0.5276941165819332] - }, { - "low": 70, - "high": 130, - "annual_failure_rate": 0.40299684542586756, - "error_interval": [0.16202563309223209, 0.8303275247667772] - }, { - "low": 130, - "high": 260, - "annual_failure_rate": 0, - "error_interval": [0, 0] + 'display_type': 'raw' + }, + '13': { + 'display_name': 'Soft Read Error Rate', + 'ideal': 'low', + 'critical': false, + 'description': 'Uncorrected read errors reported to the operating system.', + 'display_type': 'normalized' + }, + '170': { + 'display_name': 'Available Reserved Space', + 'ideal': '', + 'critical': false, + 'description': 'See attribute E8.', + 'display_type': 'normalized' + }, + '171': { + 'display_name': 'SSD Program Fail Count', + 'ideal': '', + 'critical': false, + 'description': '(Kingston) The total number of flash program operation failures since the drive was deployed.[33] Identical to attribute 181.', + 'display_type': 'normalized' + }, + '172': { + 'display_name': 'SSD Erase Fail Count', + 'ideal': '', + 'critical': false, + 'description': '(Kingston) Counts the number of flash erase failures. This attribute returns the total number of Flash erase operation failures since the drive was deployed. This attribute is identical to attribute 182.', + 'display_type': 'normalized' + }, + '173': { + 'display_name': 'SSD Wear Leveling Count', + 'ideal': '', + 'critical': false, + 'description': 'Counts the maximum worst erase count on any block.', + 'display_type': 'normalized' + }, + '174': { + 'display_name': 'Unexpected Power Loss Count', + 'ideal': '', + 'critical': false, + 'description': 'Also known as "Power-off Retract Count" per conventional HDD terminology. Raw value reports the number of unclean shutdowns, cumulative over the life of an SSD, where an "unclean shutdown" is the removal of power without STANDBY IMMEDIATE as the last command (regardless of PLI activity using capacitor power). Normalized value is always 100.', + 'display_type': '' + }, + '175': { + 'display_name': 'Power Loss Protection Failure', + 'ideal': '', + 'critical': false, + 'description': 'Last test result as microseconds to discharge cap, saturated at its maximum value. Also logs minutes since last test and lifetime number of tests. Raw value contains the following data: Bytes 0-1: Last test result as microseconds to discharge cap, saturates at max value. Test result expected in range 25 \u003c= result \u003c= 5000000, lower indicates specific error code. Bytes 2-3: Minutes since last test, saturates at max value.Bytes 4-5: Lifetime number of tests, not incremented on power cycle, saturates at max value. Normalized value is set to one on test failure or 11 if the capacitor has been tested in an excessive temperature condition, otherwise 100.', + 'display_type': 'normalized' + }, + '176': { + 'display_name': 'Erase Fail Count', + 'ideal': '', + 'critical': false, + 'description': 'S.M.A.R.T. parameter indicates a number of flash erase command failures.', + 'display_type': 'normalized' + }, + '177': { + 'display_name': 'Wear Range Delta', + 'ideal': '', + 'critical': false, + 'description': 'Delta between most-worn and least-worn Flash blocks. It describes how good/bad the wearleveling of the SSD works on a more technical way. ', + 'display_type': 'normalized' + }, + '179': { + 'display_name': 'Used Reserved Block Count Total', + 'ideal': '', + 'critical': false, + 'description': 'Pre-Fail attribute used at least in Samsung devices.', + 'display_type': 'normalized' + }, + '180': { + 'display_name': 'Unused Reserved Block Count Total', + 'ideal': '', + 'critical': false, + 'description': '"Pre-Fail" attribute used at least in HP devices. ', + 'display_type': 'normalized' + }, + '181': { + 'display_name': 'Program Fail Count Total', + 'ideal': '', + 'critical': false, + 'description': 'Total number of Flash program operation failures since the drive was deployed.', + 'display_type': 'normalized' + }, + '182': { + 'display_name': 'Erase Fail Count', + 'ideal': '', + 'critical': false, + 'description': '"Pre-Fail" Attribute used at least in Samsung devices.', + 'display_type': 'normalized' + }, + '183': { + 'display_name': 'SATA Downshift Error Count or Runtime Bad Block', + 'ideal': 'low', + 'critical': false, + 'description': 'Western Digital, Samsung or Seagate attribute: Either the number of downshifts of link speed (e.g. from 6Gbit/s to 3Gbit/s) or the total number of data blocks with detected, uncorrectable errors encountered during normal operation. Although degradation of this parameter can be an indicator of drive aging and/or potential electromechanical problems, it does not directly indicate imminent drive failure.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.09084549203210031, + 'error_interval': [0.08344373475686712, 0.09872777224842152] + }, { + 'low': 1, + 'high': 2, + 'annual_failure_rate': 0.05756065656498585, + 'error_interval': [0.04657000847949464, 0.07036491775108872] + }, { + 'low': 2, + 'high': 4, + 'annual_failure_rate': 0.6193088626208925, + 'error_interval': [0.41784508895529787, 0.8841019099092139] + }, { + 'low': 4, + 'high': 8, + 'annual_failure_rate': 0.5533447034299792, + 'error_interval': [0.31628430884775033, 0.8985971312402635] + }, { + 'low': 8, + 'high': 16, + 'annual_failure_rate': 0.3882388694727245, + 'error_interval': [0.21225380267814295, 0.6513988534774338] + }, { + 'low': 16, + 'high': 35, + 'annual_failure_rate': 0.37116708385481856, + 'error_interval': [0.19763084005134446, 0.6347070173754686] + }, { + 'low': 35, + 'high': 70, + 'annual_failure_rate': 0.2561146752205292, + 'error_interval': [0.10297138269895259, 0.5276941165819332] + }, { + 'low': 70, + 'high': 130, + 'annual_failure_rate': 0.40299684542586756, + 'error_interval': [0.16202563309223209, 0.8303275247667772] + }, { + 'low': 130, + 'high': 260, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] }], - "display_type": "raw" - }, - "184": { - "display_name": "End-to-End error", - "ideal": "low", - "critical": true, - "description": "This attribute is a part of Hewlett-Packard\"s SMART IV technology, as well as part of other vendors\" IO Error Detection and Correction schemas, and it contains a count of parity errors which occur in the data path to the media via the drive\"s cache RAM", - "observed_thresholds": [{ - "low": 93, - "high": 94, - "annual_failure_rate": 1.631212012870933, - "error_interval": [1.055634407303844, 2.407990716767714] - }, { - "low": 94, - "high": 95, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 95, - "high": 96, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 96, - "high": 97, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 97, - "high": 97, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 97, - "high": 98, - "annual_failure_rate": 1.8069306930693072, - "error_interval": [0.04574752432804858, 10.067573453924245] - }, { - "low": 98, - "high": 99, - "annual_failure_rate": 0.8371559633027523, - "error_interval": [0.10138347095016888, 3.0240951820174824] - }, { - "low": 99, - "high": 100, - "annual_failure_rate": 0.09334816849865138, - "error_interval": [0.08689499010435861, 0.10015372448181788] + 'display_type': 'raw' + }, + '184': { + 'display_name': 'End-to-End error', + 'ideal': 'low', + 'critical': true, + 'description': 'This attribute is a part of Hewlett-Packard"s SMART IV technology, as well as part of other vendors" IO Error Detection and Correction schemas, and it contains a count of parity errors which occur in the data path to the media via the drive"s cache RAM', + 'observed_thresholds': [{ + 'low': 93, + 'high': 94, + 'annual_failure_rate': 1.631212012870933, + 'error_interval': [1.055634407303844, 2.407990716767714] + }, { + 'low': 94, + 'high': 95, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 95, + 'high': 96, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 96, + 'high': 97, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 97, + 'high': 97, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 97, + 'high': 98, + 'annual_failure_rate': 1.8069306930693072, + 'error_interval': [0.04574752432804858, 10.067573453924245] + }, { + 'low': 98, + 'high': 99, + 'annual_failure_rate': 0.8371559633027523, + 'error_interval': [0.10138347095016888, 3.0240951820174824] + }, { + 'low': 99, + 'high': 100, + 'annual_failure_rate': 0.09334816849865138, + 'error_interval': [0.08689499010435861, 0.10015372448181788] }], - "display_type": "normalized" - }, - "185": { - "display_name": "Head Stability", - "ideal": "", - "critical": false, - "description": "Western Digital attribute.", - "display_type": "normalized" - }, - "186": { - "display_name": "Induced Op-Vibration Detection", - "ideal": "", - "critical": false, - "description": "Western Digital attribute.", - "display_type": "normalized" - }, - "187": { - "display_name": "Reported Uncorrectable Errors", - "ideal": "low", - "critical": true, - "description": "The count of errors that could not be recovered using hardware ECC (see attribute 195).", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.028130798308190524, - "error_interval": [0.024487830609364304, 0.032162944988161336] - }, { - "low": 1, - "high": 1, - "annual_failure_rate": 0.33877621175661743, - "error_interval": [0.22325565823630591, 0.4929016016666955] - }, { - "low": 1, - "high": 3, - "annual_failure_rate": 0.24064820598237213, - "error_interval": [0.14488594021076606, 0.3758019832614595] - }, { - "low": 3, - "high": 6, - "annual_failure_rate": 0.5014425058387142, - "error_interval": [0.3062941096766342, 0.7744372808405151] - }, { - "low": 6, - "high": 11, - "annual_failure_rate": 0.38007108544136836, - "error_interval": [0.2989500188963677, 0.4764223967570595] - }, { - "low": 11, - "high": 20, - "annual_failure_rate": 0.5346094598348444, - "error_interval": [0.40595137663302483, 0.6911066985735377] - }, { - "low": 20, - "high": 35, - "annual_failure_rate": 0.8428063943161636, - "error_interval": [0.6504601819243522, 1.0742259350903411] - }, { - "low": 35, - "high": 65, - "annual_failure_rate": 1.4429071005017484, - "error_interval": [1.1405581860945952, 1.8008133631629157] - }, { - "low": 65, - "high": 120, - "annual_failure_rate": 1.6190935390549661, - "error_interval": [1.0263664163011208, 2.4294352761068576] + 'display_type': 'normalized' + }, + '185': { + 'display_name': 'Head Stability', + 'ideal': '', + 'critical': false, + 'description': 'Western Digital attribute.', + 'display_type': 'normalized' + }, + '186': { + 'display_name': 'Induced Op-Vibration Detection', + 'ideal': '', + 'critical': false, + 'description': 'Western Digital attribute.', + 'display_type': 'normalized' + }, + '187': { + 'display_name': 'Reported Uncorrectable Errors', + 'ideal': 'low', + 'critical': true, + 'description': 'The count of errors that could not be recovered using hardware ECC (see attribute 195).', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.028130798308190524, + 'error_interval': [0.024487830609364304, 0.032162944988161336] + }, { + 'low': 1, + 'high': 1, + 'annual_failure_rate': 0.33877621175661743, + 'error_interval': [0.22325565823630591, 0.4929016016666955] + }, { + 'low': 1, + 'high': 3, + 'annual_failure_rate': 0.24064820598237213, + 'error_interval': [0.14488594021076606, 0.3758019832614595] + }, { + 'low': 3, + 'high': 6, + 'annual_failure_rate': 0.5014425058387142, + 'error_interval': [0.3062941096766342, 0.7744372808405151] + }, { + 'low': 6, + 'high': 11, + 'annual_failure_rate': 0.38007108544136836, + 'error_interval': [0.2989500188963677, 0.4764223967570595] + }, { + 'low': 11, + 'high': 20, + 'annual_failure_rate': 0.5346094598348444, + 'error_interval': [0.40595137663302483, 0.6911066985735377] + }, { + 'low': 20, + 'high': 35, + 'annual_failure_rate': 0.8428063943161636, + 'error_interval': [0.6504601819243522, 1.0742259350903411] + }, { + 'low': 35, + 'high': 65, + 'annual_failure_rate': 1.4429071005017484, + 'error_interval': [1.1405581860945952, 1.8008133631629157] + }, { + 'low': 65, + 'high': 120, + 'annual_failure_rate': 1.6190935390549661, + 'error_interval': [1.0263664163011208, 2.4294352761068576] }], - "display_type": "raw" - }, - "188": { - "display_name": "Command Timeout", - "ideal": "low", - "critical": true, - "description": "The count of aborted operations due to HDD timeout. Normally this attribute value should be equal to zero.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.024893587674442153, - "error_interval": [0.020857343769186413, 0.0294830350167543] - }, { - "low": 0, - "high": 13, - "annual_failure_rate": 0.10044174089362015, - "error_interval": [0.0812633664077498, 0.1227848196758574] - }, { - "low": 13, - "high": 26, - "annual_failure_rate": 0.334030592234279, - "error_interval": [0.2523231196342665, 0.4337665082489293] - }, { - "low": 26, - "high": 39, - "annual_failure_rate": 0.36724705400842445, - "error_interval": [0.30398009356575617, 0.4397986538328568] - }, { - "low": 39, - "high": 52, - "annual_failure_rate": 0.29848155926978354, - "error_interval": [0.2509254838615984, 0.35242890006477073] - }, { - "low": 52, - "high": 65, - "annual_failure_rate": 0.2203079701535098, - "error_interval": [0.18366082845676174, 0.26212468677179274] - }, { - "low": 65, - "high": 78, - "annual_failure_rate": 0.3018169948863018, - "error_interval": [0.23779746376787655, 0.37776897542831006] - }, { - "low": 78, - "high": 91, - "annual_failure_rate": 0.32854928239235887, - "error_interval": [0.2301118782147336, 0.4548506948185028] - }, { - "low": 91, - "high": 104, - "annual_failure_rate": 0.28488916640649387, - "error_interval": [0.1366154288236293, 0.5239213202729072] + 'display_type': 'raw' + }, + '188': { + 'display_name': 'Command Timeout', + 'ideal': 'low', + 'critical': true, + 'description': 'The count of aborted operations due to HDD timeout. Normally this attribute value should be equal to zero.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.024893587674442153, + 'error_interval': [0.020857343769186413, 0.0294830350167543] + }, { + 'low': 0, + 'high': 13, + 'annual_failure_rate': 0.10044174089362015, + 'error_interval': [0.0812633664077498, 0.1227848196758574] + }, { + 'low': 13, + 'high': 26, + 'annual_failure_rate': 0.334030592234279, + 'error_interval': [0.2523231196342665, 0.4337665082489293] + }, { + 'low': 26, + 'high': 39, + 'annual_failure_rate': 0.36724705400842445, + 'error_interval': [0.30398009356575617, 0.4397986538328568] + }, { + 'low': 39, + 'high': 52, + 'annual_failure_rate': 0.29848155926978354, + 'error_interval': [0.2509254838615984, 0.35242890006477073] + }, { + 'low': 52, + 'high': 65, + 'annual_failure_rate': 0.2203079701535098, + 'error_interval': [0.18366082845676174, 0.26212468677179274] + }, { + 'low': 65, + 'high': 78, + 'annual_failure_rate': 0.3018169948863018, + 'error_interval': [0.23779746376787655, 0.37776897542831006] + }, { + 'low': 78, + 'high': 91, + 'annual_failure_rate': 0.32854928239235887, + 'error_interval': [0.2301118782147336, 0.4548506948185028] + }, { + 'low': 91, + 'high': 104, + 'annual_failure_rate': 0.28488916640649387, + 'error_interval': [0.1366154288236293, 0.5239213202729072] }], - "display_type": "raw" - }, - "189": { - "display_name": "High Fly Writes", - "ideal": "low", - "critical": false, - "description": "HDD manufacturers implement a flying height sensor that attempts to provide additional protections for write operations by detecting when a recording head is flying outside its normal operating range. If an unsafe fly height condition is encountered, the write process is stopped, and the information is rewritten or reallocated to a safe region of the hard drive. This attribute indicates the count of these errors detected over the lifetime of the drive.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.09070551401946862, - "error_interval": [0.08018892683853401, 0.10221801211956287] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.0844336097370013, - "error_interval": [0.07299813695315267, 0.09715235540340669] - }, { - "low": 2, - "high": 5, - "annual_failure_rate": 0.07943219628781906, - "error_interval": [0.06552176680630226, 0.09542233189887633] - }, { - "low": 5, - "high": 13, - "annual_failure_rate": 0.09208847603893404, - "error_interval": [0.07385765060838133, 0.11345557807163456] - }, { - "low": 13, - "high": 30, - "annual_failure_rate": 0.18161161650924224, - "error_interval": [0.13858879602902988, 0.23377015012749933] - }, { - "low": 30, - "high": 70, - "annual_failure_rate": 0.2678117886102384, - "error_interval": [0.19044036194841887, 0.36610753129699186] - }, { - "low": 70, - "high": 150, - "annual_failure_rate": 0.26126480798826107, - "error_interval": [0.15958733218826962, 0.4035023060905559] - }, { - "low": 150, - "high": 350, - "annual_failure_rate": 0.11337164155924832, - "error_interval": [0.030889956621649995, 0.2902764300762812] + 'display_type': 'raw' + }, + '189': { + 'display_name': 'High Fly Writes', + 'ideal': 'low', + 'critical': false, + 'description': 'HDD manufacturers implement a flying height sensor that attempts to provide additional protections for write operations by detecting when a recording head is flying outside its normal operating range. If an unsafe fly height condition is encountered, the write process is stopped, and the information is rewritten or reallocated to a safe region of the hard drive. This attribute indicates the count of these errors detected over the lifetime of the drive.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.09070551401946862, + 'error_interval': [0.08018892683853401, 0.10221801211956287] + }, { + 'low': 1, + 'high': 2, + 'annual_failure_rate': 0.0844336097370013, + 'error_interval': [0.07299813695315267, 0.09715235540340669] + }, { + 'low': 2, + 'high': 5, + 'annual_failure_rate': 0.07943219628781906, + 'error_interval': [0.06552176680630226, 0.09542233189887633] + }, { + 'low': 5, + 'high': 13, + 'annual_failure_rate': 0.09208847603893404, + 'error_interval': [0.07385765060838133, 0.11345557807163456] + }, { + 'low': 13, + 'high': 30, + 'annual_failure_rate': 0.18161161650924224, + 'error_interval': [0.13858879602902988, 0.23377015012749933] + }, { + 'low': 30, + 'high': 70, + 'annual_failure_rate': 0.2678117886102384, + 'error_interval': [0.19044036194841887, 0.36610753129699186] + }, { + 'low': 70, + 'high': 150, + 'annual_failure_rate': 0.26126480798826107, + 'error_interval': [0.15958733218826962, 0.4035023060905559] + }, { + 'low': 150, + 'high': 350, + 'annual_failure_rate': 0.11337164155924832, + 'error_interval': [0.030889956621649995, 0.2902764300762812] }], - "display_type": "raw" - }, - "190": { - "display_name": "Temperature Difference", - "ideal": "", - "critical": false, - "description": "Value is equal to (100-temp. °C), allowing manufacturer to set a minimum threshold which corresponds to a maximum temperature. This also follows the convention of 100 being a best-case value and lower values being undesirable. However, some older drives may instead report raw Temperature (identical to 0xC2) or Temperature minus 50 here.", - "display_type": "normalized" - }, - "191": { - "display_name": "G-sense Error Rate", - "ideal": "low", - "critical": false, - "description": "The count of errors resulting from externally induced shock and vibration. ", - "display_type": "normalized" - }, - "192": { - "display_name": "Power-off Retract Count", - "ideal": "low", - "critical": false, - "description": "Number of power-off or emergency retract cycles.", - "observed_thresholds": [{ - "low": 1, - "high": 2, - "annual_failure_rate": 0.02861098445412803, - "error_interval": [0.022345416230915037, 0.036088863823297186] - }, { - "low": 2, - "high": 6, - "annual_failure_rate": 0.0738571777154862, - "error_interval": [0.06406927746420421, 0.0847175264009771] - }, { - "low": 6, - "high": 16, - "annual_failure_rate": 0.11970378206823593, - "error_interval": [0.10830059875098269, 0.13198105985656441] - }, { - "low": 16, - "high": 40, - "annual_failure_rate": 0.027266868552620425, - "error_interval": [0.021131448605713823, 0.03462795920968522] - }, { - "low": 40, - "high": 100, - "annual_failure_rate": 0.011741682974559688, - "error_interval": [0.00430899071133239, 0.025556700631152028] - }, { - "low": 100, - "high": 250, - "annual_failure_rate": 0.012659940134091309, - "error_interval": [0.00607093338127348, 0.023282080653656938] - }, { - "low": 250, - "high": 650, - "annual_failure_rate": 0.01634692899031039, - "error_interval": [0.009522688540043157, 0.026173016865409605] - }, { - "low": 650, - "high": 1600, - "annual_failure_rate": 0.005190074354440066, - "error_interval": [0.0025908664180103293, 0.009286476666453648] + 'display_type': 'raw' + }, + '190': { + 'display_name': 'Temperature Difference', + 'ideal': '', + 'critical': false, + 'description': 'Value is equal to (100-temp. °C), allowing manufacturer to set a minimum threshold which corresponds to a maximum temperature. This also follows the convention of 100 being a best-case value and lower values being undesirable. However, some older drives may instead report raw Temperature (identical to 0xC2) or Temperature minus 50 here.', + 'display_type': 'normalized' + }, + '191': { + 'display_name': 'G-sense Error Rate', + 'ideal': 'low', + 'critical': false, + 'description': 'The count of errors resulting from externally induced shock and vibration. ', + 'display_type': 'normalized' + }, + '192': { + 'display_name': 'Power-off Retract Count', + 'ideal': 'low', + 'critical': false, + 'description': 'Number of power-off or emergency retract cycles.', + 'observed_thresholds': [{ + 'low': 1, + 'high': 2, + 'annual_failure_rate': 0.02861098445412803, + 'error_interval': [0.022345416230915037, 0.036088863823297186] + }, { + 'low': 2, + 'high': 6, + 'annual_failure_rate': 0.0738571777154862, + 'error_interval': [0.06406927746420421, 0.0847175264009771] + }, { + 'low': 6, + 'high': 16, + 'annual_failure_rate': 0.11970378206823593, + 'error_interval': [0.10830059875098269, 0.13198105985656441] + }, { + 'low': 16, + 'high': 40, + 'annual_failure_rate': 0.027266868552620425, + 'error_interval': [0.021131448605713823, 0.03462795920968522] + }, { + 'low': 40, + 'high': 100, + 'annual_failure_rate': 0.011741682974559688, + 'error_interval': [0.00430899071133239, 0.025556700631152028] + }, { + 'low': 100, + 'high': 250, + 'annual_failure_rate': 0.012659940134091309, + 'error_interval': [0.00607093338127348, 0.023282080653656938] + }, { + 'low': 250, + 'high': 650, + 'annual_failure_rate': 0.01634692899031039, + 'error_interval': [0.009522688540043157, 0.026173016865409605] + }, { + 'low': 650, + 'high': 1600, + 'annual_failure_rate': 0.005190074354440066, + 'error_interval': [0.0025908664180103293, 0.009286476666453648] }], - "display_type": "raw" - }, - "193": { - "display_name": "Load Cycle Count", - "ideal": "low", - "critical": false, - "description": "Count of load/unload cycles into head landing zone position.[45] Some drives use 225 (0xE1) for Load Cycle Count instead.", - "display_type": "normalized" - }, - "194": { - "display_name": "Temperature", - "ideal": "low", - "critical": false, - "description": "Indicates the device temperature, if the appropriate sensor is fitted. Lowest byte of the raw value contains the exact temperature value (Celsius degrees).", - "transform_value_unit": "°C", - "display_type": "transformed" - }, - "195": { - "display_name": "Hardware ECC Recovered", - "ideal": "", - "critical": false, - "description": "(Vendor-specific raw value.) The raw value has different structure for different vendors and is often not meaningful as a decimal number.", - "observed_thresholds": [{ - "low": 12, - "high": 24, - "annual_failure_rate": 0.31472916829975706, - "error_interval": [0.15711166685282174, 0.5631374192486645] - }, { - "low": 24, - "high": 36, - "annual_failure_rate": 0.15250310197260136, - "error_interval": [0.10497611828070175, 0.21417105521823687] - }, { - "low": 36, - "high": 48, - "annual_failure_rate": 0.2193119102723874, - "error_interval": [0.16475385681835103, 0.28615447006525274] - }, { - "low": 48, - "high": 60, - "annual_failure_rate": 0.05672658497265746, - "error_interval": [0.043182904776447234, 0.07317316161437043] - }, { - "low": 60, - "high": 72, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 72, - "high": 84, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 84, - "high": 96, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 96, - "high": 108, - "annual_failure_rate": 0.04074570216566197, - "error_interval": [0.001031591863615295, 0.22702052218047528] + 'display_type': 'raw' + }, + '193': { + 'display_name': 'Load Cycle Count', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of load/unload cycles into head landing zone position.[45] Some drives use 225 (0xE1) for Load Cycle Count instead.', + 'display_type': 'normalized' + }, + '194': { + 'display_name': 'Temperature', + 'ideal': 'low', + 'critical': false, + 'description': 'Indicates the device temperature, if the appropriate sensor is fitted. Lowest byte of the raw value contains the exact temperature value (Celsius degrees).', + 'transform_value_unit': '°C', + 'display_type': 'transformed' + }, + '195': { + 'display_name': 'Hardware ECC Recovered', + 'ideal': '', + 'critical': false, + 'description': '(Vendor-specific raw value.) The raw value has different structure for different vendors and is often not meaningful as a decimal number.', + 'observed_thresholds': [{ + 'low': 12, + 'high': 24, + 'annual_failure_rate': 0.31472916829975706, + 'error_interval': [0.15711166685282174, 0.5631374192486645] + }, { + 'low': 24, + 'high': 36, + 'annual_failure_rate': 0.15250310197260136, + 'error_interval': [0.10497611828070175, 0.21417105521823687] + }, { + 'low': 36, + 'high': 48, + 'annual_failure_rate': 0.2193119102723874, + 'error_interval': [0.16475385681835103, 0.28615447006525274] + }, { + 'low': 48, + 'high': 60, + 'annual_failure_rate': 0.05672658497265746, + 'error_interval': [0.043182904776447234, 0.07317316161437043] + }, { + 'low': 60, + 'high': 72, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 72, + 'high': 84, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 84, + 'high': 96, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 96, + 'high': 108, + 'annual_failure_rate': 0.04074570216566197, + 'error_interval': [0.001031591863615295, 0.22702052218047528] }], - "display_type": "normalized" - }, - "196": { - "display_name": "Reallocation Event Count", - "ideal": "low", - "critical": true, - "description": "Count of remap operations. The raw value of this attribute shows the total count of attempts to transfer data from reallocated sectors to a spare area. Both successful and unsuccessful attempts are counted.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.007389855800729792, - "error_interval": [0.005652654139732716, 0.009492578928212054] - }, { - "low": 1, - "high": 1, - "annual_failure_rate": 0.026558331312151347, - "error_interval": [0.005476966404484466, 0.07761471429677293] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.02471894893674658, - "error_interval": [0.0006258296027540169, 0.13772516847438018] - }, { - "low": 2, - "high": 4, - "annual_failure_rate": 0.03200912040691046, - "error_interval": [0.0008104007642081744, 0.17834340416493005] - }, { - "low": 4, - "high": 7, - "annual_failure_rate": 0.043078012510326925, - "error_interval": [0.001090640849081295, 0.24001532369794615] - }, { - "low": 7, - "high": 11, - "annual_failure_rate": 0.033843300880853036, - "error_interval": [0.0008568381932559863, 0.18856280368036135] - }, { - "low": 11, - "high": 17, - "annual_failure_rate": 0.16979376647542252, - "error_interval": [0.035015556653263225, 0.49620943874336304] - }, { - "low": 17, - "high": 27, - "annual_failure_rate": 0.059042381106438044, - "error_interval": [0.0014948236677880642, 0.32896309247698113] - }, { - "low": 27, - "high": 45, - "annual_failure_rate": 0.24701105346266636, - "error_interval": [0.050939617608142244, 0.721871118983972] + 'display_type': 'normalized' + }, + '196': { + 'display_name': 'Reallocation Event Count', + 'ideal': 'low', + 'critical': true, + 'description': 'Count of remap operations. The raw value of this attribute shows the total count of attempts to transfer data from reallocated sectors to a spare area. Both successful and unsuccessful attempts are counted.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.007389855800729792, + 'error_interval': [0.005652654139732716, 0.009492578928212054] + }, { + 'low': 1, + 'high': 1, + 'annual_failure_rate': 0.026558331312151347, + 'error_interval': [0.005476966404484466, 0.07761471429677293] + }, { + 'low': 1, + 'high': 2, + 'annual_failure_rate': 0.02471894893674658, + 'error_interval': [0.0006258296027540169, 0.13772516847438018] + }, { + 'low': 2, + 'high': 4, + 'annual_failure_rate': 0.03200912040691046, + 'error_interval': [0.0008104007642081744, 0.17834340416493005] + }, { + 'low': 4, + 'high': 7, + 'annual_failure_rate': 0.043078012510326925, + 'error_interval': [0.001090640849081295, 0.24001532369794615] + }, { + 'low': 7, + 'high': 11, + 'annual_failure_rate': 0.033843300880853036, + 'error_interval': [0.0008568381932559863, 0.18856280368036135] + }, { + 'low': 11, + 'high': 17, + 'annual_failure_rate': 0.16979376647542252, + 'error_interval': [0.035015556653263225, 0.49620943874336304] + }, { + 'low': 17, + 'high': 27, + 'annual_failure_rate': 0.059042381106438044, + 'error_interval': [0.0014948236677880642, 0.32896309247698113] + }, { + 'low': 27, + 'high': 45, + 'annual_failure_rate': 0.24701105346266636, + 'error_interval': [0.050939617608142244, 0.721871118983972] }], - "display_type": "raw" - }, - "197": { - "display_name": "Current Pending Sector Count", - "ideal": "low", - "critical": true, - "description": "Count of \"unstable\" sectors (waiting to be remapped, because of unrecoverable read errors). If an unstable sector is subsequently read successfully, the sector is remapped and this value is decreased. Read errors on a sector will not remap the sector immediately (since the correct value cannot be read and so the value to remap is not known, and also it might become readable later); instead, the drive firmware remembers that the sector needs to be remapped, and will remap it the next time it\"s written.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.025540791394761345, - "error_interval": [0.023161777231213983, 0.02809784482748174] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.34196613799103254, - "error_interval": [0.22723401523750225, 0.4942362818474496] - }, { - "low": 2, - "high": 6, - "annual_failure_rate": 0.6823772508117681, - "error_interval": [0.41083568090070416, 1.0656166047061635] - }, { - "low": 6, - "high": 16, - "annual_failure_rate": 0.6108100007493069, - "error_interval": [0.47336936083368364, 0.7757071095273286] - }, { - "low": 16, - "high": 40, - "annual_failure_rate": 0.9564879341127684, - "error_interval": [0.7701044196378299, 1.174355230793638] - }, { - "low": 40, - "high": 100, - "annual_failure_rate": 1.6519989942167461, - "error_interval": [1.328402276482456, 2.0305872327541317] - }, { - "low": 100, - "high": 250, - "annual_failure_rate": 2.5137741046831956, - "error_interval": [1.9772427971560862, 3.1510376077891613] - }, { - "low": 250, - "high": 650, - "annual_failure_rate": 3.3203378817413904, - "error_interval": [2.5883662702274406, 4.195047163573006] - }, { - "low": 650, - "high": 1600, - "annual_failure_rate": 3.133047210300429, - "error_interval": [1.1497731080460096, 6.819324775707182] + 'display_type': 'raw' + }, + '197': { + 'display_name': 'Current Pending Sector Count', + 'ideal': 'low', + 'critical': true, + 'description': 'Count of "unstable" sectors (waiting to be remapped, because of unrecoverable read errors). If an unstable sector is subsequently read successfully, the sector is remapped and this value is decreased. Read errors on a sector will not remap the sector immediately (since the correct value cannot be read and so the value to remap is not known, and also it might become readable later); instead, the drive firmware remembers that the sector needs to be remapped, and will remap it the next time it"s written.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.025540791394761345, + 'error_interval': [0.023161777231213983, 0.02809784482748174] + }, { + 'low': 1, + 'high': 2, + 'annual_failure_rate': 0.34196613799103254, + 'error_interval': [0.22723401523750225, 0.4942362818474496] + }, { + 'low': 2, + 'high': 6, + 'annual_failure_rate': 0.6823772508117681, + 'error_interval': [0.41083568090070416, 1.0656166047061635] + }, { + 'low': 6, + 'high': 16, + 'annual_failure_rate': 0.6108100007493069, + 'error_interval': [0.47336936083368364, 0.7757071095273286] + }, { + 'low': 16, + 'high': 40, + 'annual_failure_rate': 0.9564879341127684, + 'error_interval': [0.7701044196378299, 1.174355230793638] + }, { + 'low': 40, + 'high': 100, + 'annual_failure_rate': 1.6519989942167461, + 'error_interval': [1.328402276482456, 2.0305872327541317] + }, { + 'low': 100, + 'high': 250, + 'annual_failure_rate': 2.5137741046831956, + 'error_interval': [1.9772427971560862, 3.1510376077891613] + }, { + 'low': 250, + 'high': 650, + 'annual_failure_rate': 3.3203378817413904, + 'error_interval': [2.5883662702274406, 4.195047163573006] + }, { + 'low': 650, + 'high': 1600, + 'annual_failure_rate': 3.133047210300429, + 'error_interval': [1.1497731080460096, 6.819324775707182] }], - "display_type": "raw" - }, - "198": { - "display_name": "(Offline) Uncorrectable Sector Count", - "ideal": "low", - "critical": true, - "description": "The total count of uncorrectable errors when reading/writing a sector. A rise in the value of this attribute indicates defects of the disk surface and/or problems in the mechanical subsystem.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.028675322159886437, - "error_interval": [0.026159385510707116, 0.03136793218577656] - }, { - "low": 0, - "high": 2, - "annual_failure_rate": 0.8135764944275583, - "error_interval": [0.40613445471964466, 1.4557130815309443] - }, { - "low": 2, - "high": 4, - "annual_failure_rate": 1.1173469387755102, - "error_interval": [0.5773494680315332, 1.9517802404552516] - }, { - "low": 4, - "high": 6, - "annual_failure_rate": 1.3558692421991083, - "error_interval": [0.4402470522980859, 3.1641465148237544] - }, { - "low": 6, - "high": 8, - "annual_failure_rate": 0.7324414715719062, - "error_interval": [0.15104704003805655, 2.140504796291604] - }, { - "low": 8, - "high": 10, - "annual_failure_rate": 0.5777213677766163, - "error_interval": [0.43275294849366835, 0.7556737733062419] - }, { - "low": 10, - "high": 12, - "annual_failure_rate": 1.7464114832535886, - "error_interval": [0.47583835092536914, 4.471507017371231] - }, { - "low": 12, - "high": 14, - "annual_failure_rate": 2.6449275362318843, - "error_interval": [0.3203129951758959, 9.554387676519005] - }, { - "low": 14, - "high": 16, - "annual_failure_rate": 0.796943231441048, - "error_interval": [0.5519063550198366, 1.113648286331181] + 'display_type': 'raw' + }, + '198': { + 'display_name': '(Offline) Uncorrectable Sector Count', + 'ideal': 'low', + 'critical': true, + 'description': 'The total count of uncorrectable errors when reading/writing a sector. A rise in the value of this attribute indicates defects of the disk surface and/or problems in the mechanical subsystem.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.028675322159886437, + 'error_interval': [0.026159385510707116, 0.03136793218577656] + }, { + 'low': 0, + 'high': 2, + 'annual_failure_rate': 0.8135764944275583, + 'error_interval': [0.40613445471964466, 1.4557130815309443] + }, { + 'low': 2, + 'high': 4, + 'annual_failure_rate': 1.1173469387755102, + 'error_interval': [0.5773494680315332, 1.9517802404552516] + }, { + 'low': 4, + 'high': 6, + 'annual_failure_rate': 1.3558692421991083, + 'error_interval': [0.4402470522980859, 3.1641465148237544] + }, { + 'low': 6, + 'high': 8, + 'annual_failure_rate': 0.7324414715719062, + 'error_interval': [0.15104704003805655, 2.140504796291604] + }, { + 'low': 8, + 'high': 10, + 'annual_failure_rate': 0.5777213677766163, + 'error_interval': [0.43275294849366835, 0.7556737733062419] + }, { + 'low': 10, + 'high': 12, + 'annual_failure_rate': 1.7464114832535886, + 'error_interval': [0.47583835092536914, 4.471507017371231] + }, { + 'low': 12, + 'high': 14, + 'annual_failure_rate': 2.6449275362318843, + 'error_interval': [0.3203129951758959, 9.554387676519005] + }, { + 'low': 14, + 'high': 16, + 'annual_failure_rate': 0.796943231441048, + 'error_interval': [0.5519063550198366, 1.113648286331181] }], - "display_type": "raw" - }, - "199": { - "display_name": "UltraDMA CRC Error Count", - "ideal": "low", - "critical": false, - "description": "The count of errors in data transfer via the interface cable as determined by ICRC (Interface Cyclic Redundancy Check).", - "observed_thresholds": [{ - "low": 0, - "high": 1, - "annual_failure_rate": 0.04068379316116366, - "error_interval": [0.037534031558106425, 0.04402730201866553] - }, { - "low": 1, - "high": 2, - "annual_failure_rate": 0.1513481259734218, - "error_interval": [0.12037165605991791, 0.18786293065527596] - }, { - "low": 2, - "high": 4, - "annual_failure_rate": 0.16849758722418978, - "error_interval": [0.12976367397863445, 0.2151676572000481] - }, { - "low": 4, - "high": 8, - "annual_failure_rate": 0.15385127340491614, - "error_interval": [0.10887431782430312, 0.21117289306426648] - }, { - "low": 8, - "high": 16, - "annual_failure_rate": 0.14882894050104387, - "error_interval": [0.09631424312463635, 0.2197008753522735] - }, { - "low": 16, - "high": 35, - "annual_failure_rate": 0.20878219917249793, - "error_interval": [0.14086447304552446, 0.29804957135975] - }, { - "low": 35, - "high": 70, - "annual_failure_rate": 0.13742940270409038, - "error_interval": [0.06860426267470295, 0.24589916335290812] - }, { - "low": 70, - "high": 130, - "annual_failure_rate": 0.22336578581363, - "error_interval": [0.11150339549604707, 0.39966309081252904] - }, { - "low": 130, - "high": 260, - "annual_failure_rate": 0.18277416124186283, - "error_interval": [0.07890890989692058, 0.3601379610272007] + 'display_type': 'raw' + }, + '199': { + 'display_name': 'UltraDMA CRC Error Count', + 'ideal': 'low', + 'critical': false, + 'description': 'The count of errors in data transfer via the interface cable as determined by ICRC (Interface Cyclic Redundancy Check).', + 'observed_thresholds': [{ + 'low': 0, + 'high': 1, + 'annual_failure_rate': 0.04068379316116366, + 'error_interval': [0.037534031558106425, 0.04402730201866553] + }, { + 'low': 1, + 'high': 2, + 'annual_failure_rate': 0.1513481259734218, + 'error_interval': [0.12037165605991791, 0.18786293065527596] + }, { + 'low': 2, + 'high': 4, + 'annual_failure_rate': 0.16849758722418978, + 'error_interval': [0.12976367397863445, 0.2151676572000481] + }, { + 'low': 4, + 'high': 8, + 'annual_failure_rate': 0.15385127340491614, + 'error_interval': [0.10887431782430312, 0.21117289306426648] + }, { + 'low': 8, + 'high': 16, + 'annual_failure_rate': 0.14882894050104387, + 'error_interval': [0.09631424312463635, 0.2197008753522735] + }, { + 'low': 16, + 'high': 35, + 'annual_failure_rate': 0.20878219917249793, + 'error_interval': [0.14086447304552446, 0.29804957135975] + }, { + 'low': 35, + 'high': 70, + 'annual_failure_rate': 0.13742940270409038, + 'error_interval': [0.06860426267470295, 0.24589916335290812] + }, { + 'low': 70, + 'high': 130, + 'annual_failure_rate': 0.22336578581363, + 'error_interval': [0.11150339549604707, 0.39966309081252904] + }, { + 'low': 130, + 'high': 260, + 'annual_failure_rate': 0.18277416124186283, + 'error_interval': [0.07890890989692058, 0.3601379610272007] }], - "display_type": "raw" - }, - "2": { - "display_name": "Throughput Performance", - "ideal": "high", - "critical": false, - "description": "Overall (general) throughput performance of a hard disk drive. If the value of this attribute is decreasing there is a high probability that there is a problem with the disk.", - "display_type": "normalized" - }, - "200": { - "display_name": "Multi-Zone Error Rate", - "ideal": "low", - "critical": false, - "description": "The count of errors found when writing a sector. The higher the value, the worse the disk\"s mechanical condition is.", - "display_type": "normalized" - }, - "201": { - "display_name": "Soft Read Error Rate", - "ideal": "low", - "critical": true, - "description": "Count indicates the number of uncorrectable software read errors.", - "display_type": "normalized" - }, - "202": { - "display_name": "Data Address Mark errors", - "ideal": "low", - "critical": false, - "description": "Count of Data Address Mark errors (or vendor-specific).", - "display_type": "normalized" - }, - "203": { - "display_name": "Run Out Cancel", - "ideal": "low", - "critical": false, - "description": "The number of errors caused by incorrect checksum during the error correction.", - "display_type": "normalized" - }, - "204": { - "display_name": "Soft ECC Correction", - "ideal": "low", - "critical": false, - "description": "Count of errors corrected by the internal error correction software.", - "display_type": "" - }, - "205": { - "display_name": "Thermal Asperity Rate", - "ideal": "low", - "critical": false, - "description": "Count of errors due to high temperature.", - "display_type": "normalized" - }, - "206": { - "display_name": "Flying Height", - "ideal": "", - "critical": false, - "description": "Height of heads above the disk surface. If too low, head crash is more likely; if too high, read/write errors are more likely.", - "display_type": "normalized" - }, - "207": { - "display_name": "Spin High Current", - "ideal": "low", - "critical": false, - "description": "Amount of surge current used to spin up the drive.", - "display_type": "normalized" - }, - "208": { - "display_name": "Spin Buzz", - "ideal": "", - "critical": false, - "description": "Count of buzz routines needed to spin up the drive due to insufficient power.", - "display_type": "normalized" - }, - "209": { - "display_name": "Offline Seek Performance", - "ideal": "", - "critical": false, - "description": "Drive\"s seek performance during its internal tests.", - "display_type": "normalized" - }, - "210": { - "display_name": "Vibration During Write", - "ideal": "", - "critical": false, - "description": "Found in Maxtor 6B200M0 200GB and Maxtor 2R015H1 15GB disks.", - "display_type": "normalized" - }, - "211": { - "display_name": "Vibration During Write", - "ideal": "", - "critical": false, - "description": "A recording of a vibration encountered during write operations.", - "display_type": "normalized" - }, - "212": { - "display_name": "Shock During Write", - "ideal": "", - "critical": false, - "description": "A recording of shock encountered during write operations.", - "display_type": "normalized" - }, - "22": { - "display_name": "Current Helium Level", - "ideal": "high", - "critical": false, - "description": "Specific to He8 drives from HGST. This value measures the helium inside of the drive specific to this manufacturer. It is a pre-fail attribute that trips once the drive detects that the internal environment is out of specification.", - "display_type": "normalized" - }, - "220": { - "display_name": "Disk Shift", - "ideal": "low", - "critical": false, - "description": "Distance the disk has shifted relative to the spindle (usually due to shock or temperature). Unit of measure is unknown.", - "display_type": "normalized" - }, - "221": { - "display_name": "G-Sense Error Rate", - "ideal": "low", - "critical": false, - "description": "The count of errors resulting from externally induced shock and vibration.", - "display_type": "normalized" - }, - "222": { - "display_name": "Loaded Hours", - "ideal": "", - "critical": false, - "description": "Time spent operating under data load (movement of magnetic head armature).", - "display_type": "normalized" - }, - "223": { - "display_name": "Load/Unload Retry Count", - "ideal": "", - "critical": false, - "description": "Count of times head changes position.", - "display_type": "normalized" - }, - "224": { - "display_name": "Load Friction", - "ideal": "low", - "critical": false, - "description": "Resistance caused by friction in mechanical parts while operating.", - "display_type": "normalized" - }, - "225": { - "display_name": "Load/Unload Cycle Count", - "ideal": "low", - "critical": false, - "description": "Total count of load cycles Some drives use 193 (0xC1) for Load Cycle Count instead. See Description for 193 for significance of this number. ", - "display_type": "normalized" - }, - "226": { - "display_name": "Load \"In\"-time", - "ideal": "", - "critical": false, - "description": "Total time of loading on the magnetic heads actuator (time not spent in parking area).", - "display_type": "normalized" - }, - "227": { - "display_name": "Torque Amplification Count", - "ideal": "low", - "critical": false, - "description": "Count of attempts to compensate for platter speed variations.[66]", - "display_type": "" - }, - "228": { - "display_name": "Power-Off Retract Cycle", - "ideal": "low", - "critical": false, - "description": "The number of power-off cycles which are counted whenever there is a \"retract event\" and the heads are loaded off of the media such as when the machine is powered down, put to sleep, or is idle.", - "display_type": "" - }, - "230": { - "display_name": "GMR Head Amplitude ", - "ideal": "", - "critical": false, - "description": "Amplitude of \"thrashing\" (repetitive head moving motions between operations).", - "display_type": "normalized" - }, - "231": { - "display_name": "Life Left", - "ideal": "", - "critical": false, - "description": "Indicates the approximate SSD life left, in terms of program/erase cycles or available reserved blocks. A normalized value of 100 represents a new drive, with a threshold value at 10 indicating a need for replacement. A value of 0 may mean that the drive is operating in read-only mode to allow data recovery.", - "display_type": "normalized" - }, - "232": { - "display_name": "Endurance Remaining", - "ideal": "", - "critical": false, - "description": "Number of physical erase cycles completed on the SSD as a percentage of the maximum physical erase cycles the drive is designed to endure.", - "display_type": "normalized" - }, - "233": { - "display_name": "Media Wearout Indicator", - "ideal": "", - "critical": false, - "description": "Intel SSDs report a normalized value from 100, a new drive, to a minimum of 1. It decreases while the NAND erase cycles increase from 0 to the maximum-rated cycles.", - "display_type": "normalized" - }, - "234": { - "display_name": "Average erase count", - "ideal": "", - "critical": false, - "description": "Decoded as: byte 0-1-2 = average erase count (big endian) and byte 3-4-5 = max erase count (big endian).", - "display_type": "normalized" - }, - "235": { - "display_name": "Good Block Count", - "ideal": "", - "critical": false, - "description": "Decoded as: byte 0-1-2 = good block count (big endian) and byte 3-4 = system (free) block count.", - "display_type": "normalized" - }, - "240": { - "display_name": "Head Flying Hours", - "ideal": "", - "critical": false, - "description": "Time spent during the positioning of the drive heads.[15][71] Some Fujitsu drives report the count of link resets during a data transfer.", - "display_type": "normalized" - }, - "241": { - "display_name": "Total LBAs Written", - "ideal": "", - "critical": false, - "description": "Total count of LBAs written.", - "display_type": "normalized" - }, - "242": { - "display_name": "Total LBAs Read", - "ideal": "", - "critical": false, - "description": "Total count of LBAs read.Some S.M.A.R.T. utilities will report a negative number for the raw value since in reality it has 48 bits rather than 32.", - "display_type": "normalized" - }, - "243": { - "display_name": "Total LBAs Written Expanded", - "ideal": "", - "critical": false, - "description": "The upper 5 bytes of the 12-byte total number of LBAs written to the device. The lower 7 byte value is located at attribute 0xF1.", - "display_type": "normalized" - }, - "244": { - "display_name": "Total LBAs Read Expanded", - "ideal": "", - "critical": false, - "description": "The upper 5 bytes of the 12-byte total number of LBAs read from the device. The lower 7 byte value is located at attribute 0xF2.", - "display_type": "normalized" - }, - "249": { - "display_name": "NAND Writes (1GiB)", - "ideal": "", - "critical": false, - "description": "Total NAND Writes. Raw value reports the number of writes to NAND in 1 GB increments.", - "display_type": "normalized" - }, - "250": { - "display_name": "Read Error Retry Rate", - "ideal": "low", - "critical": false, - "description": "Count of errors while reading from a disk.", - "display_type": "normalized" - }, - "251": { - "display_name": "Minimum Spares Remaining", - "ideal": "", - "critical": false, - "description": "The Minimum Spares Remaining attribute indicates the number of remaining spare blocks as a percentage of the total number of spare blocks available.", - "display_type": "normalized" - }, - "252": { - "display_name": "Newly Added Bad Flash Block", - "ideal": "", - "critical": false, - "description": "The Newly Added Bad Flash Block attribute indicates the total number of bad flash blocks the drive detected since it was first initialized in manufacturing.", - "display_type": "normalized" - }, - "254": { - "display_name": "Free Fall Protection", - "ideal": "low", - "critical": false, - "description": "Count of \"Free Fall Events\" detected.", - "display_type": "normalized" - }, - "3": { - "display_name": "Spin-Up Time", - "ideal": "low", - "critical": false, - "description": "Average time of spindle spin up (from zero RPM to fully operational [milliseconds]).", - "observed_thresholds": [{ - "low": 78, - "high": 96, - "annual_failure_rate": 0.11452195377351217, - "error_interval": [0.10591837762295722, 0.12363823501915781] - }, { - "low": 96, - "high": 114, - "annual_failure_rate": 0.040274562840558074, - "error_interval": [0.03465055611002801, 0.046551312468303144] - }, { - "low": 114, - "high": 132, - "annual_failure_rate": 0.009100406705780476, - "error_interval": [0.006530608971356785, 0.012345729280075591] - }, { - "low": 132, - "high": 150, - "annual_failure_rate": 0.008561351734020232, - "error_interval": [0.004273795939256936, 0.015318623141355509] - }, { - "low": 150, - "high": 168, - "annual_failure_rate": 0.015780508262068848, - "error_interval": [0.005123888078524015, 0.03682644215646287] - }, { - "low": 168, - "high": 186, - "annual_failure_rate": 0.05262688124794024, - "error_interval": [0.0325768689524594, 0.08044577830285578] - }, { - "low": 186, - "high": 204, - "annual_failure_rate": 0.01957419424036038, - "error_interval": [0.0023705257325185624, 0.0707087198669825] - }, { - "low": 204, - "high": 222, - "annual_failure_rate": 0.026050959960031404, - "error_interval": [0.0006595532020744994, 0.1451466588889228] + 'display_type': 'raw' + }, + '2': { + 'display_name': 'Throughput Performance', + 'ideal': 'high', + 'critical': false, + 'description': 'Overall (general) throughput performance of a hard disk drive. If the value of this attribute is decreasing there is a high probability that there is a problem with the disk.', + 'display_type': 'normalized' + }, + '200': { + 'display_name': 'Multi-Zone Error Rate', + 'ideal': 'low', + 'critical': false, + 'description': 'The count of errors found when writing a sector. The higher the value, the worse the disk"s mechanical condition is.', + 'display_type': 'normalized' + }, + '201': { + 'display_name': 'Soft Read Error Rate', + 'ideal': 'low', + 'critical': true, + 'description': 'Count indicates the number of uncorrectable software read errors.', + 'display_type': 'normalized' + }, + '202': { + 'display_name': 'Data Address Mark errors', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of Data Address Mark errors (or vendor-specific).', + 'display_type': 'normalized' + }, + '203': { + 'display_name': 'Run Out Cancel', + 'ideal': 'low', + 'critical': false, + 'description': 'The number of errors caused by incorrect checksum during the error correction.', + 'display_type': 'normalized' + }, + '204': { + 'display_name': 'Soft ECC Correction', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of errors corrected by the internal error correction software.', + 'display_type': '' + }, + '205': { + 'display_name': 'Thermal Asperity Rate', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of errors due to high temperature.', + 'display_type': 'normalized' + }, + '206': { + 'display_name': 'Flying Height', + 'ideal': '', + 'critical': false, + 'description': 'Height of heads above the disk surface. If too low, head crash is more likely; if too high, read/write errors are more likely.', + 'display_type': 'normalized' + }, + '207': { + 'display_name': 'Spin High Current', + 'ideal': 'low', + 'critical': false, + 'description': 'Amount of surge current used to spin up the drive.', + 'display_type': 'normalized' + }, + '208': { + 'display_name': 'Spin Buzz', + 'ideal': '', + 'critical': false, + 'description': 'Count of buzz routines needed to spin up the drive due to insufficient power.', + 'display_type': 'normalized' + }, + '209': { + 'display_name': 'Offline Seek Performance', + 'ideal': '', + 'critical': false, + 'description': 'Drive"s seek performance during its internal tests.', + 'display_type': 'normalized' + }, + '210': { + 'display_name': 'Vibration During Write', + 'ideal': '', + 'critical': false, + 'description': 'Found in Maxtor 6B200M0 200GB and Maxtor 2R015H1 15GB disks.', + 'display_type': 'normalized' + }, + '211': { + 'display_name': 'Vibration During Write', + 'ideal': '', + 'critical': false, + 'description': 'A recording of a vibration encountered during write operations.', + 'display_type': 'normalized' + }, + '212': { + 'display_name': 'Shock During Write', + 'ideal': '', + 'critical': false, + 'description': 'A recording of shock encountered during write operations.', + 'display_type': 'normalized' + }, + '22': { + 'display_name': 'Current Helium Level', + 'ideal': 'high', + 'critical': false, + 'description': 'Specific to He8 drives from HGST. This value measures the helium inside of the drive specific to this manufacturer. It is a pre-fail attribute that trips once the drive detects that the internal environment is out of specification.', + 'display_type': 'normalized' + }, + '220': { + 'display_name': 'Disk Shift', + 'ideal': 'low', + 'critical': false, + 'description': 'Distance the disk has shifted relative to the spindle (usually due to shock or temperature). Unit of measure is unknown.', + 'display_type': 'normalized' + }, + '221': { + 'display_name': 'G-Sense Error Rate', + 'ideal': 'low', + 'critical': false, + 'description': 'The count of errors resulting from externally induced shock and vibration.', + 'display_type': 'normalized' + }, + '222': { + 'display_name': 'Loaded Hours', + 'ideal': '', + 'critical': false, + 'description': 'Time spent operating under data load (movement of magnetic head armature).', + 'display_type': 'normalized' + }, + '223': { + 'display_name': 'Load/Unload Retry Count', + 'ideal': '', + 'critical': false, + 'description': 'Count of times head changes position.', + 'display_type': 'normalized' + }, + '224': { + 'display_name': 'Load Friction', + 'ideal': 'low', + 'critical': false, + 'description': 'Resistance caused by friction in mechanical parts while operating.', + 'display_type': 'normalized' + }, + '225': { + 'display_name': 'Load/Unload Cycle Count', + 'ideal': 'low', + 'critical': false, + 'description': 'Total count of load cycles Some drives use 193 (0xC1) for Load Cycle Count instead. See Description for 193 for significance of this number. ', + 'display_type': 'normalized' + }, + '226': { + 'display_name': 'Load "In"-time', + 'ideal': '', + 'critical': false, + 'description': 'Total time of loading on the magnetic heads actuator (time not spent in parking area).', + 'display_type': 'normalized' + }, + '227': { + 'display_name': 'Torque Amplification Count', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of attempts to compensate for platter speed variations.[66]', + 'display_type': '' + }, + '228': { + 'display_name': 'Power-Off Retract Cycle', + 'ideal': 'low', + 'critical': false, + 'description': 'The number of power-off cycles which are counted whenever there is a "retract event" and the heads are loaded off of the media such as when the machine is powered down, put to sleep, or is idle.', + 'display_type': '' + }, + '230': { + 'display_name': 'GMR Head Amplitude ', + 'ideal': '', + 'critical': false, + 'description': 'Amplitude of "thrashing" (repetitive head moving motions between operations).', + 'display_type': 'normalized' + }, + '231': { + 'display_name': 'Life Left', + 'ideal': '', + 'critical': false, + 'description': 'Indicates the approximate SSD life left, in terms of program/erase cycles or available reserved blocks. A normalized value of 100 represents a new drive, with a threshold value at 10 indicating a need for replacement. A value of 0 may mean that the drive is operating in read-only mode to allow data recovery.', + 'display_type': 'normalized' + }, + '232': { + 'display_name': 'Endurance Remaining', + 'ideal': '', + 'critical': false, + 'description': 'Number of physical erase cycles completed on the SSD as a percentage of the maximum physical erase cycles the drive is designed to endure.', + 'display_type': 'normalized' + }, + '233': { + 'display_name': 'Media Wearout Indicator', + 'ideal': '', + 'critical': false, + 'description': 'Intel SSDs report a normalized value from 100, a new drive, to a minimum of 1. It decreases while the NAND erase cycles increase from 0 to the maximum-rated cycles.', + 'display_type': 'normalized' + }, + '234': { + 'display_name': 'Average erase count', + 'ideal': '', + 'critical': false, + 'description': 'Decoded as: byte 0-1-2 = average erase count (big endian) and byte 3-4-5 = max erase count (big endian).', + 'display_type': 'normalized' + }, + '235': { + 'display_name': 'Good Block Count', + 'ideal': '', + 'critical': false, + 'description': 'Decoded as: byte 0-1-2 = good block count (big endian) and byte 3-4 = system (free) block count.', + 'display_type': 'normalized' + }, + '240': { + 'display_name': 'Head Flying Hours', + 'ideal': '', + 'critical': false, + 'description': 'Time spent during the positioning of the drive heads.[15][71] Some Fujitsu drives report the count of link resets during a data transfer.', + 'display_type': 'normalized' + }, + '241': { + 'display_name': 'Total LBAs Written', + 'ideal': '', + 'critical': false, + 'description': 'Total count of LBAs written.', + 'display_type': 'normalized' + }, + '242': { + 'display_name': 'Total LBAs Read', + 'ideal': '', + 'critical': false, + 'description': 'Total count of LBAs read.Some S.M.A.R.T. utilities will report a negative number for the raw value since in reality it has 48 bits rather than 32.', + 'display_type': 'normalized' + }, + '243': { + 'display_name': 'Total LBAs Written Expanded', + 'ideal': '', + 'critical': false, + 'description': 'The upper 5 bytes of the 12-byte total number of LBAs written to the device. The lower 7 byte value is located at attribute 0xF1.', + 'display_type': 'normalized' + }, + '244': { + 'display_name': 'Total LBAs Read Expanded', + 'ideal': '', + 'critical': false, + 'description': 'The upper 5 bytes of the 12-byte total number of LBAs read from the device. The lower 7 byte value is located at attribute 0xF2.', + 'display_type': 'normalized' + }, + '249': { + 'display_name': 'NAND Writes (1GiB)', + 'ideal': '', + 'critical': false, + 'description': 'Total NAND Writes. Raw value reports the number of writes to NAND in 1 GB increments.', + 'display_type': 'normalized' + }, + '250': { + 'display_name': 'Read Error Retry Rate', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of errors while reading from a disk.', + 'display_type': 'normalized' + }, + '251': { + 'display_name': 'Minimum Spares Remaining', + 'ideal': '', + 'critical': false, + 'description': 'The Minimum Spares Remaining attribute indicates the number of remaining spare blocks as a percentage of the total number of spare blocks available.', + 'display_type': 'normalized' + }, + '252': { + 'display_name': 'Newly Added Bad Flash Block', + 'ideal': '', + 'critical': false, + 'description': 'The Newly Added Bad Flash Block attribute indicates the total number of bad flash blocks the drive detected since it was first initialized in manufacturing.', + 'display_type': 'normalized' + }, + '254': { + 'display_name': 'Free Fall Protection', + 'ideal': 'low', + 'critical': false, + 'description': 'Count of "Free Fall Events" detected.', + 'display_type': 'normalized' + }, + '3': { + 'display_name': 'Spin-Up Time', + 'ideal': 'low', + 'critical': false, + 'description': 'Average time of spindle spin up (from zero RPM to fully operational [milliseconds]).', + 'observed_thresholds': [{ + 'low': 78, + 'high': 96, + 'annual_failure_rate': 0.11452195377351217, + 'error_interval': [0.10591837762295722, 0.12363823501915781] + }, { + 'low': 96, + 'high': 114, + 'annual_failure_rate': 0.040274562840558074, + 'error_interval': [0.03465055611002801, 0.046551312468303144] + }, { + 'low': 114, + 'high': 132, + 'annual_failure_rate': 0.009100406705780476, + 'error_interval': [0.006530608971356785, 0.012345729280075591] + }, { + 'low': 132, + 'high': 150, + 'annual_failure_rate': 0.008561351734020232, + 'error_interval': [0.004273795939256936, 0.015318623141355509] + }, { + 'low': 150, + 'high': 168, + 'annual_failure_rate': 0.015780508262068848, + 'error_interval': [0.005123888078524015, 0.03682644215646287] + }, { + 'low': 168, + 'high': 186, + 'annual_failure_rate': 0.05262688124794024, + 'error_interval': [0.0325768689524594, 0.08044577830285578] + }, { + 'low': 186, + 'high': 204, + 'annual_failure_rate': 0.01957419424036038, + 'error_interval': [0.0023705257325185624, 0.0707087198669825] + }, { + 'low': 204, + 'high': 222, + 'annual_failure_rate': 0.026050959960031404, + 'error_interval': [0.0006595532020744994, 0.1451466588889228] }], - "display_type": "normalized" - }, - "4": { - "display_name": "Start/Stop Count", - "ideal": "", - "critical": false, - "description": "A tally of spindle start/stop cycles. The spindle turns on, and hence the count is increased, both when the hard disk is turned on after having before been turned entirely off (disconnected from power source) and when the hard disk returns from having previously been put to sleep mode.", - "observed_thresholds": [{ - "low": 0, - "high": 13, - "annual_failure_rate": 0.01989335424860646, - "error_interval": [0.016596548909440657, 0.023653263230617408] - }, { - "low": 13, - "high": 26, - "annual_failure_rate": 0.03776935438256488, - "error_interval": [0.03310396052098642, 0.04290806173460437] - }, { - "low": 26, - "high": 39, - "annual_failure_rate": 0.11022223828187004, - "error_interval": [0.09655110535164119, 0.12528657238811672] - }, { - "low": 39, - "high": 52, - "annual_failure_rate": 0.16289995457762474, - "error_interval": [0.13926541653588131, 0.18939614504497515] - }, { - "low": 52, - "high": 65, - "annual_failure_rate": 0.19358212432279714, - "error_interval": [0.15864522253849073, 0.23392418181765526] - }, { - "low": 65, - "high": 78, - "annual_failure_rate": 0.1157094940074447, - "error_interval": [0.07861898732346269, 0.16424039052527728] - }, { - "low": 78, - "high": 91, - "annual_failure_rate": 0.12262136155304391, - "error_interval": [0.0670382394080032, 0.20573780888032978] - }, { - "low": 91, - "high": 104, - "annual_failure_rate": 0, - "error_interval": [0, 0] + 'display_type': 'normalized' + }, + '4': { + 'display_name': 'Start/Stop Count', + 'ideal': '', + 'critical': false, + 'description': 'A tally of spindle start/stop cycles. The spindle turns on, and hence the count is increased, both when the hard disk is turned on after having before been turned entirely off (disconnected from power source) and when the hard disk returns from having previously been put to sleep mode.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 13, + 'annual_failure_rate': 0.01989335424860646, + 'error_interval': [0.016596548909440657, 0.023653263230617408] + }, { + 'low': 13, + 'high': 26, + 'annual_failure_rate': 0.03776935438256488, + 'error_interval': [0.03310396052098642, 0.04290806173460437] + }, { + 'low': 26, + 'high': 39, + 'annual_failure_rate': 0.11022223828187004, + 'error_interval': [0.09655110535164119, 0.12528657238811672] + }, { + 'low': 39, + 'high': 52, + 'annual_failure_rate': 0.16289995457762474, + 'error_interval': [0.13926541653588131, 0.18939614504497515] + }, { + 'low': 52, + 'high': 65, + 'annual_failure_rate': 0.19358212432279714, + 'error_interval': [0.15864522253849073, 0.23392418181765526] + }, { + 'low': 65, + 'high': 78, + 'annual_failure_rate': 0.1157094940074447, + 'error_interval': [0.07861898732346269, 0.16424039052527728] + }, { + 'low': 78, + 'high': 91, + 'annual_failure_rate': 0.12262136155304391, + 'error_interval': [0.0670382394080032, 0.20573780888032978] + }, { + 'low': 91, + 'high': 104, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] }], - "display_type": "raw" - }, - "5": { - "display_name": "Reallocated Sectors Count", - "ideal": "low", - "critical": true, - "description": "Count of reallocated sectors. The raw value represents a count of the bad sectors that have been found and remapped.Thus, the higher the attribute value, the more sectors the drive has had to reallocate. This value is primarily used as a metric of the life expectancy of the drive; a drive which has had any reallocations at all is significantly more likely to fail in the immediate months.", - "observed_thresholds": [{ - "low": 0, - "high": 0, - "annual_failure_rate": 0.025169175350572493, - "error_interval": [0.022768612038746357, 0.027753988579272894] - }, { - "low": 1, - "high": 4, - "annual_failure_rate": 0.027432608477803388, - "error_interval": [0.010067283827589948, 0.05970923963096652] - }, { - "low": 4, - "high": 16, - "annual_failure_rate": 0.07501976284584981, - "error_interval": [0.039944864177334186, 0.12828607921150972] - }, { - "low": 16, - "high": 70, - "annual_failure_rate": 0.23589260654405794, - "error_interval": [0.1643078435800227, 0.32806951196017664] - }, { - "low": 70, - "high": 260, - "annual_failure_rate": 0.36193219378600433, - "error_interval": [0.2608488901774093, 0.4892271827875412] - }, { - "low": 260, - "high": 1100, - "annual_failure_rate": 0.5676621428968173, - "error_interval": [0.4527895568499355, 0.702804359408436] - }, { - "low": 1100, - "high": 4500, - "annual_failure_rate": 1.5028253400346423, - "error_interval": [1.2681757596263297, 1.768305221795894] - }, { - "low": 4500, - "high": 17000, - "annual_failure_rate": 2.0659987547404763, - "error_interval": [1.6809790460512237, 2.512808045182302] - }, { - "low": 17000, - "high": 70000, - "annual_failure_rate": 1.7755385684503124, - "error_interval": [1.2796520259849835, 2.400012341226441] + 'display_type': 'raw' + }, + '5': { + 'display_name': 'Reallocated Sectors Count', + 'ideal': 'low', + 'critical': true, + 'description': 'Count of reallocated sectors. The raw value represents a count of the bad sectors that have been found and remapped.Thus, the higher the attribute value, the more sectors the drive has had to reallocate. This value is primarily used as a metric of the life expectancy of the drive; a drive which has had any reallocations at all is significantly more likely to fail in the immediate months.', + 'observed_thresholds': [{ + 'low': 0, + 'high': 0, + 'annual_failure_rate': 0.025169175350572493, + 'error_interval': [0.022768612038746357, 0.027753988579272894] + }, { + 'low': 1, + 'high': 4, + 'annual_failure_rate': 0.027432608477803388, + 'error_interval': [0.010067283827589948, 0.05970923963096652] + }, { + 'low': 4, + 'high': 16, + 'annual_failure_rate': 0.07501976284584981, + 'error_interval': [0.039944864177334186, 0.12828607921150972] + }, { + 'low': 16, + 'high': 70, + 'annual_failure_rate': 0.23589260654405794, + 'error_interval': [0.1643078435800227, 0.32806951196017664] + }, { + 'low': 70, + 'high': 260, + 'annual_failure_rate': 0.36193219378600433, + 'error_interval': [0.2608488901774093, 0.4892271827875412] + }, { + 'low': 260, + 'high': 1100, + 'annual_failure_rate': 0.5676621428968173, + 'error_interval': [0.4527895568499355, 0.702804359408436] + }, { + 'low': 1100, + 'high': 4500, + 'annual_failure_rate': 1.5028253400346423, + 'error_interval': [1.2681757596263297, 1.768305221795894] + }, { + 'low': 4500, + 'high': 17000, + 'annual_failure_rate': 2.0659987547404763, + 'error_interval': [1.6809790460512237, 2.512808045182302] + }, { + 'low': 17000, + 'high': 70000, + 'annual_failure_rate': 1.7755385684503124, + 'error_interval': [1.2796520259849835, 2.400012341226441] }], - "display_type": "raw" - }, - "6": { - "display_name": "Read Channel Margin", - "ideal": "", - "critical": false, - "description": "Margin of a channel while reading data. The function of this attribute is not specified.", - "display_type": "normalized" - }, - "7": { - "display_name": "Seek Error Rate", - "ideal": "", - "critical": false, - "description": "(Vendor specific raw value.) Rate of seek errors of the magnetic heads. If there is a partial failure in the mechanical positioning system, then seek errors will arise. Such a failure may be due to numerous factors, such as damage to a servo, or thermal widening of the hard disk. The raw value has different structure for different vendors and is often not meaningful as a decimal number.", - "observed_thresholds": [{ - "low": 58, - "high": 76, - "annual_failure_rate": 0.2040131025936549, - "error_interval": [0.17032852883286412, 0.2424096283327138] - }, { - "low": 76, - "high": 94, - "annual_failure_rate": 0.08725919610118257, - "error_interval": [0.08077138510999876, 0.09412943212007528] - }, { - "low": 94, - "high": 112, - "annual_failure_rate": 0.01087335627722523, - "error_interval": [0.008732197944943352, 0.013380600544561905] - }, { - "low": 112, - "high": 130, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 130, - "high": 148, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 148, - "high": 166, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 166, - "high": 184, - "annual_failure_rate": 0, - "error_interval": [0, 0] - }, { - "low": 184, - "high": 202, - "annual_failure_rate": 0.05316285755900475, - "error_interval": [0.03370069132942804, 0.07977038905848267] + 'display_type': 'raw' + }, + '6': { + 'display_name': 'Read Channel Margin', + 'ideal': '', + 'critical': false, + 'description': 'Margin of a channel while reading data. The function of this attribute is not specified.', + 'display_type': 'normalized' + }, + '7': { + 'display_name': 'Seek Error Rate', + 'ideal': '', + 'critical': false, + 'description': '(Vendor specific raw value.) Rate of seek errors of the magnetic heads. If there is a partial failure in the mechanical positioning system, then seek errors will arise. Such a failure may be due to numerous factors, such as damage to a servo, or thermal widening of the hard disk. The raw value has different structure for different vendors and is often not meaningful as a decimal number.', + 'observed_thresholds': [{ + 'low': 58, + 'high': 76, + 'annual_failure_rate': 0.2040131025936549, + 'error_interval': [0.17032852883286412, 0.2424096283327138] + }, { + 'low': 76, + 'high': 94, + 'annual_failure_rate': 0.08725919610118257, + 'error_interval': [0.08077138510999876, 0.09412943212007528] + }, { + 'low': 94, + 'high': 112, + 'annual_failure_rate': 0.01087335627722523, + 'error_interval': [0.008732197944943352, 0.013380600544561905] + }, { + 'low': 112, + 'high': 130, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 130, + 'high': 148, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 148, + 'high': 166, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 166, + 'high': 184, + 'annual_failure_rate': 0, + 'error_interval': [0, 0] + }, { + 'low': 184, + 'high': 202, + 'annual_failure_rate': 0.05316285755900475, + 'error_interval': [0.03370069132942804, 0.07977038905848267] }], - "display_type": "normalized" - }, - "8": { - "display_name": "Seek Time Performance", - "ideal": "high", - "critical": false, - "description": "Average performance of seek operations of the magnetic heads. If this attribute is decreasing, it is a sign of problems in the mechanical subsystem.", - "display_type": "normalized" - }, - "9": { - "display_name": "Power-On Hours", - "ideal": "", - "critical": false, - "description": "Count of hours in power-on state. The raw value of this attribute shows total count of hours (or minutes, or seconds, depending on manufacturer) in power-on state. By default, the total expected lifetime of a hard disk in perfect condition is defined as 5 years (running every day and night on all days). This is equal to 1825 days in 24/7 mode or 43800 hours. On some pre-2005 drives, this raw value may advance erratically and/or \"wrap around\" (reset to zero periodically).", - "display_type": "normalized" + 'display_type': 'normalized' + }, + '8': { + 'display_name': 'Seek Time Performance', + 'ideal': 'high', + 'critical': false, + 'description': 'Average performance of seek operations of the magnetic heads. If this attribute is decreasing, it is a sign of problems in the mechanical subsystem.', + 'display_type': 'normalized' + }, + '9': { + 'display_name': 'Power-On Hours', + 'ideal': '', + 'critical': false, + 'description': 'Count of hours in power-on state. The raw value of this attribute shows total count of hours (or minutes, or seconds, depending on manufacturer) in power-on state. By default, the total expected lifetime of a hard disk in perfect condition is defined as 5 years (running every day and night on all days). This is equal to 1825 days in 24/7 mode or 43800 hours. On some pre-2005 drives, this raw value may advance erratically and/or "wrap around" (reset to zero periodically).', + 'display_type': 'normalized' } }, - "success": true + 'success': true } diff --git a/webapp/frontend/src/app/data/mock/device/details/sdd.ts b/webapp/frontend/src/app/data/mock/device/details/sdd.ts index 3442593..a35df88 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sdd.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sdd.ts @@ -1,222 +1,222 @@ export const sdd = { - "data": { - "device": { - "CreatedAt": "2021-06-24T21:17:31.30374-07:00", - "UpdatedAt": "2021-10-24T16:37:57.013758-07:00", - "DeletedAt": null, - "wwn": "0x5000cca252c859cc", - "device_name": "sdd", - "manufacturer": "ATA", - "model_name": "WDC_WD80EFAX-68LHPN0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "7SGLXXXXX", - "firmware": "", - "rotational_speed": 0, - "capacity": 8001563222016, - "form_factor": "", - "smart_support": false, - "device_protocol": "SCSI", - "device_type": "", - "label": "", - "host_id": "", - "device_status": 0 + 'data': { + 'device': { + 'CreatedAt': '2021-06-24T21:17:31.30374-07:00', + 'UpdatedAt': '2021-10-24T16:37:57.013758-07:00', + 'DeletedAt': null, + 'wwn': '0x5000cca252c859cc', + 'device_name': 'sdd', + 'manufacturer': 'ATA', + 'model_name': 'WDC_WD80EFAX-68LHPN0', + 'interface_type': 'SCSI', + 'interface_speed': '', + 'serial_number': '7SGLXXXXX', + 'firmware': '', + 'rotational_speed': 0, + 'capacity': 8001563222016, + 'form_factor': '', + 'smart_support': false, + 'device_protocol': 'SCSI', + 'device_type': '', + 'label': '', + 'host_id': '', + 'device_status': 0 }, - "smart_results": [{ - "date": "2021-10-24T23:20:44Z", - "device_wwn": "0x5000cca252c859cc", - "device_protocol": "SCSI", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "attrs": { - "read_correction_algorithm_invocations": { - "attribute_id": "read_correction_algorithm_invocations", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'smart_results': [{ + 'date': '2021-10-24T23:20:44Z', + 'device_wwn': '0x5000cca252c859cc', + 'device_protocol': 'SCSI', + 'temp': 34, + 'power_on_hours': 43549, + 'power_cycle_count': 0, + 'attrs': { + 'read_correction_algorithm_invocations': { + 'attribute_id': 'read_correction_algorithm_invocations', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "read_errors_corrected_by_eccdelayed": { - "attribute_id": "read_errors_corrected_by_eccdelayed", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'read_errors_corrected_by_eccdelayed': { + 'attribute_id': 'read_errors_corrected_by_eccdelayed', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "read_errors_corrected_by_eccfast": { - "attribute_id": "read_errors_corrected_by_eccfast", - "value": 300357663, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'read_errors_corrected_by_eccfast': { + 'attribute_id': 'read_errors_corrected_by_eccfast', + 'value': 300357663, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "read_errors_corrected_by_rereads_rewrites": { - "attribute_id": "read_errors_corrected_by_rereads_rewrites", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": 0 + 'read_errors_corrected_by_rereads_rewrites': { + 'attribute_id': 'read_errors_corrected_by_rereads_rewrites', + 'value': 0, + 'thresh': 0, + 'transformed_value': 0, + 'status': 0 }, - "read_total_errors_corrected": { - "attribute_id": "read_total_errors_corrected", - "value": 300357663, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'read_total_errors_corrected': { + 'attribute_id': 'read_total_errors_corrected', + 'value': 300357663, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "read_total_uncorrected_errors": { - "attribute_id": "read_total_uncorrected_errors", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": 0 + 'read_total_uncorrected_errors': { + 'attribute_id': 'read_total_uncorrected_errors', + 'value': 0, + 'thresh': 0, + 'transformed_value': 0, + 'status': 0 }, - "scsi_grown_defect_list": { - "attribute_id": "scsi_grown_defect_list", - "value": 56, - "thresh": 0, - "transformed_value": 0, - "status": 0 + 'scsi_grown_defect_list': { + 'attribute_id': 'scsi_grown_defect_list', + 'value': 56, + 'thresh': 0, + 'transformed_value': 0, + 'status': 0 }, - "write_correction_algorithm_invocations": { - "attribute_id": "write_correction_algorithm_invocations", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'write_correction_algorithm_invocations': { + 'attribute_id': 'write_correction_algorithm_invocations', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "write_errors_corrected_by_eccdelayed": { - "attribute_id": "write_errors_corrected_by_eccdelayed", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'write_errors_corrected_by_eccdelayed': { + 'attribute_id': 'write_errors_corrected_by_eccdelayed', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "write_errors_corrected_by_eccfast": { - "attribute_id": "write_errors_corrected_by_eccfast", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'write_errors_corrected_by_eccfast': { + 'attribute_id': 'write_errors_corrected_by_eccfast', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "write_errors_corrected_by_rereads_rewrites": { - "attribute_id": "write_errors_corrected_by_rereads_rewrites", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": 0 + 'write_errors_corrected_by_rereads_rewrites': { + 'attribute_id': 'write_errors_corrected_by_rereads_rewrites', + 'value': 0, + 'thresh': 0, + 'transformed_value': 0, + 'status': 0 }, - "write_total_errors_corrected": { - "attribute_id": "write_total_errors_corrected", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'write_total_errors_corrected': { + 'attribute_id': 'write_total_errors_corrected', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "write_total_uncorrected_errors": { - "attribute_id": "write_total_uncorrected_errors", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": 0 + 'write_total_uncorrected_errors': { + 'attribute_id': 'write_total_uncorrected_errors', + 'value': 0, + 'thresh': 0, + 'transformed_value': 0, + 'status': 0 } }, - "Status": 0 + 'Status': 0 }] }, - "metadata": { - "read_correction_algorithm_invocations": { - "display_name": "Read Correction Algorithm Invocations", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'metadata': { + 'read_correction_algorithm_invocations': { + 'display_name': 'Read Correction Algorithm Invocations', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "read_errors_corrected_by_eccdelayed": { - "display_name": "Read Errors Corrected by ECC Delayed", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'read_errors_corrected_by_eccdelayed': { + 'display_name': 'Read Errors Corrected by ECC Delayed', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "read_errors_corrected_by_eccfast": { - "display_name": "Read Errors Corrected by ECC Fast", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'read_errors_corrected_by_eccfast': { + 'display_name': 'Read Errors Corrected by ECC Fast', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "read_errors_corrected_by_rereads_rewrites": { - "display_name": "Read Errors Corrected by ReReads/ReWrites", - "ideal": "low", - "critical": true, - "description": "", - "display_type": "" + 'read_errors_corrected_by_rereads_rewrites': { + 'display_name': 'Read Errors Corrected by ReReads/ReWrites', + 'ideal': 'low', + 'critical': true, + 'description': '', + 'display_type': '' }, - "read_total_errors_corrected": { - "display_name": "Read Total Errors Corrected", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'read_total_errors_corrected': { + 'display_name': 'Read Total Errors Corrected', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "read_total_uncorrected_errors": { - "display_name": "Read Total Uncorrected Errors", - "ideal": "low", - "critical": true, - "description": "", - "display_type": "" + 'read_total_uncorrected_errors': { + 'display_name': 'Read Total Uncorrected Errors', + 'ideal': 'low', + 'critical': true, + 'description': '', + 'display_type': '' }, - "scsi_grown_defect_list": { - "display_name": "Grown Defect List", - "ideal": "low", - "critical": true, - "description": "", - "display_type": "" + 'scsi_grown_defect_list': { + 'display_name': 'Grown Defect List', + 'ideal': 'low', + 'critical': true, + 'description': '', + 'display_type': '' }, - "write_correction_algorithm_invocations": { - "display_name": "Write Correction Algorithm Invocations", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'write_correction_algorithm_invocations': { + 'display_name': 'Write Correction Algorithm Invocations', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "write_errors_corrected_by_eccdelayed": { - "display_name": "Write Errors Corrected by ECC Delayed", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'write_errors_corrected_by_eccdelayed': { + 'display_name': 'Write Errors Corrected by ECC Delayed', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "write_errors_corrected_by_eccfast": { - "display_name": "Write Errors Corrected by ECC Fast", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'write_errors_corrected_by_eccfast': { + 'display_name': 'Write Errors Corrected by ECC Fast', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "write_errors_corrected_by_rereads_rewrites": { - "display_name": "Write Errors Corrected by ReReads/ReWrites", - "ideal": "low", - "critical": true, - "description": "", - "display_type": "" + 'write_errors_corrected_by_rereads_rewrites': { + 'display_name': 'Write Errors Corrected by ReReads/ReWrites', + 'ideal': 'low', + 'critical': true, + 'description': '', + 'display_type': '' }, - "write_total_errors_corrected": { - "display_name": "Write Total Errors Corrected", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'write_total_errors_corrected': { + 'display_name': 'Write Total Errors Corrected', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "write_total_uncorrected_errors": { - "display_name": "Write Total Uncorrected Errors", - "ideal": "low", - "critical": true, - "description": "", - "display_type": "" + 'write_total_uncorrected_errors': { + 'display_name': 'Write Total Uncorrected Errors', + 'ideal': 'low', + 'critical': true, + 'description': '', + 'display_type': '' } }, - "success": true + 'success': true } diff --git a/webapp/frontend/src/app/data/mock/device/details/sde.ts b/webapp/frontend/src/app/data/mock/device/details/sde.ts index 42c5f1a..a9c5eae 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sde.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sde.ts @@ -1,222 +1,222 @@ export const sde = { - "data": { - "device": { - "CreatedAt": "2021-06-24T21:17:31.304461-07:00", - "UpdatedAt": "2021-10-24T16:40:16.495248-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264ebc248", - "device_name": "sde", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "9RK3XXXXX", - "firmware": "", - "rotational_speed": 0, - "capacity": 14000519643136, - "form_factor": "", - "smart_support": false, - "device_protocol": "SCSI", - "device_type": "", - "label": "", - "host_id": "", - "device_status": 0 + 'data': { + 'device': { + 'CreatedAt': '2021-06-24T21:17:31.304461-07:00', + 'UpdatedAt': '2021-10-24T16:40:16.495248-07:00', + 'DeletedAt': null, + 'wwn': '0x5000cca264ebc248', + 'device_name': 'sde', + 'manufacturer': 'ATA', + 'model_name': 'WDC_WD140EDFZ-11A0VA0', + 'interface_type': 'SCSI', + 'interface_speed': '', + 'serial_number': '9RK3XXXXX', + 'firmware': '', + 'rotational_speed': 0, + 'capacity': 14000519643136, + 'form_factor': '', + 'smart_support': false, + 'device_protocol': 'SCSI', + 'device_type': '', + 'label': '', + 'host_id': '', + 'device_status': 0 }, - "smart_results": [{ - "date": "2021-10-24T23:20:44Z", - "device_wwn": "0x5000cca264ebc248", - "device_protocol": "SCSI", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "attrs": { - "read_correction_algorithm_invocations": { - "attribute_id": "read_correction_algorithm_invocations", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'smart_results': [{ + 'date': '2021-10-24T23:20:44Z', + 'device_wwn': '0x5000cca264ebc248', + 'device_protocol': 'SCSI', + 'temp': 31, + 'power_on_hours': 5675, + 'power_cycle_count': 0, + 'attrs': { + 'read_correction_algorithm_invocations': { + 'attribute_id': 'read_correction_algorithm_invocations', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "read_errors_corrected_by_eccdelayed": { - "attribute_id": "read_errors_corrected_by_eccdelayed", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'read_errors_corrected_by_eccdelayed': { + 'attribute_id': 'read_errors_corrected_by_eccdelayed', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "read_errors_corrected_by_eccfast": { - "attribute_id": "read_errors_corrected_by_eccfast", - "value": 1410362924, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'read_errors_corrected_by_eccfast': { + 'attribute_id': 'read_errors_corrected_by_eccfast', + 'value': 1410362924, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "read_errors_corrected_by_rereads_rewrites": { - "attribute_id": "read_errors_corrected_by_rereads_rewrites", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": 0 + 'read_errors_corrected_by_rereads_rewrites': { + 'attribute_id': 'read_errors_corrected_by_rereads_rewrites', + 'value': 0, + 'thresh': 0, + 'transformed_value': 0, + 'status': 0 }, - "read_total_errors_corrected": { - "attribute_id": "read_total_errors_corrected", - "value": 1410362924, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'read_total_errors_corrected': { + 'attribute_id': 'read_total_errors_corrected', + 'value': 1410362924, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "read_total_uncorrected_errors": { - "attribute_id": "read_total_uncorrected_errors", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": 0 + 'read_total_uncorrected_errors': { + 'attribute_id': 'read_total_uncorrected_errors', + 'value': 0, + 'thresh': 0, + 'transformed_value': 0, + 'status': 0 }, - "scsi_grown_defect_list": { - "attribute_id": "scsi_grown_defect_list", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": 0 + 'scsi_grown_defect_list': { + 'attribute_id': 'scsi_grown_defect_list', + 'value': 0, + 'thresh': 0, + 'transformed_value': 0, + 'status': 0 }, - "write_correction_algorithm_invocations": { - "attribute_id": "write_correction_algorithm_invocations", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'write_correction_algorithm_invocations': { + 'attribute_id': 'write_correction_algorithm_invocations', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "write_errors_corrected_by_eccdelayed": { - "attribute_id": "write_errors_corrected_by_eccdelayed", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'write_errors_corrected_by_eccdelayed': { + 'attribute_id': 'write_errors_corrected_by_eccdelayed', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "write_errors_corrected_by_eccfast": { - "attribute_id": "write_errors_corrected_by_eccfast", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'write_errors_corrected_by_eccfast': { + 'attribute_id': 'write_errors_corrected_by_eccfast', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "write_errors_corrected_by_rereads_rewrites": { - "attribute_id": "write_errors_corrected_by_rereads_rewrites", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": 0 + 'write_errors_corrected_by_rereads_rewrites': { + 'attribute_id': 'write_errors_corrected_by_rereads_rewrites', + 'value': 0, + 'thresh': 0, + 'transformed_value': 0, + 'status': 0 }, - "write_total_errors_corrected": { - "attribute_id": "write_total_errors_corrected", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": 0 + 'write_total_errors_corrected': { + 'attribute_id': 'write_total_errors_corrected', + 'value': 0, + 'thresh': -1, + 'transformed_value': 0, + 'status': 0 }, - "write_total_uncorrected_errors": { - "attribute_id": "write_total_uncorrected_errors", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": 0 + 'write_total_uncorrected_errors': { + 'attribute_id': 'write_total_uncorrected_errors', + 'value': 0, + 'thresh': 0, + 'transformed_value': 0, + 'status': 0 } }, - "Status": 0 + 'Status': 0 }] }, - "metadata": { - "read_correction_algorithm_invocations": { - "display_name": "Read Correction Algorithm Invocations", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'metadata': { + 'read_correction_algorithm_invocations': { + 'display_name': 'Read Correction Algorithm Invocations', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "read_errors_corrected_by_eccdelayed": { - "display_name": "Read Errors Corrected by ECC Delayed", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'read_errors_corrected_by_eccdelayed': { + 'display_name': 'Read Errors Corrected by ECC Delayed', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "read_errors_corrected_by_eccfast": { - "display_name": "Read Errors Corrected by ECC Fast", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'read_errors_corrected_by_eccfast': { + 'display_name': 'Read Errors Corrected by ECC Fast', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "read_errors_corrected_by_rereads_rewrites": { - "display_name": "Read Errors Corrected by ReReads/ReWrites", - "ideal": "low", - "critical": true, - "description": "", - "display_type": "" + 'read_errors_corrected_by_rereads_rewrites': { + 'display_name': 'Read Errors Corrected by ReReads/ReWrites', + 'ideal': 'low', + 'critical': true, + 'description': '', + 'display_type': '' }, - "read_total_errors_corrected": { - "display_name": "Read Total Errors Corrected", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'read_total_errors_corrected': { + 'display_name': 'Read Total Errors Corrected', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "read_total_uncorrected_errors": { - "display_name": "Read Total Uncorrected Errors", - "ideal": "low", - "critical": true, - "description": "", - "display_type": "" + 'read_total_uncorrected_errors': { + 'display_name': 'Read Total Uncorrected Errors', + 'ideal': 'low', + 'critical': true, + 'description': '', + 'display_type': '' }, - "scsi_grown_defect_list": { - "display_name": "Grown Defect List", - "ideal": "low", - "critical": true, - "description": "", - "display_type": "" + 'scsi_grown_defect_list': { + 'display_name': 'Grown Defect List', + 'ideal': 'low', + 'critical': true, + 'description': '', + 'display_type': '' }, - "write_correction_algorithm_invocations": { - "display_name": "Write Correction Algorithm Invocations", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'write_correction_algorithm_invocations': { + 'display_name': 'Write Correction Algorithm Invocations', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "write_errors_corrected_by_eccdelayed": { - "display_name": "Write Errors Corrected by ECC Delayed", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'write_errors_corrected_by_eccdelayed': { + 'display_name': 'Write Errors Corrected by ECC Delayed', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "write_errors_corrected_by_eccfast": { - "display_name": "Write Errors Corrected by ECC Fast", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'write_errors_corrected_by_eccfast': { + 'display_name': 'Write Errors Corrected by ECC Fast', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "write_errors_corrected_by_rereads_rewrites": { - "display_name": "Write Errors Corrected by ReReads/ReWrites", - "ideal": "low", - "critical": true, - "description": "", - "display_type": "" + 'write_errors_corrected_by_rereads_rewrites': { + 'display_name': 'Write Errors Corrected by ReReads/ReWrites', + 'ideal': 'low', + 'critical': true, + 'description': '', + 'display_type': '' }, - "write_total_errors_corrected": { - "display_name": "Write Total Errors Corrected", - "ideal": "", - "critical": false, - "description": "", - "display_type": "" + 'write_total_errors_corrected': { + 'display_name': 'Write Total Errors Corrected', + 'ideal': '', + 'critical': false, + 'description': '', + 'display_type': '' }, - "write_total_uncorrected_errors": { - "display_name": "Write Total Uncorrected Errors", - "ideal": "low", - "critical": true, - "description": "", - "display_type": "" + 'write_total_uncorrected_errors': { + 'display_name': 'Write Total Uncorrected Errors', + 'ideal': 'low', + 'critical': true, + 'description': '', + 'display_type': '' } }, - "success": true + 'success': true } diff --git a/webapp/frontend/src/app/data/mock/device/details/sdf.ts b/webapp/frontend/src/app/data/mock/device/details/sdf.ts index 15949dd..e1a8871 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sdf.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sdf.ts @@ -1,29 +1,29 @@ export const sdf = { - "data": { - "device": { - "CreatedAt": "2021-06-24T21:17:31.305246-07:00", - "UpdatedAt": "2021-06-24T21:17:31.305246-07:00", - "DeletedAt": null, - "wwn": "0x50014ee20b2a72a9", - "device_name": "sdf", - "manufacturer": "ATA", - "model_name": "WDC_WD60EFRX-68MYMN1", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "WD-WXL1HXXXXX", - "firmware": "", - "rotational_speed": 0, - "capacity": 6001175126016, - "form_factor": "", - "smart_support": false, - "device_protocol": "", - "device_type": "", - "label": "", - "host_id": "", - "device_status": 0 + 'data': { + 'device': { + 'CreatedAt': '2021-06-24T21:17:31.305246-07:00', + 'UpdatedAt': '2021-06-24T21:17:31.305246-07:00', + 'DeletedAt': null, + 'wwn': '0x50014ee20b2a72a9', + 'device_name': 'sdf', + 'manufacturer': 'ATA', + 'model_name': 'WDC_WD60EFRX-68MYMN1', + 'interface_type': 'SCSI', + 'interface_speed': '', + 'serial_number': 'WD-WXL1HXXXXX', + 'firmware': '', + 'rotational_speed': 0, + 'capacity': 6001175126016, + 'form_factor': '', + 'smart_support': false, + 'device_protocol': '', + 'device_type': '', + 'label': '', + 'host_id': '', + 'device_status': 0 }, - "smart_results": [] + 'smart_results': [] }, - "metadata": null, - "success": true + 'metadata': null, + 'success': true } diff --git a/webapp/frontend/src/app/data/mock/summary/data.ts b/webapp/frontend/src/app/data/mock/summary/data.ts index e5f39bb..8530a8d 100644 --- a/webapp/frontend/src/app/data/mock/summary/data.ts +++ b/webapp/frontend/src/app/data/mock/summary/data.ts @@ -2,618 +2,618 @@ import * as moment from 'moment'; /* tslint:disable:max-line-length */ export const summary = { - "data": { - "summary": { - "0x5000c500673e6b5f": { - "device": { - "CreatedAt": "2021-04-30T08:17:13.155217-07:00", - "UpdatedAt": "2021-04-30T08:17:13.155217-07:00", - "DeletedAt": null, - "wwn": "0x5000c500673e6b5f", - "device_name": "sdg", - "device_label": "14TB-WD-DRIVE2", - "device_uuid": "", - "device_serial_id": "ata-ST6000DX000-1H217Z-Z4DXXXXX", - "manufacturer": "ATA", - "model_name": "ST6000DX000-1H217Z", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "Z4DXXXXX", - "firmware": "", - "rotational_speed": 0, - "capacity": 6001175126016, - "form_factor": "", - "smart_support": false, - "device_protocol": "", - "device_type": "", - "label": "", - "host_id": "", - "device_status": 0 + 'data': { + 'summary': { + '0x5000c500673e6b5f': { + 'device': { + 'CreatedAt': '2021-04-30T08:17:13.155217-07:00', + 'UpdatedAt': '2021-04-30T08:17:13.155217-07:00', + 'DeletedAt': null, + 'wwn': '0x5000c500673e6b5f', + 'device_name': 'sdg', + 'device_label': '14TB-WD-DRIVE2', + 'device_uuid': '', + 'device_serial_id': 'ata-ST6000DX000-1H217Z-Z4DXXXXX', + 'manufacturer': 'ATA', + 'model_name': 'ST6000DX000-1H217Z', + 'interface_type': 'SCSI', + 'interface_speed': '', + 'serial_number': 'Z4DXXXXX', + 'firmware': '', + 'rotational_speed': 0, + 'capacity': 6001175126016, + 'form_factor': '', + 'smart_support': false, + 'device_protocol': '', + 'device_type': '', + 'label': '', + 'host_id': '', + 'device_status': 0 } }, - "0x5000cca252c859cc": { - "device": { - "CreatedAt": "2021-04-30T08:17:13.152705-07:00", - "UpdatedAt": "2021-05-02T14:22:50.357164-07:00", - "DeletedAt": null, - "wwn": "0x5000cca252c859cc", - "device_name": "sdd", - "device_label": "14TB-WD-DRIVE1", - "device_uuid": "806cf4bc-d160-4d96-8ee9-3ab7cf2a2e1f", - "device_serial_id": "ata-WDC_WD80EFAX-68LHPN0-7SGLXXXXX", - "manufacturer": "ATA", - "model_name": "WDC_WD80EFAX-68LHPN0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "7SGLXXXXX", - "firmware": "", - "rotational_speed": 0, - "capacity": 8001563222016, - "form_factor": "", - "smart_support": false, - "device_protocol": "", - "device_type": "", - "label": "", - "host_id": "", - "device_status": 0 + '0x5000cca252c859cc': { + 'device': { + 'CreatedAt': '2021-04-30T08:17:13.152705-07:00', + 'UpdatedAt': '2021-05-02T14:22:50.357164-07:00', + 'DeletedAt': null, + 'wwn': '0x5000cca252c859cc', + 'device_name': 'sdd', + 'device_label': '14TB-WD-DRIVE1', + 'device_uuid': '806cf4bc-d160-4d96-8ee9-3ab7cf2a2e1f', + 'device_serial_id': 'ata-WDC_WD80EFAX-68LHPN0-7SGLXXXXX', + 'manufacturer': 'ATA', + 'model_name': 'WDC_WD80EFAX-68LHPN0', + 'interface_type': 'SCSI', + 'interface_speed': '', + 'serial_number': '7SGLXXXXX', + 'firmware': '', + 'rotational_speed': 0, + 'capacity': 8001563222016, + 'form_factor': '', + 'smart_support': false, + 'device_protocol': '', + 'device_type': '', + 'label': '', + 'host_id': '', + 'device_status': 0 }, - "smart": { - "collector_date": "2020-08-21T22:27:02Z", - "temp": 34, - "power_on_hours": 43549 + 'smart': { + 'collector_date': '2020-08-21T22:27:02Z', + 'temp': 34, + 'power_on_hours': 43549 }, - "temp_history": [{ - "date": "2020-08-21T22:27:02Z", - "temp": 34 + 'temp_history': [{ + 'date': '2020-08-21T22:27:02Z', + 'temp': 34 }] }, - "0x5000cca264eb01d7": { - "device": { - "CreatedAt": "2021-04-28T20:52:49.047154-07:00", - "UpdatedAt": "2021-05-02T14:22:49.86136-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264eb01d7", - "device_name": "sdb", - "device_label": "14TB-WD-DRIVE5", - "device_uuid": "8125ec6d-a7e4-4950-ac84-72d6a4d67128", - "device_serial_id": "ata-WDC_WD140EDFZ-11A0VA0-9RK1XXXXX", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "9RK1XXXXX", - "firmware": "81.00A81", - "rotational_speed": 0, - "capacity": 14000519643136, - "form_factor": "", - "smart_support": false, - "device_protocol": "", - "device_type": "", - "label": "", - "host_id": "", - "device_status": 0 + '0x5000cca264eb01d7': { + 'device': { + 'CreatedAt': '2021-04-28T20:52:49.047154-07:00', + 'UpdatedAt': '2021-05-02T14:22:49.86136-07:00', + 'DeletedAt': null, + 'wwn': '0x5000cca264eb01d7', + 'device_name': 'sdb', + 'device_label': '14TB-WD-DRIVE5', + 'device_uuid': '8125ec6d-a7e4-4950-ac84-72d6a4d67128', + 'device_serial_id': 'ata-WDC_WD140EDFZ-11A0VA0-9RK1XXXXX', + 'manufacturer': 'ATA', + 'model_name': 'WDC_WD140EDFZ-11A0VA0', + 'interface_type': 'SCSI', + 'interface_speed': '', + 'serial_number': '9RK1XXXXX', + 'firmware': '81.00A81', + 'rotational_speed': 0, + 'capacity': 14000519643136, + 'form_factor': '', + 'smart_support': false, + 'device_protocol': '', + 'device_type': '', + 'label': '', + 'host_id': '', + 'device_status': 0 }, - "smart": { - "collector_date": "2020-06-21T00:03:30Z", - "temp": 32, - "power_on_hours": 1730 + 'smart': { + 'collector_date': '2020-06-21T00:03:30Z', + 'temp': 32, + 'power_on_hours': 1730 }, - "temp_history": [{ - "date": "2020-06-21T00:03:30Z", - "temp": 32 + 'temp_history': [{ + 'date': '2020-06-21T00:03:30Z', + 'temp': 32 }] }, - "0x5000cca264ebc248": { - "device": { - "CreatedAt": "2021-04-30T08:17:13.153782-07:00", - "UpdatedAt": "2021-05-02T14:22:50.385282-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264ebc248", - "device_name": "sde", - "device_label": "14TB-WD-DRIVE3", - "device_uuid": "9eb60cde-d6d0-4172-b520-b241a6a5477f", - "device_serial_id": "ata-WDC_WD140EDFZ-11A0VA0-9RK3XXXXX", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "9RK3XXXXX", - "firmware": "", - "rotational_speed": 0, - "capacity": 14000519643136, - "form_factor": "", - "smart_support": false, - "device_protocol": "", - "device_type": "", - "label": "", - "host_id": "", - "device_status": 0 + '0x5000cca264ebc248': { + 'device': { + 'CreatedAt': '2021-04-30T08:17:13.153782-07:00', + 'UpdatedAt': '2021-05-02T14:22:50.385282-07:00', + 'DeletedAt': null, + 'wwn': '0x5000cca264ebc248', + 'device_name': 'sde', + 'device_label': '14TB-WD-DRIVE3', + 'device_uuid': '9eb60cde-d6d0-4172-b520-b241a6a5477f', + 'device_serial_id': 'ata-WDC_WD140EDFZ-11A0VA0-9RK3XXXXX', + 'manufacturer': 'ATA', + 'model_name': 'WDC_WD140EDFZ-11A0VA0', + 'interface_type': 'SCSI', + 'interface_speed': '', + 'serial_number': '9RK3XXXXX', + 'firmware': '', + 'rotational_speed': 0, + 'capacity': 14000519643136, + 'form_factor': '', + 'smart_support': false, + 'device_protocol': '', + 'device_type': '', + 'label': '', + 'host_id': '', + 'device_status': 0 } }, - "0x5000cca264ec3183": { - "device": { - "CreatedAt": "2021-04-30T08:17:13.151906-07:00", - "UpdatedAt": "2021-05-02T14:49:51.645012-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264ec3183", - "device_name": "sdc", - "device_label": "14TB-WD-DRIVE6", - "device_uuid": "e1378723-7861-49b9-8e01-0bd063f0ecdd", - "device_serial_id": "ata-WDC_WD140EDFZ-11A0VA0-9RK4XXXXX", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "9RK4XXXXX", - "firmware": "RVT02B6Q", - "rotational_speed": 0, - "capacity": 14000519643136, - "form_factor": "", - "smart_support": false, - "device_protocol": "", - "device_type": "", - "label": "", - "host_id": "custom host id", - "device_status": 1 + '0x5000cca264ec3183': { + 'device': { + 'CreatedAt': '2021-04-30T08:17:13.151906-07:00', + 'UpdatedAt': '2021-05-02T14:49:51.645012-07:00', + 'DeletedAt': null, + 'wwn': '0x5000cca264ec3183', + 'device_name': 'sdc', + 'device_label': '14TB-WD-DRIVE6', + 'device_uuid': 'e1378723-7861-49b9-8e01-0bd063f0ecdd', + 'device_serial_id': 'ata-WDC_WD140EDFZ-11A0VA0-9RK4XXXXX', + 'manufacturer': 'ATA', + 'model_name': 'WDC_WD140EDFZ-11A0VA0', + 'interface_type': 'SCSI', + 'interface_speed': '', + 'serial_number': '9RK4XXXXX', + 'firmware': 'RVT02B6Q', + 'rotational_speed': 0, + 'capacity': 14000519643136, + 'form_factor': '', + 'smart_support': false, + 'device_protocol': '', + 'device_type': '', + 'label': '', + 'host_id': 'custom host id', + 'device_status': 1 }, - "smart": { - "collector_date": "2020-09-13T16:29:23Z", - "temp": 36, - "power_on_hours": 14551 + 'smart': { + 'collector_date': '2020-09-13T16:29:23Z', + 'temp': 36, + 'power_on_hours': 14551 }, - "temp_history": [{ - "date": "2020-07-08T13:48:23Z", - "temp": 25 + 'temp_history': [{ + 'date': '2020-07-08T13:48:23Z', + 'temp': 25 }, { - "date": "2020-09-12T19:19:23Z", - "temp": 37 + 'date': '2020-09-12T19:19:23Z', + 'temp': 37 }, { - "date": "2020-09-12T19:29:23Z", - "temp": 37 + 'date': '2020-09-12T19:29:23Z', + 'temp': 37 }, { - "date": "2020-09-12T19:39:23Z", - "temp": 36 + 'date': '2020-09-12T19:39:23Z', + 'temp': 36 }, { - "date": "2020-09-12T19:49:23Z", - "temp": 36 + 'date': '2020-09-12T19:49:23Z', + 'temp': 36 }, { - "date": "2020-09-12T19:59:23Z", - "temp": 37 + 'date': '2020-09-12T19:59:23Z', + 'temp': 37 }, { - "date": "2020-09-12T20:09:23Z", - "temp": 37 + 'date': '2020-09-12T20:09:23Z', + 'temp': 37 }, { - "date": "2020-09-12T20:19:23Z", - "temp": 37 + 'date': '2020-09-12T20:19:23Z', + 'temp': 37 }, { - "date": "2020-09-12T20:29:23Z", - "temp": 37 + 'date': '2020-09-12T20:29:23Z', + 'temp': 37 }, { - "date": "2020-09-12T20:39:23Z", - "temp": 36 + 'date': '2020-09-12T20:39:23Z', + 'temp': 36 }, { - "date": "2020-09-12T20:49:23Z", - "temp": 36 + 'date': '2020-09-12T20:49:23Z', + 'temp': 36 }, { - "date": "2020-09-12T20:59:23Z", - "temp": 37 + 'date': '2020-09-12T20:59:23Z', + 'temp': 37 }, { - "date": "2020-09-12T21:09:23Z", - "temp": 36 + 'date': '2020-09-12T21:09:23Z', + 'temp': 36 }, { - "date": "2020-09-12T21:19:23Z", - "temp": 37 + 'date': '2020-09-12T21:19:23Z', + 'temp': 37 }, { - "date": "2020-09-12T21:29:23Z", - "temp": 38 + 'date': '2020-09-12T21:29:23Z', + 'temp': 38 }, { - "date": "2020-09-12T21:39:23Z", - "temp": 36 + 'date': '2020-09-12T21:39:23Z', + 'temp': 36 }, { - "date": "2020-09-12T21:49:23Z", - "temp": 36 + 'date': '2020-09-12T21:49:23Z', + 'temp': 36 }, { - "date": "2020-09-12T21:59:23Z", - "temp": 36 + 'date': '2020-09-12T21:59:23Z', + 'temp': 36 }, { - "date": "2020-09-12T22:09:23Z", - "temp": 36 + 'date': '2020-09-12T22:09:23Z', + 'temp': 36 }, { - "date": "2020-09-12T22:19:23Z", - "temp": 36 + 'date': '2020-09-12T22:19:23Z', + 'temp': 36 }, { - "date": "2020-09-12T22:29:23Z", - "temp": 36 + 'date': '2020-09-12T22:29:23Z', + 'temp': 36 }, { - "date": "2020-09-12T22:39:23Z", - "temp": 36 + 'date': '2020-09-12T22:39:23Z', + 'temp': 36 }, { - "date": "2020-09-12T22:49:23Z", - "temp": 36 + 'date': '2020-09-12T22:49:23Z', + 'temp': 36 }, { - "date": "2020-09-12T22:59:23Z", - "temp": 36 + 'date': '2020-09-12T22:59:23Z', + 'temp': 36 }, { - "date": "2020-09-12T23:09:23Z", - "temp": 36 + 'date': '2020-09-12T23:09:23Z', + 'temp': 36 }, { - "date": "2020-09-12T23:19:23Z", - "temp": 36 + 'date': '2020-09-12T23:19:23Z', + 'temp': 36 }, { - "date": "2020-09-12T23:29:23Z", - "temp": 36 + 'date': '2020-09-12T23:29:23Z', + 'temp': 36 }, { - "date": "2020-09-12T23:39:23Z", - "temp": 36 + 'date': '2020-09-12T23:39:23Z', + 'temp': 36 }, { - "date": "2020-09-12T23:49:23Z", - "temp": 36 + 'date': '2020-09-12T23:49:23Z', + 'temp': 36 }, { - "date": "2020-09-12T23:59:23Z", - "temp": 36 + 'date': '2020-09-12T23:59:23Z', + 'temp': 36 }, { - "date": "2020-09-13T00:09:23Z", - "temp": 36 + 'date': '2020-09-13T00:09:23Z', + 'temp': 36 }, { - "date": "2020-09-13T00:19:23Z", - "temp": 36 + 'date': '2020-09-13T00:19:23Z', + 'temp': 36 }, { - "date": "2020-09-13T00:29:23Z", - "temp": 37 + 'date': '2020-09-13T00:29:23Z', + 'temp': 37 }, { - "date": "2020-09-13T00:39:23Z", - "temp": 36 + 'date': '2020-09-13T00:39:23Z', + 'temp': 36 }, { - "date": "2020-09-13T00:49:23Z", - "temp": 36 + 'date': '2020-09-13T00:49:23Z', + 'temp': 36 }, { - "date": "2020-09-13T00:59:23Z", - "temp": 36 + 'date': '2020-09-13T00:59:23Z', + 'temp': 36 }, { - "date": "2020-09-13T01:09:23Z", - "temp": 36 + 'date': '2020-09-13T01:09:23Z', + 'temp': 36 }, { - "date": "2020-09-13T01:19:23Z", - "temp": 36 + 'date': '2020-09-13T01:19:23Z', + 'temp': 36 }, { - "date": "2020-09-13T01:29:23Z", - "temp": 37 + 'date': '2020-09-13T01:29:23Z', + 'temp': 37 }, { - "date": "2020-09-13T01:39:23Z", - "temp": 36 + 'date': '2020-09-13T01:39:23Z', + 'temp': 36 }, { - "date": "2020-09-13T01:49:23Z", - "temp": 37 + 'date': '2020-09-13T01:49:23Z', + 'temp': 37 }, { - "date": "2020-09-13T01:59:23Z", - "temp": 37 + 'date': '2020-09-13T01:59:23Z', + 'temp': 37 }, { - "date": "2020-09-13T02:09:23Z", - "temp": 37 + 'date': '2020-09-13T02:09:23Z', + 'temp': 37 }, { - "date": "2020-09-13T02:19:23Z", - "temp": 37 + 'date': '2020-09-13T02:19:23Z', + 'temp': 37 }, { - "date": "2020-09-13T02:29:23Z", - "temp": 38 + 'date': '2020-09-13T02:29:23Z', + 'temp': 38 }, { - "date": "2020-09-13T02:39:23Z", - "temp": 37 + 'date': '2020-09-13T02:39:23Z', + 'temp': 37 }, { - "date": "2020-09-13T02:49:23Z", - "temp": 37 + 'date': '2020-09-13T02:49:23Z', + 'temp': 37 }, { - "date": "2020-09-13T02:59:23Z", - "temp": 38 + 'date': '2020-09-13T02:59:23Z', + 'temp': 38 }, { - "date": "2020-09-13T03:09:23Z", - "temp": 38 + 'date': '2020-09-13T03:09:23Z', + 'temp': 38 }, { - "date": "2020-09-13T03:19:23Z", - "temp": 38 + 'date': '2020-09-13T03:19:23Z', + 'temp': 38 }, { - "date": "2020-09-13T03:29:23Z", - "temp": 38 + 'date': '2020-09-13T03:29:23Z', + 'temp': 38 }, { - "date": "2020-09-13T03:39:23Z", - "temp": 38 + 'date': '2020-09-13T03:39:23Z', + 'temp': 38 }, { - "date": "2020-09-13T03:49:23Z", - "temp": 38 + 'date': '2020-09-13T03:49:23Z', + 'temp': 38 }, { - "date": "2020-09-13T03:59:23Z", - "temp": 38 + 'date': '2020-09-13T03:59:23Z', + 'temp': 38 }, { - "date": "2020-09-13T04:09:23Z", - "temp": 38 + 'date': '2020-09-13T04:09:23Z', + 'temp': 38 }, { - "date": "2020-09-13T04:19:23Z", - "temp": 38 + 'date': '2020-09-13T04:19:23Z', + 'temp': 38 }, { - "date": "2020-09-13T04:29:23Z", - "temp": 38 + 'date': '2020-09-13T04:29:23Z', + 'temp': 38 }, { - "date": "2020-09-13T04:39:23Z", - "temp": 38 + 'date': '2020-09-13T04:39:23Z', + 'temp': 38 }, { - "date": "2020-09-13T04:49:23Z", - "temp": 38 + 'date': '2020-09-13T04:49:23Z', + 'temp': 38 }, { - "date": "2020-09-13T04:59:23Z", - "temp": 38 + 'date': '2020-09-13T04:59:23Z', + 'temp': 38 }, { - "date": "2020-09-13T05:09:23Z", - "temp": 37 + 'date': '2020-09-13T05:09:23Z', + 'temp': 37 }, { - "date": "2020-09-13T05:19:23Z", - "temp": 38 + 'date': '2020-09-13T05:19:23Z', + 'temp': 38 }, { - "date": "2020-09-13T05:29:23Z", - "temp": 39 + 'date': '2020-09-13T05:29:23Z', + 'temp': 39 }, { - "date": "2020-09-13T05:39:23Z", - "temp": 41 + 'date': '2020-09-13T05:39:23Z', + 'temp': 41 }, { - "date": "2020-09-13T05:49:23Z", - "temp": 42 + 'date': '2020-09-13T05:49:23Z', + 'temp': 42 }, { - "date": "2020-09-13T05:59:23Z", - "temp": 41 + 'date': '2020-09-13T05:59:23Z', + 'temp': 41 }, { - "date": "2020-09-13T06:09:23Z", - "temp": 41 + 'date': '2020-09-13T06:09:23Z', + 'temp': 41 }, { - "date": "2020-09-13T06:19:23Z", - "temp": 42 + 'date': '2020-09-13T06:19:23Z', + 'temp': 42 }, { - "date": "2020-09-13T06:29:23Z", - "temp": 41 + 'date': '2020-09-13T06:29:23Z', + 'temp': 41 }, { - "date": "2020-09-13T06:39:23Z", - "temp": 41 + 'date': '2020-09-13T06:39:23Z', + 'temp': 41 }, { - "date": "2020-09-13T06:49:23Z", - "temp": 41 + 'date': '2020-09-13T06:49:23Z', + 'temp': 41 }, { - "date": "2020-09-13T06:59:23Z", - "temp": 41 + 'date': '2020-09-13T06:59:23Z', + 'temp': 41 }, { - "date": "2020-09-13T07:09:23Z", - "temp": 40 + 'date': '2020-09-13T07:09:23Z', + 'temp': 40 }, { - "date": "2020-09-13T07:19:23Z", - "temp": 40 + 'date': '2020-09-13T07:19:23Z', + 'temp': 40 }, { - "date": "2020-09-13T07:29:23Z", - "temp": 41 + 'date': '2020-09-13T07:29:23Z', + 'temp': 41 }, { - "date": "2020-09-13T07:39:23Z", - "temp": 43 + 'date': '2020-09-13T07:39:23Z', + 'temp': 43 }, { - "date": "2020-09-13T07:49:23Z", - "temp": 42 + 'date': '2020-09-13T07:49:23Z', + 'temp': 42 }, { - "date": "2020-09-13T07:59:23Z", - "temp": 41 + 'date': '2020-09-13T07:59:23Z', + 'temp': 41 }, { - "date": "2020-09-13T08:09:23Z", - "temp": 42 + 'date': '2020-09-13T08:09:23Z', + 'temp': 42 }, { - "date": "2020-09-13T08:19:23Z", - "temp": 42 + 'date': '2020-09-13T08:19:23Z', + 'temp': 42 }, { - "date": "2020-09-13T08:29:23Z", - "temp": 41 + 'date': '2020-09-13T08:29:23Z', + 'temp': 41 }, { - "date": "2020-09-13T08:39:23Z", - "temp": 39 + 'date': '2020-09-13T08:39:23Z', + 'temp': 39 }, { - "date": "2020-09-13T08:49:23Z", - "temp": 38 + 'date': '2020-09-13T08:49:23Z', + 'temp': 38 }, { - "date": "2020-09-13T08:59:23Z", - "temp": 38 + 'date': '2020-09-13T08:59:23Z', + 'temp': 38 }, { - "date": "2020-09-13T09:09:23Z", - "temp": 38 + 'date': '2020-09-13T09:09:23Z', + 'temp': 38 }, { - "date": "2020-09-13T09:19:23Z", - "temp": 39 + 'date': '2020-09-13T09:19:23Z', + 'temp': 39 }, { - "date": "2020-09-13T09:29:23Z", - "temp": 39 + 'date': '2020-09-13T09:29:23Z', + 'temp': 39 }, { - "date": "2020-09-13T09:39:23Z", - "temp": 39 + 'date': '2020-09-13T09:39:23Z', + 'temp': 39 }, { - "date": "2020-09-13T09:49:23Z", - "temp": 39 + 'date': '2020-09-13T09:49:23Z', + 'temp': 39 }, { - "date": "2020-09-13T09:59:23Z", - "temp": 39 + 'date': '2020-09-13T09:59:23Z', + 'temp': 39 }, { - "date": "2020-09-13T10:09:23Z", - "temp": 39 + 'date': '2020-09-13T10:09:23Z', + 'temp': 39 }, { - "date": "2020-09-13T10:19:23Z", - "temp": 39 + 'date': '2020-09-13T10:19:23Z', + 'temp': 39 }, { - "date": "2020-09-13T10:29:23Z", - "temp": 39 + 'date': '2020-09-13T10:29:23Z', + 'temp': 39 }, { - "date": "2020-09-13T10:39:23Z", - "temp": 39 + 'date': '2020-09-13T10:39:23Z', + 'temp': 39 }, { - "date": "2020-09-13T10:49:23Z", - "temp": 39 + 'date': '2020-09-13T10:49:23Z', + 'temp': 39 }, { - "date": "2020-09-13T10:59:23Z", - "temp": 39 + 'date': '2020-09-13T10:59:23Z', + 'temp': 39 }, { - "date": "2020-09-13T11:09:23Z", - "temp": 38 + 'date': '2020-09-13T11:09:23Z', + 'temp': 38 }, { - "date": "2020-09-13T11:19:23Z", - "temp": 38 + 'date': '2020-09-13T11:19:23Z', + 'temp': 38 }, { - "date": "2020-09-13T11:29:23Z", - "temp": 38 + 'date': '2020-09-13T11:29:23Z', + 'temp': 38 }, { - "date": "2020-09-13T11:39:23Z", - "temp": 38 + 'date': '2020-09-13T11:39:23Z', + 'temp': 38 }, { - "date": "2020-09-13T11:49:23Z", - "temp": 38 + 'date': '2020-09-13T11:49:23Z', + 'temp': 38 }, { - "date": "2020-09-13T11:59:23Z", - "temp": 38 + 'date': '2020-09-13T11:59:23Z', + 'temp': 38 }, { - "date": "2020-09-13T12:09:23Z", - "temp": 38 + 'date': '2020-09-13T12:09:23Z', + 'temp': 38 }, { - "date": "2020-09-13T12:19:23Z", - "temp": 38 + 'date': '2020-09-13T12:19:23Z', + 'temp': 38 }, { - "date": "2020-09-13T12:29:23Z", - "temp": 39 + 'date': '2020-09-13T12:29:23Z', + 'temp': 39 }, { - "date": "2020-09-13T12:39:23Z", - "temp": 39 + 'date': '2020-09-13T12:39:23Z', + 'temp': 39 }, { - "date": "2020-09-13T12:49:23Z", - "temp": 39 + 'date': '2020-09-13T12:49:23Z', + 'temp': 39 }, { - "date": "2020-09-13T12:59:23Z", - "temp": 39 + 'date': '2020-09-13T12:59:23Z', + 'temp': 39 }, { - "date": "2020-09-13T13:09:23Z", - "temp": 39 + 'date': '2020-09-13T13:09:23Z', + 'temp': 39 }, { - "date": "2020-09-13T13:19:23Z", - "temp": 39 + 'date': '2020-09-13T13:19:23Z', + 'temp': 39 }, { - "date": "2020-09-13T13:29:23Z", - "temp": 39 + 'date': '2020-09-13T13:29:23Z', + 'temp': 39 }, { - "date": "2020-09-13T13:39:23Z", - "temp": 39 + 'date': '2020-09-13T13:39:23Z', + 'temp': 39 }, { - "date": "2020-09-13T13:49:23Z", - "temp": 39 + 'date': '2020-09-13T13:49:23Z', + 'temp': 39 }, { - "date": "2020-09-13T13:59:23Z", - "temp": 39 + 'date': '2020-09-13T13:59:23Z', + 'temp': 39 }, { - "date": "2020-09-13T14:09:23Z", - "temp": 39 + 'date': '2020-09-13T14:09:23Z', + 'temp': 39 }, { - "date": "2020-09-13T14:19:23Z", - "temp": 39 + 'date': '2020-09-13T14:19:23Z', + 'temp': 39 }, { - "date": "2020-09-13T14:29:23Z", - "temp": 39 + 'date': '2020-09-13T14:29:23Z', + 'temp': 39 }, { - "date": "2020-09-13T14:39:23Z", - "temp": 39 + 'date': '2020-09-13T14:39:23Z', + 'temp': 39 }, { - "date": "2020-09-13T14:49:23Z", - "temp": 39 + 'date': '2020-09-13T14:49:23Z', + 'temp': 39 }, { - "date": "2020-09-13T14:59:23Z", - "temp": 39 + 'date': '2020-09-13T14:59:23Z', + 'temp': 39 }, { - "date": "2020-09-13T15:09:23Z", - "temp": 39 + 'date': '2020-09-13T15:09:23Z', + 'temp': 39 }, { - "date": "2020-09-13T15:19:23Z", - "temp": 40 + 'date': '2020-09-13T15:19:23Z', + 'temp': 40 }, { - "date": "2020-09-13T15:29:23Z", - "temp": 40 + 'date': '2020-09-13T15:29:23Z', + 'temp': 40 }, { - "date": "2020-09-13T15:39:23Z", - "temp": 40 + 'date': '2020-09-13T15:39:23Z', + 'temp': 40 }, { - "date": "2020-09-13T15:49:23Z", - "temp": 39 + 'date': '2020-09-13T15:49:23Z', + 'temp': 39 }, { - "date": "2020-09-13T15:59:23Z", - "temp": 39 + 'date': '2020-09-13T15:59:23Z', + 'temp': 39 }, { - "date": "2020-09-13T16:09:23Z", - "temp": 39 + 'date': '2020-09-13T16:09:23Z', + 'temp': 39 }, { - "date": "2020-09-13T16:19:23Z", - "temp": 39 + 'date': '2020-09-13T16:19:23Z', + 'temp': 39 }, { - "date": "2020-09-13T16:29:23Z", - "temp": 39 + 'date': '2020-09-13T16:29:23Z', + 'temp': 39 }] }, - "0x50014ee20b2a72a9": { - "device": { - "CreatedAt": "2021-04-30T08:17:13.15451-07:00", - "UpdatedAt": "2021-04-30T08:17:13.15451-07:00", - "DeletedAt": null, - "wwn": "0x50014ee20b2a72a9", - "device_name": "sdf", - "device_label": "8.0TB-WD-4", - "device_uuid": "fc684dcc-aa2f-44f3-a958-d302dc7dd46d", - "device_serial_id": "ata-WDC_WD60EFRX-68MYMN1-WXL1HXXXXX", - "manufacturer": "ATA", - "model_name": "WDC_WD60EFRX-68MYMN1", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "WD-WXL1HXXXXX", - "firmware": "", - "rotational_speed": 0, - "capacity": 6001175126016, - "form_factor": "", - "smart_support": false, - "device_protocol": "", - "device_type": "", - "label": "", - "host_id": "", - "device_status": 0 + '0x50014ee20b2a72a9': { + 'device': { + 'CreatedAt': '2021-04-30T08:17:13.15451-07:00', + 'UpdatedAt': '2021-04-30T08:17:13.15451-07:00', + 'DeletedAt': null, + 'wwn': '0x50014ee20b2a72a9', + 'device_name': 'sdf', + 'device_label': '8.0TB-WD-4', + 'device_uuid': 'fc684dcc-aa2f-44f3-a958-d302dc7dd46d', + 'device_serial_id': 'ata-WDC_WD60EFRX-68MYMN1-WXL1HXXXXX', + 'manufacturer': 'ATA', + 'model_name': 'WDC_WD60EFRX-68MYMN1', + 'interface_type': 'SCSI', + 'interface_speed': '', + 'serial_number': 'WD-WXL1HXXXXX', + 'firmware': '', + 'rotational_speed': 0, + 'capacity': 6001175126016, + 'form_factor': '', + 'smart_support': false, + 'device_protocol': '', + 'device_type': '', + 'label': '', + 'host_id': '', + 'device_status': 0 } }, - "0x5002538e40a22954": { - "device": { - "CreatedAt": "2021-04-30T08:17:13.150792-07:00", - "UpdatedAt": "2021-05-02T14:22:50.330706-07:00", - "DeletedAt": null, - "wwn": "0x5002538e40a22954", - "device_name": "sda", - "device_label": "", - "device_uuid": "", - "device_serial_id": "ata-Samsung_SSD_860_EVO_500GB-S3YZNB0KBXXXXXX", - "manufacturer": "ATA", - "model_name": "Samsung_SSD_860_EVO_500GB", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "S3YZNB0KBXXXXXX", - "firmware": "002C", - "rotational_speed": 0, - "capacity": 500107862016, - "form_factor": "", - "smart_support": false, - "device_protocol": "", - "device_type": "", - "label": "", - "host_id": "", - "device_status": 0 + '0x5002538e40a22954': { + 'device': { + 'CreatedAt': '2021-04-30T08:17:13.150792-07:00', + 'UpdatedAt': '2021-05-02T14:22:50.330706-07:00', + 'DeletedAt': null, + 'wwn': '0x5002538e40a22954', + 'device_name': 'sda', + 'device_label': '', + 'device_uuid': '', + 'device_serial_id': 'ata-Samsung_SSD_860_EVO_500GB-S3YZNB0KBXXXXXX', + 'manufacturer': 'ATA', + 'model_name': 'Samsung_SSD_860_EVO_500GB', + 'interface_type': 'SCSI', + 'interface_speed': '', + 'serial_number': 'S3YZNB0KBXXXXXX', + 'firmware': '002C', + 'rotational_speed': 0, + 'capacity': 500107862016, + 'form_factor': '', + 'smart_support': false, + 'device_protocol': '', + 'device_type': '', + 'label': '', + 'host_id': '', + 'device_status': 0 }, - "smart": { - "collector_date": "2020-06-10T12:01:02Z", - "temp": 36, - "power_on_hours": 2401 + 'smart': { + 'collector_date': '2020-06-10T12:01:02Z', + 'temp': 36, + 'power_on_hours': 2401 }, - "temp_history": [{ - "date": "2020-06-10T12:01:02Z", - "temp": 36 + 'temp_history': [{ + 'date': '2020-06-10T12:01:02Z', + 'temp': 36 }] } } }, - "success": true + 'success': true } diff --git a/webapp/frontend/src/app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.component.ts b/webapp/frontend/src/app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.component.ts index 4325aa3..d995887 100644 --- a/webapp/frontend/src/app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.component.ts +++ b/webapp/frontend/src/app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, Inject } from '@angular/core'; import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; -import {DashboardDeviceDeleteDialogService} from "./dashboard-device-delete-dialog.service"; -import {Subject} from "rxjs"; +import {DashboardDeviceDeleteDialogService} from 'app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.service'; +import {Subject} from 'rxjs'; @Component({ selector: 'app-dashboard-device-delete-dialog', diff --git a/webapp/frontend/src/app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.module.ts b/webapp/frontend/src/app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.module.ts index adbe645..2605777 100644 --- a/webapp/frontend/src/app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.module.ts +++ b/webapp/frontend/src/app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.module.ts @@ -9,18 +9,18 @@ import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { SharedModule } from 'app/shared/shared.module'; import {DashboardDeviceDeleteDialogComponent} from 'app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.component' -import { MatButtonToggleModule} from "@angular/material/button-toggle"; -import {MatTabsModule} from "@angular/material/tabs"; -import {MatSliderModule} from "@angular/material/slider"; -import {MatSlideToggleModule} from "@angular/material/slide-toggle"; -import {MatTooltipModule} from "@angular/material/tooltip"; -import {dashboardRoutes} from "../../../modules/dashboard/dashboard.routing"; -import {MatDividerModule} from "@angular/material/divider"; -import {MatMenuModule} from "@angular/material/menu"; -import {MatProgressBarModule} from "@angular/material/progress-bar"; -import {MatSortModule} from "@angular/material/sort"; -import {MatTableModule} from "@angular/material/table"; -import {NgApexchartsModule} from "ng-apexcharts"; +import { MatButtonToggleModule} from '@angular/material/button-toggle'; +import {MatTabsModule} from '@angular/material/tabs'; +import {MatSliderModule} from '@angular/material/slider'; +import {MatSlideToggleModule} from '@angular/material/slide-toggle'; +import {MatTooltipModule} from '@angular/material/tooltip'; +import {dashboardRoutes} from 'app/modules/dashboard/dashboard.routing'; +import {MatDividerModule} from '@angular/material/divider'; +import {MatMenuModule} from '@angular/material/menu'; +import {MatProgressBarModule} from '@angular/material/progress-bar'; +import {MatSortModule} from '@angular/material/sort'; +import {MatTableModule} from '@angular/material/table'; +import {NgApexchartsModule} from 'ng-apexcharts'; import { MatDialogModule } from '@angular/material/dialog'; @NgModule({ diff --git a/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.ts b/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.ts index 7f18083..d2c9859 100644 --- a/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.ts +++ b/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.component.ts @@ -1,13 +1,13 @@ import { Component, Input, Output, OnInit, EventEmitter} from '@angular/core'; -import * as moment from "moment"; -import {takeUntil} from "rxjs/operators"; -import {AppConfig} from "app/core/config/app.config"; -import {TreoConfigService} from "@treo/services/config"; -import {Subject} from "rxjs"; +import * as moment from 'moment'; +import {takeUntil} from 'rxjs/operators'; +import {AppConfig} from 'app/core/config/app.config'; +import {TreoConfigService} from '@treo/services/config'; +import {Subject} from 'rxjs'; import humanizeDuration from 'humanize-duration' import {MatDialog} from '@angular/material/dialog'; -import {DashboardDeviceDeleteDialogComponent} from "app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.component"; -import {DeviceTitlePipe} from "app/shared/device-title.pipe"; +import {DashboardDeviceDeleteDialogComponent} from 'app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.component'; +import {DeviceTitlePipe} from 'app/shared/device-title.pipe'; @Component({ selector: 'app-dashboard-device', @@ -15,13 +15,6 @@ import {DeviceTitlePipe} from "app/shared/device-title.pipe"; styleUrls: ['./dashboard-device.component.scss'] }) export class DashboardDeviceComponent implements OnInit { - @Input() deviceSummary: any; - @Input() deviceWWN: string; - @Output() deviceDeleted = new EventEmitter(); - - config: AppConfig; - - private _unsubscribeAll: Subject; constructor( private _configService: TreoConfigService, @@ -30,6 +23,15 @@ export class DashboardDeviceComponent implements OnInit { // Set the private defaults this._unsubscribeAll = new Subject(); } + @Input() deviceSummary: any; + @Input() deviceWWN: string; + @Output() deviceDeleted = new EventEmitter(); + + config: AppConfig; + + private _unsubscribeAll: Subject; + + readonly humanizeDuration = humanizeDuration; ngOnInit(): void { // Subscribe to config changes @@ -45,7 +47,7 @@ export class DashboardDeviceComponent implements OnInit { // @ Public methods // ----------------------------------------------------------------------------------------------------- - classDeviceLastUpdatedOn(deviceSummary){ + classDeviceLastUpdatedOn(deviceSummary): string { if (deviceSummary.device.device_status !== 0) { return 'text-red' // if the device has failed, always highlight in red } else if(deviceSummary.device.device_status === 0 && deviceSummary.smart){ @@ -65,16 +67,14 @@ export class DashboardDeviceComponent implements OnInit { } } - deviceStatusString(deviceStatus){ - if(deviceStatus == 0){ - return "passed" + deviceStatusString(deviceStatus): string { + if(deviceStatus === 0){ + return 'passed' } else { - return "failed" + return 'failed' } } - readonly humanizeDuration = humanizeDuration; - openDeleteDialog(): void { diff --git a/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.module.ts b/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.module.ts index 209f2a1..e338330 100644 --- a/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.module.ts +++ b/webapp/frontend/src/app/layout/common/dashboard-device/dashboard-device.module.ts @@ -9,20 +9,20 @@ import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { SharedModule } from 'app/shared/shared.module'; import {DashboardDeviceComponent} from 'app/layout/common/dashboard-device/dashboard-device.component' -import { MatDialogModule } from "@angular/material/dialog"; -import { MatButtonToggleModule} from "@angular/material/button-toggle"; -import {MatTabsModule} from "@angular/material/tabs"; -import {MatSliderModule} from "@angular/material/slider"; -import {MatSlideToggleModule} from "@angular/material/slide-toggle"; -import {MatTooltipModule} from "@angular/material/tooltip"; -import {dashboardRoutes} from "../../../modules/dashboard/dashboard.routing"; -import {MatDividerModule} from "@angular/material/divider"; -import {MatMenuModule} from "@angular/material/menu"; -import {MatProgressBarModule} from "@angular/material/progress-bar"; -import {MatSortModule} from "@angular/material/sort"; -import {MatTableModule} from "@angular/material/table"; -import {NgApexchartsModule} from "ng-apexcharts"; -import {DashboardDeviceDeleteDialogModule} from "../dashboard-device-delete-dialog/dashboard-device-delete-dialog.module"; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatButtonToggleModule} from '@angular/material/button-toggle'; +import {MatTabsModule} from '@angular/material/tabs'; +import {MatSliderModule} from '@angular/material/slider'; +import {MatSlideToggleModule} from '@angular/material/slide-toggle'; +import {MatTooltipModule} from '@angular/material/tooltip'; +import {dashboardRoutes} from '../../../modules/dashboard/dashboard.routing'; +import {MatDividerModule} from '@angular/material/divider'; +import {MatMenuModule} from '@angular/material/menu'; +import {MatProgressBarModule} from '@angular/material/progress-bar'; +import {MatSortModule} from '@angular/material/sort'; +import {MatTableModule} from '@angular/material/table'; +import {NgApexchartsModule} from 'ng-apexcharts'; +import {DashboardDeviceDeleteDialogModule} from 'app/layout/common/dashboard-device-delete-dialog/dashboard-device-delete-dialog.module'; @NgModule({ declarations: [ diff --git a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts index e56ffc9..893aadf 100644 --- a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts +++ b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit } from '@angular/core'; import {AppConfig} from 'app/core/config/app.config'; import { TreoConfigService } from '@treo/services/config'; -import {Subject} from "rxjs"; -import {takeUntil} from "rxjs/operators"; +import {Subject} from 'rxjs'; +import {takeUntil} from 'rxjs/operators'; @Component({ selector: 'app-dashboard-settings', diff --git a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.module.ts b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.module.ts index 285b4d2..cbd3b3d 100644 --- a/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.module.ts +++ b/webapp/frontend/src/app/layout/common/dashboard-settings/dashboard-settings.module.ts @@ -9,12 +9,12 @@ import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { SharedModule } from 'app/shared/shared.module'; import {DashboardSettingsComponent} from 'app/layout/common/dashboard-settings/dashboard-settings.component' -import { MatDialogModule } from "@angular/material/dialog"; -import { MatButtonToggleModule} from "@angular/material/button-toggle"; -import {MatTabsModule} from "@angular/material/tabs"; -import {MatSliderModule} from "@angular/material/slider"; -import {MatSlideToggleModule} from "@angular/material/slide-toggle"; -import {MatTooltipModule} from "@angular/material/tooltip"; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatButtonToggleModule} from '@angular/material/button-toggle'; +import {MatTabsModule} from '@angular/material/tabs'; +import {MatSliderModule} from '@angular/material/slider'; +import {MatSlideToggleModule} from '@angular/material/slide-toggle'; +import {MatTooltipModule} from '@angular/material/tooltip'; @NgModule({ declarations: [ diff --git a/webapp/frontend/src/app/layout/common/detail-settings/detail-settings.module.ts b/webapp/frontend/src/app/layout/common/detail-settings/detail-settings.module.ts index 5569ed0..b8c05df 100644 --- a/webapp/frontend/src/app/layout/common/detail-settings/detail-settings.module.ts +++ b/webapp/frontend/src/app/layout/common/detail-settings/detail-settings.module.ts @@ -9,12 +9,12 @@ import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { SharedModule } from 'app/shared/shared.module'; import {DetailSettingsComponent} from 'app/layout/common/detail-settings/detail-settings.component' -import { MatDialogModule } from "@angular/material/dialog"; -import { MatButtonToggleModule} from "@angular/material/button-toggle"; -import {MatTabsModule} from "@angular/material/tabs"; -import {MatSliderModule} from "@angular/material/slider"; -import {MatSlideToggleModule} from "@angular/material/slide-toggle"; -import {MatTooltipModule} from "@angular/material/tooltip"; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatButtonToggleModule} from '@angular/material/button-toggle'; +import {MatTabsModule} from '@angular/material/tabs'; +import {MatSliderModule} from '@angular/material/slider'; +import {MatSlideToggleModule} from '@angular/material/slide-toggle'; +import {MatTooltipModule} from '@angular/material/tooltip'; @NgModule({ declarations: [ diff --git a/webapp/frontend/src/app/layout/layout.component.ts b/webapp/frontend/src/app/layout/layout.component.ts index 8196f09..6a3a68b 100644 --- a/webapp/frontend/src/app/layout/layout.component.ts +++ b/webapp/frontend/src/app/layout/layout.component.ts @@ -45,7 +45,7 @@ export class LayoutComponent implements OnInit, OnDestroy // Set the private defaults this._unsubscribeAll = new Subject(); - this.systemPrefersDark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches; + this.systemPrefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; } diff --git a/webapp/frontend/src/app/modules/dashboard/dashboard.component.ts b/webapp/frontend/src/app/modules/dashboard/dashboard.component.ts index f501f9f..eb5a2cc 100644 --- a/webapp/frontend/src/app/modules/dashboard/dashboard.component.ts +++ b/webapp/frontend/src/app/modules/dashboard/dashboard.component.ts @@ -7,11 +7,11 @@ import {ApexOptions, ChartComponent} from 'ng-apexcharts'; import { DashboardService } from 'app/modules/dashboard/dashboard.service'; import {MatDialog} from '@angular/material/dialog'; import { DashboardSettingsComponent } from 'app/layout/common/dashboard-settings/dashboard-settings.component'; -import {AppConfig} from "app/core/config/app.config"; -import {TreoConfigService} from "@treo/services/config"; -import {Router} from "@angular/router"; -import {TemperaturePipe} from "app/shared/temperature.pipe"; -import {DeviceTitlePipe} from "app/shared/device-title.pipe"; +import {AppConfig} from 'app/core/config/app.config'; +import {TreoConfigService} from '@treo/services/config'; +import {Router} from '@angular/router'; +import {TemperaturePipe} from 'app/shared/temperature.pipe'; +import {DeviceTitlePipe} from 'app/shared/device-title.pipe'; @Component({ selector : 'example', @@ -25,12 +25,12 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy data: any; hostGroups: { [hostId: string]: string[] } = {} temperatureOptions: ApexOptions; - tempDurationKey: string = "forever" + tempDurationKey = 'forever' config: AppConfig; // Private private _unsubscribeAll: Subject; - @ViewChild("tempChart", { static: false }) tempChart: ChartComponent; + @ViewChild('tempChart', { static: false }) tempChart: ChartComponent; /** * Constructor @@ -64,17 +64,17 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy .pipe(takeUntil(this._unsubscribeAll)) .subscribe((config: AppConfig) => { - //check if the old config and the new config do not match. - let oldConfig = JSON.stringify(this.config) - let newConfig = JSON.stringify(config) + // check if the old config and the new config do not match. + const oldConfig = JSON.stringify(this.config) + const newConfig = JSON.stringify(config) - if(oldConfig != newConfig){ + if(oldConfig !== newConfig){ console.log(`Configuration updated: ${newConfig} vs ${oldConfig}`) // Store the config this.config = config; if(oldConfig){ - console.log("reloading component...") + console.log('reloading component...') this.refreshComponent() } } @@ -88,10 +88,10 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy // Store the data this.data = data; - //generate group data. - for(let wwn in this.data.data.summary){ - let hostid = this.data.data.summary[wwn].device.host_id - let hostDeviceList = this.hostGroups[hostid] || [] + // generate group data. + for(const wwn in this.data.data.summary){ + const hostid = this.data.data.summary[wwn].device.host_id + const hostDeviceList = this.hostGroups[hostid] || [] hostDeviceList.push(wwn) this.hostGroups[hostid] = hostDeviceList } @@ -121,34 +121,34 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy // ----------------------------------------------------------------------------------------------------- // @ Private methods // ----------------------------------------------------------------------------------------------------- - private refreshComponent(){ + private refreshComponent(): void { - let currentUrl = this.router.url; + const currentUrl = this.router.url; this.router.routeReuseStrategy.shouldReuseRoute = () => false; this.router.onSameUrlNavigation = 'reload'; this.router.navigate([currentUrl]); } - private _deviceDataTemperatureSeries() { - var deviceTemperatureSeries = [] + private _deviceDataTemperatureSeries(): any[] { + const deviceTemperatureSeries = [] - console.log("DEVICE DATA SUMMARY", this.data) + console.log('DEVICE DATA SUMMARY', this.data) for(const wwn in this.data.data.summary){ - var deviceSummary = this.data.data.summary[wwn] + const deviceSummary = this.data.data.summary[wwn] if (!deviceSummary.temp_history){ continue } - let deviceName = DeviceTitlePipe.deviceTitleWithFallback(deviceSummary.device, this.config.dashboardDisplay) + const deviceName = DeviceTitlePipe.deviceTitleWithFallback(deviceSummary.device, this.config.dashboardDisplay) - var deviceSeriesMetadata = { + const deviceSeriesMetadata = { name: deviceName, data: [] } - for(let tempHistory of deviceSummary.temp_history){ - let newDate = new Date(tempHistory.date); + for(const tempHistory of deviceSummary.temp_history){ + const newDate = new Date(tempHistory.date); deviceSeriesMetadata.data.push({ x: newDate, y: TemperaturePipe.formatTemperature(tempHistory.temp, this.config.temperatureUnit, false) @@ -216,9 +216,9 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy // @ Public methods // ----------------------------------------------------------------------------------------------------- - deviceSummariesForHostGroup(hostGroupWWNs: string[]) { - let deviceSummaries = [] - for(let wwn of hostGroupWWNs){ + deviceSummariesForHostGroup(hostGroupWWNs: string[]): any[] { + const deviceSummaries = [] + for(const wwn of hostGroupWWNs){ if(this.data.data.summary[wwn]){ deviceSummaries.push(this.data.data.summary[wwn]) } @@ -226,7 +226,7 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy return deviceSummaries } - openDialog() { + openDialog(): void { const dialogRef = this.dialog.open(DashboardSettingsComponent); dialogRef.afterClosed().subscribe(result => { @@ -234,7 +234,7 @@ export class DashboardComponent implements OnInit, AfterViewInit, OnDestroy }); } - onDeviceDeleted(wwn: string) { + onDeviceDeleted(wwn: string): void { delete this.data.data.summary[wwn] // remove the device from the summary list. } diff --git a/webapp/frontend/src/app/modules/dashboard/dashboard.module.ts b/webapp/frontend/src/app/modules/dashboard/dashboard.module.ts index 0eca908..5edf279 100644 --- a/webapp/frontend/src/app/modules/dashboard/dashboard.module.ts +++ b/webapp/frontend/src/app/modules/dashboard/dashboard.module.ts @@ -12,8 +12,8 @@ import { MatSortModule } from '@angular/material/sort'; import { MatTableModule } from '@angular/material/table'; import { NgApexchartsModule } from 'ng-apexcharts'; import { MatTooltipModule } from '@angular/material/tooltip' -import { DashboardSettingsModule } from "app/layout/common/dashboard-settings/dashboard-settings.module"; -import { DashboardDeviceModule } from "app/layout/common/dashboard-device/dashboard-device.module"; +import { DashboardSettingsModule } from 'app/layout/common/dashboard-settings/dashboard-settings.module'; +import { DashboardDeviceModule } from 'app/layout/common/dashboard-device/dashboard-device.module'; @NgModule({ declarations: [ diff --git a/webapp/frontend/src/app/modules/dashboard/dashboard.routing.ts b/webapp/frontend/src/app/modules/dashboard/dashboard.routing.ts index e6f58c8..2df5cd4 100644 --- a/webapp/frontend/src/app/modules/dashboard/dashboard.routing.ts +++ b/webapp/frontend/src/app/modules/dashboard/dashboard.routing.ts @@ -1,6 +1,6 @@ import { Route } from '@angular/router'; import { DashboardComponent } from 'app/modules/dashboard/dashboard.component'; -import {DashboardResolver} from "./dashboard.resolvers"; +import {DashboardResolver} from 'app/modules/dashboard/dashboard.resolvers'; export const dashboardRoutes: Route[] = [ { diff --git a/webapp/frontend/src/app/modules/dashboard/dashboard.service.ts b/webapp/frontend/src/app/modules/dashboard/dashboard.service.ts index ed91799..185da9d 100644 --- a/webapp/frontend/src/app/modules/dashboard/dashboard.service.ts +++ b/webapp/frontend/src/app/modules/dashboard/dashboard.service.ts @@ -55,9 +55,9 @@ export class DashboardService getSummaryTempData(durationKey: string): Observable { - let params = {} + const params = {} if(durationKey){ - params["duration_key"] = durationKey + params['duration_key'] = durationKey } return this._httpClient.get(getBasePath() + '/api/summary/temp', {params: params}); diff --git a/webapp/frontend/src/app/modules/detail/detail.component.ts b/webapp/frontend/src/app/modules/detail/detail.component.ts index 78dc558..f37910a 100644 --- a/webapp/frontend/src/app/modules/detail/detail.component.ts +++ b/webapp/frontend/src/app/modules/detail/detail.component.ts @@ -1,18 +1,17 @@ import {AfterViewInit, Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; -import {ApexOptions} from "ng-apexcharts"; -import {MatTableDataSource} from "@angular/material/table"; -import {MatSort} from "@angular/material/sort"; -import {Subject} from "rxjs"; -import {DetailService} from "./detail.service"; -import {takeUntil} from "rxjs/operators"; -import {fadeOut} from "../../../@treo/animations/fade"; -import {DetailSettingsComponent} from "app/layout/common/detail-settings/detail-settings.component"; -import {MatDialog} from "@angular/material/dialog"; +import {ApexOptions} from 'ng-apexcharts'; +import {MatTableDataSource} from '@angular/material/table'; +import {MatSort} from '@angular/material/sort'; +import {Subject} from 'rxjs'; +import {DetailService} from './detail.service'; +import {takeUntil} from 'rxjs/operators'; +import {DetailSettingsComponent} from 'app/layout/common/detail-settings/detail-settings.component'; +import {MatDialog} from '@angular/material/dialog'; import humanizeDuration from 'humanize-duration'; -import {TreoConfigService} from "../../../@treo/services/config"; -import {AppConfig} from "../../core/config/app.config"; +import {TreoConfigService} from '@treo/services/config'; +import {AppConfig} from 'app/core/config/app.config'; import {animate, state, style, transition, trigger} from '@angular/animations'; -import {formatDate} from "@angular/common"; +import {formatDate} from '@angular/common'; import { LOCALE_ID, Inject } from '@angular/core'; // from Constants.go - these must match @@ -37,27 +36,6 @@ const AttributeStatusFailedScrutiny = 4 export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { - config: AppConfig; - - onlyCritical: boolean = true; - // data: any; - expandedAttribute: any | null; - - metadata: any; - device: any; - smart_results: any[]; - - commonSparklineOptions: Partial; - smartAttributeDataSource: MatTableDataSource; - smartAttributeTableColumns: string[]; - - @ViewChild('smartAttributeTable', {read: MatSort}) - smartAttributeTableMatSort: MatSort; - - // Private - private _unsubscribeAll: Subject; - private systemPrefersDark: boolean; - /** * Constructor * @@ -79,10 +57,33 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { // this.recentTransactionsTableColumns = ['status', 'id', 'name', 'value', 'worst', 'thresh']; this.smartAttributeTableColumns = ['status', 'id', 'name', 'value', 'worst', 'thresh','ideal', 'failure', 'history']; - this.systemPrefersDark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches; + this.systemPrefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; } + config: AppConfig; + + onlyCritical = true; + // data: any; + expandedAttribute: any | null; + + metadata: any; + device: any; + smart_results: any[]; + + commonSparklineOptions: Partial; + smartAttributeDataSource: MatTableDataSource; + smartAttributeTableColumns: string[]; + + @ViewChild('smartAttributeTable', {read: MatSort}) + smartAttributeTableMatSort: MatSort; + + // Private + private _unsubscribeAll: Subject; + private systemPrefersDark: boolean; + + readonly humanizeDuration = humanizeDuration; + // ----------------------------------------------------------------------------------------------------- // @ Lifecycle hooks // ----------------------------------------------------------------------------------------------------- @@ -181,7 +182,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { getAttributeName(attribute_data): string { - let attribute_metadata = this.metadata[attribute_data.attribute_id] + const attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata){ return 'Unknown Attribute Name' } else { @@ -189,7 +190,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { } } getAttributeDescription(attribute_data){ - let attribute_metadata = this.metadata[attribute_data.attribute_id] + const attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata){ return 'Unknown' } else { @@ -200,12 +201,12 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { getAttributeValue(attribute_data){ if(this.isAta()) { - let attribute_metadata = this.metadata[attribute_data.attribute_id] + const attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata){ return attribute_data.value - } else if (attribute_metadata.display_type == "raw") { + } else if (attribute_metadata.display_type == 'raw') { return attribute_data.raw_value - } else if (attribute_metadata.display_type == "transformed" && attribute_data.transformed_value) { + } else if (attribute_metadata.display_type == 'transformed' && attribute_data.transformed_value) { return attribute_data.transformed_value } else { return attribute_data.value @@ -218,7 +219,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { getAttributeValueType(attribute_data){ if(this.isAta()) { - let attribute_metadata = this.metadata[attribute_data.attribute_id] + const attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata){ return '' } else { @@ -231,25 +232,25 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { getAttributeIdeal(attribute_data){ if(this.isAta()){ - return this.metadata[attribute_data.attribute_id]?.display_type == "raw" ? this.metadata[attribute_data.attribute_id]?.ideal : '' + return this.metadata[attribute_data.attribute_id]?.display_type == 'raw' ? this.metadata[attribute_data.attribute_id]?.ideal : '' } else { return this.metadata[attribute_data.attribute_id]?.ideal } } getAttributeWorst(attribute_data){ - let attribute_metadata = this.metadata[attribute_data.attribute_id] + const attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata){ return attribute_data.worst } else { - return attribute_metadata?.display_type == "normalized" ? attribute_data.worst : '' + return attribute_metadata?.display_type == 'normalized' ? attribute_data.worst : '' } } getAttributeThreshold(attribute_data){ if(this.isAta()){ - let attribute_metadata = this.metadata[attribute_data.attribute_id] - if(!attribute_metadata || attribute_metadata.display_type == "normalized"){ + const attribute_metadata = this.metadata[attribute_data.attribute_id] + if(!attribute_metadata || attribute_metadata.display_type == 'normalized'){ return attribute_data.thresh } else { // if(this.data.metadata[attribute_data.attribute_id].observed_thresholds){ @@ -273,7 +274,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { } let attributes_length = 0 - let attributes = this.smart_results[0]?.attrs + const attributes = this.smart_results[0]?.attrs if (attributes) { attributes_length = Object.keys(attributes).length } @@ -292,12 +293,12 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { } private _generateSmartAttributeTableDataSource(smart_results){ - var smartAttributeDataSource = []; + const smartAttributeDataSource = []; if(smart_results.length == 0){ return smartAttributeDataSource } - var latest_smart_result = smart_results[0]; + const latest_smart_result = smart_results[0]; let attributes = {} if(this.isScsi()) { this.smartAttributeTableColumns = ['status', 'name', 'value', 'thresh', 'history']; @@ -306,20 +307,20 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { this.smartAttributeTableColumns = ['status', 'name', 'value', 'thresh', 'ideal', 'history']; attributes = latest_smart_result.attrs } else { - //ATA + // ATA attributes = latest_smart_result.attrs this.smartAttributeTableColumns = ['status', 'id', 'name', 'value', 'thresh','ideal', 'failure', 'history']; } for(const attrId in attributes){ - var attr = attributes[attrId] + const attr = attributes[attrId] - //chart history data + // chart history data if (!attr.chartData) { - var attrHistory = [] - for (let smart_result of smart_results){ + const attrHistory = [] + for (const smart_result of smart_results){ // attrHistory.push(this.getAttributeValue(smart_result.attrs[attrId])) const chartDatapoint = { @@ -342,12 +343,12 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { attributes[attrId].chartData = [ { - name: "chart-line-sparkline", + name: 'chart-line-sparkline', data: attrHistory } ] } - //determine when to include the attributes in table. + // determine when to include the attributes in table. if(!this.onlyCritical || this.onlyCritical && this.metadata[attr.attribute_id]?.critical || attr.value < attr.thresh){ smartAttributeDataSource.push(attr) @@ -367,7 +368,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { // Account balance this.commonSparklineOptions = { chart: { - type: "bar", + type: 'bar', width: 100, height: 25, sparkline: { @@ -392,7 +393,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { y: { title: { formatter: function(seriesName) { - return ""; + return ''; } } }, @@ -421,7 +422,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { // ----------------------------------------------------------------------------------------------------- toHex(decimalNumb){ - return "0x" + Number(decimalNumb).toString(16).padStart(2, '0').toUpperCase() + return '0x' + Number(decimalNumb).toString(16).padStart(2, '0').toUpperCase() } toggleOnlyCritical(){ this.onlyCritical = !this.onlyCritical @@ -449,6 +450,4 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { // return item.id || index; } - readonly humanizeDuration = humanizeDuration; - } diff --git a/webapp/frontend/src/app/modules/detail/detail.module.ts b/webapp/frontend/src/app/modules/detail/detail.module.ts index 126319a..ea118fe 100644 --- a/webapp/frontend/src/app/modules/detail/detail.module.ts +++ b/webapp/frontend/src/app/modules/detail/detail.module.ts @@ -13,7 +13,7 @@ import { MatTableModule } from '@angular/material/table'; import { MatTooltipModule } from '@angular/material/tooltip' import { NgApexchartsModule } from 'ng-apexcharts'; import { TreoCardModule } from '@treo/components/card'; -import {DetailSettingsModule} from "app/layout/common/detail-settings/detail-settings.module"; +import {DetailSettingsModule} from 'app/layout/common/detail-settings/detail-settings.module'; @NgModule({ declarations: [ diff --git a/webapp/frontend/src/app/modules/detail/detail.routing.ts b/webapp/frontend/src/app/modules/detail/detail.routing.ts index 4af0807..9ac9eb8 100644 --- a/webapp/frontend/src/app/modules/detail/detail.routing.ts +++ b/webapp/frontend/src/app/modules/detail/detail.routing.ts @@ -1,6 +1,6 @@ import { Route } from '@angular/router'; import { DetailComponent } from 'app/modules/detail/detail.component'; -import {DetailResolver} from "./detail.resolvers"; +import {DetailResolver} from './detail.resolvers'; export const detailRoutes: Route[] = [ { diff --git a/webapp/frontend/src/app/shared/device-sort.pipe.ts b/webapp/frontend/src/app/shared/device-sort.pipe.ts index 74cdc96..8a9c7ab 100644 --- a/webapp/frontend/src/app/shared/device-sort.pipe.ts +++ b/webapp/frontend/src/app/shared/device-sort.pipe.ts @@ -1,33 +1,33 @@ import { Pipe, PipeTransform } from '@angular/core'; -import {DeviceTitlePipe} from "./device-title.pipe"; +import {DeviceTitlePipe} from 'app/shared/device-title.pipe'; @Pipe({ name: 'deviceSort' }) export class DeviceSortPipe implements PipeTransform { - statusCompareFn(a: any, b: any) { + statusCompareFn(a: any, b: any): number { function deviceStatus(deviceSummary): number { if(!deviceSummary.smart){ return 0 - } else if (deviceSummary.device.device_status == 0){ + } else if (deviceSummary.device.device_status === 0){ return 1 } else { return deviceSummary.device.device_status * -1 // will return range from -1, -2, -3 } } - let left = deviceStatus(a) - let right = deviceStatus(b) + const left = deviceStatus(a) + const right = deviceStatus(b) return left - right; } titleCompareFn(dashboardDisplay: string) { return function (a: any, b: any){ - let _dashboardDisplay = dashboardDisplay - let left = DeviceTitlePipe.deviceTitleForType(a.device, _dashboardDisplay) || DeviceTitlePipe.deviceTitleForType(a.device, 'name') - let right = DeviceTitlePipe.deviceTitleForType(b.device, _dashboardDisplay) || DeviceTitlePipe.deviceTitleForType(b.device, 'name') + const _dashboardDisplay = dashboardDisplay + const left = DeviceTitlePipe.deviceTitleForType(a.device, _dashboardDisplay) || DeviceTitlePipe.deviceTitleForType(a.device, 'name') + const right = DeviceTitlePipe.deviceTitleForType(b.device, _dashboardDisplay) || DeviceTitlePipe.deviceTitleForType(b.device, 'name') if( left < right ) return -1; @@ -39,7 +39,7 @@ export class DeviceSortPipe implements PipeTransform { } } - ageCompareFn(a: any, b: any) { + ageCompareFn(a: any, b: any): number { const left = a.smart?.power_on_hours const right = b.smart?.power_on_hours diff --git a/webapp/frontend/src/app/shared/temperature.pipe.ts b/webapp/frontend/src/app/shared/temperature.pipe.ts index efcd09d..7671f95 100644 --- a/webapp/frontend/src/app/shared/temperature.pipe.ts +++ b/webapp/frontend/src/app/shared/temperature.pipe.ts @@ -1,5 +1,5 @@ import { Pipe, PipeTransform } from '@angular/core'; -import {formatNumber} from "@angular/common"; +import {formatNumber} from '@angular/common'; @Pipe({ name: 'temperature' From 7babc280a05588ea3cd3fbceb25c5eed3c5a27ed Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Mon, 20 Jun 2022 08:15:06 -0700 Subject: [PATCH 2/7] ensure that users can filter their notifications by: - failing attribute type (Critical vs All) - failure reason (Smart, Scrutiny, Both) fixes #300 --- example.scrutiny.yaml | 2 + webapp/backend/pkg/config/config.go | 3 + webapp/backend/pkg/constants.go | 7 + webapp/backend/pkg/notify/notify.go | 135 +++++++++++++-- webapp/backend/pkg/notify/notify_test.go | 161 ++++++++++++++++++ .../pkg/web/handler/send_test_notification.go | 15 +- .../pkg/web/handler/upload_device_metrics.go | 22 +-- 7 files changed, 311 insertions(+), 34 deletions(-) create mode 100644 webapp/backend/pkg/notify/notify_test.go diff --git a/example.scrutiny.yaml b/example.scrutiny.yaml index c93725e..b73b711 100644 --- a/example.scrutiny.yaml +++ b/example.scrutiny.yaml @@ -73,6 +73,8 @@ log: # - "join://shoutrrr:api-key@join/?devices=device1[,device2, ...][&icon=icon][&title=title]" # - "script:///file/path/on/disk" # - "https://www.example.com/path" +# filter_attributes: 'all' # options: 'all' or 'critical' +# level: 'fail' # options: 'fail', 'fail_scrutiny', 'fail_smart' ######################################################################################################################## # FEATURES COMING SOON diff --git a/webapp/backend/pkg/config/config.go b/webapp/backend/pkg/config/config.go index dbff261..5f5d4cc 100644 --- a/webapp/backend/pkg/config/config.go +++ b/webapp/backend/pkg/config/config.go @@ -2,6 +2,7 @@ package config import ( "github.com/analogj/go-util/utils" + "github.com/analogj/scrutiny/webapp/backend/pkg" "github.com/analogj/scrutiny/webapp/backend/pkg/errors" "github.com/spf13/viper" "log" @@ -38,6 +39,8 @@ func (c *configuration) Init() error { c.SetDefault("log.file", "") c.SetDefault("notify.urls", []string{}) + c.SetDefault("notify.filter_attributes", pkg.NotifyFilterAttributesAll) + c.SetDefault("notify.level", pkg.NotifyLevelFail) c.SetDefault("web.influxdb.scheme", "http") c.SetDefault("web.influxdb.host", "localhost") diff --git a/webapp/backend/pkg/constants.go b/webapp/backend/pkg/constants.go index fce37f8..0de6750 100644 --- a/webapp/backend/pkg/constants.go +++ b/webapp/backend/pkg/constants.go @@ -4,6 +4,13 @@ const DeviceProtocolAta = "ATA" const DeviceProtocolScsi = "SCSI" const DeviceProtocolNvme = "NVMe" +const NotifyFilterAttributesAll = "all" +const NotifyFilterAttributesCritical = "critical" + +const NotifyLevelFail = "fail" +const NotifyLevelFailScrutiny = "fail_scrutiny" +const NotifyLevelFailSmart = "fail_smart" + type AttributeStatus uint8 const ( diff --git a/webapp/backend/pkg/notify/notify.go b/webapp/backend/pkg/notify/notify.go index 5b81464..bfc6510 100644 --- a/webapp/backend/pkg/notify/notify.go +++ b/webapp/backend/pkg/notify/notify.go @@ -6,7 +6,11 @@ import ( "errors" "fmt" "github.com/analogj/go-util/utils" + "github.com/analogj/scrutiny/webapp/backend/pkg" "github.com/analogj/scrutiny/webapp/backend/pkg/config" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/measurements" + "github.com/analogj/scrutiny/webapp/backend/pkg/thresholds" "github.com/containrrr/shoutrrr" shoutrrrTypes "github.com/containrrr/shoutrrr/pkg/types" "github.com/sirupsen/logrus" @@ -14,28 +18,130 @@ import ( "net/http" "net/url" "os" + "strconv" "strings" "time" ) const NotifyFailureTypeEmailTest = "EmailTest" -const NotifyFailureTypeSmartPrefail = "SmartPreFailure" +const NotifyFailureTypeBothFailure = "SmartFailure" //SmartFailure always takes precedence when Scrutiny & Smart failed. const NotifyFailureTypeSmartFailure = "SmartFailure" -const NotifyFailureTypeSmartErrorLog = "SmartErrorLog" -const NotifyFailureTypeSmartSelfTest = "SmartSelfTestLog" +const NotifyFailureTypeScrutinyFailure = "ScrutinyFailure" + +// ShouldNotify check if the error Message should be filtered (level mismatch or filtered_attributes) +func ShouldNotify(device models.Device, smartAttrs measurements.Smart, notifyLevel string, notifyFilterAttributes string) bool { + // 1. check if the device is healthy + if device.DeviceStatus == pkg.DeviceStatusPassed { + return false + } + + // setup constants for comparison + var requiredDeviceStatus pkg.DeviceStatus + var requiredAttrStatus pkg.AttributeStatus + if notifyLevel == pkg.NotifyLevelFail { + // either scrutiny or smart failures should trigger an email + requiredDeviceStatus = pkg.DeviceStatusSet(pkg.DeviceStatusFailedSmart, pkg.DeviceStatusFailedScrutiny) + requiredAttrStatus = pkg.AttributeStatusSet(pkg.AttributeStatusFailedSmart, pkg.AttributeStatusFailedScrutiny) + } else if notifyLevel == pkg.NotifyLevelFailSmart { + //only smart failures + requiredDeviceStatus = pkg.DeviceStatusFailedSmart + requiredAttrStatus = pkg.AttributeStatusFailedSmart + } else { + requiredDeviceStatus = pkg.DeviceStatusFailedScrutiny + requiredAttrStatus = pkg.AttributeStatusFailedScrutiny + } + + // 2. check if the attributes that are failing should be filtered (non-critical) + // 3. for any unfiltered attribute, store the failure reason (Smart or Scrutiny) + if notifyFilterAttributes == pkg.NotifyFilterAttributesCritical { + hasFailingCriticalAttr := false + var statusFailingCrtiticalAttr pkg.AttributeStatus + + for attrId, attrData := range smartAttrs.Attributes { + //find failing attribute + if attrData.GetStatus() == pkg.AttributeStatusPassed { + continue //skip all passing attributes + } + + // merge the status's of all critical attributes + statusFailingCrtiticalAttr = pkg.AttributeStatusSet(statusFailingCrtiticalAttr, attrData.GetStatus()) + + //found a failing attribute, see if its critical + if device.IsScsi() && thresholds.ScsiMetadata[attrId].Critical { + hasFailingCriticalAttr = true + } else if device.IsNvme() && thresholds.NmveMetadata[attrId].Critical { + hasFailingCriticalAttr = true + } else { + //this is ATA + attrIdInt, err := strconv.Atoi(attrId) + if err != nil { + continue + } + if thresholds.AtaMetadata[attrIdInt].Critical { + hasFailingCriticalAttr = true + } + } + + } + + if !hasFailingCriticalAttr { + //no critical attributes are failing, and notifyFilterAttributes == "critical" + return false + } else { + // check if any of the critical attributes have a status that we're looking for + return pkg.AttributeStatusHas(statusFailingCrtiticalAttr, requiredAttrStatus) + } + + } else { + // 2. SKIP - we are processing every attribute. + // 3. check if the device failure level matches the wanted failure level. + return pkg.DeviceStatusHas(device.DeviceStatus, requiredDeviceStatus) + } +} // TODO: include host and/or user label for device. type Payload struct { - Date string `json:"date"` //populated by Send function. - FailureType string `json:"failure_type"` //EmailTest, SmartFail, ScrutinyFail DeviceType string `json:"device_type"` //ATA/SCSI/NVMe DeviceName string `json:"device_name"` //dev/sda DeviceSerial string `json:"device_serial"` //WDDJ324KSO Test bool `json:"test"` // false - //should not be populated - Subject string `json:"subject"` - Message string `json:"message"` + //private, populated during init (marked as Public for JSON serialization) + Date string `json:"date"` //populated by Send function. + FailureType string `json:"failure_type"` //EmailTest, BothFail, SmartFail, ScrutinyFail + Subject string `json:"subject"` + Message string `json:"message"` +} + +func NewPayload(device models.Device, test bool) Payload { + payload := Payload{ + DeviceType: device.DeviceType, + DeviceName: device.DeviceName, + DeviceSerial: device.SerialNumber, + Test: test, + } + + //validate that the Payload is populated + sendDate := time.Now() + payload.Date = sendDate.Format(time.RFC3339) + payload.FailureType = payload.GenerateFailureType(device.DeviceStatus) + payload.Subject = payload.GenerateSubject() + payload.Message = payload.GenerateMessage() + return payload +} + +func (p *Payload) GenerateFailureType(deviceStatus pkg.DeviceStatus) string { + //generate a failure type, given Test and DeviceStatus + if p.Test { + return NotifyFailureTypeEmailTest // must be an email test if "Test" is true + } + if pkg.DeviceStatusHas(deviceStatus, pkg.DeviceStatusFailedSmart) && pkg.DeviceStatusHas(deviceStatus, pkg.DeviceStatusFailedScrutiny) { + return NotifyFailureTypeBothFailure //both failed + } else if pkg.DeviceStatusHas(deviceStatus, pkg.DeviceStatusFailedSmart) { + return NotifyFailureTypeSmartFailure //only SMART failed + } else { + return NotifyFailureTypeScrutinyFailure //only Scrutiny failed + } } func (p *Payload) GenerateSubject() string { @@ -61,6 +167,14 @@ Date: %s`, p.DeviceName, p.FailureType, p.DeviceName, p.DeviceSerial, p.DeviceTy return message } +func New(logger logrus.FieldLogger, appconfig config.Interface, device models.Device, test bool) Notify { + return Notify{ + Logger: logger, + Config: appconfig, + Payload: NewPayload(device, test), + } +} + type Notify struct { Logger logrus.FieldLogger Config config.Interface @@ -68,11 +182,6 @@ type Notify struct { } func (n *Notify) Send() error { - //validate that the Payload is populated - sendDate := time.Now() - n.Payload.Date = sendDate.Format(time.RFC3339) - n.Payload.Subject = n.Payload.GenerateSubject() - n.Payload.Message = n.Payload.GenerateMessage() //retrieve list of notification endpoints from config file configUrls := n.Config.GetStringSlice("notify.urls") diff --git a/webapp/backend/pkg/notify/notify_test.go b/webapp/backend/pkg/notify/notify_test.go new file mode 100644 index 0000000..aadb5f9 --- /dev/null +++ b/webapp/backend/pkg/notify/notify_test.go @@ -0,0 +1,161 @@ +package notify + +import ( + "github.com/analogj/scrutiny/webapp/backend/pkg" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/measurements" + "github.com/stretchr/testify/require" + "testing" +) + +func TestShouldNotify_MustSkipPassingDevices(t *testing.T) { + t.Parallel() + //setup + device := models.Device{ + DeviceStatus: pkg.DeviceStatusPassed, + } + smartAttrs := measurements.Smart{} + notifyLevel := pkg.NotifyLevelFail + notifyFilterAttributes := pkg.NotifyFilterAttributesAll + + //assert + require.False(t, ShouldNotify(device, smartAttrs, notifyLevel, notifyFilterAttributes)) +} + +func TestShouldNotify_NotifyLevelFail_FailingSmartDevice(t *testing.T) { + t.Parallel() + //setup + device := models.Device{ + DeviceStatus: pkg.DeviceStatusFailedSmart, + } + smartAttrs := measurements.Smart{} + notifyLevel := pkg.NotifyLevelFail + notifyFilterAttributes := pkg.NotifyFilterAttributesAll + + //assert + require.True(t, ShouldNotify(device, smartAttrs, notifyLevel, notifyFilterAttributes)) +} + +func TestShouldNotify_NotifyLevelFailSmart_FailingSmartDevice(t *testing.T) { + t.Parallel() + //setup + device := models.Device{ + DeviceStatus: pkg.DeviceStatusFailedSmart, + } + smartAttrs := measurements.Smart{} + notifyLevel := pkg.NotifyLevelFailSmart + notifyFilterAttributes := pkg.NotifyFilterAttributesAll + + //assert + require.True(t, ShouldNotify(device, smartAttrs, notifyLevel, notifyFilterAttributes)) +} + +func TestShouldNotify_NotifyLevelFailScrutiny_FailingSmartDevice(t *testing.T) { + t.Parallel() + //setup + device := models.Device{ + DeviceStatus: pkg.DeviceStatusFailedSmart, + } + smartAttrs := measurements.Smart{} + notifyLevel := pkg.NotifyLevelFailScrutiny + notifyFilterAttributes := pkg.NotifyFilterAttributesAll + + //assert + require.False(t, ShouldNotify(device, smartAttrs, notifyLevel, notifyFilterAttributes)) +} + +func TestShouldNotify_NotifyFilterAttributesCritical_WithCriticalAttrs(t *testing.T) { + t.Parallel() + //setup + device := models.Device{ + DeviceStatus: pkg.DeviceStatusFailedSmart, + } + smartAttrs := measurements.Smart{Attributes: map[string]measurements.SmartAttribute{ + "5": &measurements.SmartAtaAttribute{ + Status: pkg.AttributeStatusFailedSmart, + }, + }} + notifyLevel := pkg.NotifyLevelFail + notifyFilterAttributes := pkg.NotifyFilterAttributesCritical + + //assert + require.True(t, ShouldNotify(device, smartAttrs, notifyLevel, notifyFilterAttributes)) +} + +func TestShouldNotify_NotifyFilterAttributesCritical_WithMultipleCriticalAttrs(t *testing.T) { + t.Parallel() + //setup + device := models.Device{ + DeviceStatus: pkg.DeviceStatusFailedSmart, + } + smartAttrs := measurements.Smart{Attributes: map[string]measurements.SmartAttribute{ + "5": &measurements.SmartAtaAttribute{ + Status: pkg.AttributeStatusPassed, + }, + "10": &measurements.SmartAtaAttribute{ + Status: pkg.AttributeStatusFailedScrutiny, + }, + }} + notifyLevel := pkg.NotifyLevelFail + notifyFilterAttributes := pkg.NotifyFilterAttributesCritical + + //assert + require.True(t, ShouldNotify(device, smartAttrs, notifyLevel, notifyFilterAttributes)) +} + +func TestShouldNotify_NotifyFilterAttributesCritical_WithNoCriticalAttrs(t *testing.T) { + t.Parallel() + //setup + device := models.Device{ + DeviceStatus: pkg.DeviceStatusFailedSmart, + } + smartAttrs := measurements.Smart{Attributes: map[string]measurements.SmartAttribute{ + "1": &measurements.SmartAtaAttribute{ + Status: pkg.AttributeStatusFailedSmart, + }, + }} + notifyLevel := pkg.NotifyLevelFail + notifyFilterAttributes := pkg.NotifyFilterAttributesCritical + + //assert + require.False(t, ShouldNotify(device, smartAttrs, notifyLevel, notifyFilterAttributes)) +} + +func TestShouldNotify_NotifyFilterAttributesCritical_WithNoFailingCriticalAttrs(t *testing.T) { + t.Parallel() + //setup + device := models.Device{ + DeviceStatus: pkg.DeviceStatusFailedSmart, + } + smartAttrs := measurements.Smart{Attributes: map[string]measurements.SmartAttribute{ + "5": &measurements.SmartAtaAttribute{ + Status: pkg.AttributeStatusPassed, + }, + }} + notifyLevel := pkg.NotifyLevelFail + notifyFilterAttributes := pkg.NotifyFilterAttributesCritical + + //assert + require.False(t, ShouldNotify(device, smartAttrs, notifyLevel, notifyFilterAttributes)) +} + +func TestShouldNotify_NotifyFilterAttributesCritical_NotifyLevelFailSmart_WithCriticalAttrsFailingScrutiny(t *testing.T) { + t.Parallel() + //setup + device := models.Device{ + DeviceStatus: pkg.DeviceStatusFailedSmart, + } + smartAttrs := measurements.Smart{Attributes: map[string]measurements.SmartAttribute{ + "5": &measurements.SmartAtaAttribute{ + Status: pkg.AttributeStatusPassed, + }, + "10": &measurements.SmartAtaAttribute{ + Status: pkg.AttributeStatusFailedScrutiny, + }, + }} + notifyLevel := pkg.NotifyLevelFailSmart + notifyFilterAttributes := pkg.NotifyFilterAttributesCritical + + //assert + require.False(t, ShouldNotify(device, smartAttrs, notifyLevel, notifyFilterAttributes)) +} diff --git a/webapp/backend/pkg/web/handler/send_test_notification.go b/webapp/backend/pkg/web/handler/send_test_notification.go index 07a1d6c..dae55ab 100644 --- a/webapp/backend/pkg/web/handler/send_test_notification.go +++ b/webapp/backend/pkg/web/handler/send_test_notification.go @@ -15,17 +15,16 @@ func SendTestNotification(c *gin.Context) { appConfig := c.MustGet("CONFIG").(config.Interface) logger := c.MustGet("LOGGER").(logrus.FieldLogger) - testNotify := notify.Notify{ - Logger: logger, - Config: appConfig, - Payload: notify.Payload{ - FailureType: "EmailTest", - DeviceSerial: "FAKEWDDJ324KSO", + testNotify := notify.New( + logger, + appConfig, + models.Device{ + SerialNumber: "FAKEWDDJ324KSO", DeviceType: pkg.DeviceProtocolAta, DeviceName: "/dev/sda", - Test: true, }, - } + true, + ) err := testNotify.Send() if err != nil { logger.Errorln("An error occurred while sending test notification", err) diff --git a/webapp/backend/pkg/web/handler/upload_device_metrics.go b/webapp/backend/pkg/web/handler/upload_device_metrics.go index 7a971bd..e893366 100644 --- a/webapp/backend/pkg/web/handler/upload_device_metrics.go +++ b/webapp/backend/pkg/web/handler/upload_device_metrics.go @@ -63,20 +63,16 @@ func UploadDeviceMetrics(c *gin.Context) { } //check for error - if updatedDevice.DeviceStatus != pkg.DeviceStatusPassed { + if notify.ShouldNotify(updatedDevice, smartData, appConfig.GetString("notify.level"), appConfig.GetString("notify.filter_attributes")) { //send notifications - testNotify := notify.Notify{ - Config: appConfig, - Payload: notify.Payload{ - FailureType: notify.NotifyFailureTypeSmartFailure, - DeviceName: updatedDevice.DeviceName, - DeviceType: updatedDevice.DeviceProtocol, - DeviceSerial: updatedDevice.SerialNumber, - Test: false, - }, - Logger: logger, - } - _ = testNotify.Send() //we ignore error message when sending notifications. + + liveNotify := notify.New( + logger, + appConfig, + updatedDevice, + false, + ) + _ = liveNotify.Send() //we ignore error message when sending notifications. } c.JSON(http.StatusOK, gin.H{"success": true}) From 157c93b967514f8c2708554f825729d132f1cd02 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Mon, 20 Jun 2022 12:09:56 -0700 Subject: [PATCH 3/7] provide a mechanism to specify the absolute path to the smartctl binary used by metrics collector. - fixes #304 --- collector/pkg/collector/metrics.go | 6 +++--- collector/pkg/config/config.go | 1 + collector/pkg/detect/detect.go | 4 ++-- example.collector.yaml | 1 + 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/collector/pkg/collector/metrics.go b/collector/pkg/collector/metrics.go index ed1b777..415516b 100644 --- a/collector/pkg/collector/metrics.go +++ b/collector/pkg/collector/metrics.go @@ -98,10 +98,10 @@ func (mc *MetricsCollector) Run() error { func (mc *MetricsCollector) Validate() error { mc.logger.Infoln("Verifying required tools") - _, lookErr := exec.LookPath("smartctl") + _, lookErr := exec.LookPath(mc.config.GetString("commands.metrics_smartctl_bin")) if lookErr != nil { - return errors.DependencyMissingError("smartctl is missing") + return errors.DependencyMissingError(fmt.Sprintf("%s binary is missing", mc.config.GetString("commands.metrics_smartctl_bin"))) } return nil @@ -124,7 +124,7 @@ func (mc *MetricsCollector) Collect(deviceWWN string, deviceName string, deviceT } args = append(args, fullDeviceName) - result, err := mc.shell.Command(mc.logger, "smartctl", args, "", os.Environ()) + result, err := mc.shell.Command(mc.logger, mc.config.GetString("commands.metrics_smartctl_bin"), args, "", os.Environ()) resultBytes := []byte(result) if err != nil { if exitError, ok := err.(*exec.ExitError); ok { diff --git a/collector/pkg/config/config.go b/collector/pkg/config/config.go index 025082e..0a0d156 100644 --- a/collector/pkg/config/config.go +++ b/collector/pkg/config/config.go @@ -43,6 +43,7 @@ func (c *configuration) Init() error { c.SetDefault("api.endpoint", "http://localhost:8080") + c.SetDefault("commands.metrics_smartctl_bin", "smartctl") c.SetDefault("commands.metrics_scan_args", "--scan --json") c.SetDefault("commands.metrics_info_args", "--info --json") c.SetDefault("commands.metrics_smart_args", "--xall --json") diff --git a/collector/pkg/detect/detect.go b/collector/pkg/detect/detect.go index 5f2fa55..6f6e5d8 100644 --- a/collector/pkg/detect/detect.go +++ b/collector/pkg/detect/detect.go @@ -29,7 +29,7 @@ type Detect struct { func (d *Detect) SmartctlScan() ([]models.Device, error) { //we use smartctl to detect all the drives available. args := strings.Split(d.Config.GetString("commands.metrics_scan_args"), " ") - detectedDeviceConnJson, err := d.Shell.Command(d.Logger, "smartctl", args, "", os.Environ()) + detectedDeviceConnJson, err := d.Shell.Command(d.Logger, d.Config.GetString("commands.metrics_smartctl_bin"), args, "", os.Environ()) if err != nil { d.Logger.Errorf("Error scanning for devices: %v", err) return nil, err @@ -60,7 +60,7 @@ func (d *Detect) SmartCtlInfo(device *models.Device) error { } args = append(args, fullDeviceName) - availableDeviceInfoJson, err := d.Shell.Command(d.Logger, "smartctl", args, "", os.Environ()) + availableDeviceInfoJson, err := d.Shell.Command(d.Logger, d.Config.GetString("commands.metrics_smartctl_bin"), args, "", os.Environ()) if err != nil { d.Logger.Errorf("Could not retrieve device information for %s: %v", device.DeviceName, err) return err diff --git a/example.collector.yaml b/example.collector.yaml index 60ab408..26260bc 100644 --- a/example.collector.yaml +++ b/example.collector.yaml @@ -73,6 +73,7 @@ devices: # example to show how to override the smartctl command args globally #commands: +# metrics_smartctl_bin: 'smartctl' # change to provide custom `smartctl` binary path, eg. `/usr/sbin/smartctl` # metrics_scan_args: '--scan --json' # used to detect devices # metrics_info_args: '--info --json' # used to determine device unique ID & register device with Scrutiny # metrics_smart_args: '--xall --json' # used to retrieve smart data for each device. From d718b0898b9adf3f8ef51b356c9bad39b8bd9aba Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Mon, 20 Jun 2022 17:21:27 -0700 Subject: [PATCH 5/7] trying to fix tests. --- collector/pkg/detect/detect_test.go | 7 +++++++ webapp/backend/pkg/web/server_test.go | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/collector/pkg/detect/detect_test.go b/collector/pkg/detect/detect_test.go index 70cb2f6..ac61395 100644 --- a/collector/pkg/detect/detect_test.go +++ b/collector/pkg/detect/detect_test.go @@ -19,6 +19,7 @@ func TestDetect_SmartctlScan(t *testing.T) { fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig.EXPECT().GetString("host.id").AnyTimes().Return("") fakeConfig.EXPECT().GetDeviceOverrides().AnyTimes().Return([]models.ScanOverride{}) + fakeConfig.EXPECT().GetString("commands.metrics_smartctl_bin").AnyTimes().Return("smartctl") fakeConfig.EXPECT().GetString("commands.metrics_scan_args").AnyTimes().Return("--scan --json") fakeShell := mock_shell.NewMockInterface(mockCtrl) @@ -47,6 +48,7 @@ func TestDetect_SmartctlScan_Megaraid(t *testing.T) { fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig.EXPECT().GetString("host.id").AnyTimes().Return("") fakeConfig.EXPECT().GetDeviceOverrides().AnyTimes().Return([]models.ScanOverride{}) + fakeConfig.EXPECT().GetString("commands.metrics_smartctl_bin").AnyTimes().Return("smartctl") fakeConfig.EXPECT().GetString("commands.metrics_scan_args").AnyTimes().Return("--scan --json") fakeShell := mock_shell.NewMockInterface(mockCtrl) @@ -78,6 +80,7 @@ func TestDetect_SmartctlScan_Nvme(t *testing.T) { fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig.EXPECT().GetString("host.id").AnyTimes().Return("") fakeConfig.EXPECT().GetDeviceOverrides().AnyTimes().Return([]models.ScanOverride{}) + fakeConfig.EXPECT().GetString("commands.metrics_smartctl_bin").AnyTimes().Return("smartctl") fakeConfig.EXPECT().GetString("commands.metrics_scan_args").AnyTimes().Return("--scan --json") fakeShell := mock_shell.NewMockInterface(mockCtrl) @@ -108,6 +111,7 @@ func TestDetect_TransformDetectedDevices_Empty(t *testing.T) { fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig.EXPECT().GetString("host.id").AnyTimes().Return("") fakeConfig.EXPECT().GetDeviceOverrides().AnyTimes().Return([]models.ScanOverride{}) + fakeConfig.EXPECT().GetString("commands.metrics_smartctl_bin").AnyTimes().Return("smartctl") fakeConfig.EXPECT().GetString("commands.metrics_scan_args").AnyTimes().Return("--scan --json") detectedDevices := models.Scan{ @@ -140,6 +144,7 @@ func TestDetect_TransformDetectedDevices_Ignore(t *testing.T) { fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig.EXPECT().GetString("host.id").AnyTimes().Return("") fakeConfig.EXPECT().GetDeviceOverrides().AnyTimes().Return([]models.ScanOverride{{Device: "/dev/sda", DeviceType: nil, Ignore: true}}) + fakeConfig.EXPECT().GetString("commands.metrics_smartctl_bin").AnyTimes().Return("smartctl") fakeConfig.EXPECT().GetString("commands.metrics_scan_args").AnyTimes().Return("--scan --json") detectedDevices := models.Scan{ @@ -170,6 +175,7 @@ func TestDetect_TransformDetectedDevices_Raid(t *testing.T) { defer mockCtrl.Finish() fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig.EXPECT().GetString("host.id").AnyTimes().Return("") + fakeConfig.EXPECT().GetString("commands.metrics_smartctl_bin").AnyTimes().Return("smartctl") fakeConfig.EXPECT().GetString("commands.metrics_scan_args").AnyTimes().Return("--scan --json") fakeConfig.EXPECT().GetDeviceOverrides().AnyTimes().Return([]models.ScanOverride{ { @@ -210,6 +216,7 @@ func TestDetect_TransformDetectedDevices_Simple(t *testing.T) { defer mockCtrl.Finish() fakeConfig := mock_config.NewMockInterface(mockCtrl) fakeConfig.EXPECT().GetString("host.id").AnyTimes().Return("") + fakeConfig.EXPECT().GetString("commands.metrics_smartctl_bin").AnyTimes().Return("smartctl") fakeConfig.EXPECT().GetString("commands.metrics_scan_args").AnyTimes().Return("--scan --json") fakeConfig.EXPECT().GetDeviceOverrides().AnyTimes().Return([]models.ScanOverride{{Device: "/dev/sda", DeviceType: []string{"sat+megaraid"}}}) detectedDevices := models.Scan{ diff --git a/webapp/backend/pkg/web/server_test.go b/webapp/backend/pkg/web/server_test.go index 9ff979f..1d867e8 100644 --- a/webapp/backend/pkg/web/server_test.go +++ b/webapp/backend/pkg/web/server_test.go @@ -219,6 +219,8 @@ func (suite *ServerTestSuite) TestPopulateMultiple() { fakeConfig := mock_config.NewMockInterface(mockCtrl) //fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return("testdata/scrutiny_test.db") fakeConfig.EXPECT().GetStringSlice("notify.urls").Return([]string{}).AnyTimes() + fakeConfig.EXPECT().GetString("notify.level").AnyTimes().Return(pkg.NotifyLevelFail) + fakeConfig.EXPECT().GetString("notify.filter_attributes").AnyTimes().Return(pkg.NotifyFilterAttributesAll) fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(path.Join(parentPath, "scrutiny_test.db")) fakeConfig.EXPECT().GetString("web.src.frontend.path").AnyTimes().Return(parentPath) fakeConfig.EXPECT().GetString("web.listen.basepath").Return(suite.Basepath).AnyTimes() @@ -326,6 +328,9 @@ func (suite *ServerTestSuite) TestSendTestNotificationRoute_WebhookFailure() { fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"https://unroutable.domain.example.asdfghj"}) + fakeConfig.EXPECT().GetString("notify.level").AnyTimes().Return(pkg.NotifyLevelFail) + fakeConfig.EXPECT().GetString("notify.filter_attributes").AnyTimes().Return(pkg.NotifyFilterAttributesAll) + if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { // when running test suite in github actions, we run an influxdb service as a sidecar. fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() @@ -365,6 +370,9 @@ func (suite *ServerTestSuite) TestSendTestNotificationRoute_ScriptFailure() { fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"script:///missing/path/on/disk"}) + fakeConfig.EXPECT().GetString("notify.level").AnyTimes().Return(pkg.NotifyLevelFail) + fakeConfig.EXPECT().GetString("notify.filter_attributes").AnyTimes().Return(pkg.NotifyFilterAttributesAll) + if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { // when running test suite in github actions, we run an influxdb service as a sidecar. fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() @@ -404,6 +412,9 @@ func (suite *ServerTestSuite) TestSendTestNotificationRoute_ScriptSuccess() { fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"script:///usr/bin/env"}) + fakeConfig.EXPECT().GetString("notify.level").AnyTimes().Return(pkg.NotifyLevelFail) + fakeConfig.EXPECT().GetString("notify.filter_attributes").AnyTimes().Return(pkg.NotifyFilterAttributesAll) + if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { // when running test suite in github actions, we run an influxdb service as a sidecar. fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() @@ -443,6 +454,9 @@ func (suite *ServerTestSuite) TestSendTestNotificationRoute_ShoutrrrFailure() { fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{"discord://invalidtoken@channel"}) + fakeConfig.EXPECT().GetString("notify.level").AnyTimes().Return(pkg.NotifyLevelFail) + fakeConfig.EXPECT().GetString("notify.filter_attributes").AnyTimes().Return(pkg.NotifyFilterAttributesAll) + if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { // when running test suite in github actions, we run an influxdb service as a sidecar. fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() @@ -481,6 +495,8 @@ func (suite *ServerTestSuite) TestGetDevicesSummaryRoute_Nvme() { fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes() fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes() fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{}) + fakeConfig.EXPECT().GetString("notify.level").AnyTimes().Return(pkg.NotifyLevelFail) + fakeConfig.EXPECT().GetString("notify.filter_attributes").AnyTimes().Return(pkg.NotifyFilterAttributesAll) if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions { // when running test suite in github actions, we run an influxdb service as a sidecar. fakeConfig.EXPECT().GetString("web.influxdb.host").Return("influxdb").AnyTimes() From fbe7d63a24d30a0668cbf40308d5ad8b6c3e2048 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Mon, 20 Jun 2022 18:01:43 -0700 Subject: [PATCH 6/7] trying to fix tests. --- webapp/backend/pkg/web/server_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/webapp/backend/pkg/web/server_test.go b/webapp/backend/pkg/web/server_test.go index 1d867e8..b64617c 100644 --- a/webapp/backend/pkg/web/server_test.go +++ b/webapp/backend/pkg/web/server_test.go @@ -186,6 +186,8 @@ func (suite *ServerTestSuite) TestUploadDeviceMetricsRoute() { } else { fakeConfig.EXPECT().GetString("web.influxdb.host").Return("localhost").AnyTimes() } + fakeConfig.EXPECT().GetString("notify.level").AnyTimes().Return(pkg.NotifyLevelFail) + fakeConfig.EXPECT().GetString("notify.filter_attributes").AnyTimes().Return(pkg.NotifyFilterAttributesAll) ae := web.AppEngine{ Config: fakeConfig, From 3d9001a5e4a8f7f488d4e79adf63bab5397d133d Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Sat, 25 Jun 2022 11:19:44 -0700 Subject: [PATCH 7/7] when deviceType not specified in collector config, scrutiny will ignore the device. We need to make sure we correctly override the device. fixes #255 --- collector/pkg/detect/detect.go | 29 +++++++++++++-- collector/pkg/detect/detect_test.go | 56 +++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/collector/pkg/detect/detect.go b/collector/pkg/detect/detect.go index 6f6e5d8..971805e 100644 --- a/collector/pkg/detect/detect.go +++ b/collector/pkg/detect/detect.go @@ -149,10 +149,35 @@ func (d *Detect) TransformDetectedDevices(detectedDeviceConns models.Scan) []mod //create a new device group, and replace the one generated by smartctl --scan overrideDeviceGroup := []models.Device{} - for _, overrideDeviceType := range overrideDevice.DeviceType { + if overrideDevice.DeviceType != nil { + for _, overrideDeviceType := range overrideDevice.DeviceType { + overrideDeviceGroup = append(overrideDeviceGroup, models.Device{ + HostId: d.Config.GetString("host.id"), + DeviceType: overrideDeviceType, + DeviceName: strings.TrimPrefix(overrideDeviceFile, DevicePrefix()), + }) + } + } else { + //user may have specified device in config file without device type (default to scanned device type) + + //check if the device file was detected by the scanner + var deviceType string + if scannedDevice, foundScannedDevice := groupedDevices[overrideDeviceFile]; foundScannedDevice { + if len(scannedDevice) > 0 { + //take the device type from the first grouped device + deviceType = scannedDevice[0].DeviceType + } else { + deviceType = "ata" + } + + } else { + //fallback to ata if no scanned device detected + deviceType = "ata" + } + overrideDeviceGroup = append(overrideDeviceGroup, models.Device{ HostId: d.Config.GetString("host.id"), - DeviceType: overrideDeviceType, + DeviceType: deviceType, DeviceName: strings.TrimPrefix(overrideDeviceFile, DevicePrefix()), }) } diff --git a/collector/pkg/detect/detect_test.go b/collector/pkg/detect/detect_test.go index ac61395..1ef6d92 100644 --- a/collector/pkg/detect/detect_test.go +++ b/collector/pkg/detect/detect_test.go @@ -241,3 +241,59 @@ func TestDetect_TransformDetectedDevices_Simple(t *testing.T) { require.Equal(t, 1, len(transformedDevices)) require.Equal(t, "sat+megaraid", transformedDevices[0].DeviceType) } + +// test https://github.com/AnalogJ/scrutiny/issues/255#issuecomment-1164024126 +func TestDetect_TransformDetectedDevices_WithoutDeviceTypeOverride(t *testing.T) { + //setup + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + fakeConfig.EXPECT().GetString("host.id").AnyTimes().Return("") + fakeConfig.EXPECT().GetString("commands.metrics_smartctl_bin").AnyTimes().Return("smartctl") + fakeConfig.EXPECT().GetString("commands.metrics_scan_args").AnyTimes().Return("--scan --json") + fakeConfig.EXPECT().GetDeviceOverrides().AnyTimes().Return([]models.ScanOverride{{Device: "/dev/sda"}}) + detectedDevices := models.Scan{ + Devices: []models.ScanDevice{ + { + Name: "/dev/sda", + InfoName: "/dev/sda", + Protocol: "ata", + Type: "scsi", + }, + }, + } + + d := detect.Detect{ + Config: fakeConfig, + } + + //test + transformedDevices := d.TransformDetectedDevices(detectedDevices) + + //assert + require.Equal(t, 1, len(transformedDevices)) + require.Equal(t, "scsi", transformedDevices[0].DeviceType) +} + +func TestDetect_TransformDetectedDevices_WhenDeviceNotDetected(t *testing.T) { + //setup + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + fakeConfig := mock_config.NewMockInterface(mockCtrl) + fakeConfig.EXPECT().GetString("host.id").AnyTimes().Return("") + fakeConfig.EXPECT().GetString("commands.metrics_smartctl_bin").AnyTimes().Return("smartctl") + fakeConfig.EXPECT().GetString("commands.metrics_scan_args").AnyTimes().Return("--scan --json") + fakeConfig.EXPECT().GetDeviceOverrides().AnyTimes().Return([]models.ScanOverride{{Device: "/dev/sda"}}) + detectedDevices := models.Scan{} + + d := detect.Detect{ + Config: fakeConfig, + } + + //test + transformedDevices := d.TransformDetectedDevices(detectedDevices) + + //assert + require.Equal(t, 1, len(transformedDevices)) + require.Equal(t, "ata", transformedDevices[0].DeviceType) +}