Skip to content

Commit

Permalink
Fix bug where tags w/o data were not returned
Browse files Browse the repository at this point in the history
Some tags with no data in the time range specified would return a
completely empty dataframe.
This has been changed so that a column should always be returned.
However, sometimes it will return columns consisting of None, sometimes
columns of NaN and sometimes empty columns. This depends on the handler,
whether the tag is queried alongside other tags that do have data etc.
At least for now it is up to the user to handle these various cases
appropriately.
  • Loading branch information
einarsi committed Oct 7, 2020
1 parent 5ac05ed commit a967a97
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 50 deletions.
2 changes: 1 addition & 1 deletion tagreader/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def _read_single_tag(self, tag, start_time, stop_time, ts, read_type, cache=None
ReaderType.RAW,
]:
cache.store(df, read_type, ts)
frames.append(df)
frames.append(df)
if len(df) < self.handler._max_rows:
break
start = df.index[-1]
Expand Down
25 changes: 7 additions & 18 deletions tagreader/odbc_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,15 +331,11 @@ def read_tag(self, tag, start_time, stop_time, sample_time, read_type, metadata)
index_col="time",
parse_dates={"time": "%Y-%m-%dT%H:%M:%S.%fZ"},
)
if len(df.index) == 0:
warnings.warn(f"Tag {tag} not found")
# This warning will trigger also for (at least some) valid tags with no data.
# if len(df.index) == 0:
# warnings.warn(f"Tag {tag} not found")
df = df.tz_localize("UTC")
# if len(df) > len(
# df.index.unique()
# ): # One hour repeated during transition from DST to standard time.
# df = df.tz_localize(start_time.tzinfo, ambiguous="infer")
# else:
# df = df.tz_localize(start_time.tzinfo)

return df.rename(columns={"value": tag})


Expand Down Expand Up @@ -531,6 +527,7 @@ def read_tag(
):
if metadata is None:
# Tag not found
# TODO: Handle better and similarly across all handlers.
return pd.DataFrame()

