diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 294bc04..034d407 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,6 +71,33 @@ go run webapp/backend/cmd/scrutiny/scrutiny.go start --config ./scrutiny.yaml Now visit http://localhost:8080 +If you'd like to populate the database with some test data, you can run the following commands: + +``` +docker run -p 8086:8086 --rm influxdb:2.0 + + +docker run -p 8086:8086 \ + -e DOCKER_INFLUXDB_INIT_USERNAME=admin \ + -e DOCKER_INFLUXDB_INIT_PASSWORD=12345678 \ + -e DOCKER_INFLUXDB_INIT_ORG=my-org \ + -e DOCKER_INFLUXDB_INIT_BUCKET=bucket \ + influxdb:2.0 + + +curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/web/testdata/register-devices-req.json localhost:8080/api/devices/register + +curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/models/testdata/smart-ata.json localhost:8080/api/device/0x5000cca264eb01d7/smart +curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/models/testdata/smart-ata-date.json localhost:8080/api/device/0x5000cca264eb01d7/smart +curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/models/testdata/smart-fail2.json localhost:8080/api/device/0x5000cca264ec3183/smart +curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/models/testdata/smart-nvme.json localhost:8080/api/device/0x5002538e40a22954/smart +curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/models/testdata/smart-scsi.json localhost:8080/api/device/0x5000cca252c859cc/smart +curl -X POST -H "Content-Type: application/json" -d @webapp/backend/pkg/models/testdata/smart-scsi2.json localhost:8080/api/device/0x5000cca264ebc248/smart + +curl localhost:8080/api/summary + +``` + ### Collector ``` brew install smartmontools diff --git a/docker/Dockerfile b/docker/Dockerfile index 5409a22..235ff60 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -30,11 +30,16 @@ FROM ubuntu:bionic as runtime EXPOSE 8080 WORKDIR /scrutiny ENV PATH="/scrutiny/bin:${PATH}" +ENV INFLUXD_CONFIG_PATH=/scrutiny/influxdb RUN apt-get update && apt-get install -y cron smartmontools=7.0-0ubuntu1~ubuntu18.04.1 ca-certificates curl && update-ca-certificates ADD https://github.com/just-containers/s6-overlay/releases/download/v1.21.8.0/s6-overlay-amd64.tar.gz /tmp/ RUN tar xzf /tmp/s6-overlay-amd64.tar.gz -C / + +ADD https://dl.influxdata.com/influxdb/releases/influxdb2-2.0.4-amd64.deb /tmp/ +RUN dpkg -i /tmp/influxdb2-2.0.4-amd64.deb && rm -rf /tmp/influxdb2-2.0.4-amd64.deb + COPY /rootfs / COPY /rootfs/etc/cron.d/scrutiny /etc/cron.d/scrutiny diff --git a/docker/entrypoint-collector.sh b/docker/entrypoint-collector.sh index c838c19..501c8d5 100755 --- a/docker/entrypoint-collector.sh +++ b/docker/entrypoint-collector.sh @@ -7,4 +7,4 @@ printenv | sed 's/^\(.*\)$/export \1/g' > /env.sh # now that we have the env start cron in the foreground echo "starting cron" -cron -f +su -c "cron -l 8 -f" root diff --git a/docs/dbdiagram.io.txt b/docs/dbdiagram.io.txt new file mode 100644 index 0000000..7d23af7 --- /dev/null +++ b/docs/dbdiagram.io.txt @@ -0,0 +1,62 @@ + +// SQLite Table(s) +Table device { + created_at timestamp + + wwn varchar [pk] + + //user provided + label varchar + host_id varchar + + // smartctl provided + device_name varchar + manufacturer varchar + model_name varchar + interface_type varchar + interface_speed varchar + serial_number varchar + firmware varchar + rotational_speed varchar + capacity varchar + form_factor varchar + smart_support varchar + device_protocol varchar + device_type varchar + +} + + +// InfluxDB Tables +Table device_temperature { + //timestamp + created_at timestamp + + //tags (indexed & queryable) + device_wwn varchar [pk] + + //fields + temp bigint + } + + +Table smart_ata_results { + //timestamp + created_at timestamp + + //tags (indexed & queryable) + device_wwn varchar [pk] + smart_status varchar + scrutiny_status varchar + + + + //fields + temp bigint + power_on_hours bigint + power_cycle_count bigint + + + } + +Ref: device.wwn < smart_ata_results.device_wwn diff --git a/example.scrutiny.yaml b/example.scrutiny.yaml index 9744f19..f7460ed 100644 --- a/example.scrutiny.yaml +++ b/example.scrutiny.yaml @@ -26,7 +26,12 @@ web: src: frontend: path: /scrutiny/web - + influxdb: + host: 0.0.0.0 + port: 8086 +# token: 'my-token' +# org: 'my-org' +# bucket: 'bucket' log: file: '' #absolute or relative paths allowed, eg. web.log diff --git a/go.mod b/go.mod index 013e908..d8d1baf 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,8 @@ require ( github.com/gin-gonic/gin v1.6.3 github.com/golang/mock v1.4.3 github.com/google/uuid v1.2.0 // indirect + github.com/hashicorp/serf v0.8.2 + github.com/influxdata/influxdb-client-go/v2 v2.2.3 github.com/jaypipes/ghw v0.6.1 github.com/klauspost/compress v1.12.1 // indirect github.com/kvz/logstreamer v0.0.0-20150507115422-a635b98146f0 // indirect diff --git a/go.sum b/go.sum index fbdbed6..8ea4b43 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,7 @@ github.com/analogj/go-util v0.0.0-20190301173314-5295e364eb14 h1:wsrSjiqQtseStRI github.com/analogj/go-util v0.0.0-20190301173314-5295e364eb14/go.mod h1:lJQVqFKMV5/oDGYR2bra2OljcF3CvolAoyDRyOA4k4E= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -53,9 +54,12 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSY github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deepmap/oapi-codegen v1.3.13 h1:9HKGCsdJqE4dnrQ8VerFS0/1ZOJPmAhN+g8xgp8y3K4= +github.com/deepmap/oapi-codegen v1.3.13/go.mod h1:WAmG5dWY8/PYHt4vKxlt90NsbHMAOCiteYKZMiIRfOo= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= @@ -69,12 +73,14 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/getkin/kin-openapi v0.13.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-interpreter/wagon v0.5.1-0.20190713202023-55a163980b6c/go.mod h1:5+b/MBYkclRZngKF5s6qrgWxSLgE9F5dFdO1hAueZLc= github.com/go-interpreter/wagon v0.6.0/go.mod h1:5+b/MBYkclRZngKF5s6qrgWxSLgE9F5dFdO1hAueZLc= @@ -119,7 +125,9 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= @@ -149,28 +157,42 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb-client-go v1.4.0 h1:+KavOkwhLClHFfYcJMHHnTL5CZQhXJzOm5IKHI9BqJk= +github.com/influxdata/influxdb-client-go/v2 v2.2.3 h1:082jdJ5t1CFeo0rpGQvKAK1mONVSbFhL4finWA5bRM8= +github.com/influxdata/influxdb-client-go/v2 v2.2.3/go.mod h1:fa/d1lAdUHxuc1jedx30ZfNG573oQTQmUni3N6pcW+0= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= github.com/jarcoal/httpmock v1.0.4 h1:jp+dy/+nonJE4g4xbVtl9QdrUNbn6/3hDT5R4nDIZnA= github.com/jarcoal/httpmock v1.0.4/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/jaypipes/ghw v0.6.1 h1:Ewt3mdpiyhWotGyzg1ursV/6SnToGcG4215X6rR2af8= @@ -210,6 +232,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kvz/logstreamer v0.0.0-20150507115422-a635b98146f0 h1:3tLzEnUizyN9YLWFTT9loC30lSBvh2y70LTDcZOTs1s= github.com/kvz/logstreamer v0.0.0-20150507115422-a635b98146f0/go.mod h1:8/LTPeDLaklcUjgSQBHbhBF1ibKAFxzS5o+H7USfMSA= +github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -220,6 +244,7 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190620125010-da37f6c1e481/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= @@ -229,6 +254,7 @@ github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -237,6 +263,7 @@ github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGw github.com/mattn/go-sqlite3 v1.14.4 h1:4rQjbDxdu9fSgI/r3KN72G3c2goxknAqHHgPWWs8UlI= github.com/mattn/go-sqlite3 v1.14.4/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -284,6 +311,8 @@ github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAv github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -301,6 +330,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -357,6 +387,9 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -373,7 +406,9 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= @@ -414,9 +449,11 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -454,7 +491,9 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190927073244-c990c680b611/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -498,6 +537,7 @@ golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/rootfs/etc/services.d/influxdb/run b/rootfs/etc/services.d/influxdb/run new file mode 100644 index 0000000..e862aaa --- /dev/null +++ b/rootfs/etc/services.d/influxdb/run @@ -0,0 +1,4 @@ +#!/usr/bin/with-contenv bash + +echo "starting influxdb" +influxd run diff --git a/rootfs/scrutiny/influxdb/config.yaml b/rootfs/scrutiny/influxdb/config.yaml new file mode 100644 index 0000000..245d541 --- /dev/null +++ b/rootfs/scrutiny/influxdb/config.yaml @@ -0,0 +1,4 @@ +bolt-path: /scrutiny/influxdb/influxd.bolt +engine-path: /scrutiny/influxdb/engine +http-bind-address: ":8086" +reporting-disabled: true diff --git a/webapp/backend/pkg/config/config.go b/webapp/backend/pkg/config/config.go index 6349b55..beccb90 100644 --- a/webapp/backend/pkg/config/config.go +++ b/webapp/backend/pkg/config/config.go @@ -37,6 +37,13 @@ func (c *configuration) Init() error { c.SetDefault("notify.urls", []string{}) + c.SetDefault("web.influxdb.host", "0.0.0.0") + c.SetDefault("web.influxdb.port", "8086") + c.SetDefault("web.influxdb.org", "scrutiny") + c.SetDefault("web.influxdb.bucket", "metrics") + c.SetDefault("web.influxdb.init_username", "admin") + c.SetDefault("web.influxdb.init_password", "password12345") + //c.SetDefault("disks.include", []string{}) //c.SetDefault("disks.exclude", []string{}) diff --git a/webapp/backend/pkg/constants.go b/webapp/backend/pkg/constants.go new file mode 100644 index 0000000..83ab99b --- /dev/null +++ b/webapp/backend/pkg/constants.go @@ -0,0 +1,28 @@ +package pkg + +const DeviceProtocolAta = "ATA" +const DeviceProtocolScsi = "SCSI" +const DeviceProtocolNvme = "NVMe" + +const SmartAttributeStatusPassed = "passed" +const SmartAttributeStatusFailed = "failed" +const SmartAttributeStatusWarning = "warn" + +const SmartWhenFailedFailingNow = "FAILING_NOW" +const SmartWhenFailedInThePast = "IN_THE_PAST" + +//const SmartStatusPassed = "passed" +//const SmartStatusFailed = "failed" + +type DeviceStatus int + +const ( + DeviceStatusPassed DeviceStatus = 0 + DeviceStatusFailedSmart DeviceStatus = iota + DeviceStatusFailedScrutiny DeviceStatus = iota +) + +func Set(b, flag DeviceStatus) DeviceStatus { return b | flag } +func Clear(b, flag DeviceStatus) DeviceStatus { return b &^ flag } +func Toggle(b, flag DeviceStatus) DeviceStatus { return b ^ flag } +func Has(b, flag DeviceStatus) bool { return b&flag != 0 } diff --git a/webapp/backend/pkg/database/interface.go b/webapp/backend/pkg/database/interface.go new file mode 100644 index 0000000..5bca804 --- /dev/null +++ b/webapp/backend/pkg/database/interface.go @@ -0,0 +1,27 @@ +package database + +import ( + "context" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/measurements" +) + +type DeviceRepo interface { + Close() error + + //GetSettings() + //SaveSetting() + + RegisterDevice(ctx context.Context, dev models.Device) error + GetDevices(ctx context.Context) ([]models.Device, error) + UpdateDevice(ctx context.Context, wwn string, collectorSmartData collector.SmartInfo) (models.Device, error) + GetDeviceDetails(ctx context.Context, wwn string) (models.Device, error) + + SaveSmartAttributes(ctx context.Context, wwn string, collectorSmartData collector.SmartInfo) (measurements.Smart, error) + GetSmartAttributeHistory(ctx context.Context, wwn string, startAt string, attributes []string) ([]measurements.Smart, error) + + SaveSmartTemperature(ctx context.Context, wwn string, deviceProtocol string, collectorSmartData collector.SmartInfo) error + + GetSummary(ctx context.Context) (map[string]*models.DeviceSummary, error) +} diff --git a/webapp/backend/pkg/database/scrutiny_repository.go b/webapp/backend/pkg/database/scrutiny_repository.go new file mode 100644 index 0000000..a7711c1 --- /dev/null +++ b/webapp/backend/pkg/database/scrutiny_repository.go @@ -0,0 +1,436 @@ +package database + +import ( + "context" + "fmt" + "github.com/analogj/scrutiny/webapp/backend/pkg/config" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/measurements" + influxdb2 "github.com/influxdata/influxdb-client-go/v2" + "github.com/influxdata/influxdb-client-go/v2/api" + "github.com/sirupsen/logrus" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "gorm.io/gorm/clause" + "time" +) + +//// GormLogger is a custom logger for Gorm, making it use logrus. +//type GormLogger struct{ Logger logrus.FieldLogger } +// +//// Print handles log events from Gorm for the custom logger. +//func (gl *GormLogger) Print(v ...interface{}) { +// switch v[0] { +// case "sql": +// gl.Logger.WithFields( +// logrus.Fields{ +// "module": "gorm", +// "type": "sql", +// "rows": v[5], +// "src_ref": v[1], +// "values": v[4], +// }, +// ).Debug(v[3]) +// case "log": +// gl.Logger.WithFields(logrus.Fields{"module": "gorm", "type": "log"}).Print(v[2]) +// } +//} + +func NewScrutinyRepository(appConfig config.Interface, globalLogger logrus.FieldLogger) (DeviceRepo, error) { + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Gorm/SQLite setup + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + fmt.Printf("Trying to connect to database stored: %s\n", appConfig.GetString("web.database.location")) + database, err := gorm.Open(sqlite.Open(appConfig.GetString("web.database.location")), &gorm.Config{ + //TODO: figure out how to log database queries again. + //Logger: logger + }) + if err != nil { + return nil, fmt.Errorf("Failed to connect to database!") + } + + //database.SetLogger() + database.AutoMigrate(&models.Device{}) + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // InfluxDB setup + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // Create a new client using an InfluxDB server base URL and an authentication token + influxdbUrl := fmt.Sprintf("http://%s:%s", appConfig.GetString("web.influxdb.host"), appConfig.GetString("web.influxdb.port")) + globalLogger.Debugf("InfluxDB url: %s", influxdbUrl) + + client := influxdb2.NewClient(influxdbUrl, appConfig.GetString("web.influxdb.token")) + + if !appConfig.IsSet("web.influxdb.token") { + globalLogger.Debugf("No influxdb token found, running first-time setup...") + + // if no token is provided, but we have a valid server, we're going to assume this is the first setup of our server. + // we will initialize with a predetermined username & password, that you should change. + onboardingResponse, err := client.Setup( + context.Background(), + appConfig.GetString("web.influxdb.init_username"), + appConfig.GetString("web.influxdb.init_password"), + appConfig.GetString("web.influxdb.org"), + appConfig.GetString("web.influxdb.bucket"), + 0) + if err != nil { + return nil, err + } + + appConfig.Set("web.influxdb.token", *onboardingResponse.Auth.Token) + //todo: determine if we should write the config file out here. + } + + // Use blocking write client for writes to desired bucket + writeAPI := client.WriteAPIBlocking(appConfig.GetString("web.influxdb.org"), appConfig.GetString("web.influxdb.bucket")) + + // Get query client + queryAPI := client.QueryAPI(appConfig.GetString("web.influxdb.org")) + + if writeAPI == nil || queryAPI == nil { + return nil, fmt.Errorf("Failed to connect to influxdb!") + } + + deviceRepo := scrutinyRepository{ + appConfig: appConfig, + logger: globalLogger, + influxClient: client, + influxWriteApi: writeAPI, + influxQueryApi: queryAPI, + gormClient: database, + } + + return &deviceRepo, nil +} + +type scrutinyRepository struct { + appConfig config.Interface + logger logrus.FieldLogger + + influxWriteApi api.WriteAPIBlocking + influxQueryApi api.QueryAPI + influxClient influxdb2.Client + + gormClient *gorm.DB +} + +func (sr *scrutinyRepository) Close() error { + sr.influxClient.Close() + return nil +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Device +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//insert device into DB (and update specified columns if device is already registered) +// update device fields that may change: (DeviceType, HostID) +func (sr *scrutinyRepository) RegisterDevice(ctx context.Context, dev models.Device) error { + if err := sr.gormClient.WithContext(ctx).Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "wwn"}}, + DoUpdates: clause.AssignmentColumns([]string{"host_id", "device_name", "device_type"}), + }).Create(&dev).Error; err != nil { + return err + } + return nil +} + +// get a list of all devices (only device metadata, no SMART data) +func (sr *scrutinyRepository) GetDevices(ctx context.Context) ([]models.Device, error) { + //Get a list of all the active devices. + devices := []models.Device{} + if err := sr.gormClient.WithContext(ctx).Find(&devices).Error; err != nil { + return nil, fmt.Errorf("Could not get device summary from DB", err) + } + return devices, nil +} + +// update device (only metadata) from collector +func (sr *scrutinyRepository) UpdateDevice(ctx context.Context, wwn string, collectorSmartData collector.SmartInfo) (models.Device, error) { + var device models.Device + if err := sr.gormClient.WithContext(ctx).Where("wwn = ?", wwn).First(&device).Error; err != nil { + return device, fmt.Errorf("Could not get device from DB", err) + } + + //TODO catch GormClient err + err := device.UpdateFromCollectorSmartInfo(collectorSmartData) + if err != nil { + return device, err + } + return device, sr.gormClient.Model(&device).Updates(device).Error +} + +func (sr *scrutinyRepository) GetDeviceDetails(ctx context.Context, wwn string) (models.Device, error) { + var device models.Device + + fmt.Println("GetDeviceDetails from GORM") + + if err := sr.gormClient.WithContext(ctx).Where("wwn = ?", wwn).First(&device).Error; err != nil { + return models.Device{}, err + } + + return device, nil +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SMART +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +func (sr *scrutinyRepository) SaveSmartAttributes(ctx context.Context, wwn string, collectorSmartData collector.SmartInfo) (measurements.Smart, error) { + deviceSmartData := measurements.Smart{} + err := deviceSmartData.FromCollectorSmartInfo(wwn, collectorSmartData) + if err != nil { + sr.logger.Errorln("Could not process SMART metrics", err) + return measurements.Smart{}, err + } + + tags, fields := deviceSmartData.Flatten() + p := influxdb2.NewPoint("smart", + tags, + fields, + deviceSmartData.Date) + + // write point immediately + return deviceSmartData, sr.influxWriteApi.WritePoint(ctx, p) +} + +func (sr *scrutinyRepository) GetSmartAttributeHistory(ctx context.Context, wwn string, startAt string, attributes []string) ([]measurements.Smart, error) { + // Get SMartResults from InfluxDB + + fmt.Println("GetDeviceDetails from INFLUXDB") + + //TODO: change the filter startrange to a real number. + + // Get parser flux query result + //appConfig.GetString("web.influxdb.bucket") + queryStr := fmt.Sprintf(` + import "influxdata/influxdb/schema" + from(bucket: "%s") + |> range(start: -2y, stop: now()) + |> filter(fn: (r) => r["_measurement"] == "smart" ) + |> filter(fn: (r) => r["device_wwn"] == "%s" ) + |> schema.fieldsAsCols() + |> group(columns: ["device_wwn"]) + |> yield(name: "last") + `, + sr.appConfig.GetString("web.influxdb.bucket"), + wwn, + ) + + smartResults := []measurements.Smart{} + + result, err := sr.influxQueryApi.Query(ctx, queryStr) + if err == nil { + fmt.Println("GetDeviceDetails NO EROR") + + // Use Next() to iterate over query result lines + for result.Next() { + fmt.Println("GetDeviceDetails NEXT") + + // Observe when there is new grouping key producing new table + if result.TableChanged() { + //fmt.Printf("table: %s\n", result.TableMetadata().String()) + } + + fmt.Printf("DECODINIG TABLE VALUES: %v", result.Record().Values()) + smartData, err := measurements.NewSmartFromInfluxDB(result.Record().Values()) + if err != nil { + return nil, err + } + smartResults = append(smartResults, *smartData) + + } + if result.Err() != nil { + fmt.Printf("Query error: %s\n", result.Err().Error()) + } + } else { + return nil, err + } + + return smartResults, nil + + //if err := device.SquashHistory(); err != nil { + // logger.Errorln("An error occurred while squashing device history", err) + // c.JSON(http.StatusInternalServerError, gin.H{"success": false}) + // return + //} + // + //if err := device.ApplyMetadataRules(); err != nil { + // logger.Errorln("An error occurred while applying scrutiny thresholds & rules", err) + // c.JSON(http.StatusInternalServerError, gin.H{"success": false}) + // return + //} + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Temperature Data +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +func (sr *scrutinyRepository) SaveSmartTemperature(ctx context.Context, wwn string, deviceProtocol string, collectorSmartData collector.SmartInfo) error { + if len(collectorSmartData.AtaSctTemperatureHistory.Table) > 0 { + + for ndx, temp := range collectorSmartData.AtaSctTemperatureHistory.Table { + + minutesOffset := collectorSmartData.AtaSctTemperatureHistory.LoggingIntervalMinutes * int64(ndx) * 60 + smartTemp := measurements.SmartTemperature{ + Date: time.Unix(collectorSmartData.LocalTime.TimeT-minutesOffset, 0), + Temp: temp, + } + + tags, fields := smartTemp.Flatten() + tags["device_wwn"] = wwn + p := influxdb2.NewPoint("temp", + tags, + fields, + smartTemp.Date) + err := sr.influxWriteApi.WritePoint(ctx, p) + if err != nil { + return err + } + } + // also add the current temperature. + } else { + + smartTemp := measurements.SmartTemperature{ + Date: time.Unix(collectorSmartData.LocalTime.TimeT, 0), + Temp: collectorSmartData.Temperature.Current, + } + + tags, fields := smartTemp.Flatten() + tags["device_wwn"] = wwn + p := influxdb2.NewPoint("temp", + tags, + fields, + smartTemp.Date) + return sr.influxWriteApi.WritePoint(ctx, p) + } + return nil +} + +func (sr *scrutinyRepository) GetSmartTemperatureHistory(ctx context.Context) (map[string][]measurements.SmartTemperature, error) { + + deviceTempHistory := map[string][]measurements.SmartTemperature{} + + //TODO: change the query range to a variable. + queryStr := fmt.Sprintf(` + import "influxdata/influxdb/schema" + from(bucket: "%s") + |> range(start: -3y, stop: now()) + |> filter(fn: (r) => r["_measurement"] == "temp" ) + |> filter(fn: (r) => r["_field"] == "temp") + |> schema.fieldsAsCols() + |> group(columns: ["device_wwn"]) + |> yield(name: "last") + `, + sr.appConfig.GetString("web.influxdb.bucket"), + ) + + result, err := sr.influxQueryApi.Query(ctx, queryStr) + if err == nil { + // Use Next() to iterate over query result lines + for result.Next() { + + if deviceWWN, ok := result.Record().Values()["device_wwn"]; ok { + + //check if deviceWWN has been seen and initialized already + if _, ok := deviceTempHistory[deviceWWN.(string)]; !ok { + deviceTempHistory[deviceWWN.(string)] = []measurements.SmartTemperature{} + } + + currentTempHistory := deviceTempHistory[deviceWWN.(string)] + smartTemp := measurements.SmartTemperature{} + + for key, val := range result.Record().Values() { + smartTemp.Inflate(key, val) + } + smartTemp.Date = result.Record().Values()["_time"].(time.Time) + currentTempHistory = append(currentTempHistory, smartTemp) + deviceTempHistory[deviceWWN.(string)] = currentTempHistory + } + } + if result.Err() != nil { + fmt.Printf("Query error: %s\n", result.Err().Error()) + } + } else { + return nil, err + } + return deviceTempHistory, nil + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DeviceSummary +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// get a map of all devices and associated SMART data +func (sr *scrutinyRepository) GetSummary(ctx context.Context) (map[string]*models.DeviceSummary, error) { + devices, err := sr.GetDevices(ctx) + if err != nil { + return nil, err + } + + summaries := map[string]*models.DeviceSummary{} + + for _, device := range devices { + summaries[device.WWN] = &models.DeviceSummary{Device: device} + } + + // Get parser flux query result + //appConfig.GetString("web.influxdb.bucket") + queryStr := fmt.Sprintf(` + import "influxdata/influxdb/schema" + from(bucket: "%s") + |> range(start: -1y, stop: now()) + |> filter(fn: (r) => r["_measurement"] == "smart" ) + |> filter(fn: (r) => r["_field"] == "temp" or r["_field"] == "power_on_hours" or r["_field"] == "date") + |> schema.fieldsAsCols() + |> group(columns: ["device_wwn"]) + |> yield(name: "last") + `, + sr.appConfig.GetString("web.influxdb.bucket"), + ) + + result, err := sr.influxQueryApi.Query(ctx, queryStr) + if err == nil { + // Use Next() to iterate over query result lines + for result.Next() { + // Observe when there is new grouping key producing new table + if result.TableChanged() { + //fmt.Printf("table: %s\n", result.TableMetadata().String()) + } + // read result + + //get summary data from Influxdb. + //result.Record().Values() + if deviceWWN, ok := result.Record().Values()["device_wwn"]; ok { + summaries[deviceWWN.(string)].SmartResults = &models.SmartSummary{ + Temp: result.Record().Values()["temp"].(int64), + PowerOnHours: result.Record().Values()["power_on_hours"].(int64), + CollectorDate: result.Record().Values()["_time"].(time.Time), + } + } + } + if result.Err() != nil { + fmt.Printf("Query error: %s\n", result.Err().Error()) + } + } else { + return nil, err + } + + deviceTempHistory, err := sr.GetSmartTemperatureHistory(ctx) + if err != nil { + sr.logger.Printf("========================>>>>>>>>======================") + sr.logger.Printf("========================>>>>>>>>======================") + sr.logger.Printf("========================>>>>>>>>======================") + sr.logger.Printf("========================>>>>>>>>======================") + sr.logger.Printf("========================>>>>>>>>======================") + sr.logger.Printf("Error: %v", err) + } + for wwn, tempHistory := range deviceTempHistory { + summaries[wwn].TempHistory = tempHistory + } + + return summaries, nil +} diff --git a/webapp/backend/pkg/metadata/ata_attribute_metadata.go b/webapp/backend/pkg/metadata/ata_attribute_metadata.go index 63dc293..2f4c6c8 100644 --- a/webapp/backend/pkg/metadata/ata_attribute_metadata.go +++ b/webapp/backend/pkg/metadata/ata_attribute_metadata.go @@ -11,10 +11,10 @@ type AtaAttributeMetadata struct { Critical bool `json:"critical"` Description string `json:"description"` - Transform func(int, int64, string) int64 `json:"-"` //this should be a method to extract/tranform the normalized or raw data to a chartable format. Str - TransformValueUnit string `json:"transform_value_unit,omitempty"` - ObservedThresholds []ObservedThreshold `json:"observed_thresholds,omitempty"` //these thresholds must match the DisplayType - DisplayType string `json:"display_type"` //"raw" "normalized" or "transformed" + Transform func(int64, int64, string) int64 `json:"-"` //this should be a method to extract/tranform the normalized or raw data to a chartable format. Str + TransformValueUnit string `json:"transform_value_unit,omitempty"` + ObservedThresholds []ObservedThreshold `json:"observed_thresholds,omitempty"` //these thresholds must match the DisplayType + DisplayType string `json:"display_type"` //"raw" "normalized" or "transformed" } const ObservedThresholdIdealLow = "low" @@ -1014,7 +1014,7 @@ var AtaMetadata = map[int]AtaAttributeMetadata{ Ideal: ObservedThresholdIdealLow, 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: func(normValue int, rawValue int64, rawString string) int64 { + Transform: func(normValue int64, rawValue int64, rawString string) int64 { return rawValue & 0b11111111 }, TransformValueUnit: "°C", diff --git a/webapp/backend/pkg/metadata/nvme_attribute_metadata.go b/webapp/backend/pkg/metadata/nvme_attribute_metadata.go index 2f9f550..80efcfa 100644 --- a/webapp/backend/pkg/metadata/nvme_attribute_metadata.go +++ b/webapp/backend/pkg/metadata/nvme_attribute_metadata.go @@ -11,9 +11,9 @@ type NvmeAttributeMetadata struct { Critical bool `json:"critical"` Description string `json:"description"` - Transform func(int, int64, string) int64 `json:"-"` //this should be a method to extract/tranform the normalized or raw data to a chartable format. Str - TransformValueUnit string `json:"transform_value_unit,omitempty"` - DisplayType string `json:"display_type"` //"raw" "normalized" or "transformed" + Transform func(int64, int64, string) int64 `json:"-"` //this should be a method to extract/tranform the normalized or raw data to a chartable format. Str + TransformValueUnit string `json:"transform_value_unit,omitempty"` + DisplayType string `json:"display_type"` //"raw" "normalized" or "transformed" } var NmveMetadata = map[string]NvmeAttributeMetadata{ diff --git a/webapp/backend/pkg/metadata/scsi_attribute_metadata.go b/webapp/backend/pkg/metadata/scsi_attribute_metadata.go index 5e83f2a..cd4f974 100644 --- a/webapp/backend/pkg/metadata/scsi_attribute_metadata.go +++ b/webapp/backend/pkg/metadata/scsi_attribute_metadata.go @@ -7,9 +7,9 @@ type ScsiAttributeMetadata struct { Critical bool `json:"critical"` Description string `json:"description"` - Transform func(int, int64, string) int64 `json:"-"` //this should be a method to extract/tranform the normalized or raw data to a chartable format. Str - TransformValueUnit string `json:"transform_value_unit,omitempty"` - DisplayType string `json:"display_type"` //"raw" "normalized" or "transformed" + Transform func(int64, int64, string) int64 `json:"-"` //this should be a method to extract/tranform the normalized or raw data to a chartable format. Str + TransformValueUnit string `json:"transform_value_unit,omitempty"` + DisplayType string `json:"display_type"` //"raw" "normalized" or "transformed" } var ScsiMetadata = map[string]ScsiAttributeMetadata{ @@ -21,96 +21,96 @@ var ScsiMetadata = map[string]ScsiAttributeMetadata{ Critical: true, Description: "", }, - "read.errors_corrected_by_eccfast": { - ID: "read.errors_corrected_by_eccfast", + "read_errors_corrected_by_eccfast": { + ID: "read_errors_corrected_by_eccfast", DisplayName: "Read Errors Corrected by ECC Fast", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "read.errors_corrected_by_eccdelayed": { - ID: "read.errors_corrected_by_eccdelayed", + "read_errors_corrected_by_eccdelayed": { + ID: "read_errors_corrected_by_eccdelayed", DisplayName: "Read Errors Corrected by ECC Delayed", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "read.errors_corrected_by_rereads_rewrites": { - ID: "read.errors_corrected_by_rereads_rewrites", + "read_errors_corrected_by_rereads_rewrites": { + ID: "read_errors_corrected_by_rereads_rewrites", DisplayName: "Read Errors Corrected by ReReads/ReWrites", DisplayType: "", Ideal: "low", Critical: true, Description: "", }, - "read.total_errors_corrected": { - ID: "read.total_errors_corrected", + "read_total_errors_corrected": { + ID: "read_total_errors_corrected", DisplayName: "Read Total Errors Corrected", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "read.correction_algorithm_invocations": { - ID: "read.correction_algorithm_invocations", + "read_correction_algorithm_invocations": { + ID: "read_correction_algorithm_invocations", DisplayName: "Read Correction Algorithm Invocations", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "read.total_uncorrected_errors": { - ID: "read.total_uncorrected_errors", + "read_total_uncorrected_errors": { + ID: "read_total_uncorrected_errors", DisplayName: "Read Total Uncorrected Errors", DisplayType: "", Ideal: "low", Critical: true, Description: "", }, - "write.errors_corrected_by_eccfast": { - ID: "write.errors_corrected_by_eccfast", + "write_errors_corrected_by_eccfast": { + ID: "write_errors_corrected_by_eccfast", DisplayName: "Write Errors Corrected by ECC Fast", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "write.errors_corrected_by_eccdelayed": { - ID: "write.errors_corrected_by_eccdelayed", + "write_errors_corrected_by_eccdelayed": { + ID: "write_errors_corrected_by_eccdelayed", DisplayName: "Write Errors Corrected by ECC Delayed", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "write.errors_corrected_by_rereads_rewrites": { - ID: "write.errors_corrected_by_rereads_rewrites", + "write_errors_corrected_by_rereads_rewrites": { + ID: "write_errors_corrected_by_rereads_rewrites", DisplayName: "Write Errors Corrected by ReReads/ReWrites", DisplayType: "", Ideal: "low", Critical: true, Description: "", }, - "write.total_errors_corrected": { - ID: "write.total_errors_corrected", + "write_total_errors_corrected": { + ID: "write_total_errors_corrected", DisplayName: "Write Total Errors Corrected", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "write.correction_algorithm_invocations": { - ID: "write.correction_algorithm_invocations", + "write_correction_algorithm_invocations": { + ID: "write_correction_algorithm_invocations", DisplayName: "Write Correction Algorithm Invocations", DisplayType: "", Ideal: "", Critical: false, Description: "", }, - "write.total_uncorrected_errors": { - ID: "write.total_uncorrected_errors", + "write_total_uncorrected_errors": { + ID: "write_total_uncorrected_errors", DisplayName: "Write Total Uncorrected Errors", DisplayType: "", Ideal: "low", diff --git a/webapp/backend/pkg/models/collector/smart.go b/webapp/backend/pkg/models/collector/smart.go index 04d5e4c..8cb5653 100644 --- a/webapp/backend/pkg/models/collector/smart.go +++ b/webapp/backend/pkg/models/collector/smart.go @@ -119,14 +119,28 @@ type SmartInfo struct { FeatureControlSupported bool `json:"feature_control_supported"` DataTableSupported bool `json:"data_table_supported"` } `json:"ata_sct_capabilities"` + AtaSctTemperatureHistory struct { + Version int `json:"version"` + SamplingPeriodMinutes int64 `json:"sampling_period_minutes"` + LoggingIntervalMinutes int64 `json:"logging_interval_minutes"` + Temperature struct { + OpLimitMin int `json:"op_limit_min"` + OpLimitMax int `json:"op_limit_max"` + LimitMin int `json:"limit_min"` + LimitMax int `json:"limit_max"` + } `json:"temperature"` + Size int `json:"size"` + Index int `json:"index"` + Table []int64 `json:"table"` + } `json:"ata_sct_temperature_history"` AtaSmartAttributes struct { Revision int `json:"revision"` Table []struct { ID int `json:"id"` Name string `json:"name"` - Value int `json:"value"` - Worst int `json:"worst"` - Thresh int `json:"thresh"` + Value int64 `json:"value"` + Worst int64 `json:"worst"` + Thresh int64 `json:"thresh"` WhenFailed string `json:"when_failed"` Flags struct { Value int `json:"value"` @@ -237,48 +251,48 @@ type SmartInfo struct { FormattedLbaSize int `json:"formatted_lba_size"` } `json:"nvme_namespaces"` NvmeSmartHealthInformationLog struct { - CriticalWarning int `json:"critical_warning"` - Temperature int `json:"temperature"` - AvailableSpare int `json:"available_spare"` - AvailableSpareThreshold int `json:"available_spare_threshold"` - PercentageUsed int `json:"percentage_used"` - DataUnitsRead int `json:"data_units_read"` - DataUnitsWritten int `json:"data_units_written"` - HostReads int `json:"host_reads"` - HostWrites int `json:"host_writes"` - ControllerBusyTime int `json:"controller_busy_time"` - PowerCycles int `json:"power_cycles"` - PowerOnHours int `json:"power_on_hours"` - UnsafeShutdowns int `json:"unsafe_shutdowns"` - MediaErrors int `json:"media_errors"` - NumErrLogEntries int `json:"num_err_log_entries"` - WarningTempTime int `json:"warning_temp_time"` - CriticalCompTime int `json:"critical_comp_time"` + CriticalWarning int64 `json:"critical_warning"` + Temperature int64 `json:"temperature"` + AvailableSpare int64 `json:"available_spare"` + AvailableSpareThreshold int64 `json:"available_spare_threshold"` + PercentageUsed int64 `json:"percentage_used"` + DataUnitsRead int64 `json:"data_units_read"` + DataUnitsWritten int64 `json:"data_units_written"` + HostReads int64 `json:"host_reads"` + HostWrites int64 `json:"host_writes"` + ControllerBusyTime int64 `json:"controller_busy_time"` + PowerCycles int64 `json:"power_cycles"` + PowerOnHours int64 `json:"power_on_hours"` + UnsafeShutdowns int64 `json:"unsafe_shutdowns"` + MediaErrors int64 `json:"media_errors"` + NumErrLogEntries int64 `json:"num_err_log_entries"` + WarningTempTime int64 `json:"warning_temp_time"` + CriticalCompTime int64 `json:"critical_comp_time"` } `json:"nvme_smart_health_information_log"` // SCSI Protocol Specific Fields Vendor string `json:"vendor"` Product string `json:"product"` ScsiVersion string `json:"scsi_version"` - ScsiGrownDefectList int `json:"scsi_grown_defect_list"` + ScsiGrownDefectList int64 `json:"scsi_grown_defect_list"` ScsiErrorCounterLog struct { Read struct { - ErrorsCorrectedByEccfast int `json:"errors_corrected_by_eccfast"` - ErrorsCorrectedByEccdelayed int `json:"errors_corrected_by_eccdelayed"` - ErrorsCorrectedByRereadsRewrites int `json:"errors_corrected_by_rereads_rewrites"` - TotalErrorsCorrected int `json:"total_errors_corrected"` - CorrectionAlgorithmInvocations int `json:"correction_algorithm_invocations"` + ErrorsCorrectedByEccfast int64 `json:"errors_corrected_by_eccfast"` + ErrorsCorrectedByEccdelayed int64 `json:"errors_corrected_by_eccdelayed"` + ErrorsCorrectedByRereadsRewrites int64 `json:"errors_corrected_by_rereads_rewrites"` + TotalErrorsCorrected int64 `json:"total_errors_corrected"` + CorrectionAlgorithmInvocations int64 `json:"correction_algorithm_invocations"` GigabytesProcessed string `json:"gigabytes_processed"` - TotalUncorrectedErrors int `json:"total_uncorrected_errors"` + TotalUncorrectedErrors int64 `json:"total_uncorrected_errors"` } `json:"read"` Write struct { - ErrorsCorrectedByEccfast int `json:"errors_corrected_by_eccfast"` - ErrorsCorrectedByEccdelayed int `json:"errors_corrected_by_eccdelayed"` - ErrorsCorrectedByRereadsRewrites int `json:"errors_corrected_by_rereads_rewrites"` - TotalErrorsCorrected int `json:"total_errors_corrected"` - CorrectionAlgorithmInvocations int `json:"correction_algorithm_invocations"` + ErrorsCorrectedByEccfast int64 `json:"errors_corrected_by_eccfast"` + ErrorsCorrectedByEccdelayed int64 `json:"errors_corrected_by_eccdelayed"` + ErrorsCorrectedByRereadsRewrites int64 `json:"errors_corrected_by_rereads_rewrites"` + TotalErrorsCorrected int64 `json:"total_errors_corrected"` + CorrectionAlgorithmInvocations int64 `json:"correction_algorithm_invocations"` GigabytesProcessed string `json:"gigabytes_processed"` - TotalUncorrectedErrors int `json:"total_uncorrected_errors"` + TotalUncorrectedErrors int64 `json:"total_uncorrected_errors"` } `json:"write"` } `json:"scsi_error_counter_log"` } diff --git a/webapp/backend/pkg/models/db/device.go b/webapp/backend/pkg/models/db/device.go deleted file mode 100644 index 2786103..0000000 --- a/webapp/backend/pkg/models/db/device.go +++ /dev/null @@ -1,160 +0,0 @@ -package db - -import ( - "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" - "time" -) - -type DeviceWrapper struct { - Success bool `json:"success"` - Errors []error `json:"errors"` - Data []Device `json:"data"` -} - -const DeviceProtocolAta = "ATA" -const DeviceProtocolScsi = "SCSI" -const DeviceProtocolNvme = "NVMe" - -type Device struct { - //GORM attributes, see: http://gorm.io/docs/conventions.html - CreatedAt time.Time - UpdatedAt time.Time - DeletedAt *time.Time - - WWN string `json:"wwn" gorm:"primary_key"` - HostId string `json:"host_id"` - - DeviceName string `json:"device_name"` - Manufacturer string `json:"manufacturer"` - ModelName string `json:"model_name"` - InterfaceType string `json:"interface_type"` - InterfaceSpeed string `json:"interface_speed"` - SerialNumber string `json:"serial_number"` - Firmware string `json:"firmware"` - RotationSpeed int `json:"rotational_speed"` - Capacity int64 `json:"capacity"` - FormFactor string `json:"form_factor"` - SmartSupport bool `json:"smart_support"` - DeviceProtocol string `json:"device_protocol"` //protocol determines which smart attribute types are available (ATA, NVMe, SCSI) - DeviceType string `json:"device_type"` //device type is used for querying with -d/t flag, should only be used by collector. - SmartResults []Smart `gorm:"foreignkey:DeviceWWN" json:"smart_results"` -} - -func (dv *Device) IsAta() bool { - return dv.DeviceProtocol == DeviceProtocolAta -} - -func (dv *Device) IsScsi() bool { - return dv.DeviceProtocol == DeviceProtocolScsi -} - -func (dv *Device) IsNvme() bool { - return dv.DeviceProtocol == DeviceProtocolNvme -} - -//This method requires a device with an array of SmartResults. -//It will remove all SmartResults other than the first (the latest one) -//All removed SmartResults, will be processed, grouping SmartAtaAttribute by attribute_id -// and adding theme to an array called History. -func (dv *Device) SquashHistory() error { - if len(dv.SmartResults) <= 1 { - return nil //no ataHistory found. ignore - } - - latestSmartResultSlice := dv.SmartResults[0:1] - historicalSmartResultSlice := dv.SmartResults[1:] - - //re-assign the latest slice to the SmartResults field - dv.SmartResults = latestSmartResultSlice - - //process the historical slice for ATA data - if len(dv.SmartResults[0].AtaAttributes) > 0 { - ataHistory := map[int][]SmartAtaAttribute{} - for _, smartResult := range historicalSmartResultSlice { - for _, smartAttribute := range smartResult.AtaAttributes { - if _, ok := ataHistory[smartAttribute.AttributeId]; !ok { - ataHistory[smartAttribute.AttributeId] = []SmartAtaAttribute{} - } - ataHistory[smartAttribute.AttributeId] = append(ataHistory[smartAttribute.AttributeId], smartAttribute) - } - } - - //now assign the historical slices to the AtaAttributes in the latest SmartResults - for sandx, smartAttribute := range dv.SmartResults[0].AtaAttributes { - if attributeHistory, ok := ataHistory[smartAttribute.AttributeId]; ok { - dv.SmartResults[0].AtaAttributes[sandx].History = attributeHistory - } - } - } - - //process the historical slice for Nvme data - if len(dv.SmartResults[0].NvmeAttributes) > 0 { - nvmeHistory := map[string][]SmartNvmeAttribute{} - for _, smartResult := range historicalSmartResultSlice { - for _, smartAttribute := range smartResult.NvmeAttributes { - if _, ok := nvmeHistory[smartAttribute.AttributeId]; !ok { - nvmeHistory[smartAttribute.AttributeId] = []SmartNvmeAttribute{} - } - nvmeHistory[smartAttribute.AttributeId] = append(nvmeHistory[smartAttribute.AttributeId], smartAttribute) - } - } - - //now assign the historical slices to the AtaAttributes in the latest SmartResults - for sandx, smartAttribute := range dv.SmartResults[0].NvmeAttributes { - if attributeHistory, ok := nvmeHistory[smartAttribute.AttributeId]; ok { - dv.SmartResults[0].NvmeAttributes[sandx].History = attributeHistory - } - } - } - //process the historical slice for Scsi data - if len(dv.SmartResults[0].ScsiAttributes) > 0 { - scsiHistory := map[string][]SmartScsiAttribute{} - for _, smartResult := range historicalSmartResultSlice { - for _, smartAttribute := range smartResult.ScsiAttributes { - if _, ok := scsiHistory[smartAttribute.AttributeId]; !ok { - scsiHistory[smartAttribute.AttributeId] = []SmartScsiAttribute{} - } - scsiHistory[smartAttribute.AttributeId] = append(scsiHistory[smartAttribute.AttributeId], smartAttribute) - } - } - - //now assign the historical slices to the AtaAttributes in the latest SmartResults - for sandx, smartAttribute := range dv.SmartResults[0].ScsiAttributes { - if attributeHistory, ok := scsiHistory[smartAttribute.AttributeId]; ok { - dv.SmartResults[0].ScsiAttributes[sandx].History = attributeHistory - } - } - } - return nil -} - -func (dv *Device) ApplyMetadataRules() error { - - //embed metadata in the latest smart attributes object - if len(dv.SmartResults) > 0 { - for ndx, attr := range dv.SmartResults[0].AtaAttributes { - attr.PopulateAttributeStatus() - dv.SmartResults[0].AtaAttributes[ndx] = attr - } - - for ndx, attr := range dv.SmartResults[0].NvmeAttributes { - attr.PopulateAttributeStatus() - dv.SmartResults[0].NvmeAttributes[ndx] = attr - - } - - for ndx, attr := range dv.SmartResults[0].ScsiAttributes { - attr.PopulateAttributeStatus() - dv.SmartResults[0].ScsiAttributes[ndx] = attr - - } - } - return nil -} - -// This function is called every time the collector sends SMART data to the API. -// It can be used to update device data that can change over time. -func (dv *Device) UpdateFromCollectorSmartInfo(info collector.SmartInfo) error { - dv.Firmware = info.FirmwareVersion - return nil -} diff --git a/webapp/backend/pkg/models/db/selftest.go b/webapp/backend/pkg/models/db/selftest.go deleted file mode 100644 index 9e3d89d..0000000 --- a/webapp/backend/pkg/models/db/selftest.go +++ /dev/null @@ -1,15 +0,0 @@ -package db - -import "time" - -type SelfTest struct { - //GORM attributes, see: http://gorm.io/docs/conventions.html - CreatedAt time.Time - UpdatedAt time.Time - DeletedAt *time.Time - - DeviceWWN string - Device Device `json:"-" gorm:"foreignkey:DeviceWWN"` // use DeviceWWN as foreign key - - Date time.Time -} diff --git a/webapp/backend/pkg/models/db/smart.go b/webapp/backend/pkg/models/db/smart.go deleted file mode 100644 index 510dcb2..0000000 --- a/webapp/backend/pkg/models/db/smart.go +++ /dev/null @@ -1,127 +0,0 @@ -package db - -import ( - "github.com/analogj/scrutiny/webapp/backend/pkg/metadata" - "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" - "gorm.io/gorm" - "time" -) - -const SmartWhenFailedFailingNow = "FAILING_NOW" -const SmartWhenFailedInThePast = "IN_THE_PAST" - -const SmartStatusPassed = "passed" -const SmartStatusFailed = "failed" - -type Smart struct { - gorm.Model - - DeviceWWN string `json:"device_wwn"` - Device Device `json:"-" gorm:"foreignkey:DeviceWWN"` // use DeviceWWN as foreign key - - TestDate time.Time `json:"date"` - SmartStatus string `json:"smart_status"` // SmartStatusPassed or SmartStatusFailed - - //Metrics - Temp int64 `json:"temp"` - PowerOnHours int64 `json:"power_on_hours"` - PowerCycleCount int64 `json:"power_cycle_count"` - - AtaAttributes []SmartAtaAttribute `json:"ata_attributes" gorm:"foreignkey:SmartId"` - NvmeAttributes []SmartNvmeAttribute `json:"nvme_attributes" gorm:"foreignkey:SmartId"` - ScsiAttributes []SmartScsiAttribute `json:"scsi_attributes" gorm:"foreignkey:SmartId"` -} - -//Parse Collector SMART data results and create Smart object (and associated SmartAtaAttribute entries) -func (sm *Smart) FromCollectorSmartInfo(wwn string, info collector.SmartInfo) error { - sm.DeviceWWN = wwn - sm.TestDate = time.Unix(info.LocalTime.TimeT, 0) - - //smart metrics - sm.Temp = info.Temperature.Current - sm.PowerCycleCount = info.PowerCycleCount - sm.PowerOnHours = info.PowerOnTime.Hours - - // process ATA/NVME/SCSI protocol data - if info.Device.Protocol == DeviceProtocolAta { - sm.ProcessAtaSmartInfo(info) - } else if info.Device.Protocol == DeviceProtocolNvme { - sm.ProcessNvmeSmartInfo(info) - } else if info.Device.Protocol == DeviceProtocolScsi { - sm.ProcessScsiSmartInfo(info) - } - - if info.SmartStatus.Passed { - sm.SmartStatus = SmartStatusPassed - } else { - sm.SmartStatus = SmartStatusFailed - } - return nil -} - -//generate SmartAtaAttribute entries from Scrutiny Collector Smart data. -func (sm *Smart) ProcessAtaSmartInfo(info collector.SmartInfo) { - sm.AtaAttributes = []SmartAtaAttribute{} - for _, collectorAttr := range info.AtaSmartAttributes.Table { - attrModel := SmartAtaAttribute{ - AttributeId: collectorAttr.ID, - Name: collectorAttr.Name, - Value: collectorAttr.Value, - Worst: collectorAttr.Worst, - Threshold: collectorAttr.Thresh, - RawValue: collectorAttr.Raw.Value, - RawString: collectorAttr.Raw.String, - WhenFailed: collectorAttr.WhenFailed, - } - - //now that we've parsed the data from the smartctl response, lets match it against our metadata rules and add additional Scrutiny specific data. - if smartMetadata, ok := metadata.AtaMetadata[collectorAttr.ID]; ok { - attrModel.Name = smartMetadata.DisplayName - if smartMetadata.Transform != nil { - attrModel.TransformedValue = smartMetadata.Transform(attrModel.Value, attrModel.RawValue, attrModel.RawString) - } - } - sm.AtaAttributes = append(sm.AtaAttributes, attrModel) - } -} - -//generate SmartNvmeAttribute entries from Scrutiny Collector Smart data. -func (sm *Smart) ProcessNvmeSmartInfo(info collector.SmartInfo) { - sm.NvmeAttributes = []SmartNvmeAttribute{ - {AttributeId: "critical_warning", Name: "Critical Warning", Value: info.NvmeSmartHealthInformationLog.CriticalWarning, Threshold: 0}, - {AttributeId: "temperature", Name: "Temperature", Value: info.NvmeSmartHealthInformationLog.Temperature, Threshold: -1}, - {AttributeId: "available_spare", Name: "Available Spare", Value: info.NvmeSmartHealthInformationLog.AvailableSpare, Threshold: info.NvmeSmartHealthInformationLog.AvailableSpareThreshold}, - {AttributeId: "percentage_used", Name: "Percentage Used", Value: info.NvmeSmartHealthInformationLog.PercentageUsed, Threshold: 100}, - {AttributeId: "data_units_read", Name: "Data Units Read", Value: info.NvmeSmartHealthInformationLog.DataUnitsRead, Threshold: -1}, - {AttributeId: "data_units_written", Name: "Data Units Written", Value: info.NvmeSmartHealthInformationLog.DataUnitsWritten, Threshold: -1}, - {AttributeId: "host_reads", Name: "Host Reads", Value: info.NvmeSmartHealthInformationLog.HostReads, Threshold: -1}, - {AttributeId: "host_writes", Name: "Host Writes", Value: info.NvmeSmartHealthInformationLog.HostWrites, Threshold: -1}, - {AttributeId: "controller_busy_time", Name: "Controller Busy Time", Value: info.NvmeSmartHealthInformationLog.ControllerBusyTime, Threshold: -1}, - {AttributeId: "power_cycles", Name: "Power Cycles", Value: info.NvmeSmartHealthInformationLog.PowerCycles, Threshold: -1}, - {AttributeId: "power_on_hours", Name: "Power on Hours", Value: info.NvmeSmartHealthInformationLog.PowerOnHours, Threshold: -1}, - {AttributeId: "unsafe_shutdowns", Name: "Unsafe Shutdowns", Value: info.NvmeSmartHealthInformationLog.UnsafeShutdowns, Threshold: -1}, - {AttributeId: "media_errors", Name: "Media Errors", Value: info.NvmeSmartHealthInformationLog.MediaErrors, Threshold: 0}, - {AttributeId: "num_err_log_entries", Name: "Numb Err Log Entries", Value: info.NvmeSmartHealthInformationLog.NumErrLogEntries, Threshold: 0}, - {AttributeId: "warning_temp_time", Name: "Warning Temp Time", Value: info.NvmeSmartHealthInformationLog.WarningTempTime, Threshold: -1}, - {AttributeId: "critical_comp_time", Name: "Critical CompTime", Value: info.NvmeSmartHealthInformationLog.CriticalCompTime, Threshold: -1}, - } -} - -//generate SmartScsiAttribute entries from Scrutiny Collector Smart data. -func (sm *Smart) ProcessScsiSmartInfo(info collector.SmartInfo) { - sm.ScsiAttributes = []SmartScsiAttribute{ - {AttributeId: "scsi_grown_defect_list", Name: "Grown Defect List", Value: info.ScsiGrownDefectList, Threshold: 0}, - {AttributeId: "read.errors_corrected_by_eccfast", Name: "Read Errors Corrected by ECC Fast", Value: info.ScsiErrorCounterLog.Read.ErrorsCorrectedByEccfast, Threshold: -1}, - {AttributeId: "read.errors_corrected_by_eccdelayed", Name: "Read Errors Corrected by ECC Delayed", Value: info.ScsiErrorCounterLog.Read.ErrorsCorrectedByEccdelayed, Threshold: -1}, - {AttributeId: "read.errors_corrected_by_rereads_rewrites", Name: "Read Errors Corrected by ReReads/ReWrites", Value: info.ScsiErrorCounterLog.Read.ErrorsCorrectedByRereadsRewrites, Threshold: 0}, - {AttributeId: "read.total_errors_corrected", Name: "Read Total Errors Corrected", Value: info.ScsiErrorCounterLog.Read.TotalErrorsCorrected, Threshold: -1}, - {AttributeId: "read.correction_algorithm_invocations", Name: "Read Correction Algorithm Invocations", Value: info.ScsiErrorCounterLog.Read.CorrectionAlgorithmInvocations, Threshold: -1}, - {AttributeId: "read.total_uncorrected_errors", Name: "Read Total Uncorrected Errors", Value: info.ScsiErrorCounterLog.Read.TotalUncorrectedErrors, Threshold: 0}, - {AttributeId: "write.errors_corrected_by_eccfast", Name: "Write Errors Corrected by ECC Fast", Value: info.ScsiErrorCounterLog.Write.ErrorsCorrectedByEccfast, Threshold: -1}, - {AttributeId: "write.errors_corrected_by_eccdelayed", Name: "Write Errors Corrected by ECC Delayed", Value: info.ScsiErrorCounterLog.Write.ErrorsCorrectedByEccdelayed, Threshold: -1}, - {AttributeId: "write.errors_corrected_by_rereads_rewrites", Name: "Write Errors Corrected by ReReads/ReWrites", Value: info.ScsiErrorCounterLog.Write.ErrorsCorrectedByRereadsRewrites, Threshold: 0}, - {AttributeId: "write.total_errors_corrected", Name: "Write Total Errors Corrected", Value: info.ScsiErrorCounterLog.Write.TotalErrorsCorrected, Threshold: -1}, - {AttributeId: "write.correction_algorithm_invocations", Name: "Write Correction Algorithm Invocations", Value: info.ScsiErrorCounterLog.Write.CorrectionAlgorithmInvocations, Threshold: -1}, - {AttributeId: "write.total_uncorrected_errors", Name: "Write Total Uncorrected Errors", Value: info.ScsiErrorCounterLog.Write.TotalUncorrectedErrors, Threshold: 0}, - } -} diff --git a/webapp/backend/pkg/models/db/smart_ata_attribute.go b/webapp/backend/pkg/models/db/smart_ata_attribute.go deleted file mode 100644 index 510672d..0000000 --- a/webapp/backend/pkg/models/db/smart_ata_attribute.go +++ /dev/null @@ -1,111 +0,0 @@ -package db - -import ( - "github.com/analogj/scrutiny/webapp/backend/pkg/metadata" - "gorm.io/gorm" - "strings" -) - -const SmartAttributeStatusPassed = "passed" -const SmartAttributeStatusFailed = "failed" -const SmartAttributeStatusWarning = "warn" - -type SmartAtaAttribute struct { - gorm.Model - - SmartId int `json:"smart_id"` - Smart Device `json:"-" gorm:"foreignkey:SmartId"` // use SmartId as foreign key - - AttributeId int `json:"attribute_id"` - Name string `json:"name"` - Value int `json:"value"` - Worst int `json:"worst"` - Threshold int `json:"thresh"` - RawValue int64 `json:"raw_value"` - RawString string `json:"raw_string"` - WhenFailed string `json:"when_failed"` - - TransformedValue int64 `json:"transformed_value"` - Status string `gorm:"-" json:"status,omitempty"` - StatusReason string `gorm:"-" json:"status_reason,omitempty"` - FailureRate float64 `gorm:"-" json:"failure_rate,omitempty"` - History []SmartAtaAttribute `gorm:"-" json:"history,omitempty"` -} - -//populate attribute status, using SMART Thresholds & Observed Metadata -func (sa *SmartAtaAttribute) PopulateAttributeStatus() { - if strings.ToUpper(sa.WhenFailed) == SmartWhenFailedFailingNow { - //this attribute has previously failed - sa.Status = SmartAttributeStatusFailed - sa.StatusReason = "Attribute is failing manufacturer SMART threshold" - - } else if strings.ToUpper(sa.WhenFailed) == SmartWhenFailedInThePast { - sa.Status = SmartAttributeStatusWarning - sa.StatusReason = "Attribute has previously failed manufacturer SMART threshold" - } - - if smartMetadata, ok := metadata.AtaMetadata[sa.AttributeId]; ok { - sa.MetadataObservedThresholdStatus(smartMetadata) - } - - //check if status is blank, set to "passed" - if len(sa.Status) == 0 { - sa.Status = SmartAttributeStatusPassed - } -} - -// compare the attribute (raw, normalized, transformed) value to observed thresholds, and update status if necessary -func (sa *SmartAtaAttribute) MetadataObservedThresholdStatus(smartMetadata metadata.AtaAttributeMetadata) { - //TODO: multiple rules - // try to predict the failure rates for observed thresholds that have 0 failure rate and error bars. - // - if the attribute is critical - // - the failure rate is over 10 - set to failed - // - the attribute does not match any threshold, set to warn - // - if the attribute is not critical - // - if failure rate is above 20 - set to failed - // - if failure rate is above 10 but below 20 - set to warn - - //update the smart attribute status based on Observed thresholds. - var value int64 - if smartMetadata.DisplayType == metadata.AtaSmartAttributeDisplayTypeNormalized { - value = int64(sa.Value) - } else if smartMetadata.DisplayType == metadata.AtaSmartAttributeDisplayTypeTransformed { - value = sa.TransformedValue - } else { - value = sa.RawValue - } - - for _, obsThresh := range smartMetadata.ObservedThresholds { - - //check if "value" is in this bucket - if ((obsThresh.Low == obsThresh.High) && value == obsThresh.Low) || - (obsThresh.Low < value && value <= obsThresh.High) { - sa.FailureRate = obsThresh.AnnualFailureRate - - if smartMetadata.Critical { - if obsThresh.AnnualFailureRate >= 0.10 { - sa.Status = SmartAttributeStatusFailed - sa.StatusReason = "Observed Failure Rate for Critical Attribute is greater than 10%" - } - } else { - if obsThresh.AnnualFailureRate >= 0.20 { - sa.Status = SmartAttributeStatusFailed - sa.StatusReason = "Observed Failure Rate for Attribute is greater than 20%" - } else if obsThresh.AnnualFailureRate >= 0.10 { - sa.Status = SmartAttributeStatusWarning - sa.StatusReason = "Observed Failure Rate for Attribute is greater than 10%" - } - } - - //we've found the correct bucket, we can drop out of this loop - return - } - } - // no bucket found - if smartMetadata.Critical { - sa.Status = SmartAttributeStatusWarning - sa.StatusReason = "Could not determine Observed Failure Rate for Critical Attribute" - } - - return -} diff --git a/webapp/backend/pkg/models/db/smart_nvme_attribute.go b/webapp/backend/pkg/models/db/smart_nvme_attribute.go deleted file mode 100644 index b681181..0000000 --- a/webapp/backend/pkg/models/db/smart_nvme_attribute.go +++ /dev/null @@ -1,46 +0,0 @@ -package db - -import ( - "github.com/analogj/scrutiny/webapp/backend/pkg/metadata" - "gorm.io/gorm" -) - -type SmartNvmeAttribute struct { - gorm.Model - - SmartId int `json:"smart_id"` - Smart Device `json:"-" gorm:"foreignkey:SmartId"` // use SmartId as foreign key - - AttributeId string `json:"attribute_id"` //json string from smartctl - Name string `json:"name"` - Value int `json:"value"` - Threshold int `json:"thresh"` - - TransformedValue int64 `json:"transformed_value"` - Status string `gorm:"-" json:"status,omitempty"` - StatusReason string `gorm:"-" json:"status_reason,omitempty"` - FailureRate float64 `gorm:"-" json:"failure_rate,omitempty"` - History []SmartNvmeAttribute `gorm:"-" json:"history,omitempty"` -} - -//populate attribute status, using SMART Thresholds & Observed Metadata -func (sa *SmartNvmeAttribute) PopulateAttributeStatus() { - - //-1 is a special number meaning no threshold. - if sa.Threshold != -1 { - if smartMetadata, ok := metadata.NmveMetadata[sa.AttributeId]; ok { - //check what the ideal is. Ideal tells us if we our recorded value needs to be above, or below the threshold - if (smartMetadata.Ideal == "low" && sa.Value > sa.Threshold) || - (smartMetadata.Ideal == "high" && sa.Value < sa.Threshold) { - sa.Status = SmartAttributeStatusFailed - sa.StatusReason = "Attribute is failing recommended SMART threshold" - } - } - } - //TODO: eventually figure out the critical_warning bits and determine correct error messages here. - - //check if status is blank, set to "passed" - if len(sa.Status) == 0 { - sa.Status = SmartAttributeStatusPassed - } -} diff --git a/webapp/backend/pkg/models/db/smart_scsci_attribute.go b/webapp/backend/pkg/models/db/smart_scsci_attribute.go deleted file mode 100644 index c6b1325..0000000 --- a/webapp/backend/pkg/models/db/smart_scsci_attribute.go +++ /dev/null @@ -1,45 +0,0 @@ -package db - -import ( - "github.com/analogj/scrutiny/webapp/backend/pkg/metadata" - "gorm.io/gorm" -) - -type SmartScsiAttribute struct { - gorm.Model - - SmartId int `json:"smart_id"` - Smart Device `json:"-" gorm:"foreignkey:SmartId"` // use SmartId as foreign key - - AttributeId string `json:"attribute_id"` //json string from smartctl - Name string `json:"name"` - Value int `json:"value"` - Threshold int `json:"thresh"` - - TransformedValue int64 `json:"transformed_value"` - Status string `gorm:"-" json:"status,omitempty"` - StatusReason string `gorm:"-" json:"status_reason,omitempty"` - FailureRate float64 `gorm:"-" json:"failure_rate,omitempty"` - History []SmartScsiAttribute `gorm:"-" json:"history,omitempty"` -} - -//populate attribute status, using SMART Thresholds & Observed Metadata -func (sa *SmartScsiAttribute) PopulateAttributeStatus() { - - //-1 is a special number meaning no threshold. - if sa.Threshold != -1 { - if smartMetadata, ok := metadata.NmveMetadata[sa.AttributeId]; ok { - //check what the ideal is. Ideal tells us if we our recorded value needs to be above, or below the threshold - if (smartMetadata.Ideal == "low" && sa.Value > sa.Threshold) || - (smartMetadata.Ideal == "high" && sa.Value < sa.Threshold) { - sa.Status = SmartAttributeStatusFailed - sa.StatusReason = "Attribute is failing recommended SMART threshold" - } - } - } - - //check if status is blank, set to "passed" - if len(sa.Status) == 0 { - sa.Status = SmartAttributeStatusPassed - } -} diff --git a/webapp/backend/pkg/models/db/smart_test.go b/webapp/backend/pkg/models/db/smart_test.go deleted file mode 100644 index 0f03715..0000000 --- a/webapp/backend/pkg/models/db/smart_test.go +++ /dev/null @@ -1,155 +0,0 @@ -package db_test - -import ( - "encoding/json" - "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" - "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" - "github.com/stretchr/testify/require" - "io/ioutil" - "os" - "testing" -) - -func TestFromCollectorSmartInfo(t *testing.T) { - //setup - smartDataFile, err := os.Open("../testdata/smart-ata.json") - require.NoError(t, err) - defer smartDataFile.Close() - - var smartJson collector.SmartInfo - - smartDataBytes, err := ioutil.ReadAll(smartDataFile) - require.NoError(t, err) - err = json.Unmarshal(smartDataBytes, &smartJson) - require.NoError(t, err) - - //test - smartMdl := db.Smart{} - err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) - - //assert - require.NoError(t, err) - require.Equal(t, "WWN-test", smartMdl.DeviceWWN) - require.Equal(t, "passed", smartMdl.SmartStatus) - require.Equal(t, 18, len(smartMdl.AtaAttributes)) - require.Equal(t, 0, len(smartMdl.NvmeAttributes)) - require.Equal(t, 0, len(smartMdl.ScsiAttributes)) - - //check that temperature was correctly parsed - for _, attr := range smartMdl.AtaAttributes { - if attr.AttributeId == 194 { - require.Equal(t, int64(163210330144), attr.RawValue) - require.Equal(t, int64(32), attr.TransformedValue) - } - } -} - -func TestFromCollectorSmartInfo_Fail(t *testing.T) { - //setup - smartDataFile, err := os.Open("../testdata/smart-fail.json") - require.NoError(t, err) - defer smartDataFile.Close() - - var smartJson collector.SmartInfo - - smartDataBytes, err := ioutil.ReadAll(smartDataFile) - require.NoError(t, err) - err = json.Unmarshal(smartDataBytes, &smartJson) - require.NoError(t, err) - - //test - smartMdl := db.Smart{} - err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) - - //assert - require.NoError(t, err) - require.Equal(t, "WWN-test", smartMdl.DeviceWWN) - require.Equal(t, "failed", smartMdl.SmartStatus) - require.Equal(t, 0, len(smartMdl.AtaAttributes)) - require.Equal(t, 0, len(smartMdl.NvmeAttributes)) - require.Equal(t, 0, len(smartMdl.ScsiAttributes)) -} - -func TestFromCollectorSmartInfo_Fail2(t *testing.T) { - //setup - smartDataFile, err := os.Open("../testdata/smart-fail2.json") - require.NoError(t, err) - defer smartDataFile.Close() - - var smartJson collector.SmartInfo - - smartDataBytes, err := ioutil.ReadAll(smartDataFile) - require.NoError(t, err) - err = json.Unmarshal(smartDataBytes, &smartJson) - require.NoError(t, err) - - //test - smartMdl := db.Smart{} - err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) - - //assert - require.NoError(t, err) - require.Equal(t, "WWN-test", smartMdl.DeviceWWN) - require.Equal(t, "failed", smartMdl.SmartStatus) - require.Equal(t, 17, len(smartMdl.AtaAttributes)) - require.Equal(t, 0, len(smartMdl.NvmeAttributes)) - require.Equal(t, 0, len(smartMdl.ScsiAttributes)) -} - -func TestFromCollectorSmartInfo_Nvme(t *testing.T) { - //setup - smartDataFile, err := os.Open("../testdata/smart-nvme.json") - require.NoError(t, err) - defer smartDataFile.Close() - - var smartJson collector.SmartInfo - - smartDataBytes, err := ioutil.ReadAll(smartDataFile) - require.NoError(t, err) - err = json.Unmarshal(smartDataBytes, &smartJson) - require.NoError(t, err) - - //test - smartMdl := db.Smart{} - err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) - - //assert - require.NoError(t, err) - require.Equal(t, "WWN-test", smartMdl.DeviceWWN) - require.Equal(t, "passed", smartMdl.SmartStatus) - require.Equal(t, 0, len(smartMdl.AtaAttributes)) - require.Equal(t, 16, len(smartMdl.NvmeAttributes)) - require.Equal(t, 0, len(smartMdl.ScsiAttributes)) - - require.Equal(t, 111303174, smartMdl.NvmeAttributes[6].Value) - require.Equal(t, 83170961, smartMdl.NvmeAttributes[7].Value) -} - -func TestFromCollectorSmartInfo_Scsi(t *testing.T) { - //setup - smartDataFile, err := os.Open("../testdata/smart-scsi.json") - require.NoError(t, err) - defer smartDataFile.Close() - - var smartJson collector.SmartInfo - - smartDataBytes, err := ioutil.ReadAll(smartDataFile) - require.NoError(t, err) - err = json.Unmarshal(smartDataBytes, &smartJson) - require.NoError(t, err) - - //test - smartMdl := db.Smart{} - err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) - - //assert - require.NoError(t, err) - require.Equal(t, "WWN-test", smartMdl.DeviceWWN) - require.Equal(t, "passed", smartMdl.SmartStatus) - require.Equal(t, 0, len(smartMdl.AtaAttributes)) - require.Equal(t, 0, len(smartMdl.NvmeAttributes)) - require.Equal(t, 13, len(smartMdl.ScsiAttributes)) - - require.Equal(t, 56, smartMdl.ScsiAttributes[0].Value) - require.Equal(t, 300357663, smartMdl.ScsiAttributes[4].Value) //total_errors_corrected -} diff --git a/webapp/backend/pkg/models/device.go b/webapp/backend/pkg/models/device.go new file mode 100644 index 0000000..c5272b4 --- /dev/null +++ b/webapp/backend/pkg/models/device.go @@ -0,0 +1,169 @@ +package models + +import ( + "github.com/analogj/scrutiny/webapp/backend/pkg" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" + "time" +) + +type DeviceWrapper struct { + Success bool `json:"success"` + Errors []error `json:"errors"` + Data []Device `json:"data"` +} + +type Device struct { + //GORM attributes, see: http://gorm.io/docs/conventions.html + CreatedAt time.Time + UpdatedAt time.Time + DeletedAt *time.Time + + WWN string `json:"wwn" gorm:"primary_key"` + + DeviceName string `json:"device_name"` + Manufacturer string `json:"manufacturer"` + ModelName string `json:"model_name"` + InterfaceType string `json:"interface_type"` + InterfaceSpeed string `json:"interface_speed"` + SerialNumber string `json:"serial_number"` + Firmware string `json:"firmware"` + RotationSpeed int `json:"rotational_speed"` + Capacity int64 `json:"capacity"` + FormFactor string `json:"form_factor"` + SmartSupport bool `json:"smart_support"` + DeviceProtocol string `json:"device_protocol"` //protocol determines which smart attribute types are available (ATA, NVMe, SCSI) + DeviceType string `json:"device_type"` //device type is used for querying with -d/t flag, should only be used by collector. + + // User provided metadata + Label string `json:"label"` + HostId string `json:"host_id"` + + // Data set by Scrutiny + DeviceStatus pkg.DeviceStatus `json:"device_status"` +} + +func (dv *Device) IsAta() bool { + return dv.DeviceProtocol == pkg.DeviceProtocolAta +} + +func (dv *Device) IsScsi() bool { + return dv.DeviceProtocol == pkg.DeviceProtocolScsi +} + +func (dv *Device) IsNvme() bool { + return dv.DeviceProtocol == pkg.DeviceProtocolNvme +} + +// +////This method requires a device with an array of SmartResults. +////It will remove all SmartResults other than the first (the latest one) +////All removed SmartResults, will be processed, grouping SmartAtaAttribute by attribute_id +//// and adding theme to an array called History. +//func (dv *Device) SquashHistory() error { +// if len(dv.SmartResults) <= 1 { +// return nil //no ataHistory found. ignore +// } +// +// latestSmartResultSlice := dv.SmartResults[0:1] +// historicalSmartResultSlice := dv.SmartResults[1:] +// +// //re-assign the latest slice to the SmartResults field +// dv.SmartResults = latestSmartResultSlice +// +// //process the historical slice for ATA data +// if len(dv.SmartResults[0].AtaAttributes) > 0 { +// ataHistory := map[int][]SmartAtaAttribute{} +// for _, smartResult := range historicalSmartResultSlice { +// for _, smartAttribute := range smartResult.AtaAttributes { +// if _, ok := ataHistory[smartAttribute.AttributeId]; !ok { +// ataHistory[smartAttribute.AttributeId] = []SmartAtaAttribute{} +// } +// ataHistory[smartAttribute.AttributeId] = append(ataHistory[smartAttribute.AttributeId], smartAttribute) +// } +// } +// +// //now assign the historical slices to the AtaAttributes in the latest SmartResults +// for sandx, smartAttribute := range dv.SmartResults[0].AtaAttributes { +// if attributeHistory, ok := ataHistory[smartAttribute.AttributeId]; ok { +// dv.SmartResults[0].AtaAttributes[sandx].History = attributeHistory +// } +// } +// } +// +// //process the historical slice for Nvme data +// if len(dv.SmartResults[0].NvmeAttributes) > 0 { +// nvmeHistory := map[string][]SmartNvmeAttribute{} +// for _, smartResult := range historicalSmartResultSlice { +// for _, smartAttribute := range smartResult.NvmeAttributes { +// if _, ok := nvmeHistory[smartAttribute.AttributeId]; !ok { +// nvmeHistory[smartAttribute.AttributeId] = []SmartNvmeAttribute{} +// } +// nvmeHistory[smartAttribute.AttributeId] = append(nvmeHistory[smartAttribute.AttributeId], smartAttribute) +// } +// } +// +// //now assign the historical slices to the AtaAttributes in the latest SmartResults +// for sandx, smartAttribute := range dv.SmartResults[0].NvmeAttributes { +// if attributeHistory, ok := nvmeHistory[smartAttribute.AttributeId]; ok { +// dv.SmartResults[0].NvmeAttributes[sandx].History = attributeHistory +// } +// } +// } +// //process the historical slice for Scsi data +// if len(dv.SmartResults[0].ScsiAttributes) > 0 { +// scsiHistory := map[string][]SmartScsiAttribute{} +// for _, smartResult := range historicalSmartResultSlice { +// for _, smartAttribute := range smartResult.ScsiAttributes { +// if _, ok := scsiHistory[smartAttribute.AttributeId]; !ok { +// scsiHistory[smartAttribute.AttributeId] = []SmartScsiAttribute{} +// } +// scsiHistory[smartAttribute.AttributeId] = append(scsiHistory[smartAttribute.AttributeId], smartAttribute) +// } +// } +// +// //now assign the historical slices to the AtaAttributes in the latest SmartResults +// for sandx, smartAttribute := range dv.SmartResults[0].ScsiAttributes { +// if attributeHistory, ok := scsiHistory[smartAttribute.AttributeId]; ok { +// dv.SmartResults[0].ScsiAttributes[sandx].History = attributeHistory +// } +// } +// } +// return nil +//} +// +//func (dv *Device) ApplyMetadataRules() error { +// +// //embed metadata in the latest smart attributes object +// if len(dv.SmartResults) > 0 { +// for ndx, attr := range dv.SmartResults[0].AtaAttributes { +// attr.PopulateAttributeStatus() +// dv.SmartResults[0].AtaAttributes[ndx] = attr +// } +// +// for ndx, attr := range dv.SmartResults[0].NvmeAttributes { +// attr.PopulateAttributeStatus() +// dv.SmartResults[0].NvmeAttributes[ndx] = attr +// +// } +// +// for ndx, attr := range dv.SmartResults[0].ScsiAttributes { +// attr.PopulateAttributeStatus() +// dv.SmartResults[0].ScsiAttributes[ndx] = attr +// +// } +// } +// return nil +//} + +// This function is called every time the collector sends SMART data to the API. +// It can be used to update device data that can change over time. +func (dv *Device) UpdateFromCollectorSmartInfo(info collector.SmartInfo) error { + dv.Firmware = info.FirmwareVersion + dv.DeviceProtocol = info.Device.Protocol + + if !info.SmartStatus.Passed { + dv.DeviceStatus = pkg.Set(dv.DeviceStatus, pkg.DeviceStatusFailedSmart) + } + + return nil +} diff --git a/webapp/backend/pkg/models/device_summary.go b/webapp/backend/pkg/models/device_summary.go new file mode 100644 index 0000000..c1781e3 --- /dev/null +++ b/webapp/backend/pkg/models/device_summary.go @@ -0,0 +1,19 @@ +package models + +import ( + "github.com/analogj/scrutiny/webapp/backend/pkg/models/measurements" + "time" +) + +type DeviceSummary struct { + Device Device `json:"device"` + + SmartResults *SmartSummary `json:"smart,omitempty"` + TempHistory []measurements.SmartTemperature `json:"temp_history,omitempty"` +} +type SmartSummary struct { + // Collector Summary Data + CollectorDate time.Time `json:"collector_date,omitempty"` + Temp int64 `json:"temp,omitempty"` + PowerOnHours int64 `json:"power_on_hours,omitempty"` +} diff --git a/webapp/backend/pkg/models/measurements/smart.go b/webapp/backend/pkg/models/measurements/smart.go new file mode 100644 index 0000000..20524ff --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart.go @@ -0,0 +1,198 @@ +package measurements + +import ( + "fmt" + "github.com/analogj/scrutiny/webapp/backend/pkg" + "github.com/analogj/scrutiny/webapp/backend/pkg/metadata" + "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" + "log" + "strings" + "time" +) + +type Smart struct { + Date time.Time `json:"date"` + DeviceWWN string `json:"device_wwn"` //(tag) + DeviceProtocol string `json:"device_protocol"` + + //Metrics (fields) + Temp int64 `json:"temp"` + PowerOnHours int64 `json:"power_on_hours"` + PowerCycleCount int64 `json:"power_cycle_count"` + + //Attributes (fields) + Attributes map[string]SmartAttribute `json:"attrs"` +} + +func (sm *Smart) Flatten() (tags map[string]string, fields map[string]interface{}) { + tags = map[string]string{ + "device_wwn": sm.DeviceWWN, + "device_protocol": sm.DeviceProtocol, + } + + fields = map[string]interface{}{ + "temp": sm.Temp, + "power_on_hours": sm.PowerOnHours, + "power_cycle_count": sm.PowerCycleCount, + } + + for _, attr := range sm.Attributes { + for attrKey, attrVal := range attr.Flatten() { + fields[attrKey] = attrVal + } + } + + return tags, fields +} + +func NewSmartFromInfluxDB(attrs map[string]interface{}) (*Smart, error) { + //go though the massive map returned from influxdb. If a key is associated with the Smart struct, assign it. If it starts with "attr.*" group it by attributeId, and pass to attribute inflate. + + sm := Smart{ + //required fields + Date: attrs["_time"].(time.Time), + DeviceWWN: attrs["device_wwn"].(string), + DeviceProtocol: attrs["device_protocol"].(string), + + Attributes: map[string]SmartAttribute{}, + } + + log.Printf("Prefetched Smart: %v\n", sm) + + //two steps (because we dont know the + for key, val := range attrs { + log.Printf("Found Attribute (%s = %v)\n", key, val) + + switch key { + case "temp": + sm.Temp = val.(int64) + case "power_on_hours": + sm.PowerOnHours = val.(int64) + case "power_cycle_count": + sm.PowerCycleCount = val.(int64) + default: + // this key is unknown. + if !strings.HasPrefix(key, "attr.") { + continue + } + //this is a attribute, lets group it with its related "siblings", populating a SmartAttribute object + keyParts := strings.Split(key, ".") + attributeId := keyParts[1] + if _, ok := sm.Attributes[attributeId]; !ok { + // init the attribute group + if sm.DeviceProtocol == pkg.DeviceProtocolAta { + sm.Attributes[attributeId] = &SmartAtaAttribute{} + } else if sm.DeviceProtocol == pkg.DeviceProtocolNvme { + sm.Attributes[attributeId] = &SmartNvmeAttribute{} + } else if sm.DeviceProtocol == pkg.DeviceProtocolScsi { + sm.Attributes[attributeId] = &SmartScsiAttribute{} + } else { + return nil, fmt.Errorf("Unknown Device Protocol: %s", sm.DeviceProtocol) + } + } + + sm.Attributes[attributeId].Inflate(key, val) + } + + } + + log.Printf("########NUMBER OF ATTRIBUTES: %v", len(sm.Attributes)) + log.Printf("########SMART: %v", sm) + + //panic("ERROR HERE.") + + //log.Printf("Sm.Attributes: %v", sm.Attributes) + //log.Printf("sm.Attributes[attributeId]: %v", sm.Attributes[attributeId]) + + return &sm, nil +} + +//Parse Collector SMART data results and create Smart object (and associated SmartAtaAttribute entries) +func (sm *Smart) FromCollectorSmartInfo(wwn string, info collector.SmartInfo) error { + sm.DeviceWWN = wwn + sm.Date = time.Unix(info.LocalTime.TimeT, 0) + + //smart metrics + sm.Temp = info.Temperature.Current + sm.PowerCycleCount = info.PowerCycleCount + sm.PowerOnHours = info.PowerOnTime.Hours + + sm.DeviceProtocol = info.Device.Protocol + // process ATA/NVME/SCSI protocol data + sm.Attributes = map[string]SmartAttribute{} + if sm.DeviceProtocol == pkg.DeviceProtocolAta { + sm.ProcessAtaSmartInfo(info) + } else if sm.DeviceProtocol == pkg.DeviceProtocolNvme { + sm.ProcessNvmeSmartInfo(info) + } else if sm.DeviceProtocol == pkg.DeviceProtocolScsi { + sm.ProcessScsiSmartInfo(info) + } + + return nil +} + +//generate SmartAtaAttribute entries from Scrutiny Collector Smart data. +func (sm *Smart) ProcessAtaSmartInfo(info collector.SmartInfo) { + for _, collectorAttr := range info.AtaSmartAttributes.Table { + attrModel := SmartAtaAttribute{ + AttributeId: collectorAttr.ID, + Name: collectorAttr.Name, + Value: collectorAttr.Value, + Worst: collectorAttr.Worst, + Threshold: collectorAttr.Thresh, + RawValue: collectorAttr.Raw.Value, + RawString: collectorAttr.Raw.String, + WhenFailed: collectorAttr.WhenFailed, + } + + //now that we've parsed the data from the smartctl response, lets match it against our metadata rules and add additional Scrutiny specific data. + if smartMetadata, ok := metadata.AtaMetadata[collectorAttr.ID]; ok { + attrModel.Name = smartMetadata.DisplayName + if smartMetadata.Transform != nil { + attrModel.TransformedValue = smartMetadata.Transform(attrModel.Value, attrModel.RawValue, attrModel.RawString) + } + } + sm.Attributes[string(collectorAttr.ID)] = &attrModel + } +} + +//generate SmartNvmeAttribute entries from Scrutiny Collector Smart data. +func (sm *Smart) ProcessNvmeSmartInfo(info collector.SmartInfo) { + sm.Attributes = map[string]SmartAttribute{ + "critical_warning": &SmartNvmeAttribute{AttributeId: "critical_warning", Name: "Critical Warning", Value: info.NvmeSmartHealthInformationLog.CriticalWarning, Threshold: 0}, + "temperature": &SmartNvmeAttribute{AttributeId: "temperature", Name: "Temperature", Value: info.NvmeSmartHealthInformationLog.Temperature, Threshold: -1}, + "available_spare": &SmartNvmeAttribute{AttributeId: "available_spare", Name: "Available Spare", Value: info.NvmeSmartHealthInformationLog.AvailableSpare, Threshold: info.NvmeSmartHealthInformationLog.AvailableSpareThreshold}, + "percentage_used": &SmartNvmeAttribute{AttributeId: "percentage_used", Name: "Percentage Used", Value: info.NvmeSmartHealthInformationLog.PercentageUsed, Threshold: 100}, + "data_units_read": &SmartNvmeAttribute{AttributeId: "data_units_read", Name: "Data Units Read", Value: info.NvmeSmartHealthInformationLog.DataUnitsRead, Threshold: -1}, + "data_units_written": &SmartNvmeAttribute{AttributeId: "data_units_written", Name: "Data Units Written", Value: info.NvmeSmartHealthInformationLog.DataUnitsWritten, Threshold: -1}, + "host_reads": &SmartNvmeAttribute{AttributeId: "host_reads", Name: "Host Reads", Value: info.NvmeSmartHealthInformationLog.HostReads, Threshold: -1}, + "host_writes": &SmartNvmeAttribute{AttributeId: "host_writes", Name: "Host Writes", Value: info.NvmeSmartHealthInformationLog.HostWrites, Threshold: -1}, + "controller_busy_time": &SmartNvmeAttribute{AttributeId: "controller_busy_time", Name: "Controller Busy Time", Value: info.NvmeSmartHealthInformationLog.ControllerBusyTime, Threshold: -1}, + "power_cycles": &SmartNvmeAttribute{AttributeId: "power_cycles", Name: "Power Cycles", Value: info.NvmeSmartHealthInformationLog.PowerCycles, Threshold: -1}, + "power_on_hours": &SmartNvmeAttribute{AttributeId: "power_on_hours", Name: "Power on Hours", Value: info.NvmeSmartHealthInformationLog.PowerOnHours, Threshold: -1}, + "unsafe_shutdowns": &SmartNvmeAttribute{AttributeId: "unsafe_shutdowns", Name: "Unsafe Shutdowns", Value: info.NvmeSmartHealthInformationLog.UnsafeShutdowns, Threshold: -1}, + "media_errors": &SmartNvmeAttribute{AttributeId: "media_errors", Name: "Media Errors", Value: info.NvmeSmartHealthInformationLog.MediaErrors, Threshold: 0}, + "num_err_log_entries": &SmartNvmeAttribute{AttributeId: "num_err_log_entries", Name: "Numb Err Log Entries", Value: info.NvmeSmartHealthInformationLog.NumErrLogEntries, Threshold: 0}, + "warning_temp_time": &SmartNvmeAttribute{AttributeId: "warning_temp_time", Name: "Warning Temp Time", Value: info.NvmeSmartHealthInformationLog.WarningTempTime, Threshold: -1}, + "critical_comp_time": &SmartNvmeAttribute{AttributeId: "critical_comp_time", Name: "Critical CompTime", Value: info.NvmeSmartHealthInformationLog.CriticalCompTime, Threshold: -1}, + } +} + +//generate SmartScsiAttribute entries from Scrutiny Collector Smart data. +func (sm *Smart) ProcessScsiSmartInfo(info collector.SmartInfo) { + sm.Attributes = map[string]SmartAttribute{ + "scsi_grown_defect_list": &SmartScsiAttribute{AttributeId: "scsi_grown_defect_list", Name: "Grown Defect List", Value: info.ScsiGrownDefectList, Threshold: 0}, + "read_errors_corrected_by_eccfast": &SmartScsiAttribute{AttributeId: "read_errors_corrected_by_eccfast", Name: "Read Errors Corrected by ECC Fast", Value: info.ScsiErrorCounterLog.Read.ErrorsCorrectedByEccfast, Threshold: -1}, + "read_errors_corrected_by_eccdelayed": &SmartScsiAttribute{AttributeId: "read_errors_corrected_by_eccdelayed", Name: "Read Errors Corrected by ECC Delayed", Value: info.ScsiErrorCounterLog.Read.ErrorsCorrectedByEccdelayed, Threshold: -1}, + "read_errors_corrected_by_rereads_rewrites": &SmartScsiAttribute{AttributeId: "read_errors_corrected_by_rereads_rewrites", Name: "Read Errors Corrected by ReReads/ReWrites", Value: info.ScsiErrorCounterLog.Read.ErrorsCorrectedByRereadsRewrites, Threshold: 0}, + "read_total_errors_corrected": &SmartScsiAttribute{AttributeId: "read_total_errors_corrected", Name: "Read Total Errors Corrected", Value: info.ScsiErrorCounterLog.Read.TotalErrorsCorrected, Threshold: -1}, + "read_correction_algorithm_invocations": &SmartScsiAttribute{AttributeId: "read_correction_algorithm_invocations", Name: "Read Correction Algorithm Invocations", Value: info.ScsiErrorCounterLog.Read.CorrectionAlgorithmInvocations, Threshold: -1}, + "read_total_uncorrected_errors": &SmartScsiAttribute{AttributeId: "read_total_uncorrected_errors", Name: "Read Total Uncorrected Errors", Value: info.ScsiErrorCounterLog.Read.TotalUncorrectedErrors, Threshold: 0}, + "write_errors_corrected_by_eccfast": &SmartScsiAttribute{AttributeId: "write_errors_corrected_by_eccfast", Name: "Write Errors Corrected by ECC Fast", Value: info.ScsiErrorCounterLog.Write.ErrorsCorrectedByEccfast, Threshold: -1}, + "write_errors_corrected_by_eccdelayed": &SmartScsiAttribute{AttributeId: "write_errors_corrected_by_eccdelayed", Name: "Write Errors Corrected by ECC Delayed", Value: info.ScsiErrorCounterLog.Write.ErrorsCorrectedByEccdelayed, Threshold: -1}, + "write_errors_corrected_by_rereads_rewrites": &SmartScsiAttribute{AttributeId: "write_errors_corrected_by_rereads_rewrites", Name: "Write Errors Corrected by ReReads/ReWrites", Value: info.ScsiErrorCounterLog.Write.ErrorsCorrectedByRereadsRewrites, Threshold: 0}, + "write_total_errors_corrected": &SmartScsiAttribute{AttributeId: "write_total_errors_corrected", Name: "Write Total Errors Corrected", Value: info.ScsiErrorCounterLog.Write.TotalErrorsCorrected, Threshold: -1}, + "write_correction_algorithm_invocations": &SmartScsiAttribute{AttributeId: "write_correction_algorithm_invocations", Name: "Write Correction Algorithm Invocations", Value: info.ScsiErrorCounterLog.Write.CorrectionAlgorithmInvocations, Threshold: -1}, + "write_total_uncorrected_errors": &SmartScsiAttribute{AttributeId: "write_total_uncorrected_errors", Name: "Write Total Uncorrected Errors", Value: info.ScsiErrorCounterLog.Write.TotalUncorrectedErrors, Threshold: 0}, + } +} diff --git a/webapp/backend/pkg/models/measurements/smart_ata_attribute.go b/webapp/backend/pkg/models/measurements/smart_ata_attribute.go new file mode 100644 index 0000000..691cac7 --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart_ata_attribute.go @@ -0,0 +1,151 @@ +package measurements + +import ( + "fmt" + "strconv" + "strings" +) + +const SmartAttributeStatusPassed = "passed" +const SmartAttributeStatusFailed = "failed" +const SmartAttributeStatusWarning = "warn" + +type SmartAtaAttribute struct { + AttributeId int `json:"attribute_id"` + Name string `json:"name"` + Value int64 `json:"value"` + Threshold int64 `json:"thresh"` + Worst int64 `json:"worst"` + RawValue int64 `json:"raw_value"` + RawString string `json:"raw_string"` + WhenFailed string `json:"when_failed"` + + //Generated data + TransformedValue int64 `json:"transformed_value"` + Status string `json:"status,omitempty"` + StatusReason string `json:"status_reason,omitempty"` + FailureRate float64 `json:"failure_rate,omitempty"` +} + +func (sa *SmartAtaAttribute) Flatten() map[string]interface{} { + + idString := strconv.Itoa(sa.AttributeId) + + return map[string]interface{}{ + fmt.Sprintf("attr.%s.attribute_id", idString): idString, + fmt.Sprintf("attr.%s.name", idString): sa.Name, + fmt.Sprintf("attr.%s.value", idString): sa.Value, + fmt.Sprintf("attr.%s.worst", idString): sa.Worst, + fmt.Sprintf("attr.%s.thresh", idString): sa.Threshold, + fmt.Sprintf("attr.%s.raw_value", idString): sa.RawValue, + fmt.Sprintf("attr.%s.raw_string", idString): sa.RawString, + fmt.Sprintf("attr.%s.when_failed", idString): sa.WhenFailed, + } +} +func (sa *SmartAtaAttribute) Inflate(key string, val interface{}) { + if val == nil { + return + } + keyParts := strings.Split(key, ".") + + switch keyParts[2] { + case "attribute_id": + attrId, err := strconv.Atoi(val.(string)) + if err == nil { + sa.AttributeId = attrId + } + case "name": + sa.Name = val.(string) + case "value": + sa.Value = val.(int64) + case "worst": + sa.Worst = val.(int64) + case "thresh": + sa.Threshold = val.(int64) + case "raw_value": + sa.RawValue = val.(int64) + case "raw_string": + sa.RawString = val.(string) + case "when_failed": + sa.WhenFailed = val.(string) + } +} + +// +////populate attribute status, using SMART Thresholds & Observed Metadata +//func (sa *SmartAtaAttribute) PopulateAttributeStatus() { +// if strings.ToUpper(sa.WhenFailed) == SmartWhenFailedFailingNow { +// //this attribute has previously failed +// sa.Status = SmartAttributeStatusFailed +// sa.StatusReason = "Attribute is failing manufacturer SMART threshold" +// +// } else if strings.ToUpper(sa.WhenFailed) == SmartWhenFailedInThePast { +// sa.Status = SmartAttributeStatusWarning +// sa.StatusReason = "Attribute has previously failed manufacturer SMART threshold" +// } +// +// if smartMetadata, ok := metadata.AtaMetadata[sa.AttributeId]; ok { +// sa.MetadataObservedThresholdStatus(smartMetadata) +// } +// +// //check if status is blank, set to "passed" +// if len(sa.Status) == 0 { +// sa.Status = SmartAttributeStatusPassed +// } +//} +// +//// compare the attribute (raw, normalized, transformed) value to observed thresholds, and update status if necessary +//func (sa *SmartAtaAttribute) MetadataObservedThresholdStatus(smartMetadata metadata.AtaAttributeMetadata) { +// //TODO: multiple rules +// // try to predict the failure rates for observed thresholds that have 0 failure rate and error bars. +// // - if the attribute is critical +// // - the failure rate is over 10 - set to failed +// // - the attribute does not match any threshold, set to warn +// // - if the attribute is not critical +// // - if failure rate is above 20 - set to failed +// // - if failure rate is above 10 but below 20 - set to warn +// +// //update the smart attribute status based on Observed thresholds. +// var value int64 +// if smartMetadata.DisplayType == metadata.AtaSmartAttributeDisplayTypeNormalized { +// value = int64(sa.Value) +// } else if smartMetadata.DisplayType == metadata.AtaSmartAttributeDisplayTypeTransformed { +// value = sa.TransformedValue +// } else { +// value = sa.RawValue +// } +// +// for _, obsThresh := range smartMetadata.ObservedThresholds { +// +// //check if "value" is in this bucket +// if ((obsThresh.Low == obsThresh.High) && value == obsThresh.Low) || +// (obsThresh.Low < value && value <= obsThresh.High) { +// sa.FailureRate = obsThresh.AnnualFailureRate +// +// if smartMetadata.Critical { +// if obsThresh.AnnualFailureRate >= 0.10 { +// sa.Status = SmartAttributeStatusFailed +// sa.StatusReason = "Observed Failure Rate for Critical Attribute is greater than 10%" +// } +// } else { +// if obsThresh.AnnualFailureRate >= 0.20 { +// sa.Status = SmartAttributeStatusFailed +// sa.StatusReason = "Observed Failure Rate for Attribute is greater than 20%" +// } else if obsThresh.AnnualFailureRate >= 0.10 { +// sa.Status = SmartAttributeStatusWarning +// sa.StatusReason = "Observed Failure Rate for Attribute is greater than 10%" +// } +// } +// +// //we've found the correct bucket, we can drop out of this loop +// return +// } +// } +// // no bucket found +// if smartMetadata.Critical { +// sa.Status = SmartAttributeStatusWarning +// sa.StatusReason = "Could not determine Observed Failure Rate for Critical Attribute" +// } +// +// return +//} diff --git a/webapp/backend/pkg/models/measurements/smart_attribute.go b/webapp/backend/pkg/models/measurements/smart_attribute.go new file mode 100644 index 0000000..1d93bc8 --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart_attribute.go @@ -0,0 +1,6 @@ +package measurements + +type SmartAttribute interface { + Flatten() (fields map[string]interface{}) + Inflate(key string, val interface{}) +} diff --git a/webapp/backend/pkg/models/measurements/smart_nvme_attribute.go b/webapp/backend/pkg/models/measurements/smart_nvme_attribute.go new file mode 100644 index 0000000..2705ea9 --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart_nvme_attribute.go @@ -0,0 +1,68 @@ +package measurements + +import ( + "fmt" + "strings" +) + +type SmartNvmeAttribute struct { + AttributeId string `json:"attribute_id"` //json string from smartctl + Name string `json:"name"` + Value int64 `json:"value"` + Threshold int64 `json:"thresh"` + + TransformedValue int64 `json:"transformed_value"` + Status string `json:"status,omitempty"` + StatusReason string `json:"status_reason,omitempty"` + FailureRate float64 `json:"failure_rate,omitempty"` +} + +func (sa *SmartNvmeAttribute) Flatten() map[string]interface{} { + return map[string]interface{}{ + fmt.Sprintf("attr.%s.attribute_id", sa.AttributeId): sa.AttributeId, + fmt.Sprintf("attr.%s.name", sa.AttributeId): sa.Name, + fmt.Sprintf("attr.%s.value", sa.AttributeId): sa.Value, + fmt.Sprintf("attr.%s.thresh", sa.AttributeId): sa.Threshold, + } +} +func (sa *SmartNvmeAttribute) Inflate(key string, val interface{}) { + if val == nil { + return + } + + keyParts := strings.Split(key, ".") + + switch keyParts[2] { + case "attribute_id": + sa.AttributeId = val.(string) + case "name": + sa.Name = val.(string) + case "value": + sa.Value = val.(int64) + case "thresh": + sa.Threshold = val.(int64) + } +} + +// +////populate attribute status, using SMART Thresholds & Observed Metadata +//func (sa *SmartNvmeAttribute) PopulateAttributeStatus() { +// +// //-1 is a special number meaning no threshold. +// if sa.Threshold != -1 { +// if smartMetadata, ok := metadata.NmveMetadata[sa.AttributeId]; ok { +// //check what the ideal is. Ideal tells us if we our recorded value needs to be above, or below the threshold +// if (smartMetadata.Ideal == "low" && sa.Value > sa.Threshold) || +// (smartMetadata.Ideal == "high" && sa.Value < sa.Threshold) { +// sa.Status = SmartAttributeStatusFailed +// sa.StatusReason = "Attribute is failing recommended SMART threshold" +// } +// } +// } +// //TODO: eventually figure out the critical_warning bits and determine correct error messages here. +// +// //check if status is blank, set to "passed" +// if len(sa.Status) == 0 { +// sa.Status = SmartAttributeStatusPassed +// } +//} diff --git a/webapp/backend/pkg/models/measurements/smart_scsci_attribute.go b/webapp/backend/pkg/models/measurements/smart_scsci_attribute.go new file mode 100644 index 0000000..830036c --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart_scsci_attribute.go @@ -0,0 +1,67 @@ +package measurements + +import ( + "fmt" + "strings" +) + +type SmartScsiAttribute struct { + AttributeId string `json:"attribute_id"` //json string from smartctl + Name string `json:"name"` + Value int64 `json:"value"` + Threshold int64 `json:"thresh"` + + TransformedValue int64 `json:"transformed_value"` + Status string `json:"status,omitempty"` + StatusReason string `json:"status_reason,omitempty"` + FailureRate float64 `json:"failure_rate,omitempty"` +} + +func (sa *SmartScsiAttribute) Flatten() map[string]interface{} { + return map[string]interface{}{ + fmt.Sprintf("attr.%s.attribute_id", sa.AttributeId): sa.AttributeId, + fmt.Sprintf("attr.%s.name", sa.AttributeId): sa.Name, + fmt.Sprintf("attr.%s.value", sa.AttributeId): sa.Value, + fmt.Sprintf("attr.%s.thresh", sa.AttributeId): sa.Threshold, + } +} +func (sa *SmartScsiAttribute) Inflate(key string, val interface{}) { + if val == nil { + return + } + + keyParts := strings.Split(key, ".") + + switch keyParts[2] { + case "attribute_id": + sa.AttributeId = val.(string) + case "name": + sa.Name = val.(string) + case "value": + sa.Value = val.(int64) + case "thresh": + sa.Threshold = val.(int64) + } +} + +// +////populate attribute status, using SMART Thresholds & Observed Metadata +//func (sa *SmartScsiAttribute) PopulateAttributeStatus() { +// +// //-1 is a special number meaning no threshold. +// if sa.Threshold != -1 { +// if smartMetadata, ok := metadata.NmveMetadata[sa.AttributeId]; ok { +// //check what the ideal is. Ideal tells us if we our recorded value needs to be above, or below the threshold +// if (smartMetadata.Ideal == "low" && sa.Value > sa.Threshold) || +// (smartMetadata.Ideal == "high" && sa.Value < sa.Threshold) { +// sa.Status = SmartAttributeStatusFailed +// sa.StatusReason = "Attribute is failing recommended SMART threshold" +// } +// } +// } +// +// //check if status is blank, set to "passed" +// if len(sa.Status) == 0 { +// sa.Status = SmartAttributeStatusPassed +// } +//} diff --git a/webapp/backend/pkg/models/measurements/smart_temperature.go b/webapp/backend/pkg/models/measurements/smart_temperature.go new file mode 100644 index 0000000..06f4d74 --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart_temperature.go @@ -0,0 +1,29 @@ +package measurements + +import ( + "time" +) + +type SmartTemperature struct { + Date time.Time `json:"date"` + Temp int64 `json:"temp"` +} + +func (st *SmartTemperature) Flatten() (tags map[string]string, fields map[string]interface{}) { + fields = map[string]interface{}{ + "temp": st.Temp, + } + tags = map[string]string{} + + return tags, fields +} + +func (st *SmartTemperature) Inflate(key string, val interface{}) { + if val == nil { + return + } + + if key == "temp" { + st.Temp = val.(int64) + } +} diff --git a/webapp/backend/pkg/models/measurements/smart_test.go b/webapp/backend/pkg/models/measurements/smart_test.go new file mode 100644 index 0000000..a1fde28 --- /dev/null +++ b/webapp/backend/pkg/models/measurements/smart_test.go @@ -0,0 +1,141 @@ +package measurements_test + +//func TestFromCollectorSmartInfo(t *testing.T) { +// //setup +// smartDataFile, err := os.Open("../testdata/smart-ata.json") +// require.NoError(t, err) +// defer smartDataFile.Close() +// +// var smartJson collector.SmartInfo +// +// smartDataBytes, err := ioutil.ReadAll(smartDataFile) +// require.NoError(t, err) +// err = json.Unmarshal(smartDataBytes, &smartJson) +// require.NoError(t, err) +// +// //test +// smartMdl := db.Smart{} +// err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) +// +// //assert +// require.NoError(t, err) +// require.Equal(t, "WWN-test", smartMdl.DeviceWWN) +// require.Equal(t, "passed", smartMdl.SmartStatus) +// require.Equal(t, 18, len(smartMdl.Attributes)) +// +// //check that temperature was correctly parsed +// for _, attr := range smartMdl.Attributes { +// if attr.AttributeId == 194 { +// require.Equal(t, int64(163210330144), attr.RawValue) +// require.Equal(t, int64(32), attr.TransformedValue) +// } +// } +//} +// +//func TestFromCollectorSmartInfo_Fail(t *testing.T) { +// //setup +// smartDataFile, err := os.Open("../testdata/smart-fail.json") +// require.NoError(t, err) +// defer smartDataFile.Close() +// +// var smartJson collector.SmartInfo +// +// smartDataBytes, err := ioutil.ReadAll(smartDataFile) +// require.NoError(t, err) +// err = json.Unmarshal(smartDataBytes, &smartJson) +// require.NoError(t, err) +// +// //test +// smartMdl := db.Smart{} +// err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) +// +// //assert +// require.NoError(t, err) +// require.Equal(t, "WWN-test", smartMdl.DeviceWWN) +// require.Equal(t, "failed", smartMdl.SmartStatus) +// require.Equal(t, 0, len(smartMdl.AtaAttributes)) +// require.Equal(t, 0, len(smartMdl.NvmeAttributes)) +// require.Equal(t, 0, len(smartMdl.ScsiAttributes)) +//} +// +//func TestFromCollectorSmartInfo_Fail2(t *testing.T) { +// //setup +// smartDataFile, err := os.Open("../testdata/smart-fail2.json") +// require.NoError(t, err) +// defer smartDataFile.Close() +// +// var smartJson collector.SmartInfo +// +// smartDataBytes, err := ioutil.ReadAll(smartDataFile) +// require.NoError(t, err) +// err = json.Unmarshal(smartDataBytes, &smartJson) +// require.NoError(t, err) +// +// //test +// smartMdl := db.Smart{} +// err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) +// +// //assert +// require.NoError(t, err) +// require.Equal(t, "WWN-test", smartMdl.DeviceWWN) +// require.Equal(t, "failed", smartMdl.SmartStatus) +// require.Equal(t, 17, len(smartMdl.Attributes)) +//} +// +//func TestFromCollectorSmartInfo_Nvme(t *testing.T) { +// //setup +// smartDataFile, err := os.Open("../testdata/smart-nvme.json") +// require.NoError(t, err) +// defer smartDataFile.Close() +// +// var smartJson collector.SmartInfo +// +// smartDataBytes, err := ioutil.ReadAll(smartDataFile) +// require.NoError(t, err) +// err = json.Unmarshal(smartDataBytes, &smartJson) +// require.NoError(t, err) +// +// //test +// smartMdl := db.Smart{} +// err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) +// +// //assert +// require.NoError(t, err) +// require.Equal(t, "WWN-test", smartMdl.DeviceWWN) +// require.Equal(t, "passed", smartMdl.SmartStatus) +// require.Equal(t, 0, len(smartMdl.AtaAttributes)) +// require.Equal(t, 16, len(smartMdl.NvmeAttributes)) +// require.Equal(t, 0, len(smartMdl.ScsiAttributes)) +// +// require.Equal(t, 111303174, smartMdl.NvmeAttributes[6].Value) +// require.Equal(t, 83170961, smartMdl.NvmeAttributes[7].Value) +//} +// +//func TestFromCollectorSmartInfo_Scsi(t *testing.T) { +// //setup +// smartDataFile, err := os.Open("../testdata/smart-scsi.json") +// require.NoError(t, err) +// defer smartDataFile.Close() +// +// var smartJson collector.SmartInfo +// +// smartDataBytes, err := ioutil.ReadAll(smartDataFile) +// require.NoError(t, err) +// err = json.Unmarshal(smartDataBytes, &smartJson) +// require.NoError(t, err) +// +// //test +// smartMdl := db.Smart{} +// err = smartMdl.FromCollectorSmartInfo("WWN-test", smartJson) +// +// //assert +// require.NoError(t, err) +// require.Equal(t, "WWN-test", smartMdl.DeviceWWN) +// require.Equal(t, "passed", smartMdl.SmartStatus) +// require.Equal(t, 0, len(smartMdl.AtaAttributes)) +// require.Equal(t, 0, len(smartMdl.NvmeAttributes)) +// require.Equal(t, 13, len(smartMdl.ScsiAttributes)) +// +// require.Equal(t, 56, smartMdl.ScsiAttributes[0].Value) +// require.Equal(t, 300357663, smartMdl.ScsiAttributes[4].Value) //total_errors_corrected +//} diff --git a/webapp/backend/pkg/models/setting.go b/webapp/backend/pkg/models/setting.go new file mode 100644 index 0000000..d9a1d6b --- /dev/null +++ b/webapp/backend/pkg/models/setting.go @@ -0,0 +1,5 @@ +package models + +// Temperature Format +// Date Format +// Device History window diff --git a/webapp/backend/pkg/models/testdata/smart-ata-date.json b/webapp/backend/pkg/models/testdata/smart-ata-date.json new file mode 100644 index 0000000..f654a3a --- /dev/null +++ b/webapp/backend/pkg/models/testdata/smart-ata-date.json @@ -0,0 +1,846 @@ +{ + "json_format_version": [ + 1, + 0 + ], + "smartctl": { + "version": [ + 7, + 0 + ], + "svn_revision": "4883", + "platform_info": "x86_64-linux-4.19.128-flatcar", + "build_info": "(local build)", + "argv": [ + "smartctl", + "-j", + "-a", + "/dev/sdb" + ], + "exit_status": 0 + }, + "device": { + "name": "/dev/sdb", + "info_name": "/dev/sdb [SAT]", + "type": "sat", + "protocol": "ATA" + }, + "model_name": "WDC WD140EDFZ-11A0VA0", + "serial_number": "9RK1XXXX", + "wwn": { + "naa": 5, + "oui": 3274, + "id": 10283057623 + }, + "firmware_version": "81.00A81", + "user_capacity": { + "blocks": 27344764928, + "bytes": 14000519643136 + }, + "logical_block_size": 512, + "physical_block_size": 4096, + "rotation_rate": 5400, + "form_factor": { + "ata_value": 2, + "name": "3.5 inches" + }, + "in_smartctl_database": false, + "ata_version": { + "string": "ACS-2, ATA8-ACS T13/1699-D revision 4", + "major_value": 1020, + "minor_value": 41 + }, + "sata_version": { + "string": "SATA 3.2", + "value": 255 + }, + "interface_speed": { + "max": { + "sata_value": 14, + "string": "6.0 Gb/s", + "units_per_second": 60, + "bits_per_unit": 100000000 + }, + "current": { + "sata_value": 3, + "string": "6.0 Gb/s", + "units_per_second": 60, + "bits_per_unit": 100000000 + } + }, + "local_time": { + "time_t": 1611419146, + "asctime": "Sun Jun 30 00:03:30 2021 UTC" + }, + "smart_status": { + "passed": true + }, + "ata_smart_data": { + "offline_data_collection": { + "status": { + "value": 130, + "string": "was completed without error", + "passed": true + }, + "completion_seconds": 101 + }, + "self_test": { + "status": { + "value": 241, + "string": "in progress, 10% remaining", + "remaining_percent": 10 + }, + "polling_minutes": { + "short": 2, + "extended": 1479 + } + }, + "capabilities": { + "values": [ + 91, + 3 + ], + "exec_offline_immediate_supported": true, + "offline_is_aborted_upon_new_cmd": false, + "offline_surface_scan_supported": true, + "self_tests_supported": true, + "conveyance_self_test_supported": false, + "selective_self_test_supported": true, + "attribute_autosave_enabled": true, + "error_logging_supported": true, + "gp_logging_supported": true + } + }, + "ata_sct_capabilities": { + "value": 61, + "error_recovery_control_supported": true, + "feature_control_supported": true, + "data_table_supported": true + }, + "ata_smart_attributes": { + "revision": 16, + "table": [ + { + "id": 1, + "name": "Raw_Read_Error_Rate", + "value": 100, + "worst": 100, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 11, + "string": "PO-R-- ", + "prefailure": true, + "updated_online": true, + "performance": false, + "error_rate": true, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 2, + "name": "Throughput_Performance", + "value": 135, + "worst": 135, + "thresh": 54, + "when_failed": "", + "flags": { + "value": 4, + "string": "--S--- ", + "prefailure": false, + "updated_online": false, + "performance": true, + "error_rate": false, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 108, + "string": "108" + } + }, + { + "id": 3, + "name": "Spin_Up_Time", + "value": 81, + "worst": 81, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 7, + "string": "POS--- ", + "prefailure": true, + "updated_online": true, + "performance": true, + "error_rate": false, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 30089675132, + "string": "380 (Average 380)" + } + }, + { + "id": 4, + "name": "Start_Stop_Count", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 18, + "string": "-O--C- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 9, + "string": "9" + } + }, + { + "id": 5, + "name": "Reallocated_Sector_Ct", + "value": 100, + "worst": 100, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 51, + "string": "PO--CK ", + "prefailure": true, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 7, + "name": "Seek_Error_Rate", + "value": 100, + "worst": 100, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 10, + "string": "-O-R-- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": true, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 8, + "name": "Seek_Time_Performance", + "value": 133, + "worst": 133, + "thresh": 20, + "when_failed": "", + "flags": { + "value": 4, + "string": "--S--- ", + "prefailure": false, + "updated_online": false, + "performance": true, + "error_rate": false, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 18, + "string": "18" + } + }, + { + "id": 9, + "name": "Power_On_Hours", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 18, + "string": "-O--C- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 1730, + "string": "1730" + } + }, + { + "id": 10, + "name": "Spin_Retry_Count", + "value": 100, + "worst": 100, + "thresh": 1, + "when_failed": "", + "flags": { + "value": 18, + "string": "-O--C- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 12, + "name": "Power_Cycle_Count", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 9, + "string": "9" + } + }, + { + "id": 22, + "name": "Unknown_Attribute", + "value": 100, + "worst": 100, + "thresh": 25, + "when_failed": "", + "flags": { + "value": 35, + "string": "PO---K ", + "prefailure": true, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": false, + "auto_keep": true + }, + "raw": { + "value": 100, + "string": "100" + } + }, + { + "id": 192, + "name": "Power-Off_Retract_Count", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 329, + "string": "329" + } + }, + { + "id": 193, + "name": "Load_Cycle_Count", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 18, + "string": "-O--C- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": false + }, + "raw": { + "value": 329, + "string": "329" + } + }, + { + "id": 194, + "name": "Temperature_Celsius", + "value": 51, + "worst": 51, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 2, + "string": "-O---- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 163210330144, + "string": "32 (Min/Max 24/38)" + } + }, + { + "id": 196, + "name": "Reallocated_Event_Count", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 50, + "string": "-O--CK ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": true, + "auto_keep": true + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 197, + "name": "Current_Pending_Sector", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 34, + "string": "-O---K ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": false, + "event_count": false, + "auto_keep": true + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 198, + "name": "Offline_Uncorrectable", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 8, + "string": "---R-- ", + "prefailure": false, + "updated_online": false, + "performance": false, + "error_rate": true, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 0, + "string": "0" + } + }, + { + "id": 199, + "name": "UDMA_CRC_Error_Count", + "value": 100, + "worst": 100, + "thresh": 0, + "when_failed": "", + "flags": { + "value": 10, + "string": "-O-R-- ", + "prefailure": false, + "updated_online": true, + "performance": false, + "error_rate": true, + "event_count": false, + "auto_keep": false + }, + "raw": { + "value": 0, + "string": "0" + } + } + ] + }, + "power_on_time": { + "hours": 1730 + }, + "power_cycle_count": 9, + "temperature": { + "current": 32 + }, + "ata_smart_error_log": { + "summary": { + "revision": 1, + "count": 0 + } + }, + "ata_smart_self_test_log": { + "standard": { + "revision": 1, + "table": [ + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1708 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1684 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1661 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1636 + }, + { + "type": { + "value": 2, + "string": "Extended offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1624 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1541 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1517 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1493 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1469 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1445 + }, + { + "type": { + "value": 2, + "string": "Extended offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1439 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1373 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1349 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1325 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1301 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1277 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1253 + }, + { + "type": { + "value": 2, + "string": "Extended offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1252 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1205 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1181 + }, + { + "type": { + "value": 1, + "string": "Short offline" + }, + "status": { + "value": 0, + "string": "Completed without error", + "passed": true + }, + "lifetime_hours": 1157 + } + ], + "count": 21, + "error_count_total": 0, + "error_count_outdated": 0 + } + }, + "ata_smart_selective_self_test_log": { + "revision": 1, + "table": [ + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + }, + { + "lba_min": 0, + "lba_max": 0, + "status": { + "value": 241, + "string": "Not_testing" + } + } + ], + "flags": { + "value": 0, + "remainder_scan_enabled": false + }, + "power_up_scan_resume_minutes": 0 + } +} diff --git a/webapp/backend/pkg/web/handler/get_device_details.go b/webapp/backend/pkg/web/handler/get_device_details.go index 4bee8fc..5807292 100644 --- a/webapp/backend/pkg/web/handler/get_device_details.go +++ b/webapp/backend/pkg/web/handler/get_device_details.go @@ -1,44 +1,25 @@ package handler import ( + "github.com/analogj/scrutiny/webapp/backend/pkg/database" "github.com/analogj/scrutiny/webapp/backend/pkg/metadata" - dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "gorm.io/gorm" "net/http" ) func GetDeviceDetails(c *gin.Context) { - db := c.MustGet("DB").(*gorm.DB) logger := c.MustGet("LOGGER").(logrus.FieldLogger) - device := dbModels.Device{} - - if err := db.Preload("SmartResults", func(db *gorm.DB) *gorm.DB { - return db.Order("smarts.created_at DESC").Limit(40) - }). - Preload("SmartResults.AtaAttributes"). - Preload("SmartResults.NvmeAttributes"). - Preload("SmartResults.ScsiAttributes"). - Where("wwn = ?", c.Param("wwn")). - First(&device).Error; err != nil { + deviceRepo := c.MustGet("DEVICE_REPOSITORY").(database.DeviceRepo) + device, err := deviceRepo.GetDeviceDetails(c, c.Param("wwn")) + if err != nil { logger.Errorln("An error occurred while retrieving device details", err) c.JSON(http.StatusInternalServerError, gin.H{"success": false}) return } - if err := device.SquashHistory(); err != nil { - logger.Errorln("An error occurred while squashing device history", err) - c.JSON(http.StatusInternalServerError, gin.H{"success": false}) - return - } - - if err := device.ApplyMetadataRules(); err != nil { - logger.Errorln("An error occurred while applying scrutiny thresholds & rules", err) - c.JSON(http.StatusInternalServerError, gin.H{"success": false}) - return - } + smartResults, err := deviceRepo.GetSmartAttributeHistory(c, c.Param("wwn"), "", nil) var deviceMetadata interface{} if device.IsAta() { @@ -49,5 +30,5 @@ func GetDeviceDetails(c *gin.Context) { deviceMetadata = metadata.ScsiMetadata } - c.JSON(http.StatusOK, gin.H{"success": true, "data": device, "metadata": deviceMetadata}) + c.JSON(http.StatusOK, gin.H{"success": true, "data": map[string]interface{}{"device": device, "smart_results": smartResults}, "metadata": deviceMetadata}) } diff --git a/webapp/backend/pkg/web/handler/get_devices_summary.go b/webapp/backend/pkg/web/handler/get_devices_summary.go index b0c9c1c..8eb392f 100644 --- a/webapp/backend/pkg/web/handler/get_devices_summary.go +++ b/webapp/backend/pkg/web/handler/get_devices_summary.go @@ -1,31 +1,28 @@ package handler import ( - dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" + "github.com/analogj/scrutiny/webapp/backend/pkg/database" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "gorm.io/gorm" "net/http" ) func GetDevicesSummary(c *gin.Context) { - db := c.MustGet("DB").(*gorm.DB) logger := c.MustGet("LOGGER").(logrus.FieldLogger) - devices := []dbModels.Device{} + deviceRepo := c.MustGet("DEVICE_REPOSITORY").(database.DeviceRepo) - //We need the last x (for now all) Smart objects for each Device, so that we can graph Temperature - //We also need the last - if err := db.Preload("SmartResults", func(db *gorm.DB) *gorm.DB { - return db.Order("smarts.created_at DESC") //OLD: .Limit(devicesCount) - }). - Find(&devices).Error; err != nil { - logger.Errorln("Could not get device summary from DB", err) + summary, err := deviceRepo.GetSummary(c) + if err != nil { + logger.Errorln("An error occurred while retrieving device summary", err) c.JSON(http.StatusInternalServerError, gin.H{"success": false}) return } c.JSON(http.StatusOK, gin.H{ "success": true, - "data": devices, + "data": map[string]interface{}{ + "summary": summary, + //"temperature": tem + }, }) } diff --git a/webapp/backend/pkg/web/handler/register_devices.go b/webapp/backend/pkg/web/handler/register_devices.go index 746278a..e1ddf95 100644 --- a/webapp/backend/pkg/web/handler/register_devices.go +++ b/webapp/backend/pkg/web/handler/register_devices.go @@ -1,22 +1,20 @@ package handler import ( - dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" + "github.com/analogj/scrutiny/webapp/backend/pkg/database" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" "github.com/gin-gonic/gin" - "gorm.io/gorm" - "gorm.io/gorm/clause" - "github.com/sirupsen/logrus" "net/http" ) // register devices that are detected by various collectors. -// This function is run everytime a collector is about to start a run. It can be used to update device data. +// This function is run everytime a collector is about to start a run. It can be used to update device metadata. func RegisterDevices(c *gin.Context) { - db := c.MustGet("DB").(*gorm.DB) + deviceRepo := c.MustGet("DEVICE_REPOSITORY").(database.DeviceRepo) logger := c.MustGet("LOGGER").(logrus.FieldLogger) - var collectorDeviceWrapper dbModels.DeviceWrapper + var collectorDeviceWrapper models.DeviceWrapper err := c.BindJSON(&collectorDeviceWrapper) if err != nil { logger.Errorln("Cannot parse detected devices", err) @@ -28,11 +26,7 @@ func RegisterDevices(c *gin.Context) { for _, dev := range collectorDeviceWrapper.Data { //insert devices into DB (and update specified columns if device is already registered) // update device fields that may change: (DeviceType, HostID) - if err := db.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "wwn"}}, - DoUpdates: clause.AssignmentColumns([]string{"host_id", "device_name", "device_type"}), - }).Create(&dev).Error; err != nil { - + if err := deviceRepo.RegisterDevice(c, dev); err != nil { errs = append(errs, err) } } @@ -44,7 +38,7 @@ func RegisterDevices(c *gin.Context) { }) return } else { - c.JSON(http.StatusOK, dbModels.DeviceWrapper{ + c.JSON(http.StatusOK, models.DeviceWrapper{ Success: true, Data: collectorDeviceWrapper.Data, }) diff --git a/webapp/backend/pkg/web/handler/send_test_notification.go b/webapp/backend/pkg/web/handler/send_test_notification.go index 52ba8f5..07a1d6c 100644 --- a/webapp/backend/pkg/web/handler/send_test_notification.go +++ b/webapp/backend/pkg/web/handler/send_test_notification.go @@ -1,8 +1,9 @@ package handler import ( + "github.com/analogj/scrutiny/webapp/backend/pkg" "github.com/analogj/scrutiny/webapp/backend/pkg/config" - dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" "github.com/analogj/scrutiny/webapp/backend/pkg/notify" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" @@ -20,7 +21,7 @@ func SendTestNotification(c *gin.Context) { Payload: notify.Payload{ FailureType: "EmailTest", DeviceSerial: "FAKEWDDJ324KSO", - DeviceType: dbModels.DeviceProtocolAta, + DeviceType: pkg.DeviceProtocolAta, DeviceName: "/dev/sda", Test: true, }, @@ -33,7 +34,7 @@ func SendTestNotification(c *gin.Context) { "errors": []string{err.Error()}, }) } else { - c.JSON(http.StatusOK, dbModels.DeviceWrapper{ + c.JSON(http.StatusOK, models.DeviceWrapper{ Success: true, }) } diff --git a/webapp/backend/pkg/web/handler/upload_device_metrics.go b/webapp/backend/pkg/web/handler/upload_device_metrics.go index 949116a..5abd134 100644 --- a/webapp/backend/pkg/web/handler/upload_device_metrics.go +++ b/webapp/backend/pkg/web/handler/upload_device_metrics.go @@ -1,20 +1,24 @@ package handler import ( + "github.com/analogj/scrutiny/webapp/backend/pkg" "github.com/analogj/scrutiny/webapp/backend/pkg/config" + "github.com/analogj/scrutiny/webapp/backend/pkg/database" "github.com/analogj/scrutiny/webapp/backend/pkg/models/collector" - dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" "github.com/analogj/scrutiny/webapp/backend/pkg/notify" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "gorm.io/gorm" "net/http" ) func UploadDeviceMetrics(c *gin.Context) { - db := c.MustGet("DB").(*gorm.DB) + //db := c.MustGet("DB").(*gorm.DB) logger := c.MustGet("LOGGER").(logrus.FieldLogger) appConfig := c.MustGet("CONFIG").(config.Interface) + //influxWriteDb := c.MustGet("INFLUXDB_WRITE").(*api.WriteAPIBlocking) + deviceRepo := c.MustGet("DEVICE_REPOSITORY").(database.DeviceRepo) + + //appConfig := c.MustGet("CONFIG").(config.Interface) var collectorSmartData collector.SmartInfo err := c.BindJSON(&collectorSmartData) @@ -25,39 +29,39 @@ func UploadDeviceMetrics(c *gin.Context) { } //update the device information if necessary - var device dbModels.Device - db.Where("wwn = ?", c.Param("wwn")).First(&device) - device.UpdateFromCollectorSmartInfo(collectorSmartData) - if err := db.Model(&device).Updates(device).Error; err != nil { + updatedDevice, err := deviceRepo.UpdateDevice(c, c.Param("wwn"), collectorSmartData) + if err != nil { logger.Errorln("An error occurred while updating device data from smartctl metrics", err) c.JSON(http.StatusInternalServerError, gin.H{"success": false}) return } // insert smart info - deviceSmartData := dbModels.Smart{} - err = deviceSmartData.FromCollectorSmartInfo(c.Param("wwn"), collectorSmartData) + _, err = deviceRepo.SaveSmartAttributes(c, c.Param("wwn"), collectorSmartData) if err != nil { - logger.Errorln("Could not process SMART metrics", err) + logger.Errorln("An error occurred while saving smartctl metrics", err) c.JSON(http.StatusInternalServerError, gin.H{"success": false}) return } - if err := db.Create(&deviceSmartData).Error; err != nil { - logger.Errorln("An error occurred while saving smartctl metrics", err) + + // save smart temperature data (ignore failures) + err = deviceRepo.SaveSmartTemperature(c, c.Param("wwn"), updatedDevice.DeviceProtocol, collectorSmartData) + if err != nil { + logger.Errorln("An error occurred while saving smartctl temp data", err) c.JSON(http.StatusInternalServerError, gin.H{"success": false}) return } //check for error - if deviceSmartData.SmartStatus == dbModels.SmartStatusFailed { + if updatedDevice.DeviceStatus != pkg.DeviceStatusPassed { //send notifications testNotify := notify.Notify{ Config: appConfig, Payload: notify.Payload{ FailureType: notify.NotifyFailureTypeSmartFailure, - DeviceName: device.DeviceName, - DeviceType: device.DeviceProtocol, - DeviceSerial: device.SerialNumber, + DeviceName: updatedDevice.DeviceName, + DeviceType: updatedDevice.DeviceProtocol, + DeviceSerial: updatedDevice.SerialNumber, Test: false, }, Logger: logger, diff --git a/webapp/backend/pkg/web/middleware/repository.go b/webapp/backend/pkg/web/middleware/repository.go new file mode 100644 index 0000000..3fe58d2 --- /dev/null +++ b/webapp/backend/pkg/web/middleware/repository.go @@ -0,0 +1,22 @@ +package middleware + +import ( + "github.com/analogj/scrutiny/webapp/backend/pkg/config" + "github.com/analogj/scrutiny/webapp/backend/pkg/database" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" +) + +func RepositoryMiddleware(appConfig config.Interface, globalLogger logrus.FieldLogger) gin.HandlerFunc { + + deviceRepo, err := database.NewScrutinyRepository(appConfig, globalLogger) + if err != nil { + panic(err) + } + + //TODO: determine where we can call defer deviceRepo.Close() + return func(c *gin.Context) { + c.Set("DEVICE_REPOSITORY", deviceRepo) + c.Next() + } +} diff --git a/webapp/backend/pkg/web/middleware/sqlite3.go b/webapp/backend/pkg/web/middleware/sqlite3.go deleted file mode 100644 index 3eeee13..0000000 --- a/webapp/backend/pkg/web/middleware/sqlite3.go +++ /dev/null @@ -1,59 +0,0 @@ -package middleware - -import ( - "fmt" - "github.com/analogj/scrutiny/webapp/backend/pkg/config" - "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" - "gorm.io/driver/sqlite" - "gorm.io/gorm" -) - -func DatabaseMiddleware(appConfig config.Interface, globalLogger logrus.FieldLogger) gin.HandlerFunc { - - //var database *gorm.DB - fmt.Printf("Trying to connect to database stored: %s\n", appConfig.GetString("web.database.location")) - database, err := gorm.Open(sqlite.Open(appConfig.GetString("web.database.location")), &gorm.Config{ - //TODO: figure out how to log database queries again. - //Logger: logger - }) - if err != nil { - panic("Failed to connect to database!") - } - - //database.SetLogger() - database.AutoMigrate(&db.Device{}) - database.AutoMigrate(&db.SelfTest{}) - database.AutoMigrate(&db.Smart{}) - database.AutoMigrate(&db.SmartAtaAttribute{}) - database.AutoMigrate(&db.SmartNvmeAttribute{}) - database.AutoMigrate(&db.SmartScsiAttribute{}) - - //TODO: detrmine where we can call defer database.Close() - return func(c *gin.Context) { - c.Set("DB", database) - c.Next() - } -} - -// GormLogger is a custom logger for Gorm, making it use logrus. -type GormLogger struct{ Logger logrus.FieldLogger } - -// Print handles log events from Gorm for the custom logger. -func (gl *GormLogger) Print(v ...interface{}) { - switch v[0] { - case "sql": - gl.Logger.WithFields( - logrus.Fields{ - "module": "gorm", - "type": "sql", - "rows": v[5], - "src_ref": v[1], - "values": v[4], - }, - ).Debug(v[3]) - case "log": - gl.Logger.WithFields(logrus.Fields{"module": "gorm", "type": "log"}).Print(v[2]) - } -} diff --git a/webapp/backend/pkg/web/server.go b/webapp/backend/pkg/web/server.go index af993e3..c685916 100644 --- a/webapp/backend/pkg/web/server.go +++ b/webapp/backend/pkg/web/server.go @@ -23,7 +23,7 @@ func (ae *AppEngine) Setup(logger logrus.FieldLogger) *gin.Engine { r := gin.New() r.Use(middleware.LoggerMiddleware(logger)) - r.Use(middleware.DatabaseMiddleware(ae.Config, logger)) + r.Use(middleware.RepositoryMiddleware(ae.Config, logger)) r.Use(middleware.ConfigMiddleware(ae.Config)) r.Use(gin.Recovery()) diff --git a/webapp/backend/pkg/web/server_test.go b/webapp/backend/pkg/web/server_test.go index 1b2d87f..01ec527 100644 --- a/webapp/backend/pkg/web/server_test.go +++ b/webapp/backend/pkg/web/server_test.go @@ -3,7 +3,7 @@ package web_test import ( "encoding/json" mock_config "github.com/analogj/scrutiny/webapp/backend/pkg/config/mock" - dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" + "github.com/analogj/scrutiny/webapp/backend/pkg/models" "github.com/analogj/scrutiny/webapp/backend/pkg/web" "github.com/golang/mock/gomock" "github.com/sirupsen/logrus" @@ -319,7 +319,7 @@ func TestGetDevicesSummaryRoute_Nvme(t *testing.T) { req, _ = http.NewRequest("GET", "/api/summary", nil) router.ServeHTTP(sr, req) require.Equal(t, 200, sr.Code) - var device dbModels.DeviceWrapper + var device models.DeviceWrapper json.Unmarshal(sr.Body.Bytes(), &device) //assert 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 2766943..733e2ee 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sda.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sda.ts @@ -1,1479 +1,151 @@ export const sda = { "data": { - "CreatedAt": "2020-08-28T07:55:27.751071002Z", - "UpdatedAt": "2020-09-08T21:39:26.571901-07:00", - "DeletedAt": null, - "wwn": "0x5002538e40a22954", - "device_name": "sda", - "manufacturer": "ATA", - "model_name": "Samsung_SSD_860_EVO_500GB", - "interface_type": "SCSI", - "interface_speed": "", - "host_id": "NAS", - "serial_number": "S3YZNB0KBXXXXXX", - "firmware": "002C", - "rotational_speed": 0, - "capacity": 1024209543168, - "form_factor": "", - "smart_support": false, - "device_protocol": "NVMe", - "device_type": "nvme", - "smart_results": [{ - "ID": 46, - "CreatedAt": "2020-09-08T21:39:26.572596-07:00", - "UpdatedAt": "2020-09-08T21:39:26.572596-07:00", + "device": { + "CreatedAt": "2021-06-24T21:17:31.301226-07:00", + "UpdatedAt": "2021-06-26T14:26:20.856273-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": "2020-06-10T12:01:02Z", "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T05:01:02-07:00", - "smart_status": "passed", + "device_protocol": "NVMe", "temp": 36, "power_on_hours": 2401, "power_cycle_count": 266, - "ata_attributes": [], - "nvme_attributes": [{ - "ID": 113, - "CreatedAt": "2020-09-08T21:39:26.572894-07:00", - "UpdatedAt": "2020-09-08T21:39:26.572894-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 97, - "CreatedAt": "2020-09-07T15:47:21.336744707Z", - "UpdatedAt": "2020-09-07T15:47:21.336744707Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 81, - "CreatedAt": "2020-09-07T15:38:56.633368699Z", - "UpdatedAt": "2020-09-07T15:38:56.633368699Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 65, - "CreatedAt": "2020-09-07T15:26:07.504953448Z", - "UpdatedAt": "2020-09-07T15:26:07.504953448Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 49, - "CreatedAt": "2020-09-07T15:19:17.467897283Z", - "UpdatedAt": "2020-09-07T15:19:17.467897283Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 33, - "CreatedAt": "2020-09-07T15:10:40.246090797Z", - "UpdatedAt": "2020-09-07T15:10:40.246090797Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 17, - "CreatedAt": "2020-09-06T23:14:39.849191275Z", - "UpdatedAt": "2020-09-06T23:14:39.849191275Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 1, - "CreatedAt": "2020-08-28T07:55:27.833308403Z", - "UpdatedAt": "2020-08-28T07:55:27.833308403Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "critical_warning", - "name": "Critical Warning", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 114, - "CreatedAt": "2020-09-08T21:39:26.573359-07:00", - "UpdatedAt": "2020-09-08T21:39:26.573359-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 98, - "CreatedAt": "2020-09-07T15:47:21.336894307Z", - "UpdatedAt": "2020-09-07T15:47:21.336894307Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 82, - "CreatedAt": "2020-09-07T15:38:56.6334864Z", - "UpdatedAt": "2020-09-07T15:38:56.6334864Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 66, - "CreatedAt": "2020-09-07T15:26:07.505094452Z", - "UpdatedAt": "2020-09-07T15:26:07.505094452Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 50, - "CreatedAt": "2020-09-07T15:19:17.468022483Z", - "UpdatedAt": "2020-09-07T15:19:17.468022483Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 34, - "CreatedAt": "2020-09-07T15:10:40.246266999Z", - "UpdatedAt": "2020-09-07T15:10:40.246266999Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 18, - "CreatedAt": "2020-09-06T23:14:39.849315479Z", - "UpdatedAt": "2020-09-06T23:14:39.849315479Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 2, - "CreatedAt": "2020-08-28T07:55:27.833462173Z", - "UpdatedAt": "2020-08-28T07:55:27.833462173Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "temperature", - "name": "Temperature", - "value": 36, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 115, - "CreatedAt": "2020-09-08T21:39:26.573466-07:00", - "UpdatedAt": "2020-09-08T21:39:26.573466-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 99, - "CreatedAt": "2020-09-07T15:47:21.336981607Z", - "UpdatedAt": "2020-09-07T15:47:21.336981607Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0 - }, { - "ID": 83, - "CreatedAt": "2020-09-07T15:38:56.6335637Z", - "UpdatedAt": "2020-09-07T15:38:56.6335637Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0 - }, { - "ID": 67, - "CreatedAt": "2020-09-07T15:26:07.505182255Z", - "UpdatedAt": "2020-09-07T15:26:07.505182255Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0 - }, { - "ID": 51, - "CreatedAt": "2020-09-07T15:19:17.468100282Z", - "UpdatedAt": "2020-09-07T15:19:17.468100282Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0 - }, { - "ID": 35, - "CreatedAt": "2020-09-07T15:10:40.246339099Z", - "UpdatedAt": "2020-09-07T15:10:40.246339099Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0 - }, { - "ID": 19, - "CreatedAt": "2020-09-06T23:14:39.849394281Z", - "UpdatedAt": "2020-09-06T23:14:39.849394281Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0 - }, { - "ID": 3, - "CreatedAt": "2020-08-28T07:55:27.833551437Z", - "UpdatedAt": "2020-08-28T07:55:27.833551437Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "available_spare", - "name": "Available Spare", - "value": 100, - "thresh": 10, - "transformed_value": 0 - }] - }, { - "ID": 116, - "CreatedAt": "2020-09-08T21:39:26.57354-07:00", - "UpdatedAt": "2020-09-08T21:39:26.57354-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 100, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 100, - "CreatedAt": "2020-09-07T15:47:21.337060308Z", - "UpdatedAt": "2020-09-07T15:47:21.337060308Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 100, - "transformed_value": 0 - }, { - "ID": 84, - "CreatedAt": "2020-09-07T15:38:56.633637401Z", - "UpdatedAt": "2020-09-07T15:38:56.633637401Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 100, - "transformed_value": 0 - }, { - "ID": 68, - "CreatedAt": "2020-09-07T15:26:07.505262357Z", - "UpdatedAt": "2020-09-07T15:26:07.505262357Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 100, - "transformed_value": 0 - }, { - "ID": 52, - "CreatedAt": "2020-09-07T15:19:17.468187982Z", - "UpdatedAt": "2020-09-07T15:19:17.468187982Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 100, - "transformed_value": 0 - }, { - "ID": 36, - "CreatedAt": "2020-09-07T15:10:40.2464335Z", - "UpdatedAt": "2020-09-07T15:10:40.2464335Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 100, - "transformed_value": 0 - }, { - "ID": 20, - "CreatedAt": "2020-09-06T23:14:39.849473683Z", - "UpdatedAt": "2020-09-06T23:14:39.849473683Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 100, - "transformed_value": 0 - }, { - "ID": 4, - "CreatedAt": "2020-08-28T07:55:27.833639555Z", - "UpdatedAt": "2020-08-28T07:55:27.833639555Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "percentage_used", - "name": "Percentage Used", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 117, - "CreatedAt": "2020-09-08T21:39:26.573622-07:00", - "UpdatedAt": "2020-09-08T21:39:26.573622-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 101, - "CreatedAt": "2020-09-07T15:47:21.337139008Z", - "UpdatedAt": "2020-09-07T15:47:21.337139008Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 85, - "CreatedAt": "2020-09-07T15:38:56.633701001Z", - "UpdatedAt": "2020-09-07T15:38:56.633701001Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 69, - "CreatedAt": "2020-09-07T15:26:07.505347059Z", - "UpdatedAt": "2020-09-07T15:26:07.505347059Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 53, - "CreatedAt": "2020-09-07T15:19:17.468256482Z", - "UpdatedAt": "2020-09-07T15:19:17.468256482Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 37, - "CreatedAt": "2020-09-07T15:10:40.2465052Z", - "UpdatedAt": "2020-09-07T15:10:40.2465052Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 21, - "CreatedAt": "2020-09-06T23:14:39.849535985Z", - "UpdatedAt": "2020-09-06T23:14:39.849535985Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 5, - "CreatedAt": "2020-08-28T07:55:27.833723448Z", - "UpdatedAt": "2020-08-28T07:55:27.833723448Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "data_units_read", - "name": "Data Units Read", - "value": 9511859, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 118, - "CreatedAt": "2020-09-08T21:39:26.57369-07:00", - "UpdatedAt": "2020-09-08T21:39:26.57369-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 102, - "CreatedAt": "2020-09-07T15:47:21.337239108Z", - "UpdatedAt": "2020-09-07T15:47:21.337239108Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 86, - "CreatedAt": "2020-09-07T15:38:56.633767202Z", - "UpdatedAt": "2020-09-07T15:38:56.633767202Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 70, - "CreatedAt": "2020-09-07T15:26:07.505469162Z", - "UpdatedAt": "2020-09-07T15:26:07.505469162Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 54, - "CreatedAt": "2020-09-07T15:19:17.468321982Z", - "UpdatedAt": "2020-09-07T15:19:17.468321982Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 38, - "CreatedAt": "2020-09-07T15:10:40.246568201Z", - "UpdatedAt": "2020-09-07T15:10:40.246568201Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 22, - "CreatedAt": "2020-09-06T23:14:39.849595287Z", - "UpdatedAt": "2020-09-06T23:14:39.849595287Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 6, - "CreatedAt": "2020-08-28T07:55:27.833814267Z", - "UpdatedAt": "2020-08-28T07:55:27.833814267Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "data_units_written", - "name": "Data Units Written", - "value": 7773431, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 119, - "CreatedAt": "2020-09-08T21:39:26.573761-07:00", - "UpdatedAt": "2020-09-08T21:39:26.573761-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 103, - "CreatedAt": "2020-09-07T15:47:21.337318208Z", - "UpdatedAt": "2020-09-07T15:47:21.337318208Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 87, - "CreatedAt": "2020-09-07T15:38:56.633832703Z", - "UpdatedAt": "2020-09-07T15:38:56.633832703Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 71, - "CreatedAt": "2020-09-07T15:26:07.505549465Z", - "UpdatedAt": "2020-09-07T15:26:07.505549465Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 55, - "CreatedAt": "2020-09-07T15:19:17.468389981Z", - "UpdatedAt": "2020-09-07T15:19:17.468389981Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 39, - "CreatedAt": "2020-09-07T15:10:40.246645901Z", - "UpdatedAt": "2020-09-07T15:10:40.246645901Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 23, - "CreatedAt": "2020-09-06T23:14:39.849654489Z", - "UpdatedAt": "2020-09-06T23:14:39.849654489Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 7, - "CreatedAt": "2020-08-28T07:55:27.833887571Z", - "UpdatedAt": "2020-08-28T07:55:27.833887571Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "host_reads", - "name": "Host Reads", - "value": 111303174, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 120, - "CreatedAt": "2020-09-08T21:39:26.573834-07:00", - "UpdatedAt": "2020-09-08T21:39:26.573834-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 104, - "CreatedAt": "2020-09-07T15:47:21.337427308Z", - "UpdatedAt": "2020-09-07T15:47:21.337427308Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 88, - "CreatedAt": "2020-09-07T15:38:56.633900603Z", - "UpdatedAt": "2020-09-07T15:38:56.633900603Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 72, - "CreatedAt": "2020-09-07T15:26:07.505627267Z", - "UpdatedAt": "2020-09-07T15:26:07.505627267Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 56, - "CreatedAt": "2020-09-07T15:19:17.468456681Z", - "UpdatedAt": "2020-09-07T15:19:17.468456681Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 40, - "CreatedAt": "2020-09-07T15:10:40.246709102Z", - "UpdatedAt": "2020-09-07T15:10:40.246709102Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 24, - "CreatedAt": "2020-09-06T23:14:39.849714291Z", - "UpdatedAt": "2020-09-06T23:14:39.849714291Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 8, - "CreatedAt": "2020-08-28T07:55:27.833973719Z", - "UpdatedAt": "2020-08-28T07:55:27.833973719Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "host_writes", - "name": "Host Writes", - "value": 83170961, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 121, - "CreatedAt": "2020-09-08T21:39:26.5739-07:00", - "UpdatedAt": "2020-09-08T21:39:26.5739-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 105, - "CreatedAt": "2020-09-07T15:47:21.337516009Z", - "UpdatedAt": "2020-09-07T15:47:21.337516009Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 89, - "CreatedAt": "2020-09-07T15:38:56.633969604Z", - "UpdatedAt": "2020-09-07T15:38:56.633969604Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 73, - "CreatedAt": "2020-09-07T15:26:07.505724769Z", - "UpdatedAt": "2020-09-07T15:26:07.505724769Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 57, - "CreatedAt": "2020-09-07T15:19:17.468521581Z", - "UpdatedAt": "2020-09-07T15:19:17.468521581Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 41, - "CreatedAt": "2020-09-07T15:10:40.246774002Z", - "UpdatedAt": "2020-09-07T15:10:40.246774002Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 25, - "CreatedAt": "2020-09-06T23:14:39.849784693Z", - "UpdatedAt": "2020-09-06T23:14:39.849784693Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "controller_busy_time", - "name": "Controller Busy Time", - "value": 3060, - "thresh": 0, + "attrs": { + "available_spare": { + "attribute_id": "available_spare", + "name": "Available Spare", + "value": 100, + "thresh": 10, "transformed_value": 0 - }, { - "ID": 9, - "CreatedAt": "2020-08-28T07:55:27.834051665Z", - "UpdatedAt": "2020-08-28T07:55:27.834051665Z", - "DeletedAt": null, - "smart_id": 4, + }, + "controller_busy_time": { "attribute_id": "controller_busy_time", "name": "Controller Busy Time", "value": 3060, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 122, - "CreatedAt": "2020-09-08T21:39:26.573967-07:00", - "UpdatedAt": "2020-09-08T21:39:26.573967-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 106, - "CreatedAt": "2020-09-07T15:47:21.337609809Z", - "UpdatedAt": "2020-09-07T15:47:21.337609809Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 90, - "CreatedAt": "2020-09-07T15:38:56.634034304Z", - "UpdatedAt": "2020-09-07T15:38:56.634034304Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 74, - "CreatedAt": "2020-09-07T15:26:07.505806272Z", - "UpdatedAt": "2020-09-07T15:26:07.505806272Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 58, - "CreatedAt": "2020-09-07T15:19:17.468586181Z", - "UpdatedAt": "2020-09-07T15:19:17.468586181Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 42, - "CreatedAt": "2020-09-07T15:10:40.246861903Z", - "UpdatedAt": "2020-09-07T15:10:40.246861903Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 26, - "CreatedAt": "2020-09-06T23:14:39.849849495Z", - "UpdatedAt": "2020-09-06T23:14:39.849849495Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 10, - "CreatedAt": "2020-08-28T07:55:27.834128174Z", - "UpdatedAt": "2020-08-28T07:55:27.834128174Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "power_cycles", - "name": "Power Cycles", - "value": 266, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 123, - "CreatedAt": "2020-09-08T21:39:26.57404-07:00", - "UpdatedAt": "2020-09-08T21:39:26.57404-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 107, - "CreatedAt": "2020-09-07T15:47:21.337689109Z", - "UpdatedAt": "2020-09-07T15:47:21.337689109Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 91, - "CreatedAt": "2020-09-07T15:38:56.634101905Z", - "UpdatedAt": "2020-09-07T15:38:56.634101905Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 75, - "CreatedAt": "2020-09-07T15:26:07.505880974Z", - "UpdatedAt": "2020-09-07T15:26:07.505880974Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 59, - "CreatedAt": "2020-09-07T15:19:17.468654081Z", - "UpdatedAt": "2020-09-07T15:19:17.468654081Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 43, - "CreatedAt": "2020-09-07T15:10:40.246931403Z", - "UpdatedAt": "2020-09-07T15:10:40.246931403Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 27, - "CreatedAt": "2020-09-06T23:14:39.849908596Z", - "UpdatedAt": "2020-09-06T23:14:39.849908596Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 11, - "CreatedAt": "2020-08-28T07:55:27.834210433Z", - "UpdatedAt": "2020-08-28T07:55:27.834210433Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "power_on_hours", - "name": "Power on Hours", - "value": 2401, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 124, - "CreatedAt": "2020-09-08T21:39:26.574108-07:00", - "UpdatedAt": "2020-09-08T21:39:26.574108-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 108, - "CreatedAt": "2020-09-07T15:47:21.337764809Z", - "UpdatedAt": "2020-09-07T15:47:21.337764809Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 92, - "CreatedAt": "2020-09-07T15:38:56.634171906Z", - "UpdatedAt": "2020-09-07T15:38:56.634171906Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 76, - "CreatedAt": "2020-09-07T15:26:07.505955776Z", - "UpdatedAt": "2020-09-07T15:26:07.505955776Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 60, - "CreatedAt": "2020-09-07T15:19:17.46871948Z", - "UpdatedAt": "2020-09-07T15:19:17.46871948Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 44, - "CreatedAt": "2020-09-07T15:10:40.247002504Z", - "UpdatedAt": "2020-09-07T15:10:40.247002504Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 28, - "CreatedAt": "2020-09-06T23:14:39.849968798Z", - "UpdatedAt": "2020-09-06T23:14:39.849968798Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 12, - "CreatedAt": "2020-08-28T07:55:27.834292136Z", - "UpdatedAt": "2020-08-28T07:55:27.834292136Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "unsafe_shutdowns", - "name": "Unsafe Shutdowns", - "value": 43, - "thresh": 0, + "thresh": -1, "transformed_value": 0 - }] - }, { - "ID": 125, - "CreatedAt": "2020-09-08T21:39:26.574178-07:00", - "UpdatedAt": "2020-09-08T21:39:26.574178-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "media_errors", - "name": "Media Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 109, - "CreatedAt": "2020-09-07T15:47:21.337839409Z", - "UpdatedAt": "2020-09-07T15:47:21.337839409Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "media_errors", - "name": "Media Errors", + }, + "critical_comp_time": { + "attribute_id": "critical_comp_time", + "name": "Critical CompTime", "value": 0, - "thresh": 0, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 93, - "CreatedAt": "2020-09-07T15:38:56.634234206Z", - "UpdatedAt": "2020-09-07T15:38:56.634234206Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "media_errors", - "name": "Media Errors", + }, + "critical_warning": { + "attribute_id": "critical_warning", + "name": "Critical Warning", "value": 0, "thresh": 0, "transformed_value": 0 - }, { - "ID": 77, - "CreatedAt": "2020-09-07T15:26:07.506062879Z", - "UpdatedAt": "2020-09-07T15:26:07.506062879Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "media_errors", - "name": "Media Errors", - "value": 0, - "thresh": 0, + }, + "data_units_read": { + "attribute_id": "data_units_read", + "name": "Data Units Read", + "value": 9511859, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 61, - "CreatedAt": "2020-09-07T15:19:17.46878678Z", - "UpdatedAt": "2020-09-07T15:19:17.46878678Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "media_errors", - "name": "Media Errors", - "value": 0, - "thresh": 0, + }, + "data_units_written": { + "attribute_id": "data_units_written", + "name": "Data Units Written", + "value": 7773431, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 45, - "CreatedAt": "2020-09-07T15:10:40.247110105Z", - "UpdatedAt": "2020-09-07T15:10:40.247110105Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "media_errors", - "name": "Media Errors", - "value": 0, - "thresh": 0, + }, + "host_reads": { + "attribute_id": "host_reads", + "name": "Host Reads", + "value": 111303174, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 29, - "CreatedAt": "2020-09-06T23:14:39.850046301Z", - "UpdatedAt": "2020-09-06T23:14:39.850046301Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "media_errors", - "name": "Media Errors", - "value": 0, - "thresh": 0, + }, + "host_writes": { + "attribute_id": "host_writes", + "name": "Host Writes", + "value": 83170961, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 13, - "CreatedAt": "2020-08-28T07:55:27.834373811Z", - "UpdatedAt": "2020-08-28T07:55:27.834373811Z", - "DeletedAt": null, - "smart_id": 4, + }, + "media_errors": { "attribute_id": "media_errors", "name": "Media Errors", "value": 0, "thresh": 0, "transformed_value": 0 - }] - }, { - "ID": 126, - "CreatedAt": "2020-09-08T21:39:26.574242-07:00", - "UpdatedAt": "2020-09-08T21:39:26.574242-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 110, - "CreatedAt": "2020-09-07T15:47:21.337915109Z", - "UpdatedAt": "2020-09-07T15:47:21.337915109Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 94, - "CreatedAt": "2020-09-07T15:38:56.634303007Z", - "UpdatedAt": "2020-09-07T15:38:56.634303007Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 78, - "CreatedAt": "2020-09-07T15:26:07.506140681Z", - "UpdatedAt": "2020-09-07T15:26:07.506140681Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 62, - "CreatedAt": "2020-09-07T15:19:17.46885548Z", - "UpdatedAt": "2020-09-07T15:19:17.46885548Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 46, - "CreatedAt": "2020-09-07T15:10:40.247212006Z", - "UpdatedAt": "2020-09-07T15:10:40.247212006Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 30, - "CreatedAt": "2020-09-06T23:14:39.850150504Z", - "UpdatedAt": "2020-09-06T23:14:39.850150504Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "num_err_log_entries", - "name": "Numb Err Log Entries", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 14, - "CreatedAt": "2020-08-28T07:55:27.834456493Z", - "UpdatedAt": "2020-08-28T07:55:27.834456493Z", - "DeletedAt": null, - "smart_id": 4, + }, + "num_err_log_entries": { "attribute_id": "num_err_log_entries", "name": "Numb Err Log Entries", "value": 0, "thresh": 0, "transformed_value": 0 - }] - }, { - "ID": 127, - "CreatedAt": "2020-09-08T21:39:26.574309-07:00", - "UpdatedAt": "2020-09-08T21:39:26.574309-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 111, - "CreatedAt": "2020-09-07T15:47:21.33801171Z", - "UpdatedAt": "2020-09-07T15:47:21.33801171Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 95, - "CreatedAt": "2020-09-07T15:38:56.634377407Z", - "UpdatedAt": "2020-09-07T15:38:56.634377407Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", + }, + "percentage_used": { + "attribute_id": "percentage_used", + "name": "Percentage Used", "value": 0, - "thresh": 0, + "thresh": 100, "transformed_value": 0 - }, { - "ID": 79, - "CreatedAt": "2020-09-07T15:26:07.506214683Z", - "UpdatedAt": "2020-09-07T15:26:07.506214683Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", - "value": 0, - "thresh": 0, + }, + "power_cycles": { + "attribute_id": "power_cycles", + "name": "Power Cycles", + "value": 266, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 63, - "CreatedAt": "2020-09-07T15:19:17.468958879Z", - "UpdatedAt": "2020-09-07T15:19:17.468958879Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", - "value": 0, - "thresh": 0, + }, + "power_on_hours": { + "attribute_id": "power_on_hours", + "name": "Power on Hours", + "value": 2401, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 47, - "CreatedAt": "2020-09-07T15:10:40.247310706Z", - "UpdatedAt": "2020-09-07T15:10:40.247310706Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", - "value": 0, - "thresh": 0, + }, + "temperature": { + "attribute_id": "temperature", + "name": "Temperature", + "value": 36, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 31, - "CreatedAt": "2020-09-06T23:14:39.850219706Z", - "UpdatedAt": "2020-09-06T23:14:39.850219706Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "warning_temp_time", - "name": "Warning Temp Time", - "value": 0, - "thresh": 0, + }, + "unsafe_shutdowns": { + "attribute_id": "unsafe_shutdowns", + "name": "Unsafe Shutdowns", + "value": 43, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 15, - "CreatedAt": "2020-08-28T07:55:27.834538882Z", - "UpdatedAt": "2020-08-28T07:55:27.834538882Z", - "DeletedAt": null, - "smart_id": 4, + }, + "warning_temp_time": { "attribute_id": "warning_temp_time", "name": "Warning Temp Time", "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 128, - "CreatedAt": "2020-09-08T21:39:26.574383-07:00", - "UpdatedAt": "2020-09-08T21:39:26.574383-07:00", - "DeletedAt": null, - "smart_id": 46, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 112, - "CreatedAt": "2020-09-07T15:47:21.33808201Z", - "UpdatedAt": "2020-09-07T15:47:21.33808201Z", - "DeletedAt": null, - "smart_id": 40, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 96, - "CreatedAt": "2020-09-07T15:38:56.634438008Z", - "UpdatedAt": "2020-09-07T15:38:56.634438008Z", - "DeletedAt": null, - "smart_id": 34, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 80, - "CreatedAt": "2020-09-07T15:26:07.506290585Z", - "UpdatedAt": "2020-09-07T15:26:07.506290585Z", - "DeletedAt": null, - "smart_id": 28, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 64, - "CreatedAt": "2020-09-07T15:19:17.469037079Z", - "UpdatedAt": "2020-09-07T15:19:17.469037079Z", - "DeletedAt": null, - "smart_id": 22, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 48, - "CreatedAt": "2020-09-07T15:10:40.247471107Z", - "UpdatedAt": "2020-09-07T15:10:40.247471107Z", - "DeletedAt": null, - "smart_id": 16, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 32, - "CreatedAt": "2020-09-06T23:14:39.850278807Z", - "UpdatedAt": "2020-09-06T23:14:39.850278807Z", - "DeletedAt": null, - "smart_id": 10, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 16, - "CreatedAt": "2020-08-28T07:55:27.834645921Z", - "UpdatedAt": "2020-08-28T07:55:27.834645921Z", - "DeletedAt": null, - "smart_id": 4, - "attribute_id": "critical_comp_time", - "name": "Critical CompTime", - "value": 0, - "thresh": 0, + "thresh": -1, "transformed_value": 0 - }] - }], - "scsi_attributes": [] + } + } }] - }, "metadata": { + }, + "metadata": { "available_spare": { "ideal": "high", "critical": true, @@ -1552,7 +224,12 @@ export const sda = { "description": "Contains the number of power-on hours. Power on hours is always logging, even when in low power mode.", "display_type": "" }, - "temperature": {"ideal": "", "critical": false, "description": "", "display_type": ""}, + "temperature": { + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, "unsafe_shutdowns": { "ideal": "", "critical": false, @@ -1565,5 +242,6 @@ export const sda = { "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 e6b3771..e658e79 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sdb.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sdb.ts @@ -1,4406 +1,651 @@ export const sdb = { "data": { - "CreatedAt": "2020-08-28T07:55:27.755292213Z", - "UpdatedAt": "2020-09-08T21:39:26.56453-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264eb01d7", - "device_name": "sdb", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "6.0 Gb/s", - "serial_number": "9RK1XXXXX", - "firmware": "81.00A81", - "rotational_speed": 5400, - "capacity": 14000519643136, - "form_factor": "3.5 inches", - "smart_support": false, - "device_protocol": "ATA", - "device_type": "sat", - "smart_results": [{ - "ID": 44, - "CreatedAt": "2020-09-08T21:39:26.565492-07:00", - "UpdatedAt": "2020-09-08T21:39:26.565492-07:00", + "device": { + "CreatedAt": "2021-06-24T21:17:31.302191-07:00", + "UpdatedAt": "2021-06-27T09:25:21.627183-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": 0 + }, + "smart_results": [{ + "date": "2020-06-21T00:03:30Z", "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-20T17:03:30-07:00", - "smart_status": "passed", + "device_protocol": "ATA", "temp": 32, "power_on_hours": 1730, "power_cycle_count": 9, - "ata_attributes": [{ - "ID": 390, - "CreatedAt": "2020-09-08T21:39:26.565859-07:00", - "UpdatedAt": "2020-09-08T21:39:26.565859-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.034155719633986996, - "history": [{ - "ID": 372, - "CreatedAt": "2020-09-08T21:39:26.554625-07:00", - "UpdatedAt": "2020-09-08T21:39:26.554625-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 337, - "CreatedAt": "2020-09-07T15:47:21.319715469Z", - "UpdatedAt": "2020-09-07T15:47:21.319715469Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 319, - "CreatedAt": "2020-09-07T15:47:21.30624404Z", - "UpdatedAt": "2020-09-07T15:47:21.30624404Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 284, - "CreatedAt": "2020-09-07T15:38:56.621607095Z", - "UpdatedAt": "2020-09-07T15:38:56.621607095Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 266, - "CreatedAt": "2020-09-07T15:38:56.608981483Z", - "UpdatedAt": "2020-09-07T15:38:56.608981483Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 231, - "CreatedAt": "2020-09-07T15:26:07.492775316Z", - "UpdatedAt": "2020-09-07T15:26:07.492775316Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 213, - "CreatedAt": "2020-09-07T15:26:07.479127343Z", - "UpdatedAt": "2020-09-07T15:26:07.479127343Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 178, - "CreatedAt": "2020-09-07T15:19:17.454721127Z", - "UpdatedAt": "2020-09-07T15:19:17.454721127Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 160, - "CreatedAt": "2020-09-07T15:19:17.441278472Z", - "UpdatedAt": "2020-09-07T15:19:17.441278472Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 125, - "CreatedAt": "2020-09-07T15:10:40.234375512Z", - "UpdatedAt": "2020-09-07T15:10:40.234375512Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 107, - "CreatedAt": "2020-09-07T15:10:40.221903021Z", - "UpdatedAt": "2020-09-07T15:10:40.221903021Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 72, - "CreatedAt": "2020-09-06T23:14:39.838774963Z", - "UpdatedAt": "2020-09-06T23:14:39.838774963Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 54, - "CreatedAt": "2020-09-06T23:14:39.828352851Z", - "UpdatedAt": "2020-09-06T23:14:39.828352851Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 19, - "CreatedAt": "2020-08-28T07:55:27.811031219Z", - "UpdatedAt": "2020-08-28T07:55:27.811031219Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 1, - "CreatedAt": "2020-08-28T07:55:27.793568936Z", - "UpdatedAt": "2020-08-28T07:55:27.793568936Z", - "DeletedAt": null, - "smart_id": 1, + "attrs": { + "1": { "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 391, - "CreatedAt": "2020-09-08T21:39:26.566009-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566009-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 373, - "CreatedAt": "2020-09-08T21:39:26.555538-07:00", - "UpdatedAt": "2020-09-08T21:39:26.555538-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 338, - "CreatedAt": "2020-09-07T15:47:21.31987157Z", - "UpdatedAt": "2020-09-07T15:47:21.31987157Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 320, - "CreatedAt": "2020-09-07T15:47:21.30639844Z", - "UpdatedAt": "2020-09-07T15:47:21.30639844Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 285, - "CreatedAt": "2020-09-07T15:38:56.621740196Z", - "UpdatedAt": "2020-09-07T15:38:56.621740196Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 267, - "CreatedAt": "2020-09-07T15:38:56.609155985Z", - "UpdatedAt": "2020-09-07T15:38:56.609155985Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 232, - "CreatedAt": "2020-09-07T15:26:07.49293042Z", - "UpdatedAt": "2020-09-07T15:26:07.49293042Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 214, - "CreatedAt": "2020-09-07T15:26:07.479321549Z", - "UpdatedAt": "2020-09-07T15:26:07.479321549Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 179, - "CreatedAt": "2020-09-07T15:19:17.454872527Z", - "UpdatedAt": "2020-09-07T15:19:17.454872527Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 161, - "CreatedAt": "2020-09-07T15:19:17.441578271Z", - "UpdatedAt": "2020-09-07T15:19:17.441578271Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 126, - "CreatedAt": "2020-09-07T15:10:40.234501713Z", - "UpdatedAt": "2020-09-07T15:10:40.234501713Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 108, - "CreatedAt": "2020-09-07T15:10:40.222051722Z", - "UpdatedAt": "2020-09-07T15:10:40.222051722Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 73, - "CreatedAt": "2020-09-06T23:14:39.838895667Z", - "UpdatedAt": "2020-09-06T23:14:39.838895667Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 55, - "CreatedAt": "2020-09-06T23:14:39.828477555Z", - "UpdatedAt": "2020-09-06T23:14:39.828477555Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 20, - "CreatedAt": "2020-08-28T07:55:27.81120328Z", - "UpdatedAt": "2020-08-28T07:55:27.81120328Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 2, - "CreatedAt": "2020-08-28T07:55:27.793695119Z", - "UpdatedAt": "2020-08-28T07:55:27.793695119Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 135, - "worst": 135, - "thresh": 54, - "raw_value": 108, - "raw_string": "108", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 392, - "CreatedAt": "2020-09-08T21:39:26.566086-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566086-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0, - "status": "warn", - "status_reason": "Observed Failure Rate for Attribute is greater than 10%", - "failure_rate": 0.11452195377351217, - "history": [{ - "ID": 374, - "CreatedAt": "2020-09-08T21:39:26.555647-07:00", - "UpdatedAt": "2020-09-08T21:39:26.555647-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 339, - "CreatedAt": "2020-09-07T15:47:21.31996407Z", - "UpdatedAt": "2020-09-07T15:47:21.31996407Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 321, - "CreatedAt": "2020-09-07T15:47:21.30649104Z", - "UpdatedAt": "2020-09-07T15:47:21.30649104Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 286, - "CreatedAt": "2020-09-07T15:38:56.621825497Z", - "UpdatedAt": "2020-09-07T15:38:56.621825497Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 268, - "CreatedAt": "2020-09-07T15:38:56.609869491Z", - "UpdatedAt": "2020-09-07T15:38:56.609869491Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 233, - "CreatedAt": "2020-09-07T15:26:07.493026823Z", - "UpdatedAt": "2020-09-07T15:26:07.493026823Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 215, - "CreatedAt": "2020-09-07T15:26:07.479457552Z", - "UpdatedAt": "2020-09-07T15:26:07.479457552Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 180, - "CreatedAt": "2020-09-07T15:19:17.454960826Z", - "UpdatedAt": "2020-09-07T15:19:17.454960826Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 162, - "CreatedAt": "2020-09-07T15:19:17.441750771Z", - "UpdatedAt": "2020-09-07T15:19:17.441750771Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 127, - "CreatedAt": "2020-09-07T15:10:40.234580613Z", - "UpdatedAt": "2020-09-07T15:10:40.234580613Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 109, - "CreatedAt": "2020-09-07T15:10:40.222249924Z", - "UpdatedAt": "2020-09-07T15:10:40.222249924Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 74, - "CreatedAt": "2020-09-06T23:14:39.838970169Z", - "UpdatedAt": "2020-09-06T23:14:39.838970169Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 56, - "CreatedAt": "2020-09-06T23:14:39.828556257Z", - "UpdatedAt": "2020-09-06T23:14:39.828556257Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 21, - "CreatedAt": "2020-08-28T07:55:27.811301517Z", - "UpdatedAt": "2020-08-28T07:55:27.811301517Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 3, - "CreatedAt": "2020-08-28T07:55:27.793803735Z", - "UpdatedAt": "2020-08-28T07:55:27.793803735Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 81, - "worst": 81, - "thresh": 1, - "raw_value": 30089675132, - "raw_string": "380 (Average 380)", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 393, - "CreatedAt": "2020-09-08T21:39:26.56616-07:00", - "UpdatedAt": "2020-09-08T21:39:26.56616-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.01989335424860646, - "history": [{ - "ID": 375, - "CreatedAt": "2020-09-08T21:39:26.555728-07:00", - "UpdatedAt": "2020-09-08T21:39:26.555728-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 340, - "CreatedAt": "2020-09-07T15:47:21.32004967Z", - "UpdatedAt": "2020-09-07T15:47:21.32004967Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 322, - "CreatedAt": "2020-09-07T15:47:21.30657324Z", - "UpdatedAt": "2020-09-07T15:47:21.30657324Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 287, - "CreatedAt": "2020-09-07T15:38:56.621906897Z", - "UpdatedAt": "2020-09-07T15:38:56.621906897Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 269, - "CreatedAt": "2020-09-07T15:38:56.609959692Z", - "UpdatedAt": "2020-09-07T15:38:56.609959692Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 234, - "CreatedAt": "2020-09-07T15:26:07.493143826Z", - "UpdatedAt": "2020-09-07T15:26:07.493143826Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 216, - "CreatedAt": "2020-09-07T15:26:07.479584956Z", - "UpdatedAt": "2020-09-07T15:26:07.479584956Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 181, - "CreatedAt": "2020-09-07T15:19:17.455045926Z", - "UpdatedAt": "2020-09-07T15:19:17.455045926Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 163, - "CreatedAt": "2020-09-07T15:19:17.442228869Z", - "UpdatedAt": "2020-09-07T15:19:17.442228869Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 128, - "CreatedAt": "2020-09-07T15:10:40.234652914Z", - "UpdatedAt": "2020-09-07T15:10:40.234652914Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 110, - "CreatedAt": "2020-09-07T15:10:40.222378024Z", - "UpdatedAt": "2020-09-07T15:10:40.222378024Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 75, - "CreatedAt": "2020-09-06T23:14:39.839060472Z", - "UpdatedAt": "2020-09-06T23:14:39.839060472Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 57, - "CreatedAt": "2020-09-06T23:14:39.82862886Z", - "UpdatedAt": "2020-09-06T23:14:39.82862886Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 22, - "CreatedAt": "2020-08-28T07:55:27.811385053Z", - "UpdatedAt": "2020-08-28T07:55:27.811385053Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 4, - "CreatedAt": "2020-08-28T07:55:27.79389462Z", - "UpdatedAt": "2020-08-28T07:55:27.79389462Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 394, - "CreatedAt": "2020-09-08T21:39:26.566242-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566242-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.025169175350572493, - "history": [{ - "ID": 376, - "CreatedAt": "2020-09-08T21:39:26.555865-07:00", - "UpdatedAt": "2020-09-08T21:39:26.555865-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 341, - "CreatedAt": "2020-09-07T15:47:21.32013207Z", - "UpdatedAt": "2020-09-07T15:47:21.32013207Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 323, - "CreatedAt": "2020-09-07T15:47:21.306652041Z", - "UpdatedAt": "2020-09-07T15:47:21.306652041Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 288, - "CreatedAt": "2020-09-07T15:38:56.621982198Z", - "UpdatedAt": "2020-09-07T15:38:56.621982198Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 270, - "CreatedAt": "2020-09-07T15:38:56.610037693Z", - "UpdatedAt": "2020-09-07T15:38:56.610037693Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 235, - "CreatedAt": "2020-09-07T15:26:07.493235628Z", - "UpdatedAt": "2020-09-07T15:26:07.493235628Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 217, - "CreatedAt": "2020-09-07T15:26:07.479976967Z", - "UpdatedAt": "2020-09-07T15:26:07.479976967Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 182, - "CreatedAt": "2020-09-07T15:19:17.455121626Z", - "UpdatedAt": "2020-09-07T15:19:17.455121626Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 164, - "CreatedAt": "2020-09-07T15:19:17.442543768Z", - "UpdatedAt": "2020-09-07T15:19:17.442543768Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 129, - "CreatedAt": "2020-09-07T15:10:40.234722314Z", - "UpdatedAt": "2020-09-07T15:10:40.234722314Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 111, - "CreatedAt": "2020-09-07T15:10:40.222455425Z", - "UpdatedAt": "2020-09-07T15:10:40.222455425Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 76, - "CreatedAt": "2020-09-06T23:14:39.839234477Z", - "UpdatedAt": "2020-09-06T23:14:39.839234477Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 58, - "CreatedAt": "2020-09-06T23:14:39.828698262Z", - "UpdatedAt": "2020-09-06T23:14:39.828698262Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 23, - "CreatedAt": "2020-08-28T07:55:27.811468471Z", - "UpdatedAt": "2020-08-28T07:55:27.811468471Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 5, - "CreatedAt": "2020-08-28T07:55:27.793989682Z", - "UpdatedAt": "2020-08-28T07:55:27.793989682Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 395, - "CreatedAt": "2020-09-08T21:39:26.566309-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566309-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.01087335627722523, - "history": [{ - "ID": 377, - "CreatedAt": "2020-09-08T21:39:26.555941-07:00", - "UpdatedAt": "2020-09-08T21:39:26.555941-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 342, - "CreatedAt": "2020-09-07T15:47:21.320264671Z", - "UpdatedAt": "2020-09-07T15:47:21.320264671Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 324, - "CreatedAt": "2020-09-07T15:47:21.307035342Z", - "UpdatedAt": "2020-09-07T15:47:21.307035342Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 289, - "CreatedAt": "2020-09-07T15:38:56.622059399Z", - "UpdatedAt": "2020-09-07T15:38:56.622059399Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 271, - "CreatedAt": "2020-09-07T15:38:56.610108993Z", - "UpdatedAt": "2020-09-07T15:38:56.610108993Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 236, - "CreatedAt": "2020-09-07T15:26:07.493371532Z", - "UpdatedAt": "2020-09-07T15:26:07.493371532Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 218, - "CreatedAt": "2020-09-07T15:26:07.480271875Z", - "UpdatedAt": "2020-09-07T15:26:07.480271875Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 183, - "CreatedAt": "2020-09-07T15:19:17.455196926Z", - "UpdatedAt": "2020-09-07T15:19:17.455196926Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 165, - "CreatedAt": "2020-09-07T15:19:17.442652368Z", - "UpdatedAt": "2020-09-07T15:19:17.442652368Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 130, - "CreatedAt": "2020-09-07T15:10:40.234829815Z", - "UpdatedAt": "2020-09-07T15:10:40.234829815Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 112, - "CreatedAt": "2020-09-07T15:10:40.222525726Z", - "UpdatedAt": "2020-09-07T15:10:40.222525726Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 77, - "CreatedAt": "2020-09-06T23:14:39.839317879Z", - "UpdatedAt": "2020-09-06T23:14:39.839317879Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 59, - "CreatedAt": "2020-09-06T23:14:39.828766564Z", - "UpdatedAt": "2020-09-06T23:14:39.828766564Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 24, - "CreatedAt": "2020-08-28T07:55:27.811550965Z", - "UpdatedAt": "2020-08-28T07:55:27.811550965Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 6, - "CreatedAt": "2020-08-28T07:55:27.794077393Z", - "UpdatedAt": "2020-08-28T07:55:27.794077393Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 396, - "CreatedAt": "2020-09-08T21:39:26.566388-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566388-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 378, - "CreatedAt": "2020-09-08T21:39:26.556011-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556011-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 343, - "CreatedAt": "2020-09-07T15:47:21.320351671Z", - "UpdatedAt": "2020-09-07T15:47:21.320351671Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 325, - "CreatedAt": "2020-09-07T15:47:21.307191042Z", - "UpdatedAt": "2020-09-07T15:47:21.307191042Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 290, - "CreatedAt": "2020-09-07T15:38:56.622135099Z", - "UpdatedAt": "2020-09-07T15:38:56.622135099Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 272, - "CreatedAt": "2020-09-07T15:38:56.610177694Z", - "UpdatedAt": "2020-09-07T15:38:56.610177694Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 237, - "CreatedAt": "2020-09-07T15:26:07.493474635Z", - "UpdatedAt": "2020-09-07T15:26:07.493474635Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 219, - "CreatedAt": "2020-09-07T15:26:07.480369577Z", - "UpdatedAt": "2020-09-07T15:26:07.480369577Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 184, - "CreatedAt": "2020-09-07T15:19:17.455270825Z", - "UpdatedAt": "2020-09-07T15:19:17.455270825Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 166, - "CreatedAt": "2020-09-07T15:19:17.442737567Z", - "UpdatedAt": "2020-09-07T15:19:17.442737567Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 131, - "CreatedAt": "2020-09-07T15:10:40.234912916Z", - "UpdatedAt": "2020-09-07T15:10:40.234912916Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 113, - "CreatedAt": "2020-09-07T15:10:40.222607826Z", - "UpdatedAt": "2020-09-07T15:10:40.222607826Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 78, - "CreatedAt": "2020-09-06T23:14:39.839390682Z", - "UpdatedAt": "2020-09-06T23:14:39.839390682Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 60, - "CreatedAt": "2020-09-06T23:14:39.828832166Z", - "UpdatedAt": "2020-09-06T23:14:39.828832166Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 25, - "CreatedAt": "2020-08-28T07:55:27.811628355Z", - "UpdatedAt": "2020-08-28T07:55:27.811628355Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 7, - "CreatedAt": "2020-08-28T07:55:27.794167288Z", - "UpdatedAt": "2020-08-28T07:55:27.794167288Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 133, - "worst": 133, - "thresh": 20, - "raw_value": 18, - "raw_string": "18", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 397, - "CreatedAt": "2020-09-08T21:39:26.566454-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566454-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 379, - "CreatedAt": "2020-09-08T21:39:26.556082-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556082-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 344, - "CreatedAt": "2020-09-07T15:47:21.320434771Z", - "UpdatedAt": "2020-09-07T15:47:21.320434771Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 326, - "CreatedAt": "2020-09-07T15:47:21.307320542Z", - "UpdatedAt": "2020-09-07T15:47:21.307320542Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 291, - "CreatedAt": "2020-09-07T15:38:56.622211Z", - "UpdatedAt": "2020-09-07T15:38:56.622211Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 273, - "CreatedAt": "2020-09-07T15:38:56.610246595Z", - "UpdatedAt": "2020-09-07T15:38:56.610246595Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 238, - "CreatedAt": "2020-09-07T15:26:07.493636539Z", - "UpdatedAt": "2020-09-07T15:26:07.493636539Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 220, - "CreatedAt": "2020-09-07T15:26:07.48045858Z", - "UpdatedAt": "2020-09-07T15:26:07.48045858Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 185, - "CreatedAt": "2020-09-07T15:19:17.455349925Z", - "UpdatedAt": "2020-09-07T15:19:17.455349925Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 167, - "CreatedAt": "2020-09-07T15:19:17.442814567Z", - "UpdatedAt": "2020-09-07T15:19:17.442814567Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 132, - "CreatedAt": "2020-09-07T15:10:40.235014517Z", - "UpdatedAt": "2020-09-07T15:10:40.235014517Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 114, - "CreatedAt": "2020-09-07T15:10:40.222673127Z", - "UpdatedAt": "2020-09-07T15:10:40.222673127Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 79, - "CreatedAt": "2020-09-06T23:14:39.839467884Z", - "UpdatedAt": "2020-09-06T23:14:39.839467884Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 61, - "CreatedAt": "2020-09-06T23:14:39.828900468Z", - "UpdatedAt": "2020-09-06T23:14:39.828900468Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 26, - "CreatedAt": "2020-08-28T07:55:27.8117049Z", - "UpdatedAt": "2020-08-28T07:55:27.8117049Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 8, - "CreatedAt": "2020-08-28T07:55:27.794251087Z", - "UpdatedAt": "2020-08-28T07:55:27.794251087Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 1730, - "raw_string": "1730", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 398, - "CreatedAt": "2020-09-08T21:39:26.566526-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566526-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.05459827163896099, - "history": [{ - "ID": 380, - "CreatedAt": "2020-09-08T21:39:26.556157-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556157-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 345, - "CreatedAt": "2020-09-07T15:47:21.320529071Z", - "UpdatedAt": "2020-09-07T15:47:21.320529071Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 327, - "CreatedAt": "2020-09-07T15:47:21.307449642Z", - "UpdatedAt": "2020-09-07T15:47:21.307449642Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 292, - "CreatedAt": "2020-09-07T15:38:56.622285101Z", - "UpdatedAt": "2020-09-07T15:38:56.622285101Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 274, - "CreatedAt": "2020-09-07T15:38:56.610358696Z", - "UpdatedAt": "2020-09-07T15:38:56.610358696Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 239, - "CreatedAt": "2020-09-07T15:26:07.493765343Z", - "UpdatedAt": "2020-09-07T15:26:07.493765343Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 221, - "CreatedAt": "2020-09-07T15:26:07.480546682Z", - "UpdatedAt": "2020-09-07T15:26:07.480546682Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 186, - "CreatedAt": "2020-09-07T15:19:17.455425525Z", - "UpdatedAt": "2020-09-07T15:19:17.455425525Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 168, - "CreatedAt": "2020-09-07T15:19:17.442892767Z", - "UpdatedAt": "2020-09-07T15:19:17.442892767Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 133, - "CreatedAt": "2020-09-07T15:10:40.235101017Z", - "UpdatedAt": "2020-09-07T15:10:40.235101017Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 115, - "CreatedAt": "2020-09-07T15:10:40.222780027Z", - "UpdatedAt": "2020-09-07T15:10:40.222780027Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 80, - "CreatedAt": "2020-09-06T23:14:39.839545886Z", - "UpdatedAt": "2020-09-06T23:14:39.839545886Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 62, - "CreatedAt": "2020-09-06T23:14:39.82896797Z", - "UpdatedAt": "2020-09-06T23:14:39.82896797Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 27, - "CreatedAt": "2020-08-28T07:55:27.81178263Z", - "UpdatedAt": "2020-08-28T07:55:27.81178263Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 9, - "CreatedAt": "2020-08-28T07:55:27.794343259Z", - "UpdatedAt": "2020-08-28T07:55:27.794343259Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 1, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 399, - "CreatedAt": "2020-09-08T21:39:26.566594-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566594-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.019835987118930823, - "history": [{ - "ID": 381, - "CreatedAt": "2020-09-08T21:39:26.556225-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556225-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 346, - "CreatedAt": "2020-09-07T15:47:21.320607871Z", - "UpdatedAt": "2020-09-07T15:47:21.320607871Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 328, - "CreatedAt": "2020-09-07T15:47:21.307575143Z", - "UpdatedAt": "2020-09-07T15:47:21.307575143Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 293, - "CreatedAt": "2020-09-07T15:38:56.622436802Z", - "UpdatedAt": "2020-09-07T15:38:56.622436802Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 275, - "CreatedAt": "2020-09-07T15:38:56.610431596Z", - "UpdatedAt": "2020-09-07T15:38:56.610431596Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 240, - "CreatedAt": "2020-09-07T15:26:07.493897347Z", - "UpdatedAt": "2020-09-07T15:26:07.493897347Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 222, - "CreatedAt": "2020-09-07T15:26:07.480631784Z", - "UpdatedAt": "2020-09-07T15:26:07.480631784Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 187, - "CreatedAt": "2020-09-07T15:19:17.455500025Z", - "UpdatedAt": "2020-09-07T15:19:17.455500025Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 169, - "CreatedAt": "2020-09-07T15:19:17.442969566Z", - "UpdatedAt": "2020-09-07T15:19:17.442969566Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 134, - "CreatedAt": "2020-09-07T15:10:40.23543132Z", - "UpdatedAt": "2020-09-07T15:10:40.23543132Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 116, - "CreatedAt": "2020-09-07T15:10:40.222855428Z", - "UpdatedAt": "2020-09-07T15:10:40.222855428Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 81, - "CreatedAt": "2020-09-06T23:14:39.839623189Z", - "UpdatedAt": "2020-09-06T23:14:39.839623189Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 63, - "CreatedAt": "2020-09-06T23:14:39.829035472Z", - "UpdatedAt": "2020-09-06T23:14:39.829035472Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 28, - "CreatedAt": "2020-08-28T07:55:27.811864251Z", - "UpdatedAt": "2020-08-28T07:55:27.811864251Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 10, - "CreatedAt": "2020-08-28T07:55:27.79442562Z", - "UpdatedAt": "2020-08-28T07:55:27.79442562Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 9, - "raw_string": "9", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 400, - "CreatedAt": "2020-09-08T21:39:26.566661-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566661-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 382, - "CreatedAt": "2020-09-08T21:39:26.556294-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556294-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 347, - "CreatedAt": "2020-09-07T15:47:21.320688272Z", - "UpdatedAt": "2020-09-07T15:47:21.320688272Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 329, - "CreatedAt": "2020-09-07T15:47:21.307698843Z", - "UpdatedAt": "2020-09-07T15:47:21.307698843Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 294, - "CreatedAt": "2020-09-07T15:38:56.622559903Z", - "UpdatedAt": "2020-09-07T15:38:56.622559903Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 276, - "CreatedAt": "2020-09-07T15:38:56.610502597Z", - "UpdatedAt": "2020-09-07T15:38:56.610502597Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 241, - "CreatedAt": "2020-09-07T15:26:07.493985749Z", - "UpdatedAt": "2020-09-07T15:26:07.493985749Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 223, - "CreatedAt": "2020-09-07T15:26:07.480743187Z", - "UpdatedAt": "2020-09-07T15:26:07.480743187Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 188, - "CreatedAt": "2020-09-07T15:19:17.455575224Z", - "UpdatedAt": "2020-09-07T15:19:17.455575224Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 170, - "CreatedAt": "2020-09-07T15:19:17.443042566Z", - "UpdatedAt": "2020-09-07T15:19:17.443042566Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 135, - "CreatedAt": "2020-09-07T15:10:40.23553022Z", - "UpdatedAt": "2020-09-07T15:10:40.23553022Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 117, - "CreatedAt": "2020-09-07T15:10:40.222932429Z", - "UpdatedAt": "2020-09-07T15:10:40.222932429Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 82, - "CreatedAt": "2020-09-06T23:14:39.839696091Z", - "UpdatedAt": "2020-09-06T23:14:39.839696091Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 64, - "CreatedAt": "2020-09-06T23:14:39.829103574Z", - "UpdatedAt": "2020-09-06T23:14:39.829103574Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 29, - "CreatedAt": "2020-08-28T07:55:27.811945021Z", - "UpdatedAt": "2020-08-28T07:55:27.811945021Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 11, - "CreatedAt": "2020-08-28T07:55:27.794526672Z", - "UpdatedAt": "2020-08-28T07:55:27.794526672Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 22, - "name": "Current Helium Level", - "value": 100, - "worst": 100, - "thresh": 25, - "raw_value": 100, - "raw_string": "100", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 401, - "CreatedAt": "2020-09-08T21:39:26.566727-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566727-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.01634692899031039, - "history": [{ - "ID": 383, - "CreatedAt": "2020-09-08T21:39:26.556363-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556363-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 348, - "CreatedAt": "2020-09-07T15:47:21.320764972Z", - "UpdatedAt": "2020-09-07T15:47:21.320764972Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 330, - "CreatedAt": "2020-09-07T15:47:21.308110544Z", - "UpdatedAt": "2020-09-07T15:47:21.308110544Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 295, - "CreatedAt": "2020-09-07T15:38:56.622638304Z", - "UpdatedAt": "2020-09-07T15:38:56.622638304Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 277, - "CreatedAt": "2020-09-07T15:38:56.610569797Z", - "UpdatedAt": "2020-09-07T15:38:56.610569797Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 242, - "CreatedAt": "2020-09-07T15:26:07.494076151Z", - "UpdatedAt": "2020-09-07T15:26:07.494076151Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 224, - "CreatedAt": "2020-09-07T15:26:07.48083529Z", - "UpdatedAt": "2020-09-07T15:26:07.48083529Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 189, - "CreatedAt": "2020-09-07T15:19:17.455652324Z", - "UpdatedAt": "2020-09-07T15:19:17.455652324Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 171, - "CreatedAt": "2020-09-07T15:19:17.443115666Z", - "UpdatedAt": "2020-09-07T15:19:17.443115666Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 136, - "CreatedAt": "2020-09-07T15:10:40.235693822Z", - "UpdatedAt": "2020-09-07T15:10:40.235693822Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 118, - "CreatedAt": "2020-09-07T15:10:40.223005329Z", - "UpdatedAt": "2020-09-07T15:10:40.223005329Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 83, - "CreatedAt": "2020-09-06T23:14:39.839769893Z", - "UpdatedAt": "2020-09-06T23:14:39.839769893Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 65, - "CreatedAt": "2020-09-06T23:14:39.829170476Z", - "UpdatedAt": "2020-09-06T23:14:39.829170476Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 30, - "CreatedAt": "2020-08-28T07:55:27.812020236Z", - "UpdatedAt": "2020-08-28T07:55:27.812020236Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 12, - "CreatedAt": "2020-08-28T07:55:27.794617502Z", - "UpdatedAt": "2020-08-28T07:55:27.794617502Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 402, - "CreatedAt": "2020-09-08T21:39:26.566795-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566795-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 384, - "CreatedAt": "2020-09-08T21:39:26.556431-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556431-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 349, - "CreatedAt": "2020-09-07T15:47:21.320843672Z", - "UpdatedAt": "2020-09-07T15:47:21.320843672Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 331, - "CreatedAt": "2020-09-07T15:47:21.308263444Z", - "UpdatedAt": "2020-09-07T15:47:21.308263444Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 296, - "CreatedAt": "2020-09-07T15:38:56.622711005Z", - "UpdatedAt": "2020-09-07T15:38:56.622711005Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 278, - "CreatedAt": "2020-09-07T15:38:56.610644498Z", - "UpdatedAt": "2020-09-07T15:38:56.610644498Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 243, - "CreatedAt": "2020-09-07T15:26:07.494160354Z", - "UpdatedAt": "2020-09-07T15:26:07.494160354Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 225, - "CreatedAt": "2020-09-07T15:26:07.480920492Z", - "UpdatedAt": "2020-09-07T15:26:07.480920492Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 190, - "CreatedAt": "2020-09-07T15:19:17.455725424Z", - "UpdatedAt": "2020-09-07T15:19:17.455725424Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 172, - "CreatedAt": "2020-09-07T15:19:17.443238266Z", - "UpdatedAt": "2020-09-07T15:19:17.443238266Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 137, - "CreatedAt": "2020-09-07T15:10:40.235762522Z", - "UpdatedAt": "2020-09-07T15:10:40.235762522Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 119, - "CreatedAt": "2020-09-07T15:10:40.22311063Z", - "UpdatedAt": "2020-09-07T15:10:40.22311063Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 84, - "CreatedAt": "2020-09-06T23:14:39.839842395Z", - "UpdatedAt": "2020-09-06T23:14:39.839842395Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 66, - "CreatedAt": "2020-09-06T23:14:39.829237678Z", - "UpdatedAt": "2020-09-06T23:14:39.829237678Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 31, - "CreatedAt": "2020-08-28T07:55:27.812094858Z", - "UpdatedAt": "2020-08-28T07:55:27.812094858Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 13, - "CreatedAt": "2020-08-28T07:55:27.794713765Z", - "UpdatedAt": "2020-08-28T07:55:27.794713765Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 329, - "raw_string": "329", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 403, - "CreatedAt": "2020-09-08T21:39:26.566869-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566869-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32, - "status": "passed", - "history": [{ - "ID": 385, - "CreatedAt": "2020-09-08T21:39:26.556503-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556503-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 350, - "CreatedAt": "2020-09-07T15:47:21.320921272Z", - "UpdatedAt": "2020-09-07T15:47:21.320921272Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 332, - "CreatedAt": "2020-09-07T15:47:21.308359744Z", - "UpdatedAt": "2020-09-07T15:47:21.308359744Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 297, - "CreatedAt": "2020-09-07T15:38:56.622787005Z", - "UpdatedAt": "2020-09-07T15:38:56.622787005Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 279, - "CreatedAt": "2020-09-07T15:38:56.610731899Z", - "UpdatedAt": "2020-09-07T15:38:56.610731899Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 244, - "CreatedAt": "2020-09-07T15:26:07.494245356Z", - "UpdatedAt": "2020-09-07T15:26:07.494245356Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 226, - "CreatedAt": "2020-09-07T15:26:07.481005295Z", - "UpdatedAt": "2020-09-07T15:26:07.481005295Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 191, - "CreatedAt": "2020-09-07T15:19:17.455795324Z", - "UpdatedAt": "2020-09-07T15:19:17.455795324Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 173, - "CreatedAt": "2020-09-07T15:19:17.443317065Z", - "UpdatedAt": "2020-09-07T15:19:17.443317065Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 138, - "CreatedAt": "2020-09-07T15:10:40.235933223Z", - "UpdatedAt": "2020-09-07T15:10:40.235933223Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 120, - "CreatedAt": "2020-09-07T15:10:40.223208631Z", - "UpdatedAt": "2020-09-07T15:10:40.223208631Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 85, - "CreatedAt": "2020-09-06T23:14:39.839917897Z", - "UpdatedAt": "2020-09-06T23:14:39.839917897Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 67, - "CreatedAt": "2020-09-06T23:14:39.82930548Z", - "UpdatedAt": "2020-09-06T23:14:39.82930548Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 32, - "CreatedAt": "2020-08-28T07:55:27.812170947Z", - "UpdatedAt": "2020-08-28T07:55:27.812170947Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }, { - "ID": 14, - "CreatedAt": "2020-08-28T07:55:27.794809537Z", - "UpdatedAt": "2020-08-28T07:55:27.794809537Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 194, - "name": "Temperature", - "value": 51, - "worst": 51, - "thresh": 0, - "raw_value": 163210330144, - "raw_string": "32 (Min/Max 24/38)", - "when_failed": "", - "transformed_value": 32 - }] - }, { - "ID": 404, - "CreatedAt": "2020-09-08T21:39:26.566946-07:00", - "UpdatedAt": "2020-09-08T21:39:26.566946-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.007389855800729792, - "history": [{ - "ID": 386, - "CreatedAt": "2020-09-08T21:39:26.556577-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556577-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 351, - "CreatedAt": "2020-09-07T15:47:21.320997672Z", - "UpdatedAt": "2020-09-07T15:47:21.320997672Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 333, - "CreatedAt": "2020-09-07T15:47:21.308448945Z", - "UpdatedAt": "2020-09-07T15:47:21.308448945Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 298, - "CreatedAt": "2020-09-07T15:38:56.622861506Z", - "UpdatedAt": "2020-09-07T15:38:56.622861506Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 280, - "CreatedAt": "2020-09-07T15:38:56.6108076Z", - "UpdatedAt": "2020-09-07T15:38:56.6108076Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 245, - "CreatedAt": "2020-09-07T15:26:07.494329358Z", - "UpdatedAt": "2020-09-07T15:26:07.494329358Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 227, - "CreatedAt": "2020-09-07T15:26:07.481094797Z", - "UpdatedAt": "2020-09-07T15:26:07.481094797Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 192, - "CreatedAt": "2020-09-07T15:19:17.455872523Z", - "UpdatedAt": "2020-09-07T15:19:17.455872523Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 174, - "CreatedAt": "2020-09-07T15:19:17.443397465Z", - "UpdatedAt": "2020-09-07T15:19:17.443397465Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 139, - "CreatedAt": "2020-09-07T15:10:40.236025724Z", - "UpdatedAt": "2020-09-07T15:10:40.236025724Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 121, - "CreatedAt": "2020-09-07T15:10:40.223270031Z", - "UpdatedAt": "2020-09-07T15:10:40.223270031Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 86, - "CreatedAt": "2020-09-06T23:14:39.8399883Z", - "UpdatedAt": "2020-09-06T23:14:39.8399883Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 68, - "CreatedAt": "2020-09-06T23:14:39.829370082Z", - "UpdatedAt": "2020-09-06T23:14:39.829370082Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 33, - "CreatedAt": "2020-08-28T07:55:27.812246492Z", - "UpdatedAt": "2020-08-28T07:55:27.812246492Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 196, - "name": "Reallocation Event Count", + "name": "Read Error Rate", "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 15, - "CreatedAt": "2020-08-28T07:55:27.794890531Z", - "UpdatedAt": "2020-08-28T07:55:27.794890531Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 196, - "name": "Reallocation Event Count", + }, + "10": { + "attribute_id": 10, + "name": "Spin Retry Count", "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }] - }, { - "ID": 405, - "CreatedAt": "2020-09-08T21:39:26.567013-07:00", - "UpdatedAt": "2020-09-08T21:39:26.567013-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.025540791394761345, - "history": [{ - "ID": 387, - "CreatedAt": "2020-09-08T21:39:26.55665-07:00", - "UpdatedAt": "2020-09-08T21:39:26.55665-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 197, - "name": "Current Pending Sector Count", + }, + "12": { + "attribute_id": 12, + "name": "Power Cycle Count", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 9, + "raw_string": "9", "when_failed": "", "transformed_value": 0 - }, { - "ID": 352, - "CreatedAt": "2020-09-07T15:47:21.321080072Z", - "UpdatedAt": "2020-09-07T15:47:21.321080072Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 197, - "name": "Current Pending Sector Count", + }, + "192": { + "attribute_id": 192, + "name": "Power-off Retract Count", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 329, + "raw_string": "329", "when_failed": "", "transformed_value": 0 - }, { - "ID": 334, - "CreatedAt": "2020-09-07T15:47:21.308534945Z", - "UpdatedAt": "2020-09-07T15:47:21.308534945Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 197, - "name": "Current Pending Sector Count", + }, + "193": { + "attribute_id": 193, + "name": "Load Cycle Count", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 329, + "raw_string": "329", "when_failed": "", "transformed_value": 0 - }, { - "ID": 299, - "CreatedAt": "2020-09-07T15:38:56.622933307Z", - "UpdatedAt": "2020-09-07T15:38:56.622933307Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, + }, + "194": { + "attribute_id": 194, + "name": "Temperature", + "value": 51, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 51, + "raw_value": 163210330144, + "raw_string": "32 (Min/Max 24/38)", "when_failed": "", "transformed_value": 0 - }, { - "ID": 281, - "CreatedAt": "2020-09-07T15:38:56.6108811Z", - "UpdatedAt": "2020-09-07T15:38:56.6108811Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 197, - "name": "Current Pending Sector Count", + }, + "196": { + "attribute_id": 196, + "name": "Reallocation Event Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 246, - "CreatedAt": "2020-09-07T15:26:07.494412661Z", - "UpdatedAt": "2020-09-07T15:26:07.494412661Z", - "DeletedAt": null, - "smart_id": 26, + }, + "197": { "attribute_id": 197, "name": "Current Pending Sector Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 228, - "CreatedAt": "2020-09-07T15:26:07.481180499Z", - "UpdatedAt": "2020-09-07T15:26:07.481180499Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 197, - "name": "Current Pending Sector Count", + }, + "198": { + "attribute_id": 198, + "name": "(Offline) Uncorrectable Sector Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 193, - "CreatedAt": "2020-09-07T15:19:17.455947323Z", - "UpdatedAt": "2020-09-07T15:19:17.455947323Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 197, - "name": "Current Pending Sector Count", + }, + "199": { + "attribute_id": 199, + "name": "UltraDMA CRC Error Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 175, - "CreatedAt": "2020-09-07T15:19:17.443471765Z", - "UpdatedAt": "2020-09-07T15:19:17.443471765Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + }, + "2": { + "attribute_id": 2, + "name": "Throughput Performance", + "value": 135, + "thresh": 54, + "worst": 135, + "raw_value": 108, + "raw_string": "108", "when_failed": "", "transformed_value": 0 - }, { - "ID": 140, - "CreatedAt": "2020-09-07T15:10:40.236107525Z", - "UpdatedAt": "2020-09-07T15:10:40.236107525Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 197, - "name": "Current Pending Sector Count", + }, + "22": { + "attribute_id": 22, + "name": "Current Helium Level", "value": 100, + "thresh": 25, "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "raw_value": 100, + "raw_string": "100", "when_failed": "", "transformed_value": 0 - }, { - "ID": 122, - "CreatedAt": "2020-09-07T15:10:40.223335031Z", - "UpdatedAt": "2020-09-07T15:10:40.223335031Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + }, + "3": { + "attribute_id": 3, + "name": "Spin-Up Time", + "value": 81, + "thresh": 1, + "worst": 81, + "raw_value": 30089675132, + "raw_string": "380 (Average 380)", "when_failed": "", "transformed_value": 0 - }, { - "ID": 87, - "CreatedAt": "2020-09-06T23:14:39.840059202Z", - "UpdatedAt": "2020-09-06T23:14:39.840059202Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 197, - "name": "Current Pending Sector Count", + }, + "4": { + "attribute_id": 4, + "name": "Start/Stop Count", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 9, + "raw_string": "9", "when_failed": "", "transformed_value": 0 - }, { - "ID": 69, - "CreatedAt": "2020-09-06T23:14:39.829440284Z", - "UpdatedAt": "2020-09-06T23:14:39.829440284Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 197, - "name": "Current Pending Sector Count", + }, + "5": { + "attribute_id": 5, + "name": "Reallocated Sectors Count", "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 34, - "CreatedAt": "2020-08-28T07:55:27.812321365Z", - "UpdatedAt": "2020-08-28T07:55:27.812321365Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 197, - "name": "Current Pending Sector Count", + }, + "7": { + "attribute_id": 7, + "name": "Seek Error Rate", "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 16, - "CreatedAt": "2020-08-28T07:55:27.794983884Z", - "UpdatedAt": "2020-08-28T07:55:27.794983884Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + }, + "8": { + "attribute_id": 8, + "name": "Seek Time Performance", + "value": 133, + "thresh": 20, + "worst": 133, + "raw_value": 18, + "raw_string": "18", "when_failed": "", "transformed_value": 0 - }] - }, { - "ID": 406, - "CreatedAt": "2020-09-08T21:39:26.567084-07:00", - "UpdatedAt": "2020-09-08T21:39:26.567084-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.028675322159886437, - "history": [{ - "ID": 388, - "CreatedAt": "2020-09-08T21:39:26.556721-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556721-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + }, + "9": { + "attribute_id": 9, + "name": "Power-On Hours", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 1730, + "raw_string": "1730", "when_failed": "", "transformed_value": 0 - }, { - "ID": 353, - "CreatedAt": "2020-09-07T15:47:21.321156173Z", - "UpdatedAt": "2020-09-07T15:47:21.321156173Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + } + } + }, { + "date": "2021-01-23T16:24:06Z", + "device_wwn": "0x5000cca264eb01d7", + "device_protocol": "ATA", + "temp": 32, + "power_on_hours": 1730, + "power_cycle_count": 9, + "attrs": { + "1": { + "attribute_id": 1, + "name": "Read Error Rate", "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 335, - "CreatedAt": "2020-09-07T15:47:21.308621645Z", - "UpdatedAt": "2020-09-07T15:47:21.308621645Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + }, + "10": { + "attribute_id": 10, + "name": "Spin Retry Count", "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 300, - "CreatedAt": "2020-09-07T15:38:56.623001907Z", - "UpdatedAt": "2020-09-07T15:38:56.623001907Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + }, + "12": { + "attribute_id": 12, + "name": "Power Cycle Count", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 9, + "raw_string": "9", "when_failed": "", "transformed_value": 0 - }, { - "ID": 282, - "CreatedAt": "2020-09-07T15:38:56.610954501Z", - "UpdatedAt": "2020-09-07T15:38:56.610954501Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + }, + "192": { + "attribute_id": 192, + "name": "Power-off Retract Count", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 329, + "raw_string": "329", "when_failed": "", "transformed_value": 0 - }, { - "ID": 247, - "CreatedAt": "2020-09-07T15:26:07.494502663Z", - "UpdatedAt": "2020-09-07T15:26:07.494502663Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + }, + "193": { + "attribute_id": 193, + "name": "Load Cycle Count", "value": 100, + "thresh": 0, "worst": 100, + "raw_value": 329, + "raw_string": "329", + "when_failed": "", + "transformed_value": 0 + }, + "194": { + "attribute_id": 194, + "name": "Temperature", + "value": 51, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 51, + "raw_value": 163210330144, + "raw_string": "32 (Min/Max 24/38)", "when_failed": "", "transformed_value": 0 - }, { - "ID": 229, - "CreatedAt": "2020-09-07T15:26:07.481263302Z", - "UpdatedAt": "2020-09-07T15:26:07.481263302Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + }, + "196": { + "attribute_id": 196, + "name": "Reallocation Event Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 194, - "CreatedAt": "2020-09-07T15:19:17.456016623Z", - "UpdatedAt": "2020-09-07T15:19:17.456016623Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + }, + "197": { + "attribute_id": 197, + "name": "Current Pending Sector Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 176, - "CreatedAt": "2020-09-07T15:19:17.443544465Z", - "UpdatedAt": "2020-09-07T15:19:17.443544465Z", - "DeletedAt": null, - "smart_id": 19, + }, + "198": { "attribute_id": 198, "name": "(Offline) Uncorrectable Sector Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 141, - "CreatedAt": "2020-09-07T15:10:40.236230025Z", - "UpdatedAt": "2020-09-07T15:10:40.236230025Z", - "DeletedAt": null, - "smart_id": 14, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + }, + "199": { + "attribute_id": 199, + "name": "UltraDMA CRC Error Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 123, - "CreatedAt": "2020-09-07T15:10:40.223397332Z", - "UpdatedAt": "2020-09-07T15:10:40.223397332Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + }, + "2": { + "attribute_id": 2, + "name": "Throughput Performance", + "value": 135, + "thresh": 54, + "worst": 135, + "raw_value": 108, + "raw_string": "108", + "when_failed": "", + "transformed_value": 0 + }, + "22": { + "attribute_id": 22, + "name": "Current Helium Level", "value": 100, + "thresh": 25, "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "raw_value": 100, + "raw_string": "100", + "when_failed": "", + "transformed_value": 0 + }, + "3": { + "attribute_id": 3, + "name": "Spin-Up Time", + "value": 81, + "thresh": 1, + "worst": 81, + "raw_value": 30089675132, + "raw_string": "380 (Average 380)", "when_failed": "", "transformed_value": 0 - }, { - "ID": 88, - "CreatedAt": "2020-09-06T23:14:39.840162905Z", - "UpdatedAt": "2020-09-06T23:14:39.840162905Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + }, + "4": { + "attribute_id": 4, + "name": "Start/Stop Count", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 9, + "raw_string": "9", "when_failed": "", "transformed_value": 0 - }, { - "ID": 70, - "CreatedAt": "2020-09-06T23:14:39.829535987Z", - "UpdatedAt": "2020-09-06T23:14:39.829535987Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + }, + "5": { + "attribute_id": 5, + "name": "Reallocated Sectors Count", "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 35, - "CreatedAt": "2020-08-28T07:55:27.812396538Z", - "UpdatedAt": "2020-08-28T07:55:27.812396538Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + }, + "7": { + "attribute_id": 7, + "name": "Seek Error Rate", "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 17, - "CreatedAt": "2020-08-28T07:55:27.795066287Z", - "UpdatedAt": "2020-08-28T07:55:27.795066287Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + }, + "8": { + "attribute_id": 8, + "name": "Seek Time Performance", + "value": 133, + "thresh": 20, + "worst": 133, + "raw_value": 18, + "raw_string": "18", "when_failed": "", "transformed_value": 0 - }] - }, { - "ID": 407, - "CreatedAt": "2020-09-08T21:39:26.567154-07:00", - "UpdatedAt": "2020-09-08T21:39:26.567154-07:00", - "DeletedAt": null, - "smart_id": 44, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 389, - "CreatedAt": "2020-09-08T21:39:26.556788-07:00", - "UpdatedAt": "2020-09-08T21:39:26.556788-07:00", - "DeletedAt": null, - "smart_id": 43, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + }, + "9": { + "attribute_id": 9, + "name": "Power-On Hours", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 1730, + "raw_string": "1730", "when_failed": "", "transformed_value": 0 - }, { - "ID": 354, - "CreatedAt": "2020-09-07T15:47:21.321272273Z", - "UpdatedAt": "2020-09-07T15:47:21.321272273Z", - "DeletedAt": null, - "smart_id": 38, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + } + } + }, { + "date": "2021-01-23T16:25:46Z", + "device_wwn": "0x5000cca264eb01d7", + "device_protocol": "ATA", + "temp": 32, + "power_on_hours": 1730, + "power_cycle_count": 9, + "attrs": { + "1": { + "attribute_id": 1, + "name": "Read Error Rate", "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 336, - "CreatedAt": "2020-09-07T15:47:21.308717545Z", - "UpdatedAt": "2020-09-07T15:47:21.308717545Z", - "DeletedAt": null, - "smart_id": 37, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + }, + "10": { + "attribute_id": 10, + "name": "Spin Retry Count", "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 301, - "CreatedAt": "2020-09-07T15:38:56.623082408Z", - "UpdatedAt": "2020-09-07T15:38:56.623082408Z", - "DeletedAt": null, - "smart_id": 32, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + }, + "12": { + "attribute_id": 12, + "name": "Power Cycle Count", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 9, + "raw_string": "9", "when_failed": "", "transformed_value": 0 - }, { - "ID": 283, - "CreatedAt": "2020-09-07T15:38:56.611027902Z", - "UpdatedAt": "2020-09-07T15:38:56.611027902Z", - "DeletedAt": null, - "smart_id": 31, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + }, + "192": { + "attribute_id": 192, + "name": "Power-off Retract Count", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 329, + "raw_string": "329", "when_failed": "", "transformed_value": 0 - }, { - "ID": 248, - "CreatedAt": "2020-09-07T15:26:07.494585565Z", - "UpdatedAt": "2020-09-07T15:26:07.494585565Z", - "DeletedAt": null, - "smart_id": 26, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + }, + "193": { + "attribute_id": 193, + "name": "Load Cycle Count", "value": 100, + "thresh": 0, "worst": 100, + "raw_value": 329, + "raw_string": "329", + "when_failed": "", + "transformed_value": 0 + }, + "194": { + "attribute_id": 194, + "name": "Temperature", + "value": 51, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 51, + "raw_value": 163210330144, + "raw_string": "32 (Min/Max 24/38)", "when_failed": "", "transformed_value": 0 - }, { - "ID": 230, - "CreatedAt": "2020-09-07T15:26:07.481350204Z", - "UpdatedAt": "2020-09-07T15:26:07.481350204Z", - "DeletedAt": null, - "smart_id": 25, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + }, + "196": { + "attribute_id": 196, + "name": "Reallocation Event Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 195, - "CreatedAt": "2020-09-07T15:19:17.456093323Z", - "UpdatedAt": "2020-09-07T15:19:17.456093323Z", - "DeletedAt": null, - "smart_id": 20, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + }, + "197": { + "attribute_id": 197, + "name": "Current Pending Sector Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 177, - "CreatedAt": "2020-09-07T15:19:17.443622964Z", - "UpdatedAt": "2020-09-07T15:19:17.443622964Z", - "DeletedAt": null, - "smart_id": 19, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + }, + "198": { + "attribute_id": 198, + "name": "(Offline) Uncorrectable Sector Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 142, - "CreatedAt": "2020-09-07T15:10:40.236299626Z", - "UpdatedAt": "2020-09-07T15:10:40.236299626Z", - "DeletedAt": null, - "smart_id": 14, + }, + "199": { "attribute_id": 199, "name": "UltraDMA CRC Error Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 124, - "CreatedAt": "2020-09-07T15:10:40.223460532Z", - "UpdatedAt": "2020-09-07T15:10:40.223460532Z", - "DeletedAt": null, - "smart_id": 13, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + }, + "2": { + "attribute_id": 2, + "name": "Throughput Performance", + "value": 135, + "thresh": 54, + "worst": 135, + "raw_value": 108, + "raw_string": "108", + "when_failed": "", + "transformed_value": 0 + }, + "22": { + "attribute_id": 22, + "name": "Current Helium Level", "value": 100, + "thresh": 25, "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "raw_value": 100, + "raw_string": "100", "when_failed": "", "transformed_value": 0 - }, { - "ID": 89, - "CreatedAt": "2020-09-06T23:14:39.840242107Z", - "UpdatedAt": "2020-09-06T23:14:39.840242107Z", - "DeletedAt": null, - "smart_id": 8, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + }, + "3": { + "attribute_id": 3, + "name": "Spin-Up Time", + "value": 81, + "thresh": 1, + "worst": 81, + "raw_value": 30089675132, + "raw_string": "380 (Average 380)", + "when_failed": "", + "transformed_value": 0 + }, + "4": { + "attribute_id": 4, + "name": "Start/Stop Count", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 9, + "raw_string": "9", "when_failed": "", "transformed_value": 0 - }, { - "ID": 71, - "CreatedAt": "2020-09-06T23:14:39.82963599Z", - "UpdatedAt": "2020-09-06T23:14:39.82963599Z", - "DeletedAt": null, - "smart_id": 7, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + }, + "5": { + "attribute_id": 5, + "name": "Reallocated Sectors Count", "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 36, - "CreatedAt": "2020-08-28T07:55:27.812495499Z", - "UpdatedAt": "2020-08-28T07:55:27.812495499Z", - "DeletedAt": null, - "smart_id": 2, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + }, + "7": { + "attribute_id": 7, + "name": "Seek Error Rate", "value": 100, + "thresh": 1, "worst": 100, - "thresh": 0, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 18, - "CreatedAt": "2020-08-28T07:55:27.795190163Z", - "UpdatedAt": "2020-08-28T07:55:27.795190163Z", - "DeletedAt": null, - "smart_id": 1, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", + }, + "8": { + "attribute_id": 8, + "name": "Seek Time Performance", + "value": 133, + "thresh": 20, + "worst": 133, + "raw_value": 18, + "raw_string": "18", + "when_failed": "", + "transformed_value": 0 + }, + "9": { + "attribute_id": 9, + "name": "Power-On Hours", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 1730, + "raw_string": "1730", "when_failed": "", "transformed_value": 0 - }] - }], - "nvme_attributes": [], - "scsi_attributes": [] + } + } }] - }, "metadata": { + }, + "metadata": { "1": { "ideal": "low", "critical": false, @@ -4420,12 +665,22 @@ export const sdb = { "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": 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": 155, + "high": 170, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 170, "high": 185, "annual_failure_rate": 0, @@ -4469,17 +724,32 @@ export const sdb = { "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": 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": 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": 400, + "high": 480, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 480, "high": 560, "annual_failure_rate": 0, @@ -4535,7 +805,12 @@ export const sdb = { "description": "Uncorrected read errors reported to the operating system.", "display_type": "normalized" }, - "170": {"ideal": "", "critical": false, "description": "See attribute E8.", "display_type": "normalized"}, + "170": { + "ideal": "", + "critical": false, + "description": "See attribute E8.", + "display_type": "normalized" + }, "171": { "ideal": "", "critical": false, @@ -4646,7 +921,12 @@ export const sdb = { "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]}], + }, { + "low": 130, + "high": 260, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }], "display_type": "raw" }, "184": { @@ -4658,12 +938,22 @@ export const sdb = { "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": 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": 96, + "high": 97, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 97, "high": 97, "annual_failure_rate": 0, @@ -4945,12 +1235,22 @@ export const sdb = { "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": 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": 84, + "high": 96, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 96, "high": 108, "annual_failure_rate": 0.04074570216566197, @@ -5492,7 +1792,12 @@ export const sdb = { "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]}], + }, { + "low": 91, + "high": 104, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }], "display_type": "raw" }, "5": { @@ -5572,12 +1877,22 @@ export const sdb = { "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": 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": 148, + "high": 166, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 166, "high": 184, "annual_failure_rate": 0, @@ -5602,5 +1917,6 @@ export const sdb = { "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 5d6935e..4bf402f 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sdc.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sdc.ts @@ -1,2127 +1,226 @@ export const sdc = { "data": { - "CreatedAt": "2020-08-28T07:55:27.75951336Z", - "UpdatedAt": "2020-09-08T21:39:26.568442-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264ec3183", - "device_name": "sdc", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "1.5 Gb/s", - "host_id": "NAS", - "serial_number": "9RK4XXXXX", - "firmware": "MS1OA650", - "rotational_speed": 7200, - "capacity": 500107862016, - "form_factor": "3.5 inches", - "smart_support": false, - "device_protocol": "ATA", - "device_type": "usbjmicron", - "smart_results": [{ - "ID": 45, - "CreatedAt": "2020-09-08T21:39:26.569345-07:00", - "UpdatedAt": "2020-09-08T21:39:26.569345-07:00", + "device": { + "CreatedAt": "2021-06-24T21:17:31.303033-07:00", + "UpdatedAt": "2021-06-26T14:26:20.449968-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": 1 + }, + "smart_results": [{ + "date": "2020-07-08T13:48:23Z", "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T06:48:23-07:00", - "smart_status": "failed", + "device_protocol": "ATA", "temp": 25, "power_on_hours": 65592, "power_cycle_count": 86, - "ata_attributes": [{ - "ID": 408, - "CreatedAt": "2020-09-08T21:39:26.569651-07:00", - "UpdatedAt": "2020-09-08T21:39:26.569651-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.034155719633986996, - "history": [{ - "ID": 355, - "CreatedAt": "2020-09-07T15:47:21.331077494Z", - "UpdatedAt": "2020-09-07T15:47:21.331077494Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 302, - "CreatedAt": "2020-09-07T15:38:56.628275154Z", - "UpdatedAt": "2020-09-07T15:38:56.628275154Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 249, - "CreatedAt": "2020-09-07T15:26:07.499652704Z", - "UpdatedAt": "2020-09-07T15:26:07.499652704Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 196, - "CreatedAt": "2020-09-07T15:19:17.461974003Z", - "UpdatedAt": "2020-09-07T15:19:17.461974003Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 143, - "CreatedAt": "2020-09-07T15:10:40.241379163Z", - "UpdatedAt": "2020-09-07T15:10:40.241379163Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 90, - "CreatedAt": "2020-09-06T23:14:39.844234727Z", - "UpdatedAt": "2020-09-06T23:14:39.844234727Z", - "DeletedAt": null, - "smart_id": 9, + "attrs": { + "1": { "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 37, - "CreatedAt": "2020-08-28T07:55:27.822615291Z", - "UpdatedAt": "2020-08-28T07:55:27.822615291Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 1, - "name": "Read Error Rate", - "value": 100, - "worst": 100, - "thresh": 16, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 409, - "CreatedAt": "2020-09-08T21:39:26.569778-07:00", - "UpdatedAt": "2020-09-08T21:39:26.569778-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 356, - "CreatedAt": "2020-09-07T15:47:21.331211195Z", - "UpdatedAt": "2020-09-07T15:47:21.331211195Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 303, - "CreatedAt": "2020-09-07T15:38:56.628397755Z", - "UpdatedAt": "2020-09-07T15:38:56.628397755Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 250, - "CreatedAt": "2020-09-07T15:26:07.499816008Z", - "UpdatedAt": "2020-09-07T15:26:07.499816008Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 197, - "CreatedAt": "2020-09-07T15:19:17.462101002Z", - "UpdatedAt": "2020-09-07T15:19:17.462101002Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 144, - "CreatedAt": "2020-09-07T15:10:40.241492664Z", - "UpdatedAt": "2020-09-07T15:10:40.241492664Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 91, - "CreatedAt": "2020-09-06T23:14:39.84435983Z", - "UpdatedAt": "2020-09-06T23:14:39.84435983Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 38, - "CreatedAt": "2020-08-28T07:55:27.822739564Z", - "UpdatedAt": "2020-08-28T07:55:27.822739564Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 2, - "name": "Throughput Performance", - "value": 136, - "worst": 136, - "thresh": 54, - "raw_value": 91, - "raw_string": "91", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 410, - "CreatedAt": "2020-09-08T21:39:26.569881-07:00", - "UpdatedAt": "2020-09-08T21:39:26.569881-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.009100406705780476, - "history": [{ - "ID": 357, - "CreatedAt": "2020-09-07T15:47:21.331308395Z", - "UpdatedAt": "2020-09-07T15:47:21.331308395Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 304, - "CreatedAt": "2020-09-07T15:38:56.628487555Z", - "UpdatedAt": "2020-09-07T15:38:56.628487555Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 251, - "CreatedAt": "2020-09-07T15:26:07.499919611Z", - "UpdatedAt": "2020-09-07T15:26:07.499919611Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 198, - "CreatedAt": "2020-09-07T15:19:17.462188402Z", - "UpdatedAt": "2020-09-07T15:19:17.462188402Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 145, - "CreatedAt": "2020-09-07T15:10:40.241569664Z", - "UpdatedAt": "2020-09-07T15:10:40.241569664Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 92, - "CreatedAt": "2020-09-06T23:14:39.844441733Z", - "UpdatedAt": "2020-09-06T23:14:39.844441733Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 39, - "CreatedAt": "2020-08-28T07:55:27.822829942Z", - "UpdatedAt": "2020-08-28T07:55:27.822829942Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 3, - "name": "Spin-Up Time", - "value": 125, - "worst": 125, - "thresh": 24, - "raw_value": 17192124596, - "raw_string": "180 (Average 187)", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 411, - "CreatedAt": "2020-09-08T21:39:26.569964-07:00", - "UpdatedAt": "2020-09-08T21:39:26.569964-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0, - "status": "warn", - "status_reason": "Observed Failure Rate for Attribute is greater than 10%", - "failure_rate": 0.12262136155304391, - "history": [{ - "ID": 358, - "CreatedAt": "2020-09-07T15:47:21.331396495Z", - "UpdatedAt": "2020-09-07T15:47:21.331396495Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 305, - "CreatedAt": "2020-09-07T15:38:56.628567356Z", - "UpdatedAt": "2020-09-07T15:38:56.628567356Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 252, - "CreatedAt": "2020-09-07T15:26:07.500014814Z", - "UpdatedAt": "2020-09-07T15:26:07.500014814Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 199, - "CreatedAt": "2020-09-07T15:19:17.462366102Z", - "UpdatedAt": "2020-09-07T15:19:17.462366102Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 146, - "CreatedAt": "2020-09-07T15:10:40.241649265Z", - "UpdatedAt": "2020-09-07T15:10:40.241649265Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 93, - "CreatedAt": "2020-09-06T23:14:39.844534936Z", - "UpdatedAt": "2020-09-06T23:14:39.844534936Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 40, - "CreatedAt": "2020-08-28T07:55:27.822921756Z", - "UpdatedAt": "2020-08-28T07:55:27.822921756Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 4, - "name": "Start/Stop Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 412, - "CreatedAt": "2020-09-08T21:39:26.570087-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570087-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0, - "status": "failed", - "status_reason": "Observed Failure Rate for Critical Attribute is greater than 10%", - "failure_rate": 1.5028253400346423, - "history": [{ - "ID": 359, - "CreatedAt": "2020-09-07T15:47:21.331487495Z", - "UpdatedAt": "2020-09-07T15:47:21.331487495Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }, { - "ID": 306, - "CreatedAt": "2020-09-07T15:38:56.628646457Z", - "UpdatedAt": "2020-09-07T15:38:56.628646457Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }, { - "ID": 253, - "CreatedAt": "2020-09-07T15:26:07.500102516Z", - "UpdatedAt": "2020-09-07T15:26:07.500102516Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }, { - "ID": 200, - "CreatedAt": "2020-09-07T15:19:17.462455401Z", - "UpdatedAt": "2020-09-07T15:19:17.462455401Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }, { - "ID": 147, - "CreatedAt": "2020-09-07T15:10:40.241718365Z", - "UpdatedAt": "2020-09-07T15:10:40.241718365Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }, { - "ID": 94, - "CreatedAt": "2020-09-06T23:14:39.844608938Z", - "UpdatedAt": "2020-09-06T23:14:39.844608938Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }, { - "ID": 41, - "CreatedAt": "2020-08-28T07:55:27.823009241Z", - "UpdatedAt": "2020-08-28T07:55:27.823009241Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 5, - "name": "Reallocated Sectors Count", - "value": 1, - "worst": 1, - "thresh": 5, - "raw_value": 1975, - "raw_string": "1975", - "when_failed": "now", - "transformed_value": 0 - }] - }, { - "ID": 413, - "CreatedAt": "2020-09-08T21:39:26.570167-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570167-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.01087335627722523, - "history": [{ - "ID": 360, - "CreatedAt": "2020-09-07T15:47:21.331571895Z", - "UpdatedAt": "2020-09-07T15:47:21.331571895Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 307, - "CreatedAt": "2020-09-07T15:38:56.628722958Z", - "UpdatedAt": "2020-09-07T15:38:56.628722958Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 254, - "CreatedAt": "2020-09-07T15:26:07.500193018Z", - "UpdatedAt": "2020-09-07T15:26:07.500193018Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 201, - "CreatedAt": "2020-09-07T15:19:17.462534501Z", - "UpdatedAt": "2020-09-07T15:19:17.462534501Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 148, - "CreatedAt": "2020-09-07T15:10:40.241808366Z", - "UpdatedAt": "2020-09-07T15:10:40.241808366Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 95, - "CreatedAt": "2020-09-06T23:14:39.84467344Z", - "UpdatedAt": "2020-09-06T23:14:39.84467344Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 42, - "CreatedAt": "2020-08-28T07:55:27.823120387Z", - "UpdatedAt": "2020-08-28T07:55:27.823120387Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 7, - "name": "Seek Error Rate", - "value": 100, - "worst": 100, - "thresh": 67, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 414, - "CreatedAt": "2020-09-08T21:39:26.57024-07:00", - "UpdatedAt": "2020-09-08T21:39:26.57024-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 361, - "CreatedAt": "2020-09-07T15:47:21.331652696Z", - "UpdatedAt": "2020-09-07T15:47:21.331652696Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 308, - "CreatedAt": "2020-09-07T15:38:56.628830258Z", - "UpdatedAt": "2020-09-07T15:38:56.628830258Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 255, - "CreatedAt": "2020-09-07T15:26:07.500281521Z", - "UpdatedAt": "2020-09-07T15:26:07.500281521Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 202, - "CreatedAt": "2020-09-07T15:19:17.462611201Z", - "UpdatedAt": "2020-09-07T15:19:17.462611201Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 149, - "CreatedAt": "2020-09-07T15:10:40.241893167Z", - "UpdatedAt": "2020-09-07T15:10:40.241893167Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 96, - "CreatedAt": "2020-09-06T23:14:39.844746142Z", - "UpdatedAt": "2020-09-06T23:14:39.844746142Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 43, - "CreatedAt": "2020-08-28T07:55:27.823221736Z", - "UpdatedAt": "2020-08-28T07:55:27.823221736Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 8, - "name": "Seek Time Performance", - "value": 118, - "worst": 118, - "thresh": 20, - "raw_value": 33, - "raw_string": "33", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 415, - "CreatedAt": "2020-09-08T21:39:26.570316-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570316-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 362, - "CreatedAt": "2020-09-07T15:47:21.331733496Z", - "UpdatedAt": "2020-09-07T15:47:21.331733496Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 309, - "CreatedAt": "2020-09-07T15:38:56.628909459Z", - "UpdatedAt": "2020-09-07T15:38:56.628909459Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 256, - "CreatedAt": "2020-09-07T15:26:07.500372023Z", - "UpdatedAt": "2020-09-07T15:26:07.500372023Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 203, - "CreatedAt": "2020-09-07T15:19:17.4627161Z", - "UpdatedAt": "2020-09-07T15:19:17.4627161Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 150, - "CreatedAt": "2020-09-07T15:10:40.241974767Z", - "UpdatedAt": "2020-09-07T15:10:40.241974767Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 97, - "CreatedAt": "2020-09-06T23:14:39.844810044Z", - "UpdatedAt": "2020-09-06T23:14:39.844810044Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 44, - "CreatedAt": "2020-08-28T07:55:27.823321577Z", - "UpdatedAt": "2020-08-28T07:55:27.823321577Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 9, - "name": "Power-On Hours", - "value": 91, - "worst": 91, - "thresh": 0, - "raw_value": 65592, - "raw_string": "65592", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 416, - "CreatedAt": "2020-09-08T21:39:26.570394-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570394-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.05459827163896099, - "history": [{ - "ID": 363, - "CreatedAt": "2020-09-07T15:47:21.331813896Z", - "UpdatedAt": "2020-09-07T15:47:21.331813896Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 310, - "CreatedAt": "2020-09-07T15:38:56.62898266Z", - "UpdatedAt": "2020-09-07T15:38:56.62898266Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 257, - "CreatedAt": "2020-09-07T15:26:07.500462326Z", - "UpdatedAt": "2020-09-07T15:26:07.500462326Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 204, - "CreatedAt": "2020-09-07T15:19:17.462794Z", - "UpdatedAt": "2020-09-07T15:19:17.462794Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 151, - "CreatedAt": "2020-09-07T15:10:40.242057668Z", - "UpdatedAt": "2020-09-07T15:10:40.242057668Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 98, - "CreatedAt": "2020-09-06T23:14:39.844880446Z", - "UpdatedAt": "2020-09-06T23:14:39.844880446Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 45, - "CreatedAt": "2020-08-28T07:55:27.823417848Z", - "UpdatedAt": "2020-08-28T07:55:27.823417848Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 10, - "name": "Spin Retry Count", - "value": 100, - "worst": 100, - "thresh": 60, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 417, - "CreatedAt": "2020-09-08T21:39:26.570475-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570475-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0, - "status": "warn", - "status_reason": "Observed Failure Rate for Attribute is greater than 10%", - "failure_rate": 0.12354840389522469, - "history": [{ - "ID": 364, - "CreatedAt": "2020-09-07T15:47:21.331899296Z", - "UpdatedAt": "2020-09-07T15:47:21.331899296Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 311, - "CreatedAt": "2020-09-07T15:38:56.629065161Z", - "UpdatedAt": "2020-09-07T15:38:56.629065161Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 258, - "CreatedAt": "2020-09-07T15:26:07.500549628Z", - "UpdatedAt": "2020-09-07T15:26:07.500549628Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 205, - "CreatedAt": "2020-09-07T15:19:17.4628661Z", - "UpdatedAt": "2020-09-07T15:19:17.4628661Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 152, - "CreatedAt": "2020-09-07T15:10:40.242167169Z", - "UpdatedAt": "2020-09-07T15:10:40.242167169Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 99, - "CreatedAt": "2020-09-06T23:14:39.844953848Z", - "UpdatedAt": "2020-09-06T23:14:39.844953848Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 46, - "CreatedAt": "2020-08-28T07:55:27.823514062Z", - "UpdatedAt": "2020-08-28T07:55:27.823514062Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 12, - "name": "Power Cycle Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 86, - "raw_string": "86", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 418, - "CreatedAt": "2020-09-08T21:39:26.570559-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570559-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 365, - "CreatedAt": "2020-09-07T15:47:21.332006096Z", - "UpdatedAt": "2020-09-07T15:47:21.332006096Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 312, - "CreatedAt": "2020-09-07T15:38:56.629162161Z", - "UpdatedAt": "2020-09-07T15:38:56.629162161Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 259, - "CreatedAt": "2020-09-07T15:26:07.500657031Z", - "UpdatedAt": "2020-09-07T15:26:07.500657031Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 206, - "CreatedAt": "2020-09-07T15:19:17.462996099Z", - "UpdatedAt": "2020-09-07T15:19:17.462996099Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 153, - "CreatedAt": "2020-09-07T15:10:40.242253969Z", - "UpdatedAt": "2020-09-07T15:10:40.242253969Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 100, - "CreatedAt": "2020-09-06T23:14:39.84503215Z", - "UpdatedAt": "2020-09-06T23:14:39.84503215Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 47, - "CreatedAt": "2020-08-28T07:55:27.823595321Z", - "UpdatedAt": "2020-08-28T07:55:27.823595321Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 192, - "name": "Power-off Retract Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 419, - "CreatedAt": "2020-09-08T21:39:26.57063-07:00", - "UpdatedAt": "2020-09-08T21:39:26.57063-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 366, - "CreatedAt": "2020-09-07T15:47:21.332093797Z", - "UpdatedAt": "2020-09-07T15:47:21.332093797Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 313, - "CreatedAt": "2020-09-07T15:38:56.629235062Z", - "UpdatedAt": "2020-09-07T15:38:56.629235062Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 260, - "CreatedAt": "2020-09-07T15:26:07.500743533Z", - "UpdatedAt": "2020-09-07T15:26:07.500743533Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 207, - "CreatedAt": "2020-09-07T15:19:17.463072899Z", - "UpdatedAt": "2020-09-07T15:19:17.463072899Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 154, - "CreatedAt": "2020-09-07T15:10:40.24235167Z", - "UpdatedAt": "2020-09-07T15:10:40.24235167Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 101, - "CreatedAt": "2020-09-06T23:14:39.845090052Z", - "UpdatedAt": "2020-09-06T23:14:39.845090052Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 48, - "CreatedAt": "2020-08-28T07:55:27.823681715Z", - "UpdatedAt": "2020-08-28T07:55:27.823681715Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 193, - "name": "Load Cycle Count", - "value": 95, - "worst": 95, - "thresh": 0, - "raw_value": 6244, - "raw_string": "6244", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 420, - "CreatedAt": "2020-09-08T21:39:26.570714-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570714-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25, - "status": "passed", - "history": [{ - "ID": 367, - "CreatedAt": "2020-09-07T15:47:21.332179497Z", - "UpdatedAt": "2020-09-07T15:47:21.332179497Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }, { - "ID": 314, - "CreatedAt": "2020-09-07T15:38:56.629309963Z", - "UpdatedAt": "2020-09-07T15:38:56.629309963Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }, { - "ID": 261, - "CreatedAt": "2020-09-07T15:26:07.500841536Z", - "UpdatedAt": "2020-09-07T15:26:07.500841536Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }, { - "ID": 208, - "CreatedAt": "2020-09-07T15:19:17.463146099Z", - "UpdatedAt": "2020-09-07T15:19:17.463146099Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }, { - "ID": 155, - "CreatedAt": "2020-09-07T15:10:40.242422871Z", - "UpdatedAt": "2020-09-07T15:10:40.242422871Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }, { - "ID": 102, - "CreatedAt": "2020-09-06T23:14:39.845149154Z", - "UpdatedAt": "2020-09-06T23:14:39.845149154Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }, { - "ID": 49, - "CreatedAt": "2020-08-28T07:55:27.823787578Z", - "UpdatedAt": "2020-08-28T07:55:27.823787578Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 194, - "name": "Temperature", - "value": 240, - "worst": 240, - "thresh": 0, - "raw_value": 167504969753, - "raw_string": "25 (Min/Max 19/39)", - "when_failed": "", - "transformed_value": 25 - }] - }, { - "ID": 421, - "CreatedAt": "2020-09-08T21:39:26.570794-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570794-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0, - "status": "warn", - "status_reason": "Could not determine Observed Failure Rate for Critical Attribute", - "history": [{ - "ID": 368, - "CreatedAt": "2020-09-07T15:47:21.332261097Z", - "UpdatedAt": "2020-09-07T15:47:21.332261097Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 315, - "CreatedAt": "2020-09-07T15:38:56.629382363Z", - "UpdatedAt": "2020-09-07T15:38:56.629382363Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 262, - "CreatedAt": "2020-09-07T15:26:07.500933439Z", - "UpdatedAt": "2020-09-07T15:26:07.500933439Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 209, - "CreatedAt": "2020-09-07T15:19:17.463228599Z", - "UpdatedAt": "2020-09-07T15:19:17.463228599Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 156, - "CreatedAt": "2020-09-07T15:10:40.242496871Z", - "UpdatedAt": "2020-09-07T15:10:40.242496871Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 103, - "CreatedAt": "2020-09-06T23:14:39.845209356Z", - "UpdatedAt": "2020-09-06T23:14:39.845209356Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 50, - "CreatedAt": "2020-08-28T07:55:27.823890798Z", - "UpdatedAt": "2020-08-28T07:55:27.823890798Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 196, - "name": "Reallocation Event Count", - "value": 1, - "worst": 1, - "thresh": 0, - "raw_value": 3831, - "raw_string": "3831", - "when_failed": "", - "transformed_value": 0 - }] - }, { - "ID": 422, - "CreatedAt": "2020-09-08T21:39:26.570866-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570866-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 8, - "raw_string": "8", - "when_failed": "", - "transformed_value": 0, - "status": "failed", - "status_reason": "Observed Failure Rate for Critical Attribute is greater than 10%", - "failure_rate": 0.6108100007493069, - "history": [{ - "ID": 369, - "CreatedAt": "2020-09-07T15:47:21.332346697Z", - "UpdatedAt": "2020-09-07T15:47:21.332346697Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 8, - "raw_string": "8", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 316, - "CreatedAt": "2020-09-07T15:38:56.629465264Z", - "UpdatedAt": "2020-09-07T15:38:56.629465264Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 8, - "raw_string": "8", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 263, - "CreatedAt": "2020-09-07T15:26:07.501028141Z", - "UpdatedAt": "2020-09-07T15:26:07.501028141Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 8, - "raw_string": "8", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 210, - "CreatedAt": "2020-09-07T15:19:17.463302498Z", - "UpdatedAt": "2020-09-07T15:19:17.463302498Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 197, - "name": "Current Pending Sector Count", + "name": "Read Error Rate", "value": 100, + "thresh": 16, "worst": 100, - "thresh": 0, - "raw_value": 8, - "raw_string": "8", + "raw_value": 0, + "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 157, - "CreatedAt": "2020-09-07T15:10:40.242564072Z", - "UpdatedAt": "2020-09-07T15:10:40.242564072Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 197, - "name": "Current Pending Sector Count", + }, + "10": { + "attribute_id": 10, + "name": "Spin Retry Count", "value": 100, + "thresh": 60, "worst": 100, - "thresh": 0, - "raw_value": 8, - "raw_string": "8", + "raw_value": 0, + "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 104, - "CreatedAt": "2020-09-06T23:14:39.845294758Z", - "UpdatedAt": "2020-09-06T23:14:39.845294758Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 197, - "name": "Current Pending Sector Count", + }, + "12": { + "attribute_id": 12, + "name": "Power Cycle Count", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 8, - "raw_string": "8", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 51, - "CreatedAt": "2020-08-28T07:55:27.823980673Z", - "UpdatedAt": "2020-08-28T07:55:27.823980673Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 197, - "name": "Current Pending Sector Count", - "value": 100, "worst": 100, - "thresh": 0, - "raw_value": 8, - "raw_string": "8", + "raw_value": 86, + "raw_string": "86", "when_failed": "", "transformed_value": 0 - }] - }, { - "ID": 423, - "CreatedAt": "2020-09-08T21:39:26.570936-07:00", - "UpdatedAt": "2020-09-08T21:39:26.570936-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "failure_rate": 0.028675322159886437, - "history": [{ - "ID": 370, - "CreatedAt": "2020-09-07T15:47:21.332430997Z", - "UpdatedAt": "2020-09-07T15:47:21.332430997Z", - "DeletedAt": null, - "smart_id": 39, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, + }, + "192": { + "attribute_id": 192, + "name": "Power-off Retract Count", + "value": 95, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 95, + "raw_value": 6244, + "raw_string": "6244", "when_failed": "", "transformed_value": 0 - }, { - "ID": 317, - "CreatedAt": "2020-09-07T15:38:56.629541365Z", - "UpdatedAt": "2020-09-07T15:38:56.629541365Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, + }, + "193": { + "attribute_id": 193, + "name": "Load Cycle Count", + "value": 95, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 95, + "raw_value": 6244, + "raw_string": "6244", "when_failed": "", "transformed_value": 0 - }, { - "ID": 264, - "CreatedAt": "2020-09-07T15:26:07.501116944Z", - "UpdatedAt": "2020-09-07T15:26:07.501116944Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, + }, + "194": { + "attribute_id": 194, + "name": "Temperature", + "value": 240, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 240, + "raw_value": 167504969753, + "raw_string": "25 (Min/Max 19/39)", "when_failed": "", "transformed_value": 0 - }, { - "ID": 211, - "CreatedAt": "2020-09-07T15:19:17.463380498Z", - "UpdatedAt": "2020-09-07T15:19:17.463380498Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, - "worst": 100, + }, + "196": { + "attribute_id": 196, + "name": "Reallocation Event Count", + "value": 1, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 1, + "raw_value": 3831, + "raw_string": "3831", "when_failed": "", "transformed_value": 0 - }, { - "ID": 158, - "CreatedAt": "2020-09-07T15:10:40.242633572Z", - "UpdatedAt": "2020-09-07T15:10:40.242633572Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", + }, + "197": { + "attribute_id": 197, + "name": "Current Pending Sector Count", "value": 100, - "worst": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0 - }, { - "ID": 105, - "CreatedAt": "2020-09-06T23:14:39.84535416Z", - "UpdatedAt": "2020-09-06T23:14:39.84535416Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 198, - "name": "(Offline) Uncorrectable Sector Count", - "value": 100, "worst": 100, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "raw_value": 8, + "raw_string": "8", "when_failed": "", "transformed_value": 0 - }, { - "ID": 52, - "CreatedAt": "2020-08-28T07:55:27.824077866Z", - "UpdatedAt": "2020-08-28T07:55:27.824077866Z", - "DeletedAt": null, - "smart_id": 3, + }, + "198": { "attribute_id": 198, "name": "(Offline) Uncorrectable Sector Count", "value": 100, - "worst": 100, "thresh": 0, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }] - }, { - "ID": 424, - "CreatedAt": "2020-09-08T21:39:26.571034-07:00", - "UpdatedAt": "2020-09-08T21:39:26.571034-07:00", - "DeletedAt": null, - "smart_id": 45, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", - "when_failed": "", - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 371, - "CreatedAt": "2020-09-07T15:47:21.332512198Z", - "UpdatedAt": "2020-09-07T15:47:21.332512198Z", - "DeletedAt": null, - "smart_id": 39, + }, + "199": { "attribute_id": 199, "name": "UltraDMA CRC Error Count", "value": 200, - "worst": 200, "thresh": 0, + "worst": 200, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 318, - "CreatedAt": "2020-09-07T15:38:56.629610265Z", - "UpdatedAt": "2020-09-07T15:38:56.629610265Z", - "DeletedAt": null, - "smart_id": 33, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + }, + "2": { + "attribute_id": 2, + "name": "Throughput Performance", + "value": 136, + "thresh": 54, + "worst": 136, + "raw_value": 91, + "raw_string": "91", "when_failed": "", "transformed_value": 0 - }, { - "ID": 265, - "CreatedAt": "2020-09-07T15:26:07.501203046Z", - "UpdatedAt": "2020-09-07T15:26:07.501203046Z", - "DeletedAt": null, - "smart_id": 27, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + }, + "3": { + "attribute_id": 3, + "name": "Spin-Up Time", + "value": 125, + "thresh": 24, + "worst": 125, + "raw_value": 17192124596, + "raw_string": "180 (Average 187)", "when_failed": "", "transformed_value": 0 - }, { - "ID": 212, - "CreatedAt": "2020-09-07T15:19:17.463463398Z", - "UpdatedAt": "2020-09-07T15:19:17.463463398Z", - "DeletedAt": null, - "smart_id": 21, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, + }, + "4": { + "attribute_id": 4, + "name": "Start/Stop Count", + "value": 100, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 100, + "raw_value": 86, + "raw_string": "86", "when_failed": "", "transformed_value": 0 - }, { - "ID": 159, - "CreatedAt": "2020-09-07T15:10:40.242702673Z", - "UpdatedAt": "2020-09-07T15:10:40.242702673Z", - "DeletedAt": null, - "smart_id": 15, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, - "thresh": 0, + }, + "5": { + "attribute_id": 5, + "name": "Reallocated Sectors Count", + "value": 1, + "thresh": 5, + "worst": 1, + "raw_value": 1975, + "raw_string": "1975", + "when_failed": "now", + "transformed_value": 0 + }, + "7": { + "attribute_id": 7, + "name": "Seek Error Rate", + "value": 100, + "thresh": 67, + "worst": 100, "raw_value": 0, "raw_string": "0", "when_failed": "", "transformed_value": 0 - }, { - "ID": 106, - "CreatedAt": "2020-09-06T23:14:39.845437463Z", - "UpdatedAt": "2020-09-06T23:14:39.845437463Z", - "DeletedAt": null, - "smart_id": 9, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, - "thresh": 0, - "raw_value": 0, - "raw_string": "0", + }, + "8": { + "attribute_id": 8, + "name": "Seek Time Performance", + "value": 118, + "thresh": 20, + "worst": 118, + "raw_value": 33, + "raw_string": "33", "when_failed": "", "transformed_value": 0 - }, { - "ID": 53, - "CreatedAt": "2020-08-28T07:55:27.824166466Z", - "UpdatedAt": "2020-08-28T07:55:27.824166466Z", - "DeletedAt": null, - "smart_id": 3, - "attribute_id": 199, - "name": "UltraDMA CRC Error Count", - "value": 200, - "worst": 200, + }, + "9": { + "attribute_id": 9, + "name": "Power-On Hours", + "value": 91, "thresh": 0, - "raw_value": 0, - "raw_string": "0", + "worst": 91, + "raw_value": 65592, + "raw_string": "65592", "when_failed": "", "transformed_value": 0 - }] - }], - "nvme_attributes": [], - "scsi_attributes": [] + } + } }] - }, "metadata": { + }, + "metadata": { "1": { "ideal": "low", "critical": false, @@ -2141,12 +240,22 @@ export const sdc = { "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": 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": 155, + "high": 170, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 170, "high": 185, "annual_failure_rate": 0, @@ -2190,17 +299,32 @@ export const sdc = { "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": 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": 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": 400, + "high": 480, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 480, "high": 560, "annual_failure_rate": 0, @@ -2256,7 +380,12 @@ export const sdc = { "description": "Uncorrected read errors reported to the operating system.", "display_type": "normalized" }, - "170": {"ideal": "", "critical": false, "description": "See attribute E8.", "display_type": "normalized"}, + "170": { + "ideal": "", + "critical": false, + "description": "See attribute E8.", + "display_type": "normalized" + }, "171": { "ideal": "", "critical": false, @@ -2367,7 +496,12 @@ export const sdc = { "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]}], + }, { + "low": 130, + "high": 260, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }], "display_type": "raw" }, "184": { @@ -2379,12 +513,22 @@ export const sdc = { "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": 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": 96, + "high": 97, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 97, "high": 97, "annual_failure_rate": 0, @@ -2666,12 +810,22 @@ export const sdc = { "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": 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": 84, + "high": 96, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 96, "high": 108, "annual_failure_rate": 0.04074570216566197, @@ -3213,7 +1367,12 @@ export const sdc = { "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]}], + }, { + "low": 91, + "high": 104, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }], "display_type": "raw" }, "5": { @@ -3293,12 +1452,22 @@ export const sdc = { "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": 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": 148, + "high": 166, + "annual_failure_rate": 0, + "error_interval": [0, 0] + }, { "low": 166, "high": 184, "annual_failure_rate": 0, @@ -3323,5 +1492,6 @@ export const sdc = { "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 5884342..35e73d1 100644 --- a/webapp/frontend/src/app/data/mock/device/details/sdd.ts +++ b/webapp/frontend/src/app/data/mock/device/details/sdd.ts @@ -1,1240 +1,208 @@ export const sdd = { "data": { - "CreatedAt": "2020-08-28T07:55:27.76380029Z", - "UpdatedAt": "2020-09-08T21:39:26.575283-07:00", - "DeletedAt": null, - "wwn": "0x5000cca252c859cc", - "device_name": "sdd", - "manufacturer": "SEAGATE", - "model_name": "WDC_WD80EFAX-68LHPN0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "7SGLXXXXX", - "firmware": "", - "rotational_speed": 7200, - "capacity": 4000787030016, - "form_factor": "3.5 inches", - "smart_support": false, - "device_protocol": "SCSI", - "device_type": "scsi", - "smart_results": [{ - "ID": 47, - "CreatedAt": "2020-09-08T21:39:26.576373-07:00", - "UpdatedAt": "2020-09-08T21:39:26.576373-07:00", + "device": { + "CreatedAt": "2021-06-24T21:17:31.30374-07:00", + "UpdatedAt": "2021-06-26T14:26:20.902325-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": "2020-08-21T22:27:02Z", "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T15:27:02-07:00", - "smart_status": "passed", + "device_protocol": "SCSI", "temp": 34, "power_on_hours": 43549, "power_cycle_count": 0, - "ata_attributes": [], - "nvme_attributes": [], - "scsi_attributes": [{ - "ID": 183, - "CreatedAt": "2020-09-08T21:39:26.576671-07:00", - "UpdatedAt": "2020-09-08T21:39:26.576671-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 157, - "CreatedAt": "2020-09-07T15:47:21.34270442Z", - "UpdatedAt": "2020-09-07T15:47:21.34270442Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 131, - "CreatedAt": "2020-09-07T15:38:56.63806264Z", - "UpdatedAt": "2020-09-07T15:38:56.63806264Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 105, - "CreatedAt": "2020-09-07T15:26:07.511359323Z", - "UpdatedAt": "2020-09-07T15:26:07.511359323Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 79, - "CreatedAt": "2020-09-07T15:19:17.472566367Z", - "UpdatedAt": "2020-09-07T15:19:17.472566367Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 53, - "CreatedAt": "2020-09-07T15:10:40.252068341Z", - "UpdatedAt": "2020-09-07T15:10:40.252068341Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 27, - "CreatedAt": "2020-09-06T23:14:39.854497534Z", - "UpdatedAt": "2020-09-06T23:14:39.854497534Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 1, - "CreatedAt": "2020-08-28T07:55:27.845073051Z", - "UpdatedAt": "2020-08-28T07:55:27.845073051Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "scsi_grown_defect_list", - "name": "Grown Defect List", - "value": 56, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 184, - "CreatedAt": "2020-09-08T21:39:26.577142-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577142-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 158, - "CreatedAt": "2020-09-07T15:47:21.34285782Z", - "UpdatedAt": "2020-09-07T15:47:21.34285782Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 132, - "CreatedAt": "2020-09-07T15:38:56.638194141Z", - "UpdatedAt": "2020-09-07T15:38:56.638194141Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 106, - "CreatedAt": "2020-09-07T15:26:07.511676732Z", - "UpdatedAt": "2020-09-07T15:26:07.511676732Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 80, - "CreatedAt": "2020-09-07T15:19:17.472704067Z", - "UpdatedAt": "2020-09-07T15:19:17.472704067Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 54, - "CreatedAt": "2020-09-07T15:10:40.252408443Z", - "UpdatedAt": "2020-09-07T15:10:40.252408443Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 28, - "CreatedAt": "2020-09-06T23:14:39.854629938Z", - "UpdatedAt": "2020-09-06T23:14:39.854629938Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 2, - "CreatedAt": "2020-08-28T07:55:27.845217252Z", - "UpdatedAt": "2020-08-28T07:55:27.845217252Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "read.errors_corrected_by_eccfast", - "name": "Read Errors Corrected by ECC Fast", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 185, - "CreatedAt": "2020-09-08T21:39:26.577223-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577223-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 159, - "CreatedAt": "2020-09-07T15:47:21.342970521Z", - "UpdatedAt": "2020-09-07T15:47:21.342970521Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 133, - "CreatedAt": "2020-09-07T15:38:56.638272842Z", - "UpdatedAt": "2020-09-07T15:38:56.638272842Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 107, - "CreatedAt": "2020-09-07T15:26:07.511771334Z", - "UpdatedAt": "2020-09-07T15:26:07.511771334Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 81, - "CreatedAt": "2020-09-07T15:19:17.472780267Z", - "UpdatedAt": "2020-09-07T15:19:17.472780267Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 55, - "CreatedAt": "2020-09-07T15:10:40.252543044Z", - "UpdatedAt": "2020-09-07T15:10:40.252543044Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 29, - "CreatedAt": "2020-09-06T23:14:39.85470424Z", - "UpdatedAt": "2020-09-06T23:14:39.85470424Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "read.errors_corrected_by_eccdelayed", - "name": "Read Errors Corrected by ECC Delayed", + "attrs": { + "read_correction_algorithm_invocations": { + "attribute_id": "read_correction_algorithm_invocations", + "name": "Read Correction Algorithm Invocations", "value": 0, - "thresh": 0, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 3, - "CreatedAt": "2020-08-28T07:55:27.845307694Z", - "UpdatedAt": "2020-08-28T07:55:27.845307694Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "read.errors_corrected_by_eccdelayed", + }, + "read_errors_corrected_by_eccdelayed": { + "attribute_id": "read_errors_corrected_by_eccdelayed", "name": "Read Errors Corrected by ECC Delayed", "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 186, - "CreatedAt": "2020-09-08T21:39:26.577322-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577322-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 160, - "CreatedAt": "2020-09-07T15:47:21.343052321Z", - "UpdatedAt": "2020-09-07T15:47:21.343052321Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 134, - "CreatedAt": "2020-09-07T15:38:56.638349442Z", - "UpdatedAt": "2020-09-07T15:38:56.638349442Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 108, - "CreatedAt": "2020-09-07T15:26:07.512120944Z", - "UpdatedAt": "2020-09-07T15:26:07.512120944Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 82, - "CreatedAt": "2020-09-07T15:19:17.472863366Z", - "UpdatedAt": "2020-09-07T15:19:17.472863366Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 56, - "CreatedAt": "2020-09-07T15:10:40.252654845Z", - "UpdatedAt": "2020-09-07T15:10:40.252654845Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 30, - "CreatedAt": "2020-09-06T23:14:39.854773542Z", - "UpdatedAt": "2020-09-06T23:14:39.854773542Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", - "name": "Read Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, + }, + "read_errors_corrected_by_eccfast": { + "attribute_id": "read_errors_corrected_by_eccfast", + "name": "Read Errors Corrected by ECC Fast", + "value": 300357663, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 4, - "CreatedAt": "2020-08-28T07:55:27.845417944Z", - "UpdatedAt": "2020-08-28T07:55:27.845417944Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "read.errors_corrected_by_rereads_rewrites", + }, + "read_errors_corrected_by_rereads_rewrites": { + "attribute_id": "read_errors_corrected_by_rereads_rewrites", "name": "Read Errors Corrected by ReReads/ReWrites", "value": 0, "thresh": 0, "transformed_value": 0 - }] - }, { - "ID": 187, - "CreatedAt": "2020-09-08T21:39:26.577402-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577402-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 300357663, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 161, - "CreatedAt": "2020-09-07T15:47:21.343130621Z", - "UpdatedAt": "2020-09-07T15:47:21.343130621Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 135, - "CreatedAt": "2020-09-07T15:38:56.638419243Z", - "UpdatedAt": "2020-09-07T15:38:56.638419243Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "read.total_errors_corrected", + }, + "read_total_errors_corrected": { + "attribute_id": "read_total_errors_corrected", "name": "Read Total Errors Corrected", "value": 300357663, - "thresh": 0, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 109, - "CreatedAt": "2020-09-07T15:26:07.512289049Z", - "UpdatedAt": "2020-09-07T15:26:07.512289049Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 83, - "CreatedAt": "2020-09-07T15:19:17.472931366Z", - "UpdatedAt": "2020-09-07T15:19:17.472931366Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 57, - "CreatedAt": "2020-09-07T15:10:40.252764246Z", - "UpdatedAt": "2020-09-07T15:10:40.252764246Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 31, - "CreatedAt": "2020-09-06T23:14:39.854857145Z", - "UpdatedAt": "2020-09-06T23:14:39.854857145Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 5, - "CreatedAt": "2020-08-28T07:55:27.84550537Z", - "UpdatedAt": "2020-08-28T07:55:27.84550537Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "read.total_errors_corrected", - "name": "Read Total Errors Corrected", - "value": 300357663, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 188, - "CreatedAt": "2020-09-08T21:39:26.577467-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577467-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 162, - "CreatedAt": "2020-09-07T15:47:21.343232021Z", - "UpdatedAt": "2020-09-07T15:47:21.343232021Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 136, - "CreatedAt": "2020-09-07T15:38:56.638492144Z", - "UpdatedAt": "2020-09-07T15:38:56.638492144Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 110, - "CreatedAt": "2020-09-07T15:26:07.512411952Z", - "UpdatedAt": "2020-09-07T15:26:07.512411952Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 84, - "CreatedAt": "2020-09-07T15:19:17.473000166Z", - "UpdatedAt": "2020-09-07T15:19:17.473000166Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 58, - "CreatedAt": "2020-09-07T15:10:40.252885147Z", - "UpdatedAt": "2020-09-07T15:10:40.252885147Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 32, - "CreatedAt": "2020-09-06T23:14:39.854921646Z", - "UpdatedAt": "2020-09-06T23:14:39.854921646Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 6, - "CreatedAt": "2020-08-28T07:55:27.845607015Z", - "UpdatedAt": "2020-08-28T07:55:27.845607015Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "read.correction_algorithm_invocations", - "name": "Read Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 189, - "CreatedAt": "2020-09-08T21:39:26.577528-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577528-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 163, - "CreatedAt": "2020-09-07T15:47:21.343302621Z", - "UpdatedAt": "2020-09-07T15:47:21.343302621Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 137, - "CreatedAt": "2020-09-07T15:38:56.638557144Z", - "UpdatedAt": "2020-09-07T15:38:56.638557144Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 111, - "CreatedAt": "2020-09-07T15:26:07.512526855Z", - "UpdatedAt": "2020-09-07T15:26:07.512526855Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 85, - "CreatedAt": "2020-09-07T15:19:17.473078066Z", - "UpdatedAt": "2020-09-07T15:19:17.473078066Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 59, - "CreatedAt": "2020-09-07T15:10:40.252987648Z", - "UpdatedAt": "2020-09-07T15:10:40.252987648Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 33, - "CreatedAt": "2020-09-06T23:14:39.854986748Z", - "UpdatedAt": "2020-09-06T23:14:39.854986748Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "read.total_uncorrected_errors", - "name": "Read Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 7, - "CreatedAt": "2020-08-28T07:55:27.845686961Z", - "UpdatedAt": "2020-08-28T07:55:27.845686961Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "read.total_uncorrected_errors", + }, + "read_total_uncorrected_errors": { + "attribute_id": "read_total_uncorrected_errors", "name": "Read Total Uncorrected Errors", "value": 0, "thresh": 0, "transformed_value": 0 - }] - }, { - "ID": 190, - "CreatedAt": "2020-09-08T21:39:26.577585-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577585-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 164, - "CreatedAt": "2020-09-07T15:47:21.343385821Z", - "UpdatedAt": "2020-09-07T15:47:21.343385821Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 138, - "CreatedAt": "2020-09-07T15:38:56.638623345Z", - "UpdatedAt": "2020-09-07T15:38:56.638623345Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 112, - "CreatedAt": "2020-09-07T15:26:07.51269696Z", - "UpdatedAt": "2020-09-07T15:26:07.51269696Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 86, - "CreatedAt": "2020-09-07T15:19:17.473144665Z", - "UpdatedAt": "2020-09-07T15:19:17.473144665Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 60, - "CreatedAt": "2020-09-07T15:10:40.253104448Z", - "UpdatedAt": "2020-09-07T15:10:40.253104448Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 34, - "CreatedAt": "2020-09-06T23:14:39.85505285Z", - "UpdatedAt": "2020-09-06T23:14:39.85505285Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 8, - "CreatedAt": "2020-08-28T07:55:27.845805078Z", - "UpdatedAt": "2020-08-28T07:55:27.845805078Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "write.errors_corrected_by_eccfast", - "name": "Write Errors Corrected by ECC Fast", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 191, - "CreatedAt": "2020-09-08T21:39:26.577642-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577642-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 165, - "CreatedAt": "2020-09-07T15:47:21.343465022Z", - "UpdatedAt": "2020-09-07T15:47:21.343465022Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 139, - "CreatedAt": "2020-09-07T15:38:56.638687045Z", - "UpdatedAt": "2020-09-07T15:38:56.638687045Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 113, - "CreatedAt": "2020-09-07T15:26:07.512816463Z", - "UpdatedAt": "2020-09-07T15:26:07.512816463Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 87, - "CreatedAt": "2020-09-07T15:19:17.473246965Z", - "UpdatedAt": "2020-09-07T15:19:17.473246965Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, + }, + "scsi_grown_defect_list": { + "attribute_id": "scsi_grown_defect_list", + "name": "Grown Defect List", + "value": 56, "thresh": 0, "transformed_value": 0 - }, { - "ID": 61, - "CreatedAt": "2020-09-07T15:10:40.253434751Z", - "UpdatedAt": "2020-09-07T15:10:40.253434751Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", + }, + "write_correction_algorithm_invocations": { + "attribute_id": "write_correction_algorithm_invocations", + "name": "Write Correction Algorithm Invocations", "value": 0, - "thresh": 0, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 35, - "CreatedAt": "2020-09-06T23:14:39.855116452Z", - "UpdatedAt": "2020-09-06T23:14:39.855116452Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "write.errors_corrected_by_eccdelayed", + }, + "write_errors_corrected_by_eccdelayed": { + "attribute_id": "write_errors_corrected_by_eccdelayed", "name": "Write Errors Corrected by ECC Delayed", "value": 0, - "thresh": 0, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 9, - "CreatedAt": "2020-08-28T07:55:27.846267863Z", - "UpdatedAt": "2020-08-28T07:55:27.846267863Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "write.errors_corrected_by_eccdelayed", - "name": "Write Errors Corrected by ECC Delayed", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 192, - "CreatedAt": "2020-09-08T21:39:26.577699-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577699-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 166, - "CreatedAt": "2020-09-07T15:47:21.343534322Z", - "UpdatedAt": "2020-09-07T15:47:21.343534322Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 140, - "CreatedAt": "2020-09-07T15:38:56.638979448Z", - "UpdatedAt": "2020-09-07T15:38:56.638979448Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 114, - "CreatedAt": "2020-09-07T15:26:07.513298876Z", - "UpdatedAt": "2020-09-07T15:26:07.513298876Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 88, - "CreatedAt": "2020-09-07T15:19:17.473324965Z", - "UpdatedAt": "2020-09-07T15:19:17.473324965Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 62, - "CreatedAt": "2020-09-07T15:10:40.253539552Z", - "UpdatedAt": "2020-09-07T15:10:40.253539552Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 36, - "CreatedAt": "2020-09-06T23:14:39.855181654Z", - "UpdatedAt": "2020-09-06T23:14:39.855181654Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", - "name": "Write Errors Corrected by ReReads/ReWrites", + }, + "write_errors_corrected_by_eccfast": { + "attribute_id": "write_errors_corrected_by_eccfast", + "name": "Write Errors Corrected by ECC Fast", "value": 0, - "thresh": 0, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 10, - "CreatedAt": "2020-08-28T07:55:27.846466097Z", - "UpdatedAt": "2020-08-28T07:55:27.846466097Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "write.errors_corrected_by_rereads_rewrites", + }, + "write_errors_corrected_by_rereads_rewrites": { + "attribute_id": "write_errors_corrected_by_rereads_rewrites", "name": "Write Errors Corrected by ReReads/ReWrites", "value": 0, "thresh": 0, "transformed_value": 0 - }] - }, { - "ID": 193, - "CreatedAt": "2020-09-08T21:39:26.577768-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577768-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 167, - "CreatedAt": "2020-09-07T15:47:21.343602322Z", - "UpdatedAt": "2020-09-07T15:47:21.343602322Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 141, - "CreatedAt": "2020-09-07T15:38:56.639119449Z", - "UpdatedAt": "2020-09-07T15:38:56.639119449Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 115, - "CreatedAt": "2020-09-07T15:26:07.513392579Z", - "UpdatedAt": "2020-09-07T15:26:07.513392579Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 89, - "CreatedAt": "2020-09-07T15:19:17.473396265Z", - "UpdatedAt": "2020-09-07T15:19:17.473396265Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 63, - "CreatedAt": "2020-09-07T15:10:40.253617252Z", - "UpdatedAt": "2020-09-07T15:10:40.253617252Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 37, - "CreatedAt": "2020-09-06T23:14:39.855245056Z", - "UpdatedAt": "2020-09-06T23:14:39.855245056Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "write.total_errors_corrected", - "name": "Write Total Errors Corrected", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 11, - "CreatedAt": "2020-08-28T07:55:27.846680695Z", - "UpdatedAt": "2020-08-28T07:55:27.846680695Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "write.total_errors_corrected", + }, + "write_total_errors_corrected": { + "attribute_id": "write_total_errors_corrected", "name": "Write Total Errors Corrected", "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 194, - "CreatedAt": "2020-09-08T21:39:26.577827-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577827-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": -1, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 168, - "CreatedAt": "2020-09-07T15:47:21.343669122Z", - "UpdatedAt": "2020-09-07T15:47:21.343669122Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 142, - "CreatedAt": "2020-09-07T15:38:56.63923905Z", - "UpdatedAt": "2020-09-07T15:38:56.63923905Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 116, - "CreatedAt": "2020-09-07T15:26:07.513473381Z", - "UpdatedAt": "2020-09-07T15:26:07.513473381Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 90, - "CreatedAt": "2020-09-07T15:19:17.473465964Z", - "UpdatedAt": "2020-09-07T15:19:17.473465964Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 64, - "CreatedAt": "2020-09-07T15:10:40.253699153Z", - "UpdatedAt": "2020-09-07T15:10:40.253699153Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 38, - "CreatedAt": "2020-09-06T23:14:39.855310158Z", - "UpdatedAt": "2020-09-06T23:14:39.855310158Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 12, - "CreatedAt": "2020-08-28T07:55:27.847304842Z", - "UpdatedAt": "2020-08-28T07:55:27.847304842Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "write.correction_algorithm_invocations", - "name": "Write Correction Algorithm Invocations", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }, { - "ID": 195, - "CreatedAt": "2020-09-08T21:39:26.577884-07:00", - "UpdatedAt": "2020-09-08T21:39:26.577884-07:00", - "DeletedAt": null, - "smart_id": 47, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0, - "status": "passed", - "history": [{ - "ID": 169, - "CreatedAt": "2020-09-07T15:47:21.343735222Z", - "UpdatedAt": "2020-09-07T15:47:21.343735222Z", - "DeletedAt": null, - "smart_id": 41, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 143, - "CreatedAt": "2020-09-07T15:38:56.639331551Z", - "UpdatedAt": "2020-09-07T15:38:56.639331551Z", - "DeletedAt": null, - "smart_id": 35, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 117, - "CreatedAt": "2020-09-07T15:26:07.513551783Z", - "UpdatedAt": "2020-09-07T15:26:07.513551783Z", - "DeletedAt": null, - "smart_id": 29, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 91, - "CreatedAt": "2020-09-07T15:19:17.473531164Z", - "UpdatedAt": "2020-09-07T15:19:17.473531164Z", - "DeletedAt": null, - "smart_id": 23, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }, { - "ID": 65, - "CreatedAt": "2020-09-07T15:10:40.253767653Z", - "UpdatedAt": "2020-09-07T15:10:40.253767653Z", - "DeletedAt": null, - "smart_id": 17, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, + "thresh": -1, "transformed_value": 0 - }, { - "ID": 39, - "CreatedAt": "2020-09-06T23:14:39.85537276Z", - "UpdatedAt": "2020-09-06T23:14:39.85537276Z", - "DeletedAt": null, - "smart_id": 11, - "attribute_id": "write.total_uncorrected_errors", + }, + "write_total_uncorrected_errors": { + "attribute_id": "write_total_uncorrected_errors", "name": "Write Total Uncorrected Errors", "value": 0, "thresh": 0, "transformed_value": 0 - }, { - "ID": 13, - "CreatedAt": "2020-08-28T07:55:27.847458217Z", - "UpdatedAt": "2020-08-28T07:55:27.847458217Z", - "DeletedAt": null, - "smart_id": 5, - "attribute_id": "write.total_uncorrected_errors", - "name": "Write Total Uncorrected Errors", - "value": 0, - "thresh": 0, - "transformed_value": 0 - }] - }] + } + } }] - }, "metadata": { - "read.correction_algorithm_invocations": { + }, + "metadata": { + "read_correction_algorithm_invocations": { + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "read_errors_corrected_by_eccdelayed": { + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "read_errors_corrected_by_eccfast": { + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "read_errors_corrected_by_rereads_rewrites": { + "ideal": "low", + "critical": true, + "description": "", + "display_type": "" + }, + "read_total_errors_corrected": { "ideal": "", "critical": false, "description": "", "display_type": "" }, - "read.errors_corrected_by_eccdelayed": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "read.errors_corrected_by_eccfast": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "read.errors_corrected_by_rereads_rewrites": { + "read_total_uncorrected_errors": { "ideal": "low", "critical": true, "description": "", "display_type": "" }, - "read.total_errors_corrected": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "read.total_uncorrected_errors": {"ideal": "low", "critical": true, "description": "", "display_type": ""}, - "scsi_grown_defect_list": {"ideal": "low", "critical": true, "description": "", "display_type": ""}, - "write.correction_algorithm_invocations": { + "scsi_grown_defect_list": { + "ideal": "low", + "critical": true, + "description": "", + "display_type": "" + }, + "write_correction_algorithm_invocations": { + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "write_errors_corrected_by_eccdelayed": { + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "write_errors_corrected_by_eccfast": { "ideal": "", "critical": false, "description": "", "display_type": "" }, - "write.errors_corrected_by_eccdelayed": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "write.errors_corrected_by_eccfast": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "write.errors_corrected_by_rereads_rewrites": { + "write_errors_corrected_by_rereads_rewrites": { "ideal": "low", "critical": true, "description": "", "display_type": "" }, - "write.total_errors_corrected": {"ideal": "", "critical": false, "description": "", "display_type": ""}, - "write.total_uncorrected_errors": {"ideal": "low", "critical": true, "description": "", "display_type": ""} - }, "success": true + "write_total_errors_corrected": { + "ideal": "", + "critical": false, + "description": "", + "display_type": "" + }, + "write_total_uncorrected_errors": { + "ideal": "low", + "critical": true, + "description": "", + "display_type": "" + } + }, + "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 7c60702..70acf16 100644 --- a/webapp/frontend/src/app/data/mock/summary/data.ts +++ b/webapp/frontend/src/app/data/mock/summary/data.ts @@ -2,812 +2,597 @@ import * as moment from 'moment'; /* tslint:disable:max-line-length */ export const summary = { - "data": [{ - "CreatedAt": "2020-08-28T07:55:27.751071002Z", - "UpdatedAt": "2020-09-08T21:39:26.571901-07:00", - "DeletedAt": null, - "wwn": "0x5002538e40a22954", - "device_name": "sda", - "manufacturer": "ATA", - "model_name": "Samsung_SSD_860_EVO_500GB", - "interface_type": "SCSI", - "host_id": "NAS", - "interface_speed": "", - "serial_number": "S3YZNB0KBXXXXXX", - "firmware": "002C", - "rotational_speed": 0, - "capacity": 1024209543168, - "form_factor": "", - "smart_support": false, - "device_protocol": "NVMe", - "device_type": "nvme", - "smart_results": [{ - "ID": 46, - "CreatedAt": "2020-09-08T21:39:26.572596-07:00", - "UpdatedAt": "2020-09-08T21:39:26.572596-07:00", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T05:01:02-07:00", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 40, - "CreatedAt": "2020-09-07T15:47:21.336531606Z", - "UpdatedAt": "2020-09-07T15:47:21.336531606Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 34, - "CreatedAt": "2020-09-07T15:38:56.633173997Z", - "UpdatedAt": "2020-09-07T15:38:56.633173997Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 28, - "CreatedAt": "2020-09-07T15:26:07.504746443Z", - "UpdatedAt": "2020-09-07T15:26:07.504746443Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 22, - "CreatedAt": "2020-09-07T15:19:17.467677684Z", - "UpdatedAt": "2020-09-07T15:19:17.467677684Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 16, - "CreatedAt": "2020-09-07T15:10:40.245856096Z", - "UpdatedAt": "2020-09-07T15:10:40.245856096Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 10, - "CreatedAt": "2020-09-06T23:14:39.848993269Z", - "UpdatedAt": "2020-09-06T23:14:39.848993269Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 4, - "CreatedAt": "2020-08-28T07:55:27.833116549Z", - "UpdatedAt": "2020-08-28T07:55:27.833116549Z", - "DeletedAt": null, - "device_wwn": "0x5002538e40a22954", - "date": "2020-06-10T12:01:02Z", - "smart_status": "passed", - "temp": 36, - "power_on_hours": 2401, - "power_cycle_count": 266, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }] - }, { - "CreatedAt": "2020-08-28T07:55:27.755292213Z", - "UpdatedAt": "2020-09-08T21:39:26.56453-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264eb01d7", - "device_name": "sdb", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "6.0 Gb/s", - "serial_number": "9RK1XXXXX", - "firmware": "81.00A81", - "rotational_speed": 5400, - "capacity": 14000519643136, - "form_factor": "3.5 inches", - "smart_support": false, - "device_protocol": "ATA", - "device_type": "sat", - "smart_results": [{ - "ID": 44, - "CreatedAt": "2020-09-08T21:39:26.565492-07:00", - "UpdatedAt": "2020-09-08T21:39:26.565492-07:00", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-20T17:03:30-07:00", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 43, - "CreatedAt": "2020-09-08T21:39:26.552765-07:00", - "UpdatedAt": "2020-09-08T21:39:26.552765-07:00", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-20T17:03:30-07:00", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 38, - "CreatedAt": "2020-09-07T15:47:21.319490869Z", - "UpdatedAt": "2020-09-07T15:47:21.319490869Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 37, - "CreatedAt": "2020-09-07T15:47:21.305997039Z", - "UpdatedAt": "2020-09-07T15:47:21.305997039Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 32, - "CreatedAt": "2020-09-07T15:38:56.621396993Z", - "UpdatedAt": "2020-09-07T15:38:56.621396993Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 31, - "CreatedAt": "2020-09-07T15:38:56.608679081Z", - "UpdatedAt": "2020-09-07T15:38:56.608679081Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 26, - "CreatedAt": "2020-09-07T15:26:07.49254641Z", - "UpdatedAt": "2020-09-07T15:26:07.49254641Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 25, - "CreatedAt": "2020-09-07T15:26:07.478522227Z", - "UpdatedAt": "2020-09-07T15:26:07.478522227Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 20, - "CreatedAt": "2020-09-07T15:19:17.454485628Z", - "UpdatedAt": "2020-09-07T15:19:17.454485628Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 19, - "CreatedAt": "2020-09-07T15:19:17.440345175Z", - "UpdatedAt": "2020-09-07T15:19:17.440345175Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 14, - "CreatedAt": "2020-09-07T15:10:40.23412631Z", - "UpdatedAt": "2020-09-07T15:10:40.23412631Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 13, - "CreatedAt": "2020-09-07T15:10:40.221593119Z", - "UpdatedAt": "2020-09-07T15:10:40.221593119Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 8, - "CreatedAt": "2020-09-06T23:14:39.838574957Z", - "UpdatedAt": "2020-09-06T23:14:39.838574957Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 7, - "CreatedAt": "2020-09-06T23:14:39.828127845Z", - "UpdatedAt": "2020-09-06T23:14:39.828127845Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 2, - "CreatedAt": "2020-08-28T07:55:27.810831029Z", - "UpdatedAt": "2020-08-28T07:55:27.810831029Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 1, - "CreatedAt": "2020-08-28T07:55:27.793332347Z", - "UpdatedAt": "2020-08-28T07:55:27.793332347Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264eb01d7", - "date": "2020-06-21T00:03:30Z", - "smart_status": "passed", - "temp": 32, - "power_on_hours": 1730, - "power_cycle_count": 9, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }] - }, { - "CreatedAt": "2020-08-28T07:55:27.75951336Z", - "UpdatedAt": "2020-09-08T21:39:26.568442-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264ec3183", - "device_name": "sdc", - "manufacturer": "ATA", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "1.5 Gb/s", - "host_id": "NAS", - "serial_number": "9RK4XXXXX", - "firmware": "MS1OA650", - "rotational_speed": 7200, - "capacity": 500107862016, - "form_factor": "3.5 inches", - "smart_support": false, - "device_protocol": "ATA", - "device_type": "usbjmicron", - "smart_results": [{ - "ID": 45, - "CreatedAt": "2020-09-08T21:39:26.569345-07:00", - "UpdatedAt": "2020-09-08T21:39:26.569345-07:00", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T06:48:23-07:00", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 39, - "CreatedAt": "2020-09-07T15:47:21.330857794Z", - "UpdatedAt": "2020-09-07T15:47:21.330857794Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 33, - "CreatedAt": "2020-09-07T15:38:56.628048752Z", - "UpdatedAt": "2020-09-07T15:38:56.628048752Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 27, - "CreatedAt": "2020-09-07T15:26:07.499431098Z", - "UpdatedAt": "2020-09-07T15:26:07.499431098Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 21, - "CreatedAt": "2020-09-07T15:19:17.461752104Z", - "UpdatedAt": "2020-09-07T15:19:17.461752104Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 15, - "CreatedAt": "2020-09-07T15:10:40.241142961Z", - "UpdatedAt": "2020-09-07T15:10:40.241142961Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 9, - "CreatedAt": "2020-09-06T23:14:39.844036921Z", - "UpdatedAt": "2020-09-06T23:14:39.844036921Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 3, - "CreatedAt": "2020-08-28T07:55:27.822428858Z", - "UpdatedAt": "2020-08-28T07:55:27.822428858Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ec3183", - "date": "2020-07-08T13:48:23Z", - "smart_status": "failed", - "temp": 25, - "power_on_hours": 65592, - "power_cycle_count": 86, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }] - }, { - "CreatedAt": "2020-08-28T07:55:27.76380029Z", - "UpdatedAt": "2020-09-08T21:39:26.575283-07:00", - "DeletedAt": null, - "wwn": "0x5000cca252c859cc", - "device_name": "sdd", - "manufacturer": "SEAGATE", - "model_name": "WDC_WD80EFAX-68LHPN0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "7SGLXXXXX", - "firmware": "", - "rotational_speed": 7200, - "capacity": 4000787030016, - "form_factor": "3.5 inches", - "smart_support": false, - "device_protocol": "SCSI", - "device_type": "scsi", - "smart_results": [{ - "ID": 47, - "CreatedAt": "2020-09-08T21:39:26.576373-07:00", - "UpdatedAt": "2020-09-08T21:39:26.576373-07:00", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T15:27:02-07:00", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 41, - "CreatedAt": "2020-09-07T15:47:21.342459019Z", - "UpdatedAt": "2020-09-07T15:47:21.342459019Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 35, - "CreatedAt": "2020-09-07T15:38:56.637866738Z", - "UpdatedAt": "2020-09-07T15:38:56.637866738Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 29, - "CreatedAt": "2020-09-07T15:26:07.511074415Z", - "UpdatedAt": "2020-09-07T15:26:07.511074415Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 23, - "CreatedAt": "2020-09-07T15:19:17.472358868Z", - "UpdatedAt": "2020-09-07T15:19:17.472358868Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 17, - "CreatedAt": "2020-09-07T15:10:40.251846539Z", - "UpdatedAt": "2020-09-07T15:10:40.251846539Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 11, - "CreatedAt": "2020-09-06T23:14:39.854284927Z", - "UpdatedAt": "2020-09-06T23:14:39.854284927Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 5, - "CreatedAt": "2020-08-28T07:55:27.844861303Z", - "UpdatedAt": "2020-08-28T07:55:27.844861303Z", - "DeletedAt": null, - "device_wwn": "0x5000cca252c859cc", - "date": "2020-08-21T22:27:02Z", - "smart_status": "passed", - "temp": 34, - "power_on_hours": 43549, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }] - }, { - "CreatedAt": "2020-08-28T07:55:27.768220079Z", - "UpdatedAt": "2020-09-08T21:39:26.578973-07:00", - "DeletedAt": null, - "wwn": "0x5000cca264ebc248", - "device_name": "sde", - "manufacturer": "SEAGATE", - "model_name": "WDC_WD140EDFZ-11A0VA0", - "interface_type": "SCSI", - "interface_speed": "", - "serial_number": "9RK3XXXXX", - "firmware": "", - "rotational_speed": 10500, - "capacity": 1200243695616, - "form_factor": "2.5 inches", - "smart_support": false, - "device_protocol": "SCSI", - "device_type": "scsi", - "smart_results": [{ - "ID": 48, - "CreatedAt": "2020-09-08T21:39:26.579623-07:00", - "UpdatedAt": "2020-09-08T21:39:26.579623-07:00", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T15:09:15-08:00", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 42, - "CreatedAt": "2020-09-07T15:47:21.347776031Z", - "UpdatedAt": "2020-09-07T15:47:21.347776031Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 36, - "CreatedAt": "2020-09-07T15:38:56.643057784Z", - "UpdatedAt": "2020-09-07T15:38:56.643057784Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 30, - "CreatedAt": "2020-09-07T15:26:07.517198383Z", - "UpdatedAt": "2020-09-07T15:26:07.517198383Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 24, - "CreatedAt": "2020-09-07T15:19:17.478179249Z", - "UpdatedAt": "2020-09-07T15:19:17.478179249Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 18, - "CreatedAt": "2020-09-07T15:10:40.257160678Z", - "UpdatedAt": "2020-09-07T15:10:40.257160678Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 12, - "CreatedAt": "2020-09-06T23:14:39.858637958Z", - "UpdatedAt": "2020-09-06T23:14:39.858637958Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }, { - "ID": 6, - "CreatedAt": "2020-08-28T07:55:27.879998203Z", - "UpdatedAt": "2020-08-28T07:55:27.879998203Z", - "DeletedAt": null, - "device_wwn": "0x5000cca264ebc248", - "date": "2018-12-16T23:09:15Z", - "smart_status": "passed", - "temp": 31, - "power_on_hours": 5675, - "power_cycle_count": 0, - "ata_attributes": null, - "nvme_attributes": null, - "scsi_attributes": null - }] - }, { - "CreatedAt": "2020-08-28T07:55:27.772557223Z", - "UpdatedAt": "2020-08-28T07:55:27.772557223Z", - "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": "", - "smart_results": [] - }, { - "CreatedAt": "2020-08-28T07:55:27.776820757Z", - "UpdatedAt": "2020-08-28T07:55:27.776820757Z", - "DeletedAt": null, - "wwn": "0x5000c500673e6b5f", - "device_name": "sdg", - "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": "", - "smart_results": [] - }], "success": true -}; + "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", + "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", + "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 + }, + "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", + "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 + }, + "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", + "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", + "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": "", + "device_status": 1 + }, + "smart": { + "collector_date": "2020-09-13T16:29:23Z", + "temp": 36, + "power_on_hours": 14551 + }, + "temp_history": [{ + "date": "2020-07-08T13:48:23Z", + "temp": 25 + }, { + "date": "2020-09-12T19:19:23Z", + "temp": 37 + }, { + "date": "2020-09-12T19:29:23Z", + "temp": 37 + }, { + "date": "2020-09-12T19:39:23Z", + "temp": 36 + }, { + "date": "2020-09-12T19:49:23Z", + "temp": 36 + }, { + "date": "2020-09-12T19:59:23Z", + "temp": 37 + }, { + "date": "2020-09-12T20:09:23Z", + "temp": 37 + }, { + "date": "2020-09-12T20:19:23Z", + "temp": 37 + }, { + "date": "2020-09-12T20:29:23Z", + "temp": 37 + }, { + "date": "2020-09-12T20:39:23Z", + "temp": 36 + }, { + "date": "2020-09-12T20:49:23Z", + "temp": 36 + }, { + "date": "2020-09-12T20:59:23Z", + "temp": 37 + }, { + "date": "2020-09-12T21:09:23Z", + "temp": 36 + }, { + "date": "2020-09-12T21:19:23Z", + "temp": 37 + }, { + "date": "2020-09-12T21:29:23Z", + "temp": 38 + }, { + "date": "2020-09-12T21:39:23Z", + "temp": 36 + }, { + "date": "2020-09-12T21:49:23Z", + "temp": 36 + }, { + "date": "2020-09-12T21:59:23Z", + "temp": 36 + }, { + "date": "2020-09-12T22:09:23Z", + "temp": 36 + }, { + "date": "2020-09-12T22:19:23Z", + "temp": 36 + }, { + "date": "2020-09-12T22:29:23Z", + "temp": 36 + }, { + "date": "2020-09-12T22:39:23Z", + "temp": 36 + }, { + "date": "2020-09-12T22:49:23Z", + "temp": 36 + }, { + "date": "2020-09-12T22:59:23Z", + "temp": 36 + }, { + "date": "2020-09-12T23:09:23Z", + "temp": 36 + }, { + "date": "2020-09-12T23:19:23Z", + "temp": 36 + }, { + "date": "2020-09-12T23:29:23Z", + "temp": 36 + }, { + "date": "2020-09-12T23:39:23Z", + "temp": 36 + }, { + "date": "2020-09-12T23:49:23Z", + "temp": 36 + }, { + "date": "2020-09-12T23:59:23Z", + "temp": 36 + }, { + "date": "2020-09-13T00:09:23Z", + "temp": 36 + }, { + "date": "2020-09-13T00:19:23Z", + "temp": 36 + }, { + "date": "2020-09-13T00:29:23Z", + "temp": 37 + }, { + "date": "2020-09-13T00:39:23Z", + "temp": 36 + }, { + "date": "2020-09-13T00:49:23Z", + "temp": 36 + }, { + "date": "2020-09-13T00:59:23Z", + "temp": 36 + }, { + "date": "2020-09-13T01:09:23Z", + "temp": 36 + }, { + "date": "2020-09-13T01:19:23Z", + "temp": 36 + }, { + "date": "2020-09-13T01:29:23Z", + "temp": 37 + }, { + "date": "2020-09-13T01:39:23Z", + "temp": 36 + }, { + "date": "2020-09-13T01:49:23Z", + "temp": 37 + }, { + "date": "2020-09-13T01:59:23Z", + "temp": 37 + }, { + "date": "2020-09-13T02:09:23Z", + "temp": 37 + }, { + "date": "2020-09-13T02:19:23Z", + "temp": 37 + }, { + "date": "2020-09-13T02:29:23Z", + "temp": 38 + }, { + "date": "2020-09-13T02:39:23Z", + "temp": 37 + }, { + "date": "2020-09-13T02:49:23Z", + "temp": 37 + }, { + "date": "2020-09-13T02:59:23Z", + "temp": 38 + }, { + "date": "2020-09-13T03:09:23Z", + "temp": 38 + }, { + "date": "2020-09-13T03:19:23Z", + "temp": 38 + }, { + "date": "2020-09-13T03:29:23Z", + "temp": 38 + }, { + "date": "2020-09-13T03:39:23Z", + "temp": 38 + }, { + "date": "2020-09-13T03:49:23Z", + "temp": 38 + }, { + "date": "2020-09-13T03:59:23Z", + "temp": 38 + }, { + "date": "2020-09-13T04:09:23Z", + "temp": 38 + }, { + "date": "2020-09-13T04:19:23Z", + "temp": 38 + }, { + "date": "2020-09-13T04:29:23Z", + "temp": 38 + }, { + "date": "2020-09-13T04:39:23Z", + "temp": 38 + }, { + "date": "2020-09-13T04:49:23Z", + "temp": 38 + }, { + "date": "2020-09-13T04:59:23Z", + "temp": 38 + }, { + "date": "2020-09-13T05:09:23Z", + "temp": 37 + }, { + "date": "2020-09-13T05:19:23Z", + "temp": 38 + }, { + "date": "2020-09-13T05:29:23Z", + "temp": 39 + }, { + "date": "2020-09-13T05:39:23Z", + "temp": 41 + }, { + "date": "2020-09-13T05:49:23Z", + "temp": 42 + }, { + "date": "2020-09-13T05:59:23Z", + "temp": 41 + }, { + "date": "2020-09-13T06:09:23Z", + "temp": 41 + }, { + "date": "2020-09-13T06:19:23Z", + "temp": 42 + }, { + "date": "2020-09-13T06:29:23Z", + "temp": 41 + }, { + "date": "2020-09-13T06:39:23Z", + "temp": 41 + }, { + "date": "2020-09-13T06:49:23Z", + "temp": 41 + }, { + "date": "2020-09-13T06:59:23Z", + "temp": 41 + }, { + "date": "2020-09-13T07:09:23Z", + "temp": 40 + }, { + "date": "2020-09-13T07:19:23Z", + "temp": 40 + }, { + "date": "2020-09-13T07:29:23Z", + "temp": 41 + }, { + "date": "2020-09-13T07:39:23Z", + "temp": 43 + }, { + "date": "2020-09-13T07:49:23Z", + "temp": 42 + }, { + "date": "2020-09-13T07:59:23Z", + "temp": 41 + }, { + "date": "2020-09-13T08:09:23Z", + "temp": 42 + }, { + "date": "2020-09-13T08:19:23Z", + "temp": 42 + }, { + "date": "2020-09-13T08:29:23Z", + "temp": 41 + }, { + "date": "2020-09-13T08:39:23Z", + "temp": 39 + }, { + "date": "2020-09-13T08:49:23Z", + "temp": 38 + }, { + "date": "2020-09-13T08:59:23Z", + "temp": 38 + }, { + "date": "2020-09-13T09:09:23Z", + "temp": 38 + }, { + "date": "2020-09-13T09:19:23Z", + "temp": 39 + }, { + "date": "2020-09-13T09:29:23Z", + "temp": 39 + }, { + "date": "2020-09-13T09:39:23Z", + "temp": 39 + }, { + "date": "2020-09-13T09:49:23Z", + "temp": 39 + }, { + "date": "2020-09-13T09:59:23Z", + "temp": 39 + }, { + "date": "2020-09-13T10:09:23Z", + "temp": 39 + }, { + "date": "2020-09-13T10:19:23Z", + "temp": 39 + }, { + "date": "2020-09-13T10:29:23Z", + "temp": 39 + }, { + "date": "2020-09-13T10:39:23Z", + "temp": 39 + }, { + "date": "2020-09-13T10:49:23Z", + "temp": 39 + }, { + "date": "2020-09-13T10:59:23Z", + "temp": 39 + }, { + "date": "2020-09-13T11:09:23Z", + "temp": 38 + }, { + "date": "2020-09-13T11:19:23Z", + "temp": 38 + }, { + "date": "2020-09-13T11:29:23Z", + "temp": 38 + }, { + "date": "2020-09-13T11:39:23Z", + "temp": 38 + }, { + "date": "2020-09-13T11:49:23Z", + "temp": 38 + }, { + "date": "2020-09-13T11:59:23Z", + "temp": 38 + }, { + "date": "2020-09-13T12:09:23Z", + "temp": 38 + }, { + "date": "2020-09-13T12:19:23Z", + "temp": 38 + }, { + "date": "2020-09-13T12:29:23Z", + "temp": 39 + }, { + "date": "2020-09-13T12:39:23Z", + "temp": 39 + }, { + "date": "2020-09-13T12:49:23Z", + "temp": 39 + }, { + "date": "2020-09-13T12:59:23Z", + "temp": 39 + }, { + "date": "2020-09-13T13:09:23Z", + "temp": 39 + }, { + "date": "2020-09-13T13:19:23Z", + "temp": 39 + }, { + "date": "2020-09-13T13:29:23Z", + "temp": 39 + }, { + "date": "2020-09-13T13:39:23Z", + "temp": 39 + }, { + "date": "2020-09-13T13:49:23Z", + "temp": 39 + }, { + "date": "2020-09-13T13:59:23Z", + "temp": 39 + }, { + "date": "2020-09-13T14:09:23Z", + "temp": 39 + }, { + "date": "2020-09-13T14:19:23Z", + "temp": 39 + }, { + "date": "2020-09-13T14:29:23Z", + "temp": 39 + }, { + "date": "2020-09-13T14:39:23Z", + "temp": 39 + }, { + "date": "2020-09-13T14:49:23Z", + "temp": 39 + }, { + "date": "2020-09-13T14:59:23Z", + "temp": 39 + }, { + "date": "2020-09-13T15:09:23Z", + "temp": 39 + }, { + "date": "2020-09-13T15:19:23Z", + "temp": 40 + }, { + "date": "2020-09-13T15:29:23Z", + "temp": 40 + }, { + "date": "2020-09-13T15:39:23Z", + "temp": 40 + }, { + "date": "2020-09-13T15:49:23Z", + "temp": 39 + }, { + "date": "2020-09-13T15:59:23Z", + "temp": 39 + }, { + "date": "2020-09-13T16:09:23Z", + "temp": 39 + }, { + "date": "2020-09-13T16:19: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", + "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", + "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 + }, + "temp_history": [{ + "date": "2020-06-10T12:01:02Z", + "temp": 36 + }] + } + } + }, + "success": true +} diff --git a/webapp/frontend/src/app/modules/dashboard/dashboard.component.html b/webapp/frontend/src/app/modules/dashboard/dashboard.component.html index 82a723f..4fd1574 100644 --- a/webapp/frontend/src/app/modules/dashboard/dashboard.component.html +++ b/webapp/frontend/src/app/modules/dashboard/dashboard.component.html @@ -1,4 +1,5 @@ -
+ +
@@ -47,38 +48,37 @@
- -
-
+
- {{deviceTitle(disk)}} -
- Last Updated on {{disk.smart_results[0]?.date | date:'MMMM dd, yyyy - HH:mm' }} + {{deviceTitle(summary.value.device)}} +
+ Last Updated on {{summary.value.smart.collector_date | date:'MMMM dd, yyyy - HH:mm' }}
-
-
-
/dev/{{data.data.device_name}}
+
/dev/{{device?.device_name}}
-
-
{{data.data.host_id}}
+
+
{{device?.host_id}}
Host ID
-
-
{{data.data.device_type | uppercase}}
+
+
{{device?.device_type | uppercase}}
Device Type
-
-
{{data.data.manufacturer}}
+
+
{{device?.manufacturer}}
Model Family
-
{{data.data.model_name}}
+
{{device?.model_name}}
Device Model
-
{{data.data.serial_number}}
+
{{device?.serial_number}}
Serial Number
-
{{data.data.wwn}}
+
{{device?.wwn}}
LU WWN Device Id
-
{{data.data.firmware}}
+
{{device?.firmware}}
Firmware Version
-
{{data.data.capacity | fileSize}}
+
{{device?.capacity | fileSize}}
Capacity
-
-
{{data.data.rotational_speed}} RPM
+
+
{{device?.rotational_speed}} RPM
Rotation Rate
-
-
{{data.data.device_protocol}}
+
+
{{device?.device_protocol}}
Protocol
-
{{data.data.smart_results[0]?.power_cycle_count}}
+
{{smart_results[0]?.power_cycle_count}}
Power Cycle Count
-
-
{{humanizeDuration(data.data.smart_results[0]?.power_on_hours *60 * 60 * 1000, { round: true, largest: 1, units: ['y', 'd', 'h'] })}}
+
+
{{humanizeDuration(smart_results[0]?.power_on_hours *60 * 60 * 1000, { round: true, largest: 1, units: ['y', 'd', 'h'] })}}
Powered On
-
{{data.data.smart_results[0]?.temp}}°C
+
{{smart_results[0]?.temp}}°C
Temperature
@@ -115,7 +115,7 @@
-
S.M.A.R.T {{data.data.device_protocol}} Attributes
+
S.M.A.R.T {{device?.device_protocol}} Attributes
{{this.smartAttributeDataSource.data.length}} visible, {{getHiddenAttributes()}} hidden
diff --git a/webapp/frontend/src/app/modules/detail/detail.component.ts b/webapp/frontend/src/app/modules/detail/detail.component.ts index a4321ec..eaf5b7c 100644 --- a/webapp/frontend/src/app/modules/detail/detail.component.ts +++ b/webapp/frontend/src/app/modules/detail/detail.component.ts @@ -19,7 +19,12 @@ import humanizeDuration from 'humanize-duration'; export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { onlyCritical: boolean = true; - data: any; + // data: any; + + metadata: any; + device: any; + smart_results: any[]; + commonSparklineOptions: Partial; smartAttributeDataSource: MatTableDataSource; smartAttributeTableColumns: string[]; @@ -66,10 +71,14 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { .subscribe((data) => { // Store the data - this.data = data; + // this.data = data; + this.device = data.data.device; + this.smart_results = data.data.smart_results + this.metadata = data.metadata; + // Store the table data - this.smartAttributeDataSource.data = this._generateSmartAttributeTableDataSource(data.data.smart_results); + this.smartAttributeDataSource.data = this._generateSmartAttributeTableDataSource(this.smart_results); // Prepare the chart data this._prepareChartData(); @@ -99,7 +108,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { // @ Private methods // ----------------------------------------------------------------------------------------------------- getAttributeDescription(attribute_data){ - let attribute_metadata = this.data.metadata[attribute_data.attribute_id] + let attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata){ return 'Unknown' } else { @@ -110,7 +119,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { getAttributeValue(attribute_data){ if(this.isAta()) { - let attribute_metadata = this.data.metadata[attribute_data.attribute_id] + let attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata){ return attribute_data.value } else if (attribute_metadata.display_type == "raw") { @@ -128,7 +137,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { getAttributeValueType(attribute_data){ if(this.isAta()) { - let attribute_metadata = this.data.metadata[attribute_data.attribute_id] + let attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata){ return '' } else { @@ -141,14 +150,14 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { getAttributeIdeal(attribute_data){ if(this.isAta()){ - return this.data.metadata[attribute_data.attribute_id]?.display_type == "raw" ? this.data.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.data.metadata[attribute_data.attribute_id]?.ideal + return this.metadata[attribute_data.attribute_id]?.ideal } } getAttributeWorst(attribute_data){ - let attribute_metadata = this.data.metadata[attribute_data.attribute_id] + let attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata){ return attribute_data.worst } else { @@ -158,7 +167,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { getAttributeThreshold(attribute_data){ if(this.isAta()){ - let attribute_metadata = this.data.metadata[attribute_data.attribute_id] + let attribute_metadata = this.metadata[attribute_data.attribute_id] if(!attribute_metadata || attribute_metadata.display_type == "normalized"){ return attribute_data.thresh } else { @@ -175,29 +184,30 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { } getAttributeCritical(attribute_data){ - return this.data.metadata[attribute_data.attribute_id]?.critical + return this.metadata[attribute_data.attribute_id]?.critical } getHiddenAttributes(){ - let attributes_list - if(this.isAta()){ - attributes_list = this.data.data.smart_results[0]?.ata_attributes - } else if(this.isNvme()){ - attributes_list = this.data.data.smart_results[0]?.nvme_attributes - } else { - attributes_list = this.data.data.smart_results[0]?.scsi_attributes + if (!this.smart_results || this.smart_results.length == 0) { + return 0 + } + + let attributes_length = 0 + let attributes = this.smart_results[0]?.attrs + if (attributes) { + attributes_length = Object.keys(attributes).length } - return attributes_list.length - this.smartAttributeDataSource.data.length + return attributes_length - this.smartAttributeDataSource.data.length } isAta(): boolean { - return this.data.data.device_protocol == 'ATA' + return this.device.device_protocol == 'ATA' } isScsi(): boolean { - return this.data.data.device_protocol == 'SCSI' + return this.device.device_protocol == 'SCSI' } isNvme(): boolean { - return this.data.data.device_protocol == 'NVMe' + return this.device.device_protocol == 'NVMe' } private _generateSmartAttributeTableDataSource(smart_results){ @@ -207,21 +217,22 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { return smartAttributeDataSource } var latest_smart_result = smart_results[0]; - let attributes_list = [] + let attributes = {} if(this.isScsi()) { this.smartAttributeTableColumns = ['status', 'name', 'value', 'thresh', 'history']; - attributes_list = latest_smart_result.scsi_attributes + attributes = latest_smart_result.attrs } else if(this.isNvme()){ this.smartAttributeTableColumns = ['status', 'name', 'value', 'thresh', 'ideal', 'history']; - attributes_list = latest_smart_result.nvme_attributes + attributes = latest_smart_result.attrs } else { //ATA - attributes_list = latest_smart_result.ata_attributes + attributes = latest_smart_result.attrs this.smartAttributeTableColumns = ['status', 'id', 'name', 'value', 'worst', 'thresh','ideal', 'failure', 'history']; } + for(const attrId in attributes){ + var attr = attributes[attrId] - for(let attr of attributes_list){ //chart history data if (!attr.chartData) { var rawHistory = (attr.history || []).map(hist_attr => this.getAttributeValue(hist_attr)).reverse() @@ -235,7 +246,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { } //determine when to include the attributes in table. - if(!this.onlyCritical || this.onlyCritical && this.data.metadata[attr.attribute_id]?.critical || attr.value < attr.thresh){ + if(!this.onlyCritical || this.onlyCritical && this.metadata[attr.attribute_id]?.critical || attr.value < attr.thresh){ smartAttributeDataSource.push(attr) } } @@ -297,7 +308,7 @@ export class DetailComponent implements OnInit, AfterViewInit, OnDestroy { } toggleOnlyCritical(){ this.onlyCritical = !this.onlyCritical - this.smartAttributeDataSource.data = this._generateSmartAttributeTableDataSource(this.data.data.smart_results); + this.smartAttributeDataSource.data = this._generateSmartAttributeTableDataSource(this.smart_results); }