Compare commits

...

5 Commits

Author SHA1 Message Date
FigurinePanda43 570c67a5e6
Merge 58b9da9b80 into 965f562c53 2026-02-01 13:07:44 +01:00
Lukas Svoboda 965f562c53
Merge pull request #92 from schizza/wslink_api_update
Update Windy integration to use new API endpoint
2026-01-30 17:17:08 +01:00
SchiZzA cf1026f2b9
Update Windy integration to use station ID and password authentication
- Replace API key with station ID and password for Windy data push
- Change Windy update URL and add authorization header
- Update config flow and constants to support new credentials
- Adjust data mapping for WSLink compatibility
- Change WSLink endpoint HTTP method to POST
2026-01-30 17:14:21 +01:00
FigurinePanda43 58b9da9b80 Add support for channels 4-8
- Add CH4-CH8 constants and sensor definitions
- Fix REMAP_ITEMS to include soiltemp4f-7f mappings for Weather API
- Add battery support for all channels
- Add translations for new sensors
- Fix JSON structure in strings.json
- Update README.md with multi-channel documentation
2026-01-12 22:15:58 +01:00
FigurinePanda43 fa2aa9a925 Add support for channels 4-8 2026-01-12 22:08:32 +01:00
10 changed files with 574 additions and 48 deletions

View File

@ -112,6 +112,43 @@ As soon as the integration is added into Home Assistant it will listen for incom
- You are done. - You are done.
## Multi-channel sensor support (CH2-CH8)
This integration supports up to 8 external sensor channels for temperature, humidity, and battery monitoring.
### Supported channels
- **CH2-CH3**: Enabled by default
- **CH4-CH8**: Available but disabled by default (enable manually in Home Assistant)
### Available sensors per channel
Each channel provides:
- **Temperature sensor** (with configurable unit conversion)
- **Humidity sensor** (percentage)
- **Battery level sensor** (percentage)
- **Connection status** (connected/disconnected)
### Enabling additional channels
By default, channels 4-8 are disabled to avoid cluttering your interface. To enable them:
1. Go to **Settings** → **Devices & Services**
2. Find **Sencor SWS 12500** and click on it
3. You'll see all available entities, including disabled ones
4. Click on any disabled channel sensor (e.g., "Channel 5 Temperature")
5. Click the settings icon and enable the entity
6. Repeat for other sensors you want to use
### Station configuration
Your weather station must be configured to send data for these channels. Refer to your station's manual on how to pair and configure external sensors to specific channels.
**Note**: The integration automatically detects incoming data from any channel. If you don't see data for a channel you've enabled, verify that:
- The external sensor is properly paired with your station
- The sensor is sending data (check battery level)
- Your station firmware supports the channel you're trying to use
## WSLink notes ## WSLink notes
While your station is using WSLink you have to have Home Assistant in SSL mode or behind SSL proxy server. While your station is using WSLink you have to have Home Assistant in SSL mode or behind SSL proxy server.

View File

