feat(sensor): add device sensors

- status, algorithm, speed, temp, load, rpm
This commit is contained in:
Brian Berg 2020-07-05 18:02:46 +00:00
parent 7f79e0e739
commit d5f9f56f98
3 changed files with 435 additions and 5 deletions

View File

@ -10,12 +10,14 @@ VERSION = "0.1.0"
ISSUE_URL = "https://github.com/brianberg/ha-nicehash/issues" ISSUE_URL = "https://github.com/brianberg/ha-nicehash/issues"
# Icons # Icons
ICON = "mdi:pickaxe"
ICON_CURRENCY_BTC = "mdi:currency-btc" ICON_CURRENCY_BTC = "mdi:currency-btc"
ICON_CURRENCY_EUR = "mdi:currency-eur" ICON_CURRENCY_EUR = "mdi:currency-eur"
ICON_CURRENCY_USD = "mdi:currency-usd" ICON_CURRENCY_USD = "mdi:currency-usd"
ICON_MEMORY = "mdi:memory"
ICON_PICKAXE = "mdi:pickaxe"
ICON_PULSE = "mdi:pulse" ICON_PULSE = "mdi:pulse"
ICON_TEMPERATURE = "mdi:thermometer" ICON_THERMOMETER = "mdi:thermometer"
ICON_SPEEDOMETER = "mdi:speedometer"
# Platforms # Platforms
SENSOR = "sensor" SENSOR = "sensor"
@ -46,12 +48,15 @@ If you have any issues with this you need to open an issue here:
# NiceHash # NiceHash
NICEHASH_API_URL = "https://api2.nicehash.com" NICEHASH_API_URL = "https://api2.nicehash.com"
# Currency
CURRENCY_BTC = "BTC" CURRENCY_BTC = "BTC"
CURRENCY_USD = "USD" CURRENCY_USD = "USD"
CURRENCY_EUR = "EUR" CURRENCY_EUR = "EUR"
# Balance type
BALANCE_TYPE_AVAILABLE = "available" BALANCE_TYPE_AVAILABLE = "available"
BALANCE_TYPE_PENDING = "pending" BALANCE_TYPE_PENDING = "pending"
BALANCE_TYPE_TOTAL = "total" BALANCE_TYPE_TOTAL = "total"
# Device status
DEVICE_STATUS_UNKNOWN = "UNKNOWN" DEVICE_STATUS_UNKNOWN = "UNKNOWN"
DEVICE_STATUS_DISABLED = "DISABLED" DEVICE_STATUS_DISABLED = "DISABLED"
DEVICE_STATUS_INACTIVE = "INACTIVE" DEVICE_STATUS_INACTIVE = "INACTIVE"
@ -60,3 +65,8 @@ DEVICE_STATUS_BENCHMARKING = "BENCHMARKING"
DEVICE_STATUS_ERROR = "ERROR" DEVICE_STATUS_ERROR = "ERROR"
DEVICE_STATUS_PENDING = "PENDING" DEVICE_STATUS_PENDING = "PENDING"
DEVICE_STATUS_OFFLINE = "OFFLINE" DEVICE_STATUS_OFFLINE = "OFFLINE"
# Device stat
DEVICE_SPEED_RATE = "device-speed-rate"
DEVICE_SPEED_ALGORITHM = "device-speed-algorithm"
DEVICE_LOAD = "device-load"
DEVICE_RPM = "device-rpm"

View File

