Skip to content

Commit

Permalink
Merge pull request #21 from MarcoGos/beta
Browse files Browse the repository at this point in the history
Added Set Yearly Rain and Set Archive Period services
  • Loading branch information
MarcoGos authored Feb 1, 2025
2 parents db7d44d + 6aafc7c commit 178ac9f
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 23 deletions.
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,24 @@ Diagnostic entities:

The entity information is updated every 30 seconds (default or other value is choosen otherwise during setup).

## Actions

The following actions are available:

- Davis Vantage: Set Davis Time
- Set the time of the Davis weather station
- Davis Vantage: Get Davis Time
- Get the time of the Davis weather station
- Davis Vantage: Get Raw Data
- Get the raw, unprocessed data from the last fetch
- Davis Vantage: Get Information
- Get information about firmware and diagnostics
- Davis Vantage: Set Yearly Rain
- Change yearly rain in clicks (depending on setup one click = 0.01" or 0.2mm)
- Davis Vantage: Set Archive Period
- Change archive period in minutes (accepted values: 1, 5, 10, 15, 30, 60, 120). WARNING: This will erase all archived data.=


## Known problems

During first setup the communication to the weather station can be a bit tricky, resulting in an error saying the device didn't communicate. Please try again to set it up (can take up to 5 times).
Expand All @@ -171,6 +189,6 @@ Due to the somewhat unstable hardware interface some communication runs result i
[release-url]: https://github.com/MarcoGos/davis_vantage/releases

[^1]: If Wind Gust doesn't show a value or "Unknown" make sure the Davis time is set correctly. You can check this by using action "Davis Vantage: Get Davis Time" and, if necessary, correct it by using action "Davis Vantage: Set Davis Time".
[^2]: The Archive Interval value can only be changed by using the original WeatherLink software.
[^2]: The Archive Interval value can be set by action "Set Archive Period"


48 changes: 41 additions & 7 deletions custom_components/davis_vantage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Any
import logging
import json
import voluptuous as vol
from zoneinfo import ZoneInfo

from homeassistant.config_entries import ConfigEntry
Expand All @@ -20,6 +21,8 @@
SERVICE_GET_DAVIS_TIME,
SERVICE_GET_RAW_DATA,
SERVICE_GET_INFO,
SERVICE_SET_YEARLY_RAIN,
SERVICE_SET_ARCHIVE_PERIOD,
CONFIG_RAIN_COLLECTOR,
CONFIG_STATION_MODEL,
CONFIG_INTERVAL,
Expand Down Expand Up @@ -97,7 +100,7 @@ async def get_davis_time(_: ServiceCall) -> dict[str, Any]:

async def get_raw_data(_: ServiceCall) -> dict[str, Any]:
raw_data = client.get_raw_data()
json_data = safe_serialize(raw_data)
json_data = Serializer.serialize(raw_data)
return json.loads(json_data)

async def get_info(_: ServiceCall) -> dict[str, Any]:
Expand All @@ -109,6 +112,12 @@ async def get_info(_: ServiceCall) -> dict[str, Any]:
"error": "Couldn't get firmware information from Davis weather station"
}

async def set_yearly_rain(call: ServiceCall) -> None:
await client.async_set_yearly_rain(call.data["rain_clicks"])

async def set_archive_period(call: ServiceCall) -> None:
await client.async_set_archive_period(call.data["archive_period"])

hass.services.async_register(DOMAIN, SERVICE_SET_DAVIS_TIME, set_davis_time)
hass.services.async_register(
DOMAIN,
Expand All @@ -128,13 +137,25 @@ async def get_info(_: ServiceCall) -> dict[str, Any]:
DOMAIN, SERVICE_GET_INFO, get_info, supports_response=SupportsResponse.ONLY
)

