refactor: split out data coordinators and sensors
- remove unused imports
This commit is contained in:
parent
da7e12c75d
commit
96498e580e
@ -4,16 +4,13 @@ Integrates NiceHash with Home Assistant
|
|||||||
For more details about this integration, please refer to
|
For more details about this integration, please refer to
|
||||||
https://github.com/brianberg/ha-nicehash
|
https://github.com/brianberg/ha-nicehash
|
||||||
"""
|
"""
|
||||||
from datetime import timedelta
|
|
||||||
import logging
|
import logging
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.const import CONF_DEVICES, CONF_TIMEOUT
|
from homeassistant.const import CONF_DEVICES, CONF_TIMEOUT
|
||||||
from homeassistant.core import Config, HomeAssistant
|
from homeassistant.core import Config, HomeAssistant
|
||||||
from homeassistant.helpers import discovery
|
from homeassistant.helpers import discovery
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
|
||||||
from homeassistant.exceptions import PlatformNotReady
|
from homeassistant.exceptions import PlatformNotReady
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -21,15 +18,15 @@ from .const import (
|
|||||||
CONF_API_SECRET,
|
CONF_API_SECRET,
|
||||||
CONF_CURRENCY,
|
CONF_CURRENCY,
|
||||||
CONF_ORGANIZATION_ID,
|
CONF_ORGANIZATION_ID,
|
||||||
CURRENCY_BTC,
|
|
||||||
CURRENCY_USD,
|
CURRENCY_USD,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
STARTUP_MESSAGE,
|
STARTUP_MESSAGE,
|
||||||
)
|
)
|
||||||
from .nicehash import NiceHashPrivateClient, NiceHashPublicClient
|
from .nicehash import NiceHashPrivateClient
|
||||||
|
from .data_coordinators import (
|
||||||
SCAN_INTERVAL_RIGS = timedelta(minutes=1)
|
NiceHashAccountsDataUpdateCoordinator,
|
||||||
SCAN_INTERVAL_ACCOUNTS = timedelta(minutes=60)
|
NiceHashMiningRigsDataUpdateCoordinator,
|
||||||
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -86,63 +83,3 @@ async def async_setup(hass: HomeAssistant, config: Config):
|
|||||||
await discovery.async_load_platform(hass, "sensor", DOMAIN, {}, config)
|
await discovery.async_load_platform(hass, "sensor", DOMAIN, {}, config)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class NiceHashAccountsDataUpdateCoordinator(DataUpdateCoordinator):
|
|
||||||
"""Manages fetching accounts data from NiceHash API"""
|
|
||||||
|
|
||||||
def __init__(self, hass: HomeAssistant, client: NiceHashPrivateClient):
|
|
||||||
"""Initialize"""
|
|
||||||
self.name = f"{DOMAIN}_accounts_coordinator"
|
|
||||||
self._client = client
|
|
||||||
|
|
||||||
super().__init__(
|
|
||||||
hass, _LOGGER, name=self.name, update_interval=SCAN_INTERVAL_ACCOUNTS
|
|
||||||
)
|
|
||||||
|
|
||||||
async def _async_update_data(self):
|
|
||||||
"""Update accounts data and exchange rates"""
|
|
||||||
try:
|
|
||||||
accounts = await self._client.get_accounts()
|
|
||||||
exchange_rates = await NiceHashPublicClient().get_exchange_rates()
|
|
||||||
rates_dict = dict()
|
|
||||||
for rate in exchange_rates:
|
|
||||||
fromCurrency = rate.get("fromCurrency")
|
|
||||||
# Only care about the Bitcoin exchange rates
|
|
||||||
if fromCurrency == CURRENCY_BTC:
|
|
||||||
toCurrency = rate.get("toCurrency")
|
|
||||||
exchange_rate = float(rate.get("exchangeRate"))
|
|
||||||
rates_dict[f"{fromCurrency}-{toCurrency}"] = exchange_rate
|
|
||||||
return {
|
|
||||||
"accounts": accounts,
|
|
||||||
"exchange_rates": rates_dict,
|
|
||||||
}
|
|
||||||
except Exception as e:
|
|
||||||
raise UpdateFailed(e)
|
|
||||||
|
|
||||||
|
|
||||||
class NiceHashMiningRigsDataUpdateCoordinator(DataUpdateCoordinator):
|
|
||||||
"""Manages fetching mining rigs data from NiceHash API"""
|
|
||||||
|
|
||||||
def __init__(self, hass: HomeAssistant, client: NiceHashPrivateClient):
|
|
||||||
"""Initialize"""
|
|
||||||
self.name = f"{DOMAIN}_mining_rigs_coordinator"
|
|
||||||
self._client = client
|
|
||||||
|
|
||||||
super().__init__(
|
|
||||||
hass, _LOGGER, name=self.name, update_interval=SCAN_INTERVAL_RIGS
|
|
||||||
)
|
|
||||||
|
|
||||||
async def _async_update_data(self):
|
|
||||||
"""Update mining rigs data"""
|
|
||||||
try:
|
|
||||||
data = await self._client.get_mining_rigs()
|
|
||||||
mining_rigs = data.get("miningRigs")
|
|
||||||
rigs_dict = dict()
|
|
||||||
for rig in mining_rigs:
|
|
||||||
rig_id = rig.get("rigId")
|
|
||||||
rigs_dict[f"{rig_id}"] = rig
|
|
||||||
data["miningRigs"] = rigs_dict
|
|
||||||
return data
|
|
||||||
except Exception as e:
|
|
||||||
raise UpdateFailed(e)
|
|
||||||
|
82
custom_components/nicehash/data_coordinators.py
Normal file
82
custom_components/nicehash/data_coordinators.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
"""
|
||||||
|
NiceHash Data Update Coordinators
|
||||||
|
"""
|
||||||
|
from datetime import timedelta
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.update_coordinator import (
|
||||||
|
DataUpdateCoordinator,
|
||||||
|
UpdateFailed,
|
||||||
|
)
|
||||||
|
|
||||||
|
from .const import (
|
||||||
|
CURRENCY_BTC,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
|
from .nicehash import NiceHashPrivateClient, NiceHashPublicClient
|
||||||
|
|
||||||
|
SCAN_INTERVAL_RIGS = timedelta(minutes=1)
|
||||||
|
SCAN_INTERVAL_ACCOUNTS = timedelta(minutes=60)
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class NiceHashAccountsDataUpdateCoordinator(DataUpdateCoordinator):
|
||||||
|
"""Manages fetching accounts data from NiceHash API"""
|
||||||
|
|
||||||
|
def __init__(self, hass: HomeAssistant, client: NiceHashPrivateClient):
|
||||||
|
"""Initialize"""
|
||||||
|
self.name = f"{DOMAIN}_accounts_coordinator"
|
||||||
|
self._client = client
|
||||||
|
|
||||||
|
super().__init__(
|
||||||
|
hass, _LOGGER, name=self.name, update_interval=SCAN_INTERVAL_ACCOUNTS
|
||||||
|
)
|
||||||
|
|
||||||
|
async def _async_update_data(self):
|
||||||
|
"""Update accounts data and exchange rates"""
|
||||||
|
try:
|
||||||
|
accounts = await self._client.get_accounts()
|
||||||
|
exchange_rates = await NiceHashPublicClient().get_exchange_rates()
|
||||||
|
rates_dict = dict()
|
||||||
|
for rate in exchange_rates:
|
||||||
|
fromCurrency = rate.get("fromCurrency")
|
||||||
|
# Only care about the Bitcoin exchange rates
|
||||||
|
if fromCurrency == CURRENCY_BTC:
|
||||||
|
toCurrency = rate.get("toCurrency")
|
||||||
|
exchange_rate = float(rate.get("exchangeRate"))
|
||||||
|
rates_dict[f"{fromCurrency}-{toCurrency}"] = exchange_rate
|
||||||
|
return {
|
||||||
|
"accounts": accounts,
|
||||||
|
"exchange_rates": rates_dict,
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
raise UpdateFailed(e)
|
||||||
|
|
||||||
|
|
||||||
|
class NiceHashMiningRigsDataUpdateCoordinator(DataUpdateCoordinator):
|
||||||
|
"""Manages fetching mining rigs data from NiceHash API"""
|
||||||
|
|
||||||
|
def __init__(self, hass: HomeAssistant, client: NiceHashPrivateClient):
|
||||||
|
"""Initialize"""
|
||||||
|
self.name = f"{DOMAIN}_mining_rigs_coordinator"
|
||||||
|
self._client = client
|
||||||
|
|
||||||
|
super().__init__(
|
||||||
|
hass, _LOGGER, name=self.name, update_interval=SCAN_INTERVAL_RIGS
|
||||||
|
)
|
||||||
|
|
||||||
|
async def _async_update_data(self):
|
||||||
|
"""Update mining rigs data"""
|
||||||
|
try:
|
||||||
|
data = await self._client.get_mining_rigs()
|
||||||
|
mining_rigs = data.get("miningRigs")
|
||||||
|
rigs_dict = dict()
|
||||||
|
for rig in mining_rigs:
|
||||||
|
rig_id = rig.get("rigId")
|
||||||
|
rigs_dict[f"{rig_id}"] = rig
|
||||||
|
data["miningRigs"] = rigs_dict
|
||||||
|
return data
|
||||||
|
except Exception as e:
|
||||||
|
raise UpdateFailed(e)
|
@ -1,16 +1,13 @@
|
|||||||
"""
|
"""
|
||||||
Sensor platform for NiceHash
|
Sensor platform for NiceHash
|
||||||
"""
|
"""
|
||||||
from datetime import datetime, timedelta
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
|
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import ATTR_ATTRIBUTION
|
from homeassistant.const import ATTR_ATTRIBUTION
|
||||||
from homeassistant.core import Config, HomeAssistant
|
from homeassistant.core import Config, HomeAssistant
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.util import Throttle
|
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
BALANCE_TYPE_AVAILABLE,
|
BALANCE_TYPE_AVAILABLE,
|
||||||
@ -28,11 +25,7 @@ from .const import (
|
|||||||
ICON_TEMPERATURE,
|
ICON_TEMPERATURE,
|
||||||
)
|
)
|
||||||
from .nicehash import NiceHashPrivateClient, NiceHashPublicClient
|
from .nicehash import NiceHashPrivateClient, NiceHashPublicClient
|
||||||
|
from .sensors import NiceHashBalanceSensor, NiceHashRigTemperatureSensor
|
||||||
ATTRIBUTION = "Data provided by NiceHash"
|
|
||||||
FORMAT_DATETIME = "%d-%m-%Y %H:%M"
|
|
||||||
SCAN_INTERVAL_RIGS = timedelta(minutes=1)
|
|
||||||
SCAN_INTERVAL_ACCOUNTS = timedelta(minutes=60)
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -109,202 +102,3 @@ async def async_setup_platform(
|
|||||||
[NiceHashRigTemperatureSensor(rigs_coordinator, rig) for rig in mining_rigs],
|
[NiceHashRigTemperatureSensor(rigs_coordinator, rig) for rig in mining_rigs],
|
||||||
True,
|
True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class NiceHashBalanceSensor(Entity):
|
|
||||||
"""NiceHash Account Balance Sensor"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
coordinator,
|
|
||||||
organization_id,
|
|
||||||
currency,
|
|
||||||
balance_type=BALANCE_TYPE_AVAILABLE,
|
|
||||||
):
|
|
||||||
"""Initialize the sensor"""
|
|
||||||
_LOGGER.debug(f"Account Balance Sensor: {balance_type} {currency}")
|
|
||||||
self.coordinator = coordinator
|
|
||||||
self.currency = currency
|
|
||||||
self.organization_id = organization_id
|
|
||||||
self.balance_type = balance_type
|
|
||||||
self._available = 0.00
|
|
||||||
self._pending = 0.00
|
|
||||||
self._total_balance = 0.00
|
|
||||||
self._exchange_rate = 0.00
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
"""Sensor name"""
|
|
||||||
balance_type = self.balance_type[0].upper() + self.balance_type[1:]
|
|
||||||
return f"{DEFAULT_NAME} {balance_type} Account Balance {self.currency}"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unique_id(self):
|
|
||||||
"""Unique entity id"""
|
|
||||||
return f"{self.organization_id}:{self.currency}:{self.balance_type}"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def should_poll(self):
|
|
||||||
"""No need to pool, Coordinator notifies entity of updates"""
|
|
||||||
return False
|
|
||||||
|
|
||||||
@property
|
|
||||||
def available(self):
|
|
||||||
"""Whether sensor is available"""
|
|
||||||
return self.coordinator.last_update_success
|
|
||||||
|
|
||||||
@property
|
|
||||||
def state(self):
|
|
||||||
"""Sensor state"""
|
|
||||||
accounts = self.coordinator.data.get("accounts")
|
|
||||||
total = accounts.get("total")
|
|
||||||
self._pending = float(total.get("pending"))
|
|
||||||
self._available = float(total.get("available"))
|
|
||||||
self._total_balance = float(total.get("totalBalance"))
|
|
||||||
|
|
||||||
if self.balance_type == BALANCE_TYPE_TOTAL:
|
|
||||||
balance = self._total_balance
|
|
||||||
elif self.balance_type == BALANCE_TYPE_PENDING:
|
|
||||||
balance = self._pending
|
|
||||||
else:
|
|
||||||
balance = self._available
|
|
||||||
|
|
||||||
if self.currency == CURRENCY_BTC:
|
|
||||||
return balance
|
|
||||||
else:
|
|
||||||
exchange_rates = self.coordinator.data.get("exchange_rates")
|
|
||||||
self._exchange_rate = exchange_rates.get(f"{CURRENCY_BTC}-{self.currency}")
|
|
||||||
return round(balance * self._exchange_rate, 2)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def icon(self):
|
|
||||||
"""Sensor icon"""
|
|
||||||
if self.currency == CURRENCY_EUR:
|
|
||||||
return ICON_CURRENCY_EUR
|
|
||||||
elif self.currency == CURRENCY_USD:
|
|
||||||
return ICON_CURRENCY_USD
|
|
||||||
return ICON_CURRENCY_BTC
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unit_of_measurement(self):
|
|
||||||
"""Sensor unit of measurement"""
|
|
||||||
return self.currency
|
|
||||||
|
|
||||||
@property
|
|
||||||
def device_state_attributes(self):
|
|
||||||
"""Sensor device state attributes"""
|
|
||||||
return {
|
|
||||||
ATTR_ATTRIBUTION: ATTRIBUTION,
|
|
||||||
"total": self._total_balance,
|
|
||||||
"available": self._available,
|
|
||||||
"pending": self._pending,
|
|
||||||
"exchange_rate": self._exchange_rate,
|
|
||||||
}
|
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
|
||||||
"""Connect to dispatcher listening for entity data notifications"""
|
|
||||||
self.async_on_remove(
|
|
||||||
self.coordinator.async_add_listener(self.async_write_ha_state)
|
|
||||||
)
|
|
||||||
|
|
||||||
async def async_update(self):
|
|
||||||
"""Update entity"""
|
|
||||||
await self.coordinator.async_request_refresh()
|
|
||||||
|
|
||||||
|
|
||||||
class NiceHashRigTemperatureSensor(Entity):
|
|
||||||
"""NichHash Mining Rig Temperature Sensor"""
|
|
||||||
|
|
||||||
def __init__(self, coordinator, rig):
|
|
||||||
"""Initialize the sensor"""
|
|
||||||
self.coordinator = coordinator
|
|
||||||
self._rig_id = rig["rigId"]
|
|
||||||
self._name = rig["name"]
|
|
||||||
self._temps = []
|
|
||||||
self._num_devices = 0
|
|
||||||
self._num_active_devices = 0
|
|
||||||
_LOGGER.debug(f"Mining Rig Temperature Sensor: {self._name} ({self._rig_id})")
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
"""Sensor name"""
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unique_id(self):
|
|
||||||
"""Unique entity id"""
|
|
||||||
return self._rig_id
|
|
||||||
|
|
||||||
@property
|
|
||||||
def should_poll(self):
|
|
||||||
"""No need to pool, Coordinator notifies entity of updates"""
|
|
||||||
return False
|
|
||||||
|
|
||||||
@property
|
|
||||||
def available(self):
|
|
||||||
"""Whether sensor is available"""
|
|
||||||
return self.coordinator.last_update_success
|
|
||||||
|
|
||||||
@property
|
|
||||||
def state(self):
|
|
||||||
"""Sensor state"""
|
|
||||||
mining_rigs = self.coordinator.data.get("miningRigs")
|
|
||||||
try:
|
|
||||||
rig_data = mining_rigs.get(self._rig_id)
|
|
||||||
devices = rig_data.get("devices")
|
|
||||||
highest_temp = 0
|
|
||||||
self._temps = []
|
|
||||||
self._num_devices = len(devices)
|
|
||||||
|
|
||||||
if self._num_devices > 0:
|
|
||||||
_LOGGER.debug(f"{self._name}: Found {self._num_devices} devices")
|
|
||||||
for device in devices:
|
|
||||||
status = device.get("status").get("enumName")
|
|
||||||
# Ignore inactive devices
|
|
||||||
if status == DEVICE_STATUS_INACTIVE:
|
|
||||||
continue
|
|
||||||
temp = int(device.get("temperature"))
|
|
||||||
self._temps.append(temp)
|
|
||||||
if temp > highest_temp:
|
|
||||||
highest_temp = temp
|
|
||||||
|
|
||||||
self._num_active_devices = len(self._temps)
|
|
||||||
return highest_temp
|
|
||||||
else:
|
|
||||||
_LOGGER.debug(f"{self._name}: No devices found")
|
|
||||||
self._num_devices = 0
|
|
||||||
return 0
|
|
||||||
except Exception as e:
|
|
||||||
_LOGGER.error(f"Unable to get mining rig {self._rig_id}\n{e}")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
@property
|
|
||||||
def icon(self):
|
|
||||||
"""Sensor icon"""
|
|
||||||
return ICON_TEMPERATURE
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unit_of_measurement(self):
|
|
||||||
"""Sensor unit of measurement"""
|
|
||||||
# Not Celsius because then HA might convert to Fahrenheit
|
|
||||||
return "C"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def device_state_attributes(self):
|
|
||||||
"""Sensor device state attributes"""
|
|
||||||
return {
|
|
||||||
ATTR_ATTRIBUTION: ATTRIBUTION,
|
|
||||||
"temperatures": self._temps,
|
|
||||||
"active_devices": self._num_active_devices,
|
|
||||||
"total_devices": self._num_devices,
|
|
||||||
}
|
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
|
||||||
"""Connect to dispatcher listening for entity data notifications"""
|
|
||||||
self.async_on_remove(
|
|
||||||
self.coordinator.async_add_listener(self.async_write_ha_state)
|
|
||||||
)
|
|
||||||
|
|
||||||
async def async_update(self):
|
|
||||||
"""Update entity"""
|
|
||||||
await self.coordinator.async_request_refresh()
|
|
||||||
|
226
custom_components/nicehash/sensors.py
Normal file
226
custom_components/nicehash/sensors.py
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
"""
|
||||||
|
NiceHash Mining Rig Temperature Sensor
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from homeassistant.const import ATTR_ATTRIBUTION
|
||||||
|
from homeassistant.helpers.entity import Entity
|
||||||
|
|
||||||
|
from .const import (
|
||||||
|
BALANCE_TYPE_AVAILABLE,
|
||||||
|
BALANCE_TYPE_PENDING,
|
||||||
|
BALANCE_TYPE_TOTAL,
|
||||||
|
CURRENCY_BTC,
|
||||||
|
CURRENCY_EUR,
|
||||||
|
CURRENCY_USD,
|
||||||
|
DEFAULT_NAME,
|
||||||
|
DEVICE_STATUS_INACTIVE,
|
||||||
|
ICON_CURRENCY_BTC,
|
||||||
|
ICON_CURRENCY_EUR,
|
||||||
|
ICON_CURRENCY_USD,
|
||||||
|
ICON_TEMPERATURE,
|
||||||
|
)
|
||||||
|
|
||||||
|
ATTRIBUTION = "Data provided by NiceHash"
|
||||||
|
FORMAT_DATETIME = "%d-%m-%Y %H:%M"
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class NiceHashBalanceSensor(Entity):
|
||||||
|
"""NiceHash Account Balance Sensor"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
coordinator,
|
||||||
|
organization_id,
|
||||||
|
currency,
|
||||||
|
balance_type=BALANCE_TYPE_AVAILABLE,
|
||||||
|
):
|
||||||
|
"""Initialize the sensor"""
|
||||||
|
_LOGGER.debug(f"Account Balance Sensor: {balance_type} {currency}")
|
||||||
|
self.coordinator = coordinator
|
||||||
|
self.currency = currency
|
||||||
|
self.organization_id = organization_id
|
||||||
|
self.balance_type = balance_type
|
||||||
|
self._available = 0.00
|
||||||
|
self._pending = 0.00
|
||||||
|
self._total_balance = 0.00
|
||||||
|
self._exchange_rate = 0.00
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Sensor name"""
|
||||||
|
balance_type = self.balance_type[0].upper() + self.balance_type[1:]
|
||||||
|
return f"{DEFAULT_NAME} {balance_type} Account Balance {self.currency}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unique_id(self):
|
||||||
|
"""Unique entity id"""
|
||||||
|
return f"{self.organization_id}:{self.currency}:{self.balance_type}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def should_poll(self):
|
||||||
|
"""No need to pool, Coordinator notifies entity of updates"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self):
|
||||||
|
"""Whether sensor is available"""
|
||||||
|
return self.coordinator.last_update_success
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state(self):
|
||||||
|
"""Sensor state"""
|
||||||
|
accounts = self.coordinator.data.get("accounts")
|
||||||
|
total = accounts.get("total")
|
||||||
|
self._pending = float(total.get("pending"))
|
||||||
|
self._available = float(total.get("available"))
|
||||||
|
self._total_balance = float(total.get("totalBalance"))
|
||||||
|
|
||||||
|
if self.balance_type == BALANCE_TYPE_TOTAL:
|
||||||
|
balance = self._total_balance
|
||||||
|
elif self.balance_type == BALANCE_TYPE_PENDING:
|
||||||
|
balance = self._pending
|
||||||
|
else:
|
||||||
|
balance = self._available
|
||||||
|
|
||||||
|
if self.currency == CURRENCY_BTC:
|
||||||
|
return balance
|
||||||
|
else:
|
||||||
|
exchange_rates = self.coordinator.data.get("exchange_rates")
|
||||||
|
self._exchange_rate = exchange_rates.get(f"{CURRENCY_BTC}-{self.currency}")
|
||||||
|
return round(balance * self._exchange_rate, 2)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def icon(self):
|
||||||
|
"""Sensor icon"""
|
||||||
|
if self.currency == CURRENCY_EUR:
|
||||||
|
return ICON_CURRENCY_EUR
|
||||||
|
elif self.currency == CURRENCY_USD:
|
||||||
|
return ICON_CURRENCY_USD
|
||||||
|
return ICON_CURRENCY_BTC
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unit_of_measurement(self):
|
||||||
|
"""Sensor unit of measurement"""
|
||||||
|
return self.currency
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_state_attributes(self):
|
||||||
|
"""Sensor device state attributes"""
|
||||||
|
return {
|
||||||
|
ATTR_ATTRIBUTION: ATTRIBUTION,
|
||||||
|
"total": self._total_balance,
|
||||||
|
"available": self._available,
|
||||||
|
"pending": self._pending,
|
||||||
|
"exchange_rate": self._exchange_rate,
|
||||||
|
}
|
||||||
|
|
||||||
|
async def async_added_to_hass(self):
|
||||||
|
"""Connect to dispatcher listening for entity data notifications"""
|
||||||
|
self.async_on_remove(
|
||||||
|
self.coordinator.async_add_listener(self.async_write_ha_state)
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_update(self):
|
||||||
|
"""Update entity"""
|
||||||
|
await self.coordinator.async_request_refresh()
|
||||||
|
|
||||||
|
|
||||||
|
class NiceHashRigTemperatureSensor(Entity):
|
||||||
|
"""Displays highest temperature of active mining rig devices"""
|
||||||
|
|
||||||
|
def __init__(self, coordinator, rig):
|
||||||
|
"""Initialize the sensor"""
|
||||||
|
self.coordinator = coordinator
|
||||||
|
self._rig_id = rig["rigId"]
|
||||||
|
self._name = rig["name"]
|
||||||
|
self._temps = []
|
||||||
|
self._num_devices = 0
|
||||||
|
self._num_active_devices = 0
|
||||||
|
_LOGGER.debug(f"Mining Rig Temperature Sensor: {self._name} ({self._rig_id})")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Sensor name"""
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unique_id(self):
|
||||||
|
"""Unique entity id"""
|
||||||
|
return self._rig_id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def should_poll(self):
|
||||||
|
"""No need to pool, Coordinator notifies entity of updates"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self):
|
||||||
|
"""Whether sensor is available"""
|
||||||
|
return self.coordinator.last_update_success
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state(self):
|
||||||
|
"""Sensor state"""
|
||||||
|
mining_rigs = self.coordinator.data.get("miningRigs")
|
||||||
|
try:
|
||||||
|
rig_data = mining_rigs.get(self._rig_id)
|
||||||
|
devices = rig_data.get("devices")
|
||||||
|
highest_temp = 0
|
||||||
|
self._temps = []
|
||||||
|
self._num_devices = len(devices)
|
||||||
|
|
||||||
|
if self._num_devices > 0:
|
||||||
|
_LOGGER.debug(f"{self._name}: Found {self._num_devices} devices")
|
||||||
|
for device in devices:
|
||||||
|
status = device.get("status").get("enumName")
|
||||||
|
# Ignore inactive devices
|
||||||
|
if status == DEVICE_STATUS_INACTIVE:
|
||||||
|
continue
|
||||||
|
temp = int(device.get("temperature"))
|
||||||
|
self._temps.append(temp)
|
||||||
|
if temp > highest_temp:
|
||||||
|
highest_temp = temp
|
||||||
|
|
||||||
|
self._num_active_devices = len(self._temps)
|
||||||
|
return highest_temp
|
||||||
|
else:
|
||||||
|
_LOGGER.debug(f"{self._name}: No devices found")
|
||||||
|
self._num_devices = 0
|
||||||
|
return 0
|
||||||
|
except Exception as e:
|
||||||
|
_LOGGER.error(f"Unable to get mining rig {self._rig_id}\n{e}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def icon(self):
|
||||||
|
"""Sensor icon"""
|
||||||
|
return ICON_TEMPERATURE
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unit_of_measurement(self):
|
||||||
|
"""Sensor unit of measurement"""
|
||||||
|
# Not Celsius because then HA might convert to Fahrenheit
|
||||||
|
return "C"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_state_attributes(self):
|
||||||
|
"""Sensor device state attributes"""
|
||||||
|
return {
|
||||||
|
ATTR_ATTRIBUTION: ATTRIBUTION,
|
||||||
|
"temperatures": self._temps,
|
||||||
|
"active_devices": self._num_active_devices,
|
||||||
|
"total_devices": self._num_devices,
|
||||||
|
}
|
||||||
|
|
||||||
|
async def async_added_to_hass(self):
|
||||||
|
"""Connect to dispatcher listening for entity data notifications"""
|
||||||
|
self.async_on_remove(
|
||||||
|
self.coordinator.async_add_listener(self.async_write_ha_state)
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_update(self):
|
||||||
|
"""Update entity"""
|
||||||
|
await self.coordinator.async_request_refresh()
|
Loading…
Reference in New Issue
Block a user