Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ad8bd7c
Allowing changing the polling rate through GUI
anthonymonti2 Feb 4, 2026
8746544
Bumping version number
anthonymonti2 Feb 4, 2026
46e279b
Readding the original comments
anthonymonti2 Feb 4, 2026
d3bfa51
Trying to make it report an error with invalid input
anthonymonti2 Feb 4, 2026
b400c8f
Preventing user inputting invalid polling
anthonymonti2 Feb 4, 2026
9ee8561
Readding comments that got removed
anthonymonti2 Feb 4, 2026
5ead8bf
Fix difficulty sensors when value is string or float
DerMiika Feb 9, 2026
82936b5
updated hacs.json
DerMiika Feb 9, 2026
b3fbab4
Add HACS validation workflow
DerMiika Feb 9, 2026
fddfad6
Fix HACS validation errors
DerMiika Feb 10, 2026
3c56def
Update hacs.json
DerMiika Feb 10, 2026
6790dc3
Update hacs.json
DerMiika Feb 10, 2026
fe8c3e5
Update hacs.json
DerMiika Feb 10, 2026
a77dd2b
Update hacs.json
DerMiika Feb 10, 2026
85d2a32
Update hacs.json
DerMiika Feb 10, 2026
7699030
Allowing changing the polling rate through GUI
anthonymonti2 Feb 4, 2026
eab611d
Bumping version number
anthonymonti2 Feb 4, 2026
e85b504
Readding the original comments
anthonymonti2 Feb 4, 2026
d4ed735
Trying to make it report an error with invalid input
anthonymonti2 Feb 4, 2026
6f4475b
Preventing user inputting invalid polling
anthonymonti2 Feb 4, 2026
c1c50fb
Readding comments that got removed
anthonymonti2 Feb 4, 2026
fbbf22f
Merge branch 'main' of https://github.com/anthonymonti2/Bitaxe-HA-Int…
anthonymonti2 Feb 11, 2026
b91a890
Bumping version number for configurable polling rate.
anthonymonti2 Feb 11, 2026
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
18 changes: 18 additions & 0 deletions .github/workflows/hacs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: HACS Validation

on:
push:
pull_request:
workflow_dispatch:

jobs:
hacs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: HACS validation
uses: hacs/action@main
with:
category: integration
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ To set up the integration, follow these steps:
5. Complete the setup.

## Version
This is version (v1.1.0) compatible with HACS!
This is version (v1.3.0) compatible with HACS!

## Screenshots

Expand Down
21 changes: 18 additions & 3 deletions custom_components/bitaxe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from homeassistant.helpers.event import async_track_time_interval

DOMAIN = "bitaxe"
from .const import DOMAIN, CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL

_LOGGER = logging.getLogger(__name__)

async def async_setup_entry(hass: HomeAssistant, entry: config_entries.ConfigEntry):
ip_address = entry.data["ip_address"]
device_id = entry.unique_id or ip_address
scan_interval = entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)

coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
name=f"BitAxe Sensor Data ({device_id})",
update_method=lambda: fetch_bitaxe_data(ip_address),
update_interval=timedelta(seconds=30),
update_interval=timedelta(seconds=scan_interval),
)