query = self.generate_read_query(
Expand All @@ -550,14 +547,8 @@ def read_tag(
df.index = df.index - sample_time
df = df.drop(df.index[0])

# One hour repeated during transition from DST to standard time:
# if len(df) > len(df.index.unique()):
# df = df.tz_localize(start_time.tzinfo, ambiguous='infer')
# else:
# df = df.tz_localize(start_time.tzinfo)
# df = df.tz_localize(start_time.tzinfo)
# df = df.tz_localize("UTC").tz_convert(start_time.tzinfo)
df = df.tz_localize("UTC")

if len(metadata["digitalset"]) > 0:
self.cursor.execute(
f"SELECT code, offset FROM pids WHERE digitalset='{metadata['digitalset']}'" # noqa E501
Expand All @@ -566,7 +557,5 @@ def read_tag(
code = [x[0] for x in digitalset]
offset = [x[1] for x in digitalset]
df = df.replace(code, offset)
# cols = tuple(['value', metadata['engunits'], metadata['descriptor']])
# df.columns = cols
# df.columns.names = ['Tag', 'Unit', 'Description']

return df.rename(columns={"value": tag})
5 changes: 4 additions & 1 deletion tagreader/web_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,10 +414,13 @@ def read_tag(
if res.status_code != 200:
raise ConnectionError

if len(res.text) == 0: # res.text='' for timestamps in future
return pd.DataFrame(columns=[tag])

j = res.json()
if "er" in j['data'][0]['samples'][0]:
warnings.warn(j['data'][0]['samples'][0]['es'])
return pd.DataFrame()
return pd.DataFrame(columns=[tag])
df = (
pd.DataFrame.from_dict(j["data"][0]["samples"])
.drop(labels=["l", "s", "V"], axis="columns")
Expand Down
17 changes: 9 additions & 8 deletions tests/test_AspenHandlerODBC_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ def test_list_sources_aspen():
assert 3 <= len(r) <= 20


def test_read_unknown_tag(Client):
with pytest.warns(UserWarning):
df = Client.read(["sorandomitcantexist"], START_TIME, STOP_TIME)
assert len(df.index) == 0
with pytest.warns(UserWarning):
df = Client.read(["ATCAI", "sorandomitcantexist"], START_TIME, STOP_TIME)
assert len(df.index) > 0
assert len(df.columns == 1)
# def test_read_unknown_tag(Client):
# with pytest.warns(UserWarning):
# df = Client.read(["sorandomitcantexist"], START_TIME, STOP_TIME)
# assert len(df.index) == 0
# assert len(df.columns) == 0
# with pytest.warns(UserWarning):
# df = Client.read(["ATCAI", "sorandomitcantexist"], START_TIME, STOP_TIME)
# assert len(df.index) > 0
# assert len(df.columns) == 1
27 changes: 17 additions & 10 deletions tests/test_PIHandlerODBC_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,20 @@ def test_to_DST_skips_time(Client):
)


def test_read_unknown_tag(Client):
with pytest.warns(UserWarning):
df = Client.read(["sorandomitcantexist"], START_TIME, STOP_TIME)
assert len(df.index) == 0
with pytest.warns(UserWarning):
df = Client.read(
[TAGS["Float32"], "sorandomitcantexist"], START_TIME, STOP_TIME
)
assert len(df.index) > 0
assert len(df.columns == 1)
# def test_read_unknown_tag(Client):
# with pytest.warns(UserWarning):
# df = Client.read(["sorandomitcantexist"], START_TIME, STOP_TIME)
# assert len(df.index) == 0
# with pytest.warns(UserWarning):
# df = Client.read(
# [TAGS["Float32"], "sorandomitcantexist"], START_TIME, STOP_TIME
# )
# assert len(df.index) > 0
# assert len(df.columns) == 1


def test_tags_with_no_data_included_in_results(Client):
df = Client.read(
[TAGS["Float32"]], "2099-01-01 00:00:00", "2099-01-02 00:00:00"
)
assert len(df.columns) == 1
31 changes: 19 additions & 12 deletions tests/test_PIHandlerREST_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,9 @@ def test_read(Client, read_type, size):
SAMPLE_TIME, unit="s"
)
elif read_type in "RAW":
# Weirdness for test-tag which can have two different results,
# Weirdness for test-tag which can have two different results,
# apparently depending on the day of the week, mood, lunar cycle...
assert df.shape == (size, 1) or df.shape == (size-1, 1)
assert df.shape == (size, 1) or df.shape == (size - 1, 1)
assert df.index[0] >= ensure_datetime_with_tz(START_TIME)
assert df.index[-1] <= ensure_datetime_with_tz(STOP_TIME)

Expand Down Expand Up @@ -225,13 +225,20 @@ def test_to_DST_skips_time(Client):
)


def test_read_unknown_tag(Client):
with pytest.warns(UserWarning):
df = Client.read(["sorandomitcantexist"], START_TIME, STOP_TIME)
assert len(df.index) == 0
with pytest.warns(UserWarning):
df = Client.read(
[TAGS["Float32"], "sorandomitcantexist"], START_TIME, STOP_TIME
)
assert len(df.index) > 0
assert len(df.columns == 1)
# def test_read_unknown_tag(Client):
# with pytest.warns(UserWarning):
# df = Client.read(["sorandomitcantexist"], START_TIME, STOP_TIME)
# assert len(df.index) == 0
# with pytest.warns(UserWarning):
# df = Client.read(
# [TAGS["Float32"], "sorandomitcantexist"], START_TIME, STOP_TIME
# )
# assert len(df.index) > 0
# assert len(df.columns == 1)


def test_tags_with_no_data_included_in_results(Client):
df = Client.read(
[TAGS["Float32"]], "2099-01-01 00:00:00", "2099-01-02 00:00:00"
)
assert len(df.columns) == 1

0 comments on commit a967a97

Please sign in to comment.