Skip to content

Commit

Permalink
Converted market times sensor to ISO Date Time format & added AUD Cur…
Browse files Browse the repository at this point in the history
…rency (#130)

* Update const.py

Added 
- 'aud' to CURRENCY_CODES
Added New Constants
- ATTR_REGULAR_MARKET_TIME
- ATTR_POST_MARKET_TIME
- DATA_REGULAR_MARKET_TIME
- DATA_POST_MARKET_TIME

* epoch to datetime conversion for market times

Added Code to convert
Regular & Post market times epoch values to ISO time formats

* Add Extra Numeric Value tests

Validate new datetime conversions

* Update const.py

Added new Constant

* refactor Epoch timestamp conversions

Refactored and renamed Epoch timestamp conversion

* Update sensor.py - fixed return value

Updated convert_timestamp_to_datetime to return date_timestamp value to support both None and 0 options. IF 0 was allowed to continue on to Epoch conversion  then it would return datetime for Epoch 0 which is 1970

* Update test_sensor.py - rewrote test for timestamp conversion

rewrote test to use the convert_timestamp_to_datetime which replaced the dividend_date function.
Added additional tests to valid the functionality and confirm it correctly returns 0 or None based on the input value.
  • Loading branch information
cabberley authored May 9, 2024
1 parent afcc867 commit a8b9b90
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 25 deletions.
15 changes: 12 additions & 3 deletions custom_components/yahoofinance/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
ATTR_TRENDING: Final = "trending"
ATTR_MARKET_STATE: Final = "marketState"
ATTR_DIVIDEND_DATE: Final = "dividendDate"
ATTR_REGULAR_MARKET_TIME: Final = "regularMarketTime"
ATTR_PRE_MARKET_TIME: Final = "preMarketTime"
ATTR_POST_MARKET_TIME: Final = "postMarketTime"

# Hass data
HASS_DATA_CONFIG: Final = "config"
Expand All @@ -26,6 +29,11 @@
DATA_SHORT_NAME: Final = "shortName"
DATA_MARKET_STATE: Final = "marketState"
DATA_DIVIDEND_DATE: Final = "dividendDate"
DATA_REGULAR_MARKET_TIME: Final = "regularMarketTime"
DATA_PRE_MARKET_TIME: Final = 'preMarketTime'
DATA_POST_MARKET_TIME: Final = "postMarketTime"



DATA_REGULAR_MARKET_PREVIOUS_CLOSE: Final = "regularMarketPreviousClose"
DATA_REGULAR_MARKET_PRICE: Final = "regularMarketPrice"
Expand Down Expand Up @@ -66,7 +74,7 @@
(DATA_REGULAR_MARKET_PREVIOUS_CLOSE, True),
(DATA_REGULAR_MARKET_PRICE, True),
("regularMarketVolume", False),
("regularMarketTime", False),
(DATA_REGULAR_MARKET_TIME, False),
(DATA_DIVIDEND_DATE, False),
],
CONF_INCLUDE_FIFTY_DAY_VALUES: [
Expand All @@ -77,14 +85,14 @@
CONF_INCLUDE_PRE_VALUES: [
("preMarketChange", True),
("preMarketChangePercent", False),
("preMarketTime", False),
(DATA_PRE_MARKET_TIME, False),
("preMarketPrice", True),
],
CONF_INCLUDE_POST_VALUES: [
("postMarketChange", True),
("postMarketChangePercent", False),
("postMarketPrice", True),
("postMarketTime", False),
(DATA_POST_MARKET_TIME, False),
],
CONF_INCLUDE_TWO_HUNDRED_DAY_VALUES: [
("twoHundredDayAverage", True),
Expand Down Expand Up @@ -160,6 +168,7 @@
"""Duration for crumb re-try when receiving 429 code."""

CURRENCY_CODES: Final = {
"aud": "$",
"bdt": "৳",
"brl": "R$",
"btc": "₿",
Expand Down
42 changes: 31 additions & 11 deletions custom_components/yahoofinance/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from __future__ import annotations

from datetime import date, datetime, timedelta
from datetime import date, datetime, timedelta, time
import logging

from homeassistant.components.sensor import (
Expand All @@ -26,8 +26,11 @@
ATTR_CURRENCY_SYMBOL,
ATTR_DIVIDEND_DATE,
ATTR_MARKET_STATE,
ATTR_PRE_MARKET_TIME,
ATTR_POST_MARKET_TIME,
ATTR_QUOTE_SOURCE_NAME,
ATTR_QUOTE_TYPE,
ATTR_REGULAR_MARKET_TIME,
ATTR_SYMBOL,
ATTR_TRENDING,
ATTRIBUTION,
Expand All @@ -39,10 +42,13 @@
DATA_DIVIDEND_DATE,
DATA_FINANCIAL_CURRENCY,
DATA_MARKET_STATE,
DATA_PRE_MARKET_TIME,
DATA_POST_MARKET_TIME,
DATA_QUOTE_SOURCE_NAME,
DATA_QUOTE_TYPE,
DATA_REGULAR_MARKET_PREVIOUS_CLOSE,
DATA_REGULAR_MARKET_PRICE,
DATA_REGULAR_MARKET_TIME,
DATA_SHORT_NAME,
DEFAULT_CURRENCY,
DEFAULT_NUMERIC_DATA_GROUP,
Expand Down Expand Up @@ -166,18 +172,20 @@ def safe_convert(value: float | None, conversion: float | None) -> float | None:
if conversion is None:
return value
return value * conversion

@staticmethod
def parse_dividend_date(dividend_date_timestamp) -> str | None:
"""Parse dividendDate JSON element."""
def convert_timestamp_to_datetime(date_timestamp, return_format) -> str | None:
"""Convert Epoch JSON element to datetime."""

dividend_date_timestamp = convert_to_float(dividend_date_timestamp)
if dividend_date_timestamp is None:
return None
date_timestamp = convert_to_float(date_timestamp)
if date_timestamp is None or date_timestamp == 0:
return date_timestamp

dividend_date = datetime.fromtimestamp(dividend_date_timestamp,tz=dt_util.DEFAULT_TIME_ZONE)
dividend_date_date = dividend_date.date()
return dividend_date_date.isoformat()
converted_date = datetime.fromtimestamp(date_timestamp,tz=dt_util.DEFAULT_TIME_ZONE)
if return_format == "date":
converted_date = converted_date.date()

return converted_date.isoformat()

@property
def unique_id(self) -> str:
Expand Down Expand Up @@ -371,7 +379,19 @@ def update_properties(self) -> None:

self._attr_extra_state_attributes[
ATTR_DIVIDEND_DATE
] = self.parse_dividend_date(symbol_data.get(DATA_DIVIDEND_DATE))
] = self.convert_timestamp_to_datetime(symbol_data.get(DATA_DIVIDEND_DATE),'date')

self._attr_extra_state_attributes[
ATTR_REGULAR_MARKET_TIME
] = self.convert_timestamp_to_datetime(symbol_data.get(DATA_REGULAR_MARKET_TIME),'dateTime')

self._attr_extra_state_attributes[
ATTR_POST_MARKET_TIME
] = self.convert_timestamp_to_datetime(symbol_data.get(DATA_POST_MARKET_TIME),'dateTime')

self._attr_extra_state_attributes[
ATTR_PRE_MARKET_TIME
] = self.convert_timestamp_to_datetime(symbol_data.get(DATA_PRE_MARKET_TIME),'dateTime')

# Use target_currency if we have conversion data. Otherwise keep using the
# currency from data.
Expand Down
31 changes: 20 additions & 11 deletions tests/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
DATA_DIVIDEND_DATE,
DATA_REGULAR_MARKET_PREVIOUS_CLOSE,
DATA_REGULAR_MARKET_PRICE,
DATA_PRE_MARKET_TIME,
DATA_POST_MARKET_TIME,
DATA_REGULAR_MARKET_TIME,
DATA_SHORT_NAME,
DEFAULT_CONF_DECIMAL_PLACES,
DEFAULT_CONF_INCLUDE_FIFTY_DAY_VALUES,
Expand Down Expand Up @@ -165,9 +168,9 @@ def test_sensor_creation(
for data_group in NUMERIC_DATA_GROUPS.values():
for value in data_group:
key = value[0]
if (key != DATA_REGULAR_MARKET_PRICE) and (key != DATA_DIVIDEND_DATE): # noqa: PLR1714
if (key != DATA_REGULAR_MARKET_PRICE) and (key != DATA_DIVIDEND_DATE) and (key != DATA_REGULAR_MARKET_TIME) and (key != DATA_PRE_MARKET_TIME) and (key != DATA_POST_MARKET_TIME): # noqa: PLR1714
assert attributes[key] == 0

# Since we did not provide any data so currency should be the default value
assert sensor.unit_of_measurement == DEFAULT_CURRENCY
assert attributes[ATTR_CURRENCY_SYMBOL] == DEFAULT_CURRENCY_SYMBOL
Expand Down Expand Up @@ -455,15 +458,21 @@ def test_conversion_not_attempted_if_target_currency_same(hass):


@pytest.mark.parametrize(
"dividend_date,expected_date",
"epoch_date,return_format,expected_datetime",
[
(None, None),
(1642118400, "2022-01-14"),
(1646870400, "2022-03-10"),
("1646870400", "2022-03-10"),
("164687040 0", None),
(None, "date", None),
(1642118400, "date","2022-01-14"),
(1646870400, "date","2022-03-10"),
("1646870400", "date","2022-03-10"),
("164687040 0", "date",None),
(1642118453, "datetime","2022-01-14T00:00:53+00:00"),
(1646878750, "datetime","2022-03-10T02:19:10+00:00"),
("1646878750", "datetime","2022-03-10T02:19:10+00:00"),
("164687040 0", "datetime",None),
(0, "date",0),
(0, "datetime",0),
],
)
def test_parse_dividend_date(dividend_date, expected_date):
"""Test dividend date parsing."""
assert YahooFinanceSensor.parse_dividend_date(dividend_date) == expected_date
def test_convert_timestamp_to_datetime(epoch_date,return_format,expected_datetime):
"""Test converting Epoch times to datetime and return date or datetime based on return format."""
assert YahooFinanceSensor.convert_timestamp_to_datetime(epoch_date,return_format) == expected_datetime

0 comments on commit a8b9b90

Please sign in to comment.