@ -86,7 +86,7 @@ class WeatherDataUpdateCoordinator(DataUpdateCoordinator):
raise HTTPUnauthorized raise HTTPUnauthorized
if self.config_entry.options.get(WINDY_ENABLED): if self.config_entry.options.get(WINDY_ENABLED):
response = await self.windy.push_data_to_windy(data) response = await self.windy.push_data_to_windy(data, _wslink)
if self.config.options.get(POCASI_CZ_ENABLED): if self.config.options.get(POCASI_CZ_ENABLED):
await self.pocasi.push_data_to_server(data, "WSLINK" if _wslink else "WU") await self.pocasi.push_data_to_server(data, "WSLINK" if _wslink else "WU")
@ -160,7 +160,7 @@ def register_path(
if debug: if debug:
_LOGGER.debug("Default route: %s", default_route) _LOGGER.debug("Default route: %s", default_route)
wslink_route = hass.http.app.router.add_get( wslink_route = hass.http.app.router.add_post(
WSLINK_URL, WSLINK_URL,
coordinator.recieved_data if _wslink else unregistred, coordinator.recieved_data if _wslink else unregistred,
name="weather_wslink_url", name="weather_wslink_url",

View File

@ -21,9 +21,10 @@ from .const import (
POCASI_CZ_SEND_INTERVAL, POCASI_CZ_SEND_INTERVAL,
POCASI_CZ_SEND_MINIMUM, POCASI_CZ_SEND_MINIMUM,
SENSORS_TO_LOAD, SENSORS_TO_LOAD,
WINDY_API_KEY,
WINDY_ENABLED, WINDY_ENABLED,
WINDY_LOGGER_ENABLED, WINDY_LOGGER_ENABLED,
WINDY_STATION_ID,
WINDY_STATION_PW,
WSLINK, WSLINK,
) )
@ -82,7 +83,8 @@ class ConfigOptionsFlowHandler(OptionsFlow):
} }
self.windy_data = { self.windy_data = {
WINDY_API_KEY: self.config_entry.options.get(WINDY_API_KEY), WINDY_STATION_ID: self.config_entry.options.get(WINDY_STATION_ID),
WINDY_STATION_PW: self.config_entry.options.get(WINDY_STATION_PW),
WINDY_ENABLED: self.config_entry.options.get(WINDY_ENABLED, False), WINDY_ENABLED: self.config_entry.options.get(WINDY_ENABLED, False),
WINDY_LOGGER_ENABLED: self.config_entry.options.get( WINDY_LOGGER_ENABLED: self.config_entry.options.get(
WINDY_LOGGER_ENABLED, False WINDY_LOGGER_ENABLED, False
@ -91,7 +93,10 @@ class ConfigOptionsFlowHandler(OptionsFlow):
self.windy_data_schema = { self.windy_data_schema = {
vol.Optional( vol.Optional(
WINDY_API_KEY, default=self.windy_data.get(WINDY_API_KEY, "") WINDY_STATION_ID, default=self.windy_data.get(WINDY_STATION_ID, "")
): str,
vol.Optional(
WINDY_STATION_PW, default=self.windy_data.get(WINDY_STATION_PW, "")
): str, ): str,
vol.Optional(WINDY_ENABLED, default=self.windy_data[WINDY_ENABLED]): bool vol.Optional(WINDY_ENABLED, default=self.windy_data[WINDY_ENABLED]): bool
or False, or False,
@ -192,8 +197,8 @@ class ConfigOptionsFlowHandler(OptionsFlow):
errors=errors, errors=errors,
) )
if (user_input[WINDY_ENABLED] is True) and (user_input[WINDY_API_KEY] == ""): if (user_input[WINDY_ENABLED] is True) and ((user_input[WINDY_STATION_ID] == "") or (user_input[WINDY_STATION_PW] == "")):
errors[WINDY_API_KEY] = "windy_key_required" errors[WINDY_STATION_ID] = "windy_key_required"
return self.async_show_form( return self.async_show_form(
step_id="windy", step_id="windy",
data_schema=vol.Schema(self.windy_data_schema), data_schema=vol.Schema(self.windy_data_schema),

View File

@ -6,7 +6,7 @@ from typing import Final
DOMAIN = "sws12500" DOMAIN = "sws12500"
DEFAULT_URL = "/weatherstation/updateweatherstation.php" DEFAULT_URL = "/weatherstation/updateweatherstation.php"
WSLINK_URL = "/data/upload.php" WSLINK_URL = "/data/upload.php"
WINDY_URL = "https://stations.windy.com/pws/update/" WINDY_URL = "https://stations.windy.com/api/v2/observation/update"
DATABASE_PATH = "/config/home-assistant_v2.db" DATABASE_PATH = "/config/home-assistant_v2.db"
POCASI_CZ_URL: Final = "http://ms.pocasimeteo.cz" POCASI_CZ_URL: Final = "http://ms.pocasimeteo.cz"
@ -36,7 +36,8 @@ POCASI_CZ_UNEXPECTED: Final = (
"Pocasti Meteo responded unexpectedly 3 times in row. Resendig is now disabled!" "Pocasti Meteo responded unexpectedly 3 times in row. Resendig is now disabled!"
) )
WINDY_API_KEY = "WINDY_API_KEY" WINDY_STATION_ID = "WINDY_STATION_ID"
WINDY_STATION_PW = "WINDY_STATION_PWD"
WINDY_ENABLED: Final = "windy_enabled_checkbox" WINDY_ENABLED: Final = "windy_enabled_checkbox"
WINDY_LOGGER_ENABLED: Final = "windy_logger_checkbox" WINDY_LOGGER_ENABLED: Final = "windy_logger_checkbox"
WINDY_NOT_INSERTED: Final = "Data was succefuly sent to Windy, but not inserted by Windy API. Does anyone else sent data to Windy?" WINDY_NOT_INSERTED: Final = "Data was succefuly sent to Windy, but not inserted by Windy API. Does anyone else sent data to Windy?"
@ -71,6 +72,8 @@ PURGE_DATA: Final = [
"indoortempf", "indoortempf",
"indoorhumidity", "indoorhumidity",
"dailyrainin", "dailyrainin",
"wspw",
"wsid",
] ]
PURGE_DATA_POCAS: Final = [ PURGE_DATA_POCAS: Final = [
@ -109,9 +112,27 @@ CH2_BATTERY: Final = "ch2_battery"
CH3_TEMP: Final = "ch3_temp" CH3_TEMP: Final = "ch3_temp"
CH3_HUMIDITY: Final = "ch3_humidity" CH3_HUMIDITY: Final = "ch3_humidity"
CH3_CONNECTION: Final = "ch3_connection" CH3_CONNECTION: Final = "ch3_connection"
CH3_BATTERY: Final = "ch3_battery"
CH4_TEMP: Final = "ch4_temp" CH4_TEMP: Final = "ch4_temp"
CH4_HUMIDITY: Final = "ch4_humidity" CH4_HUMIDITY: Final = "ch4_humidity"
CH4_CONNECTION: Final = "ch4_connection" CH4_CONNECTION: Final = "ch4_connection"
CH4_BATTERY: Final = "ch4_battery"
CH5_TEMP: Final = "ch5_temp"
CH5_HUMIDITY: Final = "ch5_humidity"
CH5_CONNECTION: Final = "ch5_connection"
CH5_BATTERY: Final = "ch5_battery"
CH6_TEMP: Final = "ch6_temp"
CH6_HUMIDITY: Final = "ch6_humidity"
CH6_CONNECTION: Final = "ch6_connection"
CH6_BATTERY: Final = "ch6_battery"
CH7_TEMP: Final = "ch7_temp"
CH7_HUMIDITY: Final = "ch7_humidity"
CH7_CONNECTION: Final = "ch7_connection"
CH7_BATTERY: Final = "ch7_battery"
CH8_TEMP: Final = "ch8_temp"
CH8_HUMIDITY: Final = "ch8_humidity"
CH8_CONNECTION: Final = "ch8_connection"
CH8_BATTERY: Final = "ch8_battery"
HEAT_INDEX: Final = "heat_index" HEAT_INDEX: Final = "heat_index"
CHILL_INDEX: Final = "chill_index" CHILL_INDEX: Final = "chill_index"
WBGT_TEMP: Final = "wbgt_temp" WBGT_TEMP: Final = "wbgt_temp"
@ -137,6 +158,14 @@ REMAP_ITEMS: dict[str, str] = {
"soilmoisture2": CH3_HUMIDITY, "soilmoisture2": CH3_HUMIDITY,
"soiltemp3f": CH4_TEMP, "soiltemp3f": CH4_TEMP,
"soilmoisture3": CH4_HUMIDITY, "soilmoisture3": CH4_HUMIDITY,
"soiltemp4f": CH5_TEMP,
"soilmoisture4": CH5_HUMIDITY,
"soiltemp5f": CH6_TEMP,
"soilmoisture5": CH6_HUMIDITY,
"soiltemp6f": CH7_TEMP,
"soilmoisture6": CH7_HUMIDITY,
"soiltemp7f": CH8_TEMP,
"soilmoisture7": CH8_HUMIDITY,
} }
REMAP_WSLINK_ITEMS: dict[str, str] = { REMAP_WSLINK_ITEMS: dict[str, str] = {
@ -158,6 +187,11 @@ REMAP_WSLINK_ITEMS: dict[str, str] = {
"t1cn": OUTSIDE_CONNECTION, "t1cn": OUTSIDE_CONNECTION,
"t234c1cn": CH2_CONNECTION, "t234c1cn": CH2_CONNECTION,
"t234c2cn": CH3_CONNECTION, "t234c2cn": CH3_CONNECTION,
"t234c3cn": CH4_CONNECTION,
"t234c4cn": CH5_CONNECTION,
"t234c5cn": CH6_CONNECTION,
"t234c6cn": CH7_CONNECTION,
"t234c7cn": CH8_CONNECTION,
"t1chill": CHILL_INDEX, "t1chill": CHILL_INDEX,
"t1heat": HEAT_INDEX, "t1heat": HEAT_INDEX,
"t1rainhr": HOURLY_RAIN, "t1rainhr": HOURLY_RAIN,
@ -166,9 +200,25 @@ REMAP_WSLINK_ITEMS: dict[str, str] = {
"t1rainyr": YEARLY_RAIN, "t1rainyr": YEARLY_RAIN,
"t234c2tem": CH3_TEMP, "t234c2tem": CH3_TEMP,
"t234c2hum": CH3_HUMIDITY, "t234c2hum": CH3_HUMIDITY,
"t234c3tem": CH4_TEMP,
"t234c3hum": CH4_HUMIDITY,
"t234c4tem": CH5_TEMP,
"t234c4hum": CH5_HUMIDITY,
"t234c5tem": CH6_TEMP,
"t234c5hum": CH6_HUMIDITY,
"t234c6tem": CH7_TEMP,
"t234c6hum": CH7_HUMIDITY,
"t234c7tem": CH8_TEMP,
"t234c7hum": CH8_HUMIDITY,
"t1bat": OUTSIDE_BATTERY, "t1bat": OUTSIDE_BATTERY,
"inbat": INDOOR_BATTERY, "inbat": INDOOR_BATTERY,
"t234c1bat": CH2_BATTERY, "t234c1bat": CH2_BATTERY,
"t234c2bat": CH3_BATTERY,
"t234c3bat": CH4_BATTERY,
"t234c4bat": CH5_BATTERY,
"t234c5bat": CH6_BATTERY,
"t234c6bat": CH7_BATTERY,
"t234c7bat": CH8_BATTERY,
"t1wbgt": WBGT_TEMP, "t1wbgt": WBGT_TEMP,
} }
@ -185,8 +235,22 @@ DISABLED_BY_DEFAULT: Final = [
CH2_BATTERY, CH2_BATTERY,
CH3_TEMP, CH3_TEMP,
CH3_HUMIDITY, CH3_HUMIDITY,
CH3_BATTERY,
CH4_TEMP, CH4_TEMP,
CH4_HUMIDITY, CH4_HUMIDITY,
CH4_BATTERY,
CH5_TEMP,
CH5_HUMIDITY,
CH5_BATTERY,
CH6_TEMP,
CH6_HUMIDITY,
CH6_BATTERY,
CH7_TEMP,
CH7_HUMIDITY,
CH7_BATTERY,
CH8_TEMP,
CH8_HUMIDITY,
CH8_BATTERY,
OUTSIDE_BATTERY, OUTSIDE_BATTERY,
WBGT_TEMP, WBGT_TEMP,
] ]
@ -195,6 +259,12 @@ BATTERY_LIST = [
OUTSIDE_BATTERY, OUTSIDE_BATTERY,
INDOOR_BATTERY, INDOOR_BATTERY,
CH2_BATTERY, CH2_BATTERY,
CH3_BATTERY,
CH4_BATTERY,
CH5_BATTERY,
CH6_BATTERY,
CH7_BATTERY,
CH8_BATTERY,
] ]

View File

@ -23,6 +23,14 @@ from .const import (
CH3_TEMP, CH3_TEMP,
CH4_HUMIDITY, CH4_HUMIDITY,
CH4_TEMP, CH4_TEMP,
CH5_HUMIDITY,
CH5_TEMP,
CH6_HUMIDITY,
CH6_TEMP,
CH7_HUMIDITY,
CH7_TEMP,
CH8_HUMIDITY,
CH8_TEMP,
CHILL_INDEX, CHILL_INDEX,
DAILY_RAIN, DAILY_RAIN,
DEW_POINT, DEW_POINT,
@ -234,6 +242,82 @@ SENSOR_TYPES_WEATHER_API: tuple[WeatherSensorEntityDescription, ...] = (
translation_key=CH4_HUMIDITY, translation_key=CH4_HUMIDITY,
value_fn=lambda data: cast("int", data), value_fn=lambda data: cast("int", data),
), ),
WeatherSensorEntityDescription(
key=CH5_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH5_TEMP,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=CH5_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH5_HUMIDITY,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription(
key=CH6_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH6_TEMP,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=CH6_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH6_HUMIDITY,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription(
key=CH7_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH7_TEMP,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=CH7_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH7_HUMIDITY,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription(
key=CH8_TEMP,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH8_TEMP,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=CH8_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH8_HUMIDITY,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription( WeatherSensorEntityDescription(
key=HEAT_INDEX, key=HEAT_INDEX,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT, native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,

View File

@ -20,8 +20,24 @@ from .const import (
CH2_BATTERY, CH2_BATTERY,
CH2_HUMIDITY, CH2_HUMIDITY,
CH2_TEMP, CH2_TEMP,
CH3_BATTERY,
CH3_HUMIDITY, CH3_HUMIDITY,
CH3_TEMP, CH3_TEMP,
CH4_BATTERY,
CH4_HUMIDITY,
CH4_TEMP,
CH5_BATTERY,
CH5_HUMIDITY,
CH5_TEMP,
CH6_BATTERY,
CH6_HUMIDITY,
CH6_TEMP,
CH7_BATTERY,
CH7_HUMIDITY,
CH7_TEMP,
CH8_BATTERY,
CH8_HUMIDITY,
CH8_TEMP,
CHILL_INDEX, CHILL_INDEX,
DAILY_RAIN, DAILY_RAIN,
DEW_POINT, DEW_POINT,
@ -265,25 +281,101 @@ SENSOR_TYPES_WSLINK: tuple[WeatherSensorEntityDescription, ...] = (
translation_key=CH3_HUMIDITY, translation_key=CH3_HUMIDITY,
value_fn=lambda data: cast("int", data), value_fn=lambda data: cast("int", data),
), ),
# WeatherSensorEntityDescription( WeatherSensorEntityDescription(
# key=CH4_TEMP, key=CH4_TEMP,
# native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT, native_unit_of_measurement=UnitOfTemperature.CELSIUS,
# state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
# device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
# suggested_unit_of_measurement=UnitOfTemperature.CELSIUS, suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
# icon="mdi:weather-sunny", icon="mdi:weather-sunny",
# translation_key=CH4_TEMP, translation_key=CH4_TEMP,
# value_fn=lambda data: cast(float, data), value_fn=lambda data: cast("float", data),
# ), ),
# WeatherSensorEntityDescription( WeatherSensorEntityDescription(
# key=CH4_HUMIDITY, key=CH4_HUMIDITY,
# native_unit_of_measurement=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
# state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
# device_class=SensorDeviceClass.HUMIDITY, device_class=SensorDeviceClass.HUMIDITY,
# icon="mdi:weather-sunny", icon="mdi:weather-sunny",
# translation_key=CH4_HUMIDITY, translation_key=CH4_HUMIDITY,
# value_fn=lambda data: cast(int, data), value_fn=lambda data: cast("int", data),
# ), ),
WeatherSensorEntityDescription(
key=CH5_TEMP,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH5_TEMP,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=CH5_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH5_HUMIDITY,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription(
key=CH6_TEMP,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH6_TEMP,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=CH6_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH6_HUMIDITY,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription(
key=CH7_TEMP,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH7_TEMP,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=CH7_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH7_HUMIDITY,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription(
key=CH8_TEMP,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.TEMPERATURE,
suggested_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:weather-sunny",
translation_key=CH8_TEMP,
value_fn=lambda data: cast("float", data),
),
WeatherSensorEntityDescription(
key=CH8_HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.HUMIDITY,
icon="mdi:weather-sunny",
translation_key=CH8_HUMIDITY,
value_fn=lambda data: cast("int", data),
),
WeatherSensorEntityDescription( WeatherSensorEntityDescription(
key=HEAT_INDEX, key=HEAT_INDEX,
native_unit_of_measurement=UnitOfTemperature.CELSIUS, native_unit_of_measurement=UnitOfTemperature.CELSIUS,
@ -320,6 +412,48 @@ SENSOR_TYPES_WSLINK: tuple[WeatherSensorEntityDescription, ...] = (
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
value_fn=lambda data: (data), value_fn=lambda data: (data),
), ),
WeatherSensorEntityDescription(
key=CH3_BATTERY,
translation_key=CH3_BATTERY,
icon="mdi:battery-unknown",
device_class=SensorDeviceClass.ENUM,
value_fn=lambda data: (data),
),
WeatherSensorEntityDescription(
key=CH4_BATTERY,
translation_key=CH4_BATTERY,
icon="mdi:battery-unknown",
device_class=SensorDeviceClass.ENUM,
value_fn=lambda data: (data),
),
WeatherSensorEntityDescription(
key=CH5_BATTERY,
translation_key=CH5_BATTERY,
icon="mdi:battery-unknown",
device_class=SensorDeviceClass.ENUM,
value_fn=lambda data: (data),
),
WeatherSensorEntityDescription(
key=CH6_BATTERY,
translation_key=CH6_BATTERY,
icon="mdi:battery-unknown",
device_class=SensorDeviceClass.ENUM,
value_fn=lambda data: (data),
),
WeatherSensorEntityDescription(
key=CH7_BATTERY,
translation_key=CH7_BATTERY,
icon="mdi:battery-unknown",
device_class=SensorDeviceClass.ENUM,
value_fn=lambda data: (data),
),
WeatherSensorEntityDescription(
key=CH8_BATTERY,
translation_key=CH8_BATTERY,
icon="mdi:battery-unknown",
device_class=SensorDeviceClass.ENUM,
value_fn=lambda data: (data),
),
WeatherSensorEntityDescription( WeatherSensorEntityDescription(
key=INDOOR_BATTERY, key=INDOOR_BATTERY,
translation_key=INDOOR_BATTERY, translation_key=INDOOR_BATTERY,

View File

@ -160,6 +160,30 @@
"ch4_humidity": { "ch4_humidity": {
"name": "Channel 4 humidity" "name": "Channel 4 humidity"
}, },
"ch5_temp": {
"name": "Channel 5 temperature"
},
"ch5_humidity": {
"name": "Channel 5 humidity"
},
"ch6_temp": {
"name": "Channel 6 temperature"
},
"ch6_humidity": {
"name": "Channel 6 humidity"
},
"ch7_temp": {
"name": "Channel 7 temperature"
},
"ch7_humidity": {
"name": "Channel 7 humidity"
},
"ch8_temp": {
"name": "Channel 8 temperature"
},
"ch8_humidity": {
"name": "Channel 8 humidity"
},
"heat_index": { "heat_index": {
"name": "Apparent temperature" "name": "Apparent temperature"
}, },
@ -185,6 +209,7 @@
"wnw": "WNW", "wnw": "WNW",
"nw": "NW", "nw": "NW",
"nnw": "NNW" "nnw": "NNW"
}
}, },
"outside_battery": { "outside_battery": {
"name": "Outside battery level", "name": "Outside battery level",
@ -193,7 +218,73 @@
"low": "Low", "low": "Low",
"unknown": "Unknown / drained out" "unknown": "Unknown / drained out"
} }
},
"indoor_battery": {
"name": "Indoor battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
} }
},
"ch2_battery": {
"name": "Channel 2 battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
}
},
"ch3_battery": {
"name": "Channel 3 battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
}
},
"ch4_battery": {
"name": "Channel 4 battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
}
},
"ch5_battery": {
"name": "Channel 5 battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
}
},
"ch6_battery": {
"name": "Channel 6 battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
}
},
"ch7_battery": {
"name": "Channel 7 battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
}
},
"ch8_battery": {
"name": "Channel 8 battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
}
},
"wbgt_temp": {
"name": "WBGT temperature"
} }
} }
}, },

