Skip to content

Commit

Permalink
Release 2023.10.1 Remove Live Sensors
Browse files Browse the repository at this point in the history
* Remove Live Sensors
  • Loading branch information
jobvk committed Oct 19, 2023
1 parent 67ae502 commit 4e52a1f
Show file tree
Hide file tree
Showing 9 changed files with 16 additions and 359 deletions.
39 changes: 1 addition & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,10 @@ The official websites are https://www.windcentrale.nl and https://winddelen.nl
* [Set Up](#set-up)
* [Options](#options)
* [Sensors](#sensors)
* [Live](#live)
* [History](#history)
* [News](#news)
* [Button](#button)
* [Example](#example)
* [Energy Management tab](#energy-management-tab)
* [Contributors](#contributors)
* [Stargazers](#stargazers)
* [License](#license)
Expand Down Expand Up @@ -73,28 +71,6 @@ Go to Settings and then Devices & Service, select Integrations and search for th

## Sensors

### Live

These sensors show live data from the wind turbine.

|ID|Type|Description|Unit of Measurement|
|------------|------------|------------|------------|
| `sensor.name` | Int | The total amount of power you currently generate with the number of wind shares. | Watt (W) |
| `sensor.name_energy` | Int | The energy that the wind turbine has produced this year. | Kilowatt-hour (kWh) |
| `sensor.name_energy_prognoses_this_year` | Float | The percentage of how much the wind turbine should produce in a year. | Percentage (%) |
| `sensor.name_energy_shares` | Float | The energy that your shares of the wind turbine has produced this year. | Kilowatt-hour (kWh) |
| `sensor.name_hours_run_this_year` | Int | The number of hours the wind turbine has operated this year. | Hours (h) |
| `sensor.name_hours_run_total` | Int | The number of hours the wind turbine has operated in total. | Hours (h) |
| `sensor.name_last_update` | DateTime | Returns when the wind turbine last updated. | DateTime |
| `sensor.name_power_per_share` | Int | The power per wind share that the wind turbine currently generates. | Watt (W) |
| `sensor.name_power_percentage` | Int | The ability in percentage the wind turbine can generate power. | Percentage (%) |
| `sensor.name_power_total` | Int | The total power that the wind turbine currently generates. | Kilowatt (kW) |
| `binary_sensor.name_pulsating` | Bool | The wind turbine is at max power. | Boolean |
| `sensor.name_revolutions_per_minute` | Float | The speed at which the blades of the wind turbine rotate. | Revolutions Per minute (RPM) |
| `sensor.name_run_percentage` | Float | The percentage of the wind turbine is operational since the start date. | Percentage (%) |
| `sensor.name_wind_direction` | String | The direction of the wind at the wind turbine. | Wind rose |
| `sensor.name_wind_speed` | Int | The speed of the wind at the wind turbine. | Beaufort scale (BFT) |

### History

These sensors show how much power the wind turbine has delivered over a certain time.
Expand Down Expand Up @@ -135,24 +111,11 @@ This button `button.the_windcentrale_update_wind_shares` updates your shares. Th

Below is an example of the sensors.

![image](https://user-images.githubusercontent.com/32730202/195425402-9ecdb159-898e-4a13-a0a8-c406d5b3ccf8.png)

## Energy Management tab

To use of Energy Management tab you need to use the sensor `sensor.name_energy_shares`

The sensor state_class is "total" and not "total_increasing" because of energy use of the wind turbine. If the wind turbine is not spinning the wind turbine can use more power than it produces. Found this on their site:

![image](https://user-images.githubusercontent.com/32730202/194364186-bf6ce362-11df-4471-9f1e-014b80835a3b.png)

But there is also a problem. The API uses live data for the power management tab. But for the graph on the official site has a small correction. But this means there is a difference between the graph of energy management tab and the official site. This also means that when the day is past, the total does not match the correct values. When I have found a solution I will certainly update it.

If you found a solution please start a [Discussion](https://github.com/jobvk/Home-Assistant-Windcentrale/discussions).
![image](https://github.com/jobvk/Home-Assistant-Windcentrale/assets/32730202/cb7c24e9-d27f-4c06-9c29-9d36a3393b6d)

## Contributors
Special Thanks to all contributors
* [@vdheidenet](https://github.com/vdheidenet): Sharing his data for creating the signing in function
* [@rob-on-git](https://github.com/rob-on-git): For creating a formula for the run percentage sensor

## Stargazers
Thanks to everyone having starred my repo!
Expand Down
80 changes: 0 additions & 80 deletions custom_components/windcentrale/binary_sensor.py

This file was deleted.

26 changes: 3 additions & 23 deletions custom_components/windcentrale/const.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
"""Constants for the Windcentrale integration."""
import datetime as dt
from homeassistant.components.sensor import SensorDeviceClass
from homeassistant.const import POWER_WATT, POWER_KILO_WATT, ENERGY_KILO_WATT_HOUR, TIME_HOURS, PERCENTAGE, Platform
from homeassistant.const import ENERGY_KILO_WATT_HOUR, Platform

DOMAIN = "windcentrale"

PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.BINARY_SENSOR, Platform.BUTTON]
PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.BUTTON]

CONF_WINDTURBINES = "windturbines"

LIVE_INTERVAL = 1 #min
PRODUCTION_INTERVAL = 1 #hour
NEWS_INTERVAL = 5 #min
TOKEN_INTERVAL = 55 #min
Expand Down Expand Up @@ -41,25 +40,6 @@
"Het Vliegend Hert": ["Lagerwey", "L82", "Rouveen", 52.59131, 6.22014, 9751, dt.datetime(2018, 9, 15), 5000000]
}

# Format:
# Id: [Name, Device Class, Unit Of Measurement, Icon, Json Key]
LIVE_SENSOR_TYPES = {
"windturbine": [None, SensorDeviceClass.POWER, POWER_WATT, "mdi:wind-turbine", "power_per_share"],
"windspeed": ["Wind Speed", None, "BFT", "mdi:windsock", "wind_power"],
"winddirection": ["Wind Direction", None, None, "mdi:compass", "wind_direction"],
"powertotal": ["Power Total", SensorDeviceClass.POWER, POWER_KILO_WATT, None, "power"],
"powerpershare": ["Power Per Share", SensorDeviceClass.POWER, POWER_WATT, None, "power_per_share"],
"powerpercentage": ["Power Percentage", None, PERCENTAGE, "mdi:percent", "power_percentage"],
"rpm": ["Revolutions Per Minute", None, "RPM", "mdi:gauge", "rpm"],
"energy": ["Energy", SensorDeviceClass.ENERGY, ENERGY_KILO_WATT_HOUR, None, "year_production"],
"energyshares": ["Energy shares", SensorDeviceClass.ENERGY, ENERGY_KILO_WATT_HOUR, None, "year_production"],
"energyprognoses": ["Energy Prognoses This Year", None, PERCENTAGE, "mdi:percent", "year_production"],
"runtimeyear": ["Hours Run This Year", None, TIME_HOURS, "mdi:calendar-clock", "year_runtime"],
"runtimetotal": ["Hours Run Total", None, TIME_HOURS, "mdi:calendar-clock", "total_runtime"],
"runpercentage": ["Run Percentage", None, PERCENTAGE, "mdi:percent", "year_runtime"],
"timestamp": ["Last Update", SensorDeviceClass.TIMESTAMP, None, None, "timestamp"]
}

# Format:
# Id: [Name, Unit Of Measurement, Device Class, Timeframe Type]
PRODUCTION_SENSOR_TYPES = {
Expand All @@ -82,4 +62,4 @@ def to_dict(self) -> dict:
'name': self.name,
'code': self.code,
'shares': self.shares
}
}
8 changes: 4 additions & 4 deletions custom_components/windcentrale/diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ async def async_get_config_entry_diagnostics(hass, config_entry) -> dict[str, An
"start_date": windturbine.start_date,
"energy_prognoses": windturbine.energy_prognoses,
"data": {
"live_data": windturbine.liveapi.response_data,
"production_windtrubine_year_data": windturbine.production_windtrubine_year_api.response_data,
"production_windtrubine_month_data": windturbine.production_windtrubine_month_api.response_data,
"production_windtrubine_week_data": windturbine.production_windtrubine_week_api.response_data,
"production_windtrubine_day_data": windturbine.production_windtrubine_day_api.response_data,
"production_shares_year_data": windturbine.production_shares_year_api.response_data,
"production_shares_month_data": windturbine.production_shares_month_api.response_data,
"production_shares_week_data": windturbine.production_shares_week_api.response_data
"production_shares_week_data": windturbine.production_shares_week_api.response_data,
"production_shares_day_data": windturbine.production_shares_day_api.response_data
}
})

Expand All @@ -47,7 +48,6 @@ async def async_get_config_entry_diagnostics(hass, config_entry) -> dict[str, An
"default_show_on_map": DEFAULT_SHOW_ON_MAP,
"conf_windtubines": CONF_WINDTURBINES,
"intervals": {
"live": LIVE_INTERVAL,
"production": PRODUCTION_INTERVAL,
"news": NEWS_INTERVAL,
"token": TOKEN_INTERVAL
Expand Down Expand Up @@ -76,4 +76,4 @@ async def async_get_config_entry_diagnostics(hass, config_entry) -> dict[str, An
"news_data": wind.newsapi.response_data,
"windturbines": windturbine_data
}
}
}
4 changes: 2 additions & 2 deletions custom_components/windcentrale/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/jobvk/Home-Assistant-Windcentrale/issues",
"loggers": ["boto3"],
"requirements": ["boto3==1.28.58", "pycognito==2023.5.0"],
"version": "2023.10.0"
"requirements": ["boto3==1.28.66", "pycognito==2023.5.0"],
"version": "2023.10.1"
}
118 changes: 2 additions & 116 deletions custom_components/windcentrale/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
import logging
import dateutil.relativedelta
from datetime import timedelta, datetime
from .const import DOMAIN, LIVE_SENSOR_TYPES, PRODUCTION_SENSOR_TYPES
from homeassistant.const import ATTR_LOCATION, ATTR_LATITUDE, ATTR_LONGITUDE
from .const import DOMAIN, PRODUCTION_SENSOR_TYPES
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.components.sensor import SensorDeviceClass, SensorStateClass, SensorEntity, ATTR_LAST_RESET, CONF_STATE_CLASS
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity

_LOGGER = logging.getLogger(__name__)

Expand All @@ -18,13 +17,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):

new_entities = []
for windturbine in wind.windturbines:
for live_sensor in LIVE_SENSOR_TYPES:
new_entities.append(LiveSensor(windturbine, live_sensor.lower()))

for production_sensor in PRODUCTION_SENSOR_TYPES:
new_entities.append(ProductionSensor(windturbine, production_sensor.lower()))

await windturbine.schedule_update_live(timedelta())
await windturbine.schedule_update_production(timedelta())

new_entities.append(NewsSensor(wind))
Expand Down Expand Up @@ -55,114 +49,6 @@ def available(self) -> bool:
"""Return True if windturbine and wind is available."""
return True

class LiveSensor(SensorBase):
"""Representation of a Sensor."""

def __init__(self, windturbine, live_sensor_type):
"""Initialize the sensor."""
super().__init__(windturbine)
self.type = live_sensor_type
self._name = LIVE_SENSOR_TYPES[self.type][0]
self._device_class = LIVE_SENSOR_TYPES[self.type][1]
self._unit_of_measurement = LIVE_SENSOR_TYPES[self.type][2]
self._icon = LIVE_SENSOR_TYPES[self.type][3]
self._sensor = LIVE_SENSOR_TYPES[self.type][4]
self.degrees = {
"N": 0,
"NO": 45,
"O": 90,
"ZO": 135,
"Z": 180,
"ZW": 225,
"W": 270,
"NW": 315
}

@property
def unique_id(self) -> str:
"""Unique ID for the sensor."""
if self.type == "windturbine":
return f"{self._windturbine.name}"
else:
return f"{self._windturbine.name} {self._name}"

@property
def name(self) -> str:
"""Name for the sensor."""
if self.type == "windturbine":
return f"{self._windturbine.name}"
else:
return f"{self._windturbine.name} {self._name}"

@property
def device_class(self) -> SensorDeviceClass:
"""Device class of the sensor."""
return self._device_class

@property
def state(self):
"""State value for the sensor."""
return self._state

@property
def icon(self) -> str:
"""Icon for the sensor."""
return self._icon

@property
def unit_of_measurement(self) -> str:
"""Unit of measurement for the sensor."""
return self._unit_of_measurement

@property
def extra_state_attributes(self):
"""Return the state attributes of the entity."""
attr = {}
if self.type == "windturbine":
attr["Id"] = self._windturbine.id
attr["Shares"] = self._windturbine.shares
attr["Total_Shares"] = self._windturbine.total_shares
attr[ATTR_LOCATION] = self._windturbine.location
if self._windturbine.show_on_map:
attr[ATTR_LATITUDE] = self._windturbine.latitude
attr[ATTR_LONGITUDE] = self._windturbine.longitude
else:
attr["Latitude"] = self._windturbine.latitude
attr["Longitude"] = self._windturbine.longitude
attr[CONF_STATE_CLASS] = SensorStateClass.MEASUREMENT
elif self.type == "winddirection":
attr["Degrees"] = self.degrees.get(self._state)
elif self.type in ["windspeed", "powertotal", "powerpershare", "powerpercentage", "rpm"]:
attr[CONF_STATE_CLASS] = SensorStateClass.MEASUREMENT
elif self.type in ["energy", "energyshares"]:
attr[ATTR_LAST_RESET] = datetime(datetime.now().year, 1, 1)
attr[CONF_STATE_CLASS] = SensorStateClass.TOTAL
return attr

async def async_added_to_hass(self):
"""Call when entity is about to be added to Home Assistant."""
if (state := await self.async_get_last_state()) is None:
self._state = None
return

self._state = state.state

def update(self):
"""Update the sensor."""
try:
if self.type == "windturbine":
self._state = self._windturbine.liveapi.response_data[self._sensor] * self._windturbine.shares
elif self.type == "energyshares":
self._state = self._windturbine.liveapi.response_data[self._sensor] / self._windturbine.total_shares * self._windturbine.shares
elif self.type == "runpercentage":
self._state = round(timedelta(hours=self._windturbine.liveapi.response_data[self._sensor]) / (datetime.now() - datetime(datetime.now().year, 1, 1)) * 100, 2)
elif self.type == "energyprognoses":
self._state = round((self._windturbine.liveapi.response_data[self._sensor] / self._windturbine.energy_prognoses) * 100, 2)
else:
self._state = self._windturbine.liveapi.response_data[self._sensor]
except Exception as exc:
_LOGGER.error('There was an exception when updating live sensor with type {}.\n\nThe data of the sensor: {}\n\nThe total live data: {}\n\nThe type of the data: {}\n\nWith the exception: {}'.format(self.type, self._windturbine.live_data[self._sensor], self._windturbine.live_data, type(self._windturbine.live_data), exc))

class ProductionSensor(SensorBase):
"""Representation of a Sensor."""
def __init__(self, windturbine, production_sensor_type):
Expand Down
Loading

0 comments on commit 4e52a1f

Please sign in to comment.