def safe_serialize(obj: Any):
# default = lambda obj: f"<<non-serializable: {type(obj).__qualname__}>>" # type: ignore
default = get_default(obj)
return json.dumps(obj, default=default) # type: ignore
hass.services.async_register(
DOMAIN,
SERVICE_SET_YEARLY_RAIN,
set_yearly_rain,
schema=vol.Schema({
vol.Required('rain_clicks'): int
})
)

def get_default(obj: Any):
return f"<<non-serializable: {type(obj).__qualname__}>>"
hass.services.async_register(
DOMAIN,
SERVICE_SET_ARCHIVE_PERIOD,
set_archive_period,
schema=vol.Schema({
vol.Required('archive_period'): vol.In(
["1", "5", "10", "15", "30", "60", "120"]
)
})
)

return True

Expand All @@ -150,3 +171,16 @@ async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Reload config entry."""
await async_unload_entry(hass, entry)
await async_setup_entry(hass, entry)

class Serializer(object):
@staticmethod
def serialize(obj):
def check(o):
for k, v in o.__dict__.items():
try:
_ = json.dumps(v)
o.__dict__[k] = v
except TypeError:
o.__dict__[k] = str(v)
return o
return json.dumps(check(obj).__dict__, indent=2)
44 changes: 41 additions & 3 deletions custom_components/davis_vantage/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,15 @@ def get_current_data(
pass

if self._hass.data.get(DATA_ARCHIVE_PERIOD, None) is None:
self._hass.data.setdefault(DATA_ARCHIVE_PERIOD, self._vantagepro2.archive_period)
self._hass.data.setdefault(
DATA_ARCHIVE_PERIOD, self._vantagepro2.archive_period
)

try:
end_datetime = datetime.now()
start_datetime = end_datetime - \
timedelta(minutes=self._vantagepro2.archive_period * 2) # type: ignore
start_datetime = end_datetime - timedelta(
minutes=self._vantagepro2.archive_period * 2
) # type: ignore
archives = self._vantagepro2.get_archives(start_datetime, end_datetime) # type: ignore
except Exception:
pass
Expand Down Expand Up @@ -255,6 +258,41 @@ async def async_get_static_info(self) -> dict[str, Any] | None:
_LOGGER.error("Couldn't get static info: %s", e)
return info

def set_yearly_rain(self, rain_clicks: int) -> None:
"""Set yearly rain of weather station."""
try:
self._vantagepro2.link.open()
self._vantagepro2.set_yearly_rain(rain_clicks)
except Exception as e:
raise e
finally:
self._vantagepro2.link.close()

async def async_set_yearly_rain(self, rain_clicks: int) -> None:
"""Set yearly rain of weather station async."""
try:
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, self.set_yearly_rain, rain_clicks)
except Exception as e:
_LOGGER.error("Couldn't set yearly rain: %s", e)

def set_archive_period(self, archive_period: int) -> None:
"""Set archive periode, this will erase all archive data"""
try:
self._vantagepro2.link.open()
self._vantagepro2.set_archive_period(archive_period)
except Exception as e:
raise e
finally:
self._vantagepro2.link.close()

async def async_set_archive_period(self, archive_period: int) -> None:
try:
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, self.set_archive_period, archive_period)
except Exception as e:
_LOGGER.error("Couldn't set archive period: %s", e)

def add_additional_info(self, data: dict[str, Any]) -> None:
if data["TempOut"] is not None:
if data["HumOut"] is not None:
Expand Down
4 changes: 3 additions & 1 deletion custom_components/davis_vantage/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
NAME = "Davis Vantage"
DOMAIN = "davis_vantage"
MANUFACTURER = "Davis"
VERSION = "1.3.1"
VERSION = "1.3.2"

DEFAULT_SYNC_INTERVAL = 30 # seconds
DEFAULT_NAME = NAME
Expand All @@ -20,6 +20,8 @@
SERVICE_GET_DAVIS_TIME = 'get_davis_time'
SERVICE_GET_RAW_DATA = 'get_raw_data'
SERVICE_GET_INFO = 'get_info'
SERVICE_SET_YEARLY_RAIN = 'set_yearly_rain'
SERVICE_SET_ARCHIVE_PERIOD = 'set_archive_period'

MODEL_VANTAGE_PRO2 = 'Vantage Pro2'
MODEL_VANTAGE_PRO2PLUS = 'Vantage Pro2 Plus'
Expand Down
4 changes: 3 additions & 1 deletion custom_components/davis_vantage/icons.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"set_davis_time": "mdi:clock-edit-outline",
"get_davis_time": "mdi:clock-outline",
"get_raw_data": "mdi:export",
"get_info": "mdi:information-box-outline"
"get_info": "mdi:information-box-outline",
"set_yearly_rain": "mdi:weather-pouring",
"set_archive_period": "mdi:archive-clock-outline"
},
"entity": {
"sensor": {
Expand Down
4 changes: 2 additions & 2 deletions custom_components/davis_vantage/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"homekit": {},
"iot_class": "local_polling",
"issue_tracker": "https://github.com/MarcoGos/davis_vantage/issues",
"requirements": ["PyVantagePro-MarcoGos==0.3.13"],
"requirements": ["PyVantagePro-MarcoGos==0.3.16"],
"ssdp": [],
"version": "1.3.1",
"version": "1.3.2",
"zeroconf": []
}
8 changes: 1 addition & 7 deletions custom_components/davis_vantage/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,13 @@ def get_sensor_descriptions(model: str) -> list[SensorEntityDescription]:
icon="mdi:clock-outline",
device_class=SensorDeviceClass.TIMESTAMP,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False
),
SensorEntityDescription(
key="LastSuccessTime",
translation_key="last_success_time",
icon="mdi:clock-outline",
device_class=SensorDeviceClass.TIMESTAMP,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False
),
SensorEntityDescription(
key="LastErrorTime",
Expand All @@ -71,15 +69,13 @@ def get_sensor_descriptions(model: str) -> list[SensorEntityDescription]:
key="LastError",
translation_key="last_error_message",
icon="mdi:message-alert-outline",
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False
entity_category=EntityCategory.DIAGNOSTIC
),
SensorEntityDescription(
key="ArchiveInterval",
translation_key="archive_interval",
icon="mdi:archive-clock-outline",
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
native_unit_of_measurement=UnitOfTime.MINUTES
),
SensorEntityDescription(
Expand Down Expand Up @@ -321,7 +317,6 @@ def get_sensor_descriptions(model: str) -> list[SensorEntityDescription]:
translation_key="wind_speed_bft",
icon="mdi:weather-windy",
state_class="measurement",
entity_registry_enabled_default=False
),
SensorEntityDescription(
key="RainDay",
Expand Down Expand Up @@ -439,7 +434,6 @@ def get_sensor_descriptions(model: str) -> list[SensorEntityDescription]:
translation_key="rain_collector",
icon="mdi:bucket-outline",
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
device_class=SensorDeviceClass.ENUM,
options=[
RAIN_COLLECTOR_IMPERIAL,
Expand Down
33 changes: 32 additions & 1 deletion custom_components/davis_vantage/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,35 @@ get_raw_data:
description: Get the raw, unprocessed data from the last fetch
get_info:
name: Get Information
description: Get information about firmware and diagnostics
description: Get information about firmware and diagnostics
set_yearly_rain:
name: Set Yearly Rain
description: Set yearly rain in clicks
fields:
rain_clicks:
name: "Rain Clicks"
description: Rain in clicks (depending on setup one click = 0.01" or 0.2mm)
required: true
example: 500
selector:
number:
set_archive_period:
name: Set Archive Period
description: "Set the archive period in minutes. Please restart HA after change. WARNING: All stored archive data will be erased!!!"
fields:
archive_period:
name: "Archive Period"
description: "Archive Period in minutes"
required: true
example: 10
selector:
select:
options:
- "1"
- "5"
- "10"
- "15"
- "30"
- "60"
- "120"

0 comments on commit 178ac9f

Please sign in to comment.