View File

@ -65,12 +65,14 @@
"description": "Přeposílání dat z metostanice na Windy", "description": "Přeposílání dat z metostanice na Windy",
"title": "Konfigurace Windy", "title": "Konfigurace Windy",
"data": { "data": {
"WINDY_API_KEY": "Klíč API KEY získaný z Windy", "WINDY_STATION_ID": "ID stanice, získaný z Windy",
"WINDY_STATION_PWD": "Heslo stanice, získané z Windy",
"windy_enabled_checkbox": "Povolit přeposílání dat na Windy", "windy_enabled_checkbox": "Povolit přeposílání dat na Windy",
"windy_logger_checkbox": "Logovat data a odpovědi z Windy" "windy_logger_checkbox": "Logovat data a odpovědi z Windy"
}, },
"data_description": { "data_description": {
"WINDY_API_KEY": "Klíč API KEY získaný z https://api.windy.com/keys", "WINDY_STATION_ID": "ID stanice získaný z https://stations.windy.com/station",
"WINDY_STATION_PWD": "Heslo stanice získané z https://stations.windy.com/station",
"windy_logger_checkbox": "Zapnout pouze v případě, že chcete poslat ladící informace vývojáři." "windy_logger_checkbox": "Zapnout pouze v případě, že chcete poslat ladící informace vývojáři."
} }
}, },