@ -17,12 +17,23 @@ from .const import (
CURRENCY_EUR, CURRENCY_EUR,
CURRENCY_USD, CURRENCY_USD,
DOMAIN, DOMAIN,
DEVICE_LOAD,
DEVICE_RPM,
DEVICE_SPEED_RATE,
DEVICE_SPEED_ALGORITHM,
) )
from .nicehash import NiceHashPrivateClient, NiceHashPublicClient from .nicehash import NiceHashPrivateClient, NiceHashPublicClient
from .sensors import ( from .sensors import (
NiceHashBalanceSensor, NiceHashBalanceSensor,
NiceHashRigStatusSensor, NiceHashRigStatusSensor,
NiceHashRigTemperatureSensor, NiceHashRigTemperatureSensor,
NiceHashRigProfitabilitySensor,
NiceHashDeviceAlgorithmSensor,
NiceHashDeviceSpeedSensor,
NiceHashDeviceStatusSensor,
NiceHashDeviceLoadSensor,
NiceHashDeviceRPMSensor,
NiceHashDeviceTemperatureSensor,
) )
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -94,7 +105,8 @@ async def async_setup_platform(
# Add mining rig sensors # Add mining rig sensors
rig_data = await client.get_mining_rigs() rig_data = await client.get_mining_rigs()
mining_rigs = rig_data["miningRigs"] mining_rigs = rig_data.get("miningRigs")
# Add status sensors # Add status sensors
async_add_entities( async_add_entities(
[NiceHashRigStatusSensor(rigs_coordinator, rig) for rig in mining_rigs], True, [NiceHashRigStatusSensor(rigs_coordinator, rig) for rig in mining_rigs], True,
@ -104,3 +116,34 @@ 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,
) )
# Add profitability sensors
async_add_entities(
[NiceHashRigProfitabilitySensor(rigs_coordinator, rig) for rig in mining_rigs],
True,
)
# Add device sensors
device_sensors = []
for rig in mining_rigs:
devices = rig.get("devices")
for i in range(len(devices)):
device = devices[i]
device_sensors.append(
NiceHashDeviceAlgorithmSensor(rigs_coordinator, rig, device)
)
device_sensors.append(
NiceHashDeviceSpeedSensor(rigs_coordinator, rig, device)
)
device_sensors.append(
NiceHashDeviceStatusSensor(rigs_coordinator, rig, device)
)
device_sensors.append(
NiceHashDeviceTemperatureSensor(rigs_coordinator, rig, device)
)
device_sensors.append(
NiceHashDeviceLoadSensor(rigs_coordinator, rig, device)
)
device_sensors.append(
NiceHashDeviceRPMSensor(rigs_coordinator, rig, device)
)
async_add_entities(device_sensors, True)

View File

@ -16,11 +16,18 @@ from .const import (
CURRENCY_USD, CURRENCY_USD,
DEFAULT_NAME, DEFAULT_NAME,
DEVICE_STATUS_UNKNOWN, DEVICE_STATUS_UNKNOWN,
DEVICE_LOAD,
DEVICE_RPM,
DEVICE_SPEED_ALGORITHM,
DEVICE_SPEED_RATE,
ICON_CURRENCY_BTC, ICON_CURRENCY_BTC,
ICON_CURRENCY_EUR, ICON_CURRENCY_EUR,
ICON_CURRENCY_USD, ICON_CURRENCY_USD,
ICON_MEMORY,
ICON_PICKAXE,
ICON_PULSE, ICON_PULSE,
ICON_TEMPERATURE, ICON_THERMOMETER,
ICON_SPEEDOMETER,
) )
ATTRIBUTION = "Data provided by NiceHash" ATTRIBUTION = "Data provided by NiceHash"
@ -210,7 +217,7 @@ class NiceHashRigTemperatureSensor(Entity):
@property @property
def icon(self): def icon(self):
"""Sensor icon""" """Sensor icon"""
return ICON_TEMPERATURE return ICON_THERMOMETER
@property @property
def unit_of_measurement(self): def unit_of_measurement(self):
@ -324,3 +331,373 @@ class NiceHashRigStatusSensor(Entity):
async def async_update(self): async def async_update(self):
"""Update entity""" """Update entity"""
await self.coordinator.async_request_refresh() await self.coordinator.async_request_refresh()
class NiceHashRigProfitabilitySensor(Entity):
"""
Displays profitability of a mining rig
"""
def __init__(self, coordinator, rig):
"""Initialize the sensor"""
self.coordinator = coordinator
self._rig_id = rig["rigId"]
self._rig_name = rig["name"]
self._profitability = 0
self._unpaid_amount = 0
_LOGGER.debug(
f"Mining Rig Profitability Sensor: {self._rig_name} ({self._rig_id})"
)
@property
def name(self):
"""Sensor name"""
return f"{self._rig_name} Profitability"
@property
def unique_id(self):
"""Unique entity id"""
return f"{self._rig_id}:profitability"
@property
def should_poll(self):
"""No need to poll, 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)
self._profitability = rig_data.get("profitability")
self._unpaid_amount = rig_data.get("unpaidAmount")
except Exception as e:
_LOGGER.error(f"Unable to get mining rig ({self._rig_id}) status\n{e}")
self._profitability = 0
self._unpaid_amount = 0
return self._profitability
@property
def icon(self):
"""Sensor icon"""
return ICON_CURRENCY_BTC
@property
def unit_of_measurement(self):
"""Sensor unit of measurement"""
return CURRENCY_BTC
@property
def device_state_attributes(self):
"""Sensor device state attributes"""
return {
ATTR_ATTRIBUTION: ATTRIBUTION,
"profitability": self._profitability,
"unpaid_amount": self._unpaid_amount,
}
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()
#######################################
# Mining Device Sensors
#######################################
class NiceHashDeviceSensor(Entity):
"""
Mining rig device sensor
"""
def __init__(self, coordinator, rig, device):
"""Initialize the sensor"""
self.coordinator = coordinator
self._rig_id = rig.get("rigId")
self._rig_name = rig.get("name")
self._device_name = device.get("name")
self._device_id = device.get("id")
self._status = DEVICE_STATUS_UNKNOWN
self._load = 0
self._rpm = 0
self._algorithm = None
self._speed = 0
self._speed_title = "Unknown"
self._speed_unit = "MH"
self._temperature = 0
@property
def name(self):
"""Sensor name"""
return f"{self._device_name}"
@property
def should_poll(self):
"""No need to poll, Coordinator notifies entity of updates"""
return False
@property
def available(self):
"""Whether sensor is available"""
return self.coordinator.last_update_success
@property
def icon(self):
"""Sensor icon"""
return ICON_PICKAXE
@property
def unit_of_measurement(self):
"""Sensor unit of measurement"""
return None
@property
def device_state_attributes(self):
"""Sensor device state attributes"""
return {
ATTR_ATTRIBUTION: ATTRIBUTION,
"status": self._status,
"algorithm": self._algorithm,
"speed": self._speed,
"speed_unit": f"{self._speed_unit}/s",
"temperature": self._temperature,
"load": f"{self._load}%",
"rpm": self._rpm,
}
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()
mining_rigs = self.coordinator.data.get("miningRigs")
try:
rig_data = mining_rigs.get(self._rig_id)
devices = rig_data.get("devices")
for device in devices:
if device.get("id") == self._device_id:
algorithms = device.get("speeds")
if len(algorithms) > 0:
status = device.get("status")
self._status = status.get("description")
algorithm = algorithms[0]
self._load = float(device.get("load"))
self._rpm = float(device.get("revolutionsPerMinute"))
self._algorithm = algorithm.get("title")
self._speed = float(algorithm.get("speed"))
self._speed_title = algorithm.get("title")
self._speed_unit = algorithm.get("displaySuffix")
self._temperature = int(device.get("temperature"))
else:
self._status = DEVICE_STATUS_UNKNOWN
self._load = 0
self._rpm = 0
self._speed = 0
self._speed_title = "Unknown"
self._speed_unit = "MH"
self._algorithm = None
except Exception as e:
_LOGGER.error(f"Unable to get mining device ({self._device_id}) speed\n{e}")
self._status = DEVICE_STATUS_UNKNOWN
self._load = 0
self._rpm = 0
self._speed = 0
self._speed_title = "Unknown"
self._speed_unit = "MH"
self._algorithm = None
class NiceHashDeviceStatusSensor(NiceHashDeviceSensor):
"""
Displays status of a mining rig device
"""
@property
def name(self):
"""Sensor name"""
return f"{self._device_name} Status"
@property
def unique_id(self):
"""Unique entity id"""
return f"{self._device_id}:status"
@property
def state(self):
"""Sensor state"""
return self._status
@property
def icon(self):
"""Sensor icon"""
return ICON_PULSE
class NiceHashDeviceSpeedSensor(NiceHashDeviceSensor):
"""
Displays speed of a mining rig device
"""
@property
def name(self):
"""Sensor name"""
return f"{self._device_name} Speed"
@property
def unique_id(self):
"""Unique entity id"""
return f"{self._device_id}:speed"
@property
def state(self):
"""Sensor state"""
return self._speed
@property
def icon(self):
"""Sensor icon"""
return ICON_SPEEDOMETER
@property
def unit_of_measurement(self):
"""Sensor unit of measurement"""
return f"{self._speed_unit}/s"
class NiceHashDeviceAlgorithmSensor(NiceHashDeviceSensor):
"""
Displays algorithm of a mining rig device
"""
@property
def name(self):
"""Sensor name"""
return f"{self._device_name} Algorithm"
@property
def unique_id(self):
"""Unique entity id"""
return f"{self._device_id}:algorithm"
@property
def state(self):
"""Sensor state"""
return self._algorithm
@property
def icon(self):
"""Sensor icon"""
return ICON_PICKAXE
class NiceHashDeviceTemperatureSensor(NiceHashDeviceSensor):
"""
Displays temperature of a mining rig device
"""
@property
def name(self):
"""Sensor name"""
return f"{self._device_name} Temperature"
@property
def unique_id(self):
"""Unique entity id"""
return f"{self._device_id}:temperature"
@property
def state(self):
"""Sensor state"""
return self._temperature
@property
def icon(self):
"""Sensor icon"""
return ICON_THERMOMETER
@property
def unit_of_measurement(self):
"""Sensor unit of measurement"""
# Not Celsius because then HA might convert to Fahrenheit
return "C"
class NiceHashDeviceLoadSensor(NiceHashDeviceSensor):
"""
Displays load of a mining rig device
"""
@property
def name(self):
"""Sensor name"""
return f"{self._device_name} Load"
@property
def unique_id(self):
"""Unique entity id"""
return f"{self._device_id}:load"
@property
def state(self):
"""Sensor state"""
return self._load
@property
def icon(self):
"""Sensor icon"""
return ICON_SPEEDOMETER
@property
def unit_of_measurement(self):
"""Sensor unit of measurement"""
return "%"
class NiceHashDeviceRPMSensor(NiceHashDeviceSensor):
"""
Displays RPM of a mining rig device
"""
@property
def name(self):
"""Sensor name"""
return f"{self._device_name} RPM"
@property
def unique_id(self):
"""Unique entity id"""
return f"{self._device_id}:rpm"
@property
def state(self):
"""Sensor state"""
return self._rpm
@property
def icon(self):
"""Sensor icon"""
return ICON_SPEEDOMETER
@property
def unit_of_measurement(self):
"""Sensor unit of measurement"""
return "RPM"