Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions .github/dependabot

This file was deleted.

16 changes: 16 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
- package-ecosystem: pip
directories:
- /
- /library
schedule:
interval: weekly
cooldown:
default-days: 7
2 changes: 2 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ jobs:
fail-fast: false
matrix:
include:
- language: javascript-typescript
build-mode: none
- language: python
build-mode: none
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
Expand Down
14 changes: 0 additions & 14 deletions .github/workflows/hassfest

This file was deleted.

48 changes: 48 additions & 0 deletions .github/workflows/release-library.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Release aiosmartctl

# Publishes the library to PyPI when a tag like "aiosmartctl-v0.1.0" is pushed.
# Uses PyPI trusted publishing: add this repository and workflow as a trusted
# publisher for the "aiosmartctl" project on pypi.org first.
on:
push:
tags: ["aiosmartctl-v*"]

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2
with:
python-version: "3.14"
- name: Check the tag matches the version
env:
TAG: ${{ github.ref_name }}
run: |
version=$(sed -n 's/^__version__ = "\(.*\)"/\1/p' library/src/aiosmartctl/__init__.py)
test "$TAG" = "aiosmartctl-v$version"
- run: uv build --out-dir dist library
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: dist
path: dist/

publish:
needs: build
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/project/aiosmartctl/
permissions:
id-token: write
steps:
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: dist
path: dist/
- uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
74 changes: 74 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Tests

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
library:
name: aiosmartctl (Python ${{ matrix.python }})
runs-on: ubuntu-latest
strategy:
matrix:
python: ["3.13", "3.14"]
defaults:
run:
working-directory: library
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2
with:
python-version: ${{ matrix.python }}
activate-environment: true
working-directory: library
- run: uv pip install -e ".[test]" mypy ruff
- run: ruff check . && ruff format --check .
- run: mypy --strict src
- run: pytest --cov --cov-report=term-missing --cov-fail-under=90

integration:
name: Integration
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2
with:
python-version: "3.14"
activate-environment: true
- run: uv pip install -r requirements_test.txt ./library ruff
- run: ruff check custom_components tests script && ruff format --check custom_components tests script
- name: Translations are up to date
run: python script/gen_translations.py --check
- run: pytest --cov --cov-report=term-missing --cov-fail-under=100

core:
name: Home Assistant core checks (${{ matrix.platforms || 'all platforms' }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# The first core pull request may only contain one platform.
platforms: ["", "sensor"]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e # v10.3.2
with:
python-version: "3.14"
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: 22
- name: Run core checks
env:
PLATFORMS: ${{ matrix.platforms }}
run: script/run_core_checks.sh "$RUNNER_TEMP/core-checks"
32 changes: 32 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Validate

on:
push:
branches: [main]
pull_request:
schedule:
- cron: "0 3 * * 1"
workflow_dispatch:

permissions:
contents: read

jobs:
hassfest:
name: hassfest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: home-assistant/actions/hassfest@cd6f3635a740c84d8a14f6121a90068b8ece6bf6 # master

hacs:
name: HACS
runs-on: ubuntu-latest
steps:
- uses: hacs/action@d556e736723344f83838d08488c983a15381059a # 22.5.0
with:
category: integration
# Brand images are submitted to home-assistant/brands separately.
ignore: brands
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
__pycache__/
*.py[cod]
.coverage
.pytest_cache/
.ruff_cache/
.mypy_cache/
*.egg-info/
dist/
build/
.venv/
venv/
47 changes: 47 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Changelog

## 2.0.0

A rewrite that prepares the integration for Home Assistant core.

### Breaking changes

- Requires Home Assistant 2026.10 or newer.
- Hosts added with 1.x must be confirmed again: Home Assistant asks for the
password or private key and shows the SSH host key to confirm.
- Disks are identified by WWN or serial number instead of their `/dev` path,
so all entity IDs change. Delete the old, unavailable entities.
- Health states are now `passed`, `warning` and `failed`.
- The **Download SMART Report** button was removed; use **Download
diagnostics**. Self-test errors are shown as errors instead of persistent
notifications.
- The scan interval is fixed at 5 minutes; disable polling and use
`homeassistant.update_entity` for another schedule.
- The server type option was removed; the host's operating system is detected.

### New

- SAS/SCSI disks: grown defects, uncorrected read/write/verify errors,
endurance of SAS SSDs.
- Disks behind RAID controllers (MegaRAID/PERC, and HP Smart Array, Areca,
3ware and aacraid through the **Devices** option), found with
`smartctl --scan-open`.
- Sleeping disks are not woken up; a **Standby** binary sensor.
- Run smartctl through `sudo -n`.
- SSH host key pinning, private keys pasted in the UI, reauthentication and
reconfiguration flows.
- One device per host with its disks below it; disks that are gone can be
deleted.
- Endurance used, data read and written, NVMe available spare and more.
- **Self-test running** binary sensor and an **Abort self-test** button.
- Diagnostics.
- The `aiosmartctl` library and the SMART Monitor dashboard card.

### Fixed

- Options for password and key were saved but never used.
- A smartctl message containing "failed" marked the whole disk as unreadable.
- The binary sensor platform kept listening for new disks after the
integration was unloaded.
- Starting a self-test during a poll could break the poll, because both
shared one SSH connection object.
Loading
Loading