View File

@ -60,12 +60,14 @@
"description": "Resend weather data to your Windy stations.", "description": "Resend weather data to your Windy stations.",
"title": "Configure Windy", "title": "Configure Windy",
"data": { "data": {
"WINDY_API_KEY": "API KEY provided by Windy", "WINDY_STATION_ID": "Station ID obtained form Windy",
"WINDY_STATION_PWD": "Station password obtained from Windy",
"windy_enabled_checkbox": "Enable resending data to Windy", "windy_enabled_checkbox": "Enable resending data to Windy",
"windy_logger_checkbox": "Log Windy data and responses" "windy_logger_checkbox": "Log Windy data and responses"
}, },
"data_description": { "data_description": {
"WINDY_API_KEY": "Windy API KEY obtained from https://https://api.windy.com/keys", "WINDY_STATION_ID": "Windy station ID obtained from https://stations.windy.com/stations",
"WINDY_STATION_PWD": "Windy station password obtained from https://stations.windy.com/stations",
"windy_logger_checkbox": "Enable only if you want to send debuging data to the developer." "windy_logger_checkbox": "Enable only if you want to send debuging data to the developer."
} }
}, },
@ -160,6 +162,30 @@
"ch4_humidity": { "ch4_humidity": {
"name": "Channel 4 humidity" "name": "Channel 4 humidity"
}, },
"ch5_temp": {
"name": "Channel 5 temperature"
},
"ch5_humidity": {
"name": "Channel 5 humidity"
},
"ch6_temp": {
"name": "Channel 6 temperature"
},
"ch6_humidity": {
"name": "Channel 6 humidity"
},
"ch7_temp": {
"name": "Channel 7 temperature"
},
"ch7_humidity": {
"name": "Channel 7 humidity"
},
"ch8_temp": {
"name": "Channel 8 temperature"
},
"ch8_humidity": {
"name": "Channel 8 humidity"
},
"heat_index": { "heat_index": {
"name": "Apparent temperature" "name": "Apparent temperature"
}, },
@ -218,6 +244,54 @@
"unknown": "Unknown / drained out" "unknown": "Unknown / drained out"
} }
}, },
"ch3_battery": {
"name": "Channel 3 battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
}
},
"ch4_battery": {
"name": "Channel 4 battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
}
},
"ch5_battery": {
"name": "Channel 5 battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
}
},
"ch6_battery": {
"name": "Channel 6 battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
}
},
"ch7_battery": {
"name": "Channel 7 battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
}
},
"ch8_battery": {
"name": "Channel 8 battery level",
"state": {
"normal": "OK",
"low": "Low",
"unknown": "Unknown / drained out"
}
},
"indoor_battery": { "indoor_battery": {
"name": "Console battery level", "name": "Console battery level",
"state": { "state": {

View File

@ -11,11 +11,12 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import ( from .const import (
PURGE_DATA, PURGE_DATA,
WINDY_API_KEY,
WINDY_ENABLED, WINDY_ENABLED,
WINDY_INVALID_KEY, WINDY_INVALID_KEY,
WINDY_LOGGER_ENABLED, WINDY_LOGGER_ENABLED,
WINDY_NOT_INSERTED, WINDY_NOT_INSERTED,
WINDY_STATION_ID,
WINDY_STATION_PW,
WINDY_SUCCESS, WINDY_SUCCESS,
WINDY_UNEXPECTED, WINDY_UNEXPECTED,
WINDY_URL, WINDY_URL,
@ -87,7 +88,7 @@ class WindyPush:
return None return None
async def push_data_to_windy(self, data): async def push_data_to_windy(self, data, wslink: bool = False):
"""Pushes weather data do Windy stations. """Pushes weather data do Windy stations.
Interval is 5 minutes, otherwise Windy would not accepts data. Interval is 5 minutes, otherwise Windy would not accepts data.
@ -114,18 +115,46 @@ class WindyPush:
if purge in purged_data: if purge in purged_data:
purged_data.pop(purge) purged_data.pop(purge)
if "dewptf" in purged_data: if wslink:
dewpoint = round(((float(purged_data.pop("dewptf")) - 32) / 1.8), 1) # WSLink -> Windy params
purged_data["dewpoint"] = str(dewpoint) if "t1ws" in purged_data:
purged_data["wind"] = purged_data.pop("t1ws")
if "t1wgust" in purged_data:
purged_data["gust"] = purged_data.pop("t1wgust")
if "t1wdir" in purged_data:
purged_data["winddir"] = purged_data.pop("t1wdir")
if "t1hum" in purged_data:
purged_data["humidity"] = purged_data.pop("t1hum")
if "t1dew" in purged_data:
purged_data["dewpoint"] = purged_data.pop("t1dew")
if "t1tem" in purged_data:
purged_data["temp"] = purged_data.pop("t1tem")
if "rbar" in purged_data:
purged_data["mbar"] = purged_data.pop("rbar")
if "t1rainhr" in purged_data:
purged_data["precip"] = purged_data.pop("t1rainhr")
if "t1uvi" in purged_data:
purged_data["uv"] = purged_data.pop("t1uvi")
if "t1solrad" in purged_data:
purged_data["solarradiation"] = purged_data.pop("t1solrad")
windy_api_key = self.config.options.get(WINDY_API_KEY) windy_station_id = self.config.options.get(WINDY_STATION_ID)
request_url = f"{WINDY_URL}{windy_api_key}" windy_station_pw = self.config.options.get(WINDY_STATION_PW)
request_url = f"{WINDY_URL}"
purged_data["id"] = windy_station_id
purged_data["time"] = "now"
headers = {"Authorization": f"Bearer {windy_station_pw}"}
if self.log: if self.log:
_LOGGER.info("Dataset for windy: %s", purged_data) _LOGGER.info("Dataset for windy: %s", purged_data)
session = async_get_clientsession(self.hass, verify_ssl=False) session = async_get_clientsession(self.hass, verify_ssl=False)
try: try:
async with session.get(request_url, params=purged_data) as resp: async with session.get(
request_url, params=purged_data, headers=headers
) as resp:
status = await resp.text() status = await resp.text()
try: try:
self.verify_windy_response(status) self.verify_windy_response(status)