await coordinator.async_refresh()
Expand All @@ -27,16 +29,29 @@ async def async_setup_entry(hass: HomeAssistant, entry: config_entries.ConfigEnt
hass.data[DOMAIN] = {}
hass.data[DOMAIN][device_id] = {"coordinator": coordinator}

# Add option to edit settings after creating instance
entry.async_on_unload(
entry.add_update_listener(_options_update_listener)
)

await hass.config_entries.async_forward_entry_setups(entry, ["sensor"])

async_track_time_interval(
hass,
_update_coordinator(coordinator),
timedelta(seconds=30)
timedelta(seconds=scan_interval)
)

return True

async def _options_update_listener(hass, entry):
await hass.config_entries.async_reload(entry.entry_id)

async def async_unload_entry(hass, entry):
unload_ok = await hass.config_entries.async_unload_platforms(entry, ["sensor"])
hass.data[DOMAIN].pop(entry.unique_id, None)
return unload_ok

def _update_coordinator(coordinator: DataUpdateCoordinator):
async def refresh(now):
await coordinator.async_request_refresh()
Expand Down
58 changes: 45 additions & 13 deletions custom_components/bitaxe/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.core import callback
import ipaddress # Import für IP-Adressenvalidierung
import ipaddress # Import für IP-Adressenvalidierung

from .const import DOMAIN
from .const import (
DOMAIN, MIN_SCAN_INTERVAL, MAX_SCAN_INTERVAL,
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
)

class BitAxeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
VERSION = 1
Expand All @@ -15,6 +18,7 @@ async def async_step_user(self, user_input=None):
if user_input is not None:
ip_address = user_input["ip_address"]
device_name = user_input["device_name"]
scan_interval = user_input[CONF_SCAN_INTERVAL]

# Validierung der IP-Adresse
try:
Expand All @@ -24,7 +28,7 @@ async def async_step_user(self, user_input=None):
return self.async_show_form(
step_id="user",
data_schema=self.get_data_schema(),
errors=errors
errors=errors,
)

# Entry mit IP-Adresse und Gerätenamen erstellen
Expand All @@ -33,32 +37,60 @@ async def async_step_user(self, user_input=None):

return self.async_create_entry(
title=device_name,
data={"ip_address": ip_address, "device_name": device_name}
data={
"ip_address": ip_address,
"device_name": device_name,
},
options={
CONF_SCAN_INTERVAL: scan_interval,
},
)

return self.async_show_form(
step_id="user",
data_schema=self.get_data_schema(),
errors=errors
errors=errors,
)

def get_data_schema(self):
"""Return the schema for user input."""
"""Return the schema for user input and check for validity."""
return vol.Schema({
vol.Required("ip_address"): str,
vol.Required("device_name"): str,
vol.Optional(
CONF_SCAN_INTERVAL,
default=DEFAULT_SCAN_INTERVAL,
): vol.All(
vol.Coerce(int),
vol.Range(min=MIN_SCAN_INTERVAL, max=MAX_SCAN_INTERVAL),
),
})

@staticmethod
@callback
def async_get_options_flow(config_entry):
return BitAxeOptionsFlowHandler(config_entry)
return BitAxeOptionsFlowHandler()

class BitAxeOptionsFlowHandler(config_entries.OptionsFlow):
def __init__(self, config_entry):
"""Initialize options flow."""
self.config_entry = config_entry

class BitAxeOptionsFlowHandler(config_entries.OptionsFlow):
async def async_step_init(self, user_input=None):
"""Manage the options."""
return self.async_show_form(step_id="init")
if user_input is not None:
return self.async_create_entry(title="", data=user_input)

return self.async_show_form(
step_id="init",
data_schema=vol.Schema({
vol.Optional(
CONF_SCAN_INTERVAL,
default=self.config_entry.options.get(
CONF_SCAN_INTERVAL,
DEFAULT_SCAN_INTERVAL,
),
): vol.All(
vol.Coerce(int),
vol.Range(min=MIN_SCAN_INTERVAL, max=MAX_SCAN_INTERVAL),
),
}),
)

6 changes: 6 additions & 0 deletions custom_components/bitaxe/const.py
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
DOMAIN = "bitaxe"

CONF_SCAN_INTERVAL = "Polling_Rate_(s)"

DEFAULT_SCAN_INTERVAL = 60 # seconds
MIN_SCAN_INTERVAL = 30
MAX_SCAN_INTERVAL = 3600
14 changes: 0 additions & 14 deletions custom_components/bitaxe/hacs.json

This file was deleted.

2 changes: 1 addition & 1 deletion custom_components/bitaxe/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"domain": "bitaxe",
"name": "Bitaxe Home Assistant Integration",
"version": "v1.1.0",
"version": "v1.1.2",
"config_flow": true,
"documentation": "https://github.com/DerMiika/Bitaxe-HA-Integration",
"issue_tracker": "https://github.com/DerMiika/Bitaxe-HA-Integration/issues",
Expand Down
13 changes: 10 additions & 3 deletions custom_components/bitaxe/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,17 @@ async def async_setup_entry(hass, entry, async_add_entities):
async_add_entities(sensors, update_before_add=True)


def format_difficulty(value: int) -> str:
"""Convert difficulty values into human-readable units."""
def format_difficulty(value) -> str | None:
"""Convert difficulty values into human-readable units (k, M, G, T, P, E)."""
if value is None:
return None

# AxeOS may return difficulty as string or float
try:
value = float(value)
except (ValueError, TypeError):
return str(value)

units = [
(1e18, "E"),
(1e15, "P"),
Expand All @@ -62,7 +68,8 @@ def format_difficulty(value: int) -> str:
if value >= factor:
return f"{value / factor:.2f} {suffix}"

return str(value)
return str(int(value))



class BitAxeSensor(Entity):
Expand Down
6 changes: 2 additions & 4 deletions hacs.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
{
"name": "Bitaxe Home Assistant Integration",
"name": "Bitaxe Monitoring",
"content_in_root": false,
"country": "DE",
"description": "Integration for monitoring BitAxe miners in Home Assistant",
"domains": ["bitaxe"],
"iot_class": "local_polling",
"render_readme": true,
"documentation": "https://github.com/DerMiika/Bitaxe-HA-Integration",
"version": "1.1.0",
"version": "1.3.0",
"zip_release": false,
"filename": "custom_components/bitaxe",
"codeowners": ["@DerMiika"]
"logo": "custom_components/bitaxe/images/bitaxe_icon.png"
}