Skip to content

Commit

Permalink
Add UoM to SDK Time Series Queries and Update Unit Tests (#775)
Browse files Browse the repository at this point in the history
* add uom option to resample query

Signed-off-by: Chloe Ching <[email protected]>

* add unit test for resample uom

Signed-off-by: Chloe Ching <[email protected]>

* Interpolate updates and test

Signed-off-by: Chloe Ching <[email protected]>

* interpolate tests

Signed-off-by: Chloe Ching <[email protected]>

* add uom parameter to time series query builder

Signed-off-by: Chloe Ching <[email protected]>

* Remove code

Signed-off-by: Chloe Ching <[email protected]>

* interpolate unit tests with uom

Signed-off-by: Chloe Ching <[email protected]>

* uom for plot query and unit tests

Signed-off-by: Chloe Ching <[email protected]>

* add uom to cirucular avg, std, latest, interpolate at time, summary and update unit tests

Signed-off-by: Chloe Ching <[email protected]>

---------

Signed-off-by: Chloe Ching <[email protected]>
  • Loading branch information
cching95 authored Jul 18, 2024
1 parent 4fe52f8 commit 89b4cdd
Show file tree
Hide file tree
Showing 21 changed files with 324 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,12 @@ def _sample_query(parameters_dict: dict) -> tuple:
"{% endif %}"
"))) SELECT * FROM pivot ORDER BY `{{ timestamp_column }}` "
"{% else %}"
"{% if display_uom is defined and display_uom == true %}"
"SELECT p.`EventTime`, p.`TagName`, p.`Value`, m.`UoM` FROM project p LEFT OUTER JOIN `{{ business_unit|lower }}`.`sensors`.`{{ asset|lower }}_{{ data_security_level|lower }}_metadata` m ON p.`TagName` = m.`TagName` "
"{% else %}"
"SELECT * FROM project "
"{% endif %}"
"{% endif %}"
"{% if is_resample is defined and is_resample == true and limit is defined and limit is not none %}"
"LIMIT {{ limit }} "
"{% endif %}"
Expand Down Expand Up @@ -203,6 +207,7 @@ def _sample_query(parameters_dict: dict) -> tuple:
"case_insensitivity_tag_search": parameters_dict.get(
"case_insensitivity_tag_search", False
),
"display_uom": parameters_dict.get("display_uom", False),
}

sql_template = Template(sample_query)
Expand Down Expand Up @@ -253,8 +258,12 @@ def _plot_query(parameters_dict: dict) -> tuple:
"{% endif %}"
"))) SELECT * FROM pivot ORDER BY `{{ timestamp_column }}` "
"{% else %}"
"{% if display_uom is defined and display_uom == true %}"
"SELECT p.`EventTime`, p.`TagName`, p.`Value`, m.`UoM` FROM project p LEFT OUTER JOIN `{{ business_unit|lower }}`.`sensors`.`{{ asset|lower }}_{{ data_security_level|lower }}_metadata` m ON p.`TagName` = m.`TagName` "
"{% else %}"
"SELECT * FROM project "
"{% endif %}"
"{% endif %}"
"{% if is_resample is defined and is_resample == true and limit is defined and limit is not none %}"
"LIMIT {{ limit }} "
"{% endif %}"
Expand All @@ -277,7 +286,8 @@ def _plot_query(parameters_dict: dict) -> tuple:
"time_interval_rate": parameters_dict["time_interval_rate"],
"time_interval_unit": parameters_dict["time_interval_unit"],
"time_zone": parameters_dict["time_zone"],
"pivot": False,
"pivot": parameters_dict.get("pivot", None),
"display_uom": parameters_dict.get("display_uom", False),
"limit": parameters_dict.get("limit", None),
"offset": parameters_dict.get("offset", None),
"is_resample": True,
Expand Down Expand Up @@ -354,8 +364,12 @@ def _interpolation_query(
"{% endif %}"
"))) SELECT * FROM pivot ORDER BY `{{ timestamp_column }}` "
"{% else %}"
"{% if display_uom is defined and display_uom == true %}"
"SELECT p.`EventTime`, p.`TagName`, p.`Value`, m.`UoM` FROM project p LEFT OUTER JOIN `{{ business_unit|lower }}`.`sensors`.`{{ asset|lower }}_{{ data_security_level|lower }}_metadata` m ON p.`TagName` = m.`TagName` ORDER BY `{{ tagname_column }}`, `{{ timestamp_column }}` "
"{% else%}"
"SELECT * FROM project ORDER BY `{{ tagname_column }}`, `{{ timestamp_column }}` "
"{% endif %}"
"{% endif %}"
"{% if limit is defined and limit is not none %}"
"LIMIT {{ limit }} "
"{% endif %}"
Expand Down Expand Up @@ -441,8 +455,12 @@ def _interpolation_at_time(parameters_dict: dict) -> str:
"{% endif %}"
"))) SELECT * FROM pivot ORDER BY `{{ timestamp_column }}` "
"{% else %}"
"{% if display_uom is defined and display_uom == true %}"
"SELECT p.`EventTime`, p.`TagName`, p.`Value`, m.`UoM` FROM project p LEFT OUTER JOIN `{{ business_unit|lower }}`.`sensors`.`{{ asset|lower }}_{{ data_security_level|lower }}_metadata` m ON p.`TagName` = m.`TagName` ORDER BY `{{ tagname_column }}`, `{{ timestamp_column }}` "
"{% else%}"
"SELECT * FROM project ORDER BY `{{ tagname_column }}`, `{{ timestamp_column }}` "
"{% endif %}"
"{% endif %}"
"{% if limit is defined and limit is not none %}"
"LIMIT {{ limit }} "
"{% endif %}"
Expand All @@ -466,6 +484,7 @@ def _interpolation_at_time(parameters_dict: dict) -> str:
"max_timestamp": parameters_dict["max_timestamp"],
"window_length": parameters_dict["window_length"],
"pivot": parameters_dict.get("pivot", None),
"display_uom": parameters_dict.get("display_uom", False),
"limit": parameters_dict.get("limit", None),
"offset": parameters_dict.get("offset", None),
"tagname_column": parameters_dict.get("tagname_column", "TagName"),
Expand Down Expand Up @@ -536,7 +555,7 @@ def _metadata_query(parameters_dict: dict) -> str:

def _latest_query(parameters_dict: dict) -> str:
latest_query = (
"SELECT * FROM "
"WITH latest AS (SELECT * FROM "
"{% if source is defined and source is not none %}"
"`{{ source|lower }}` "
"{% else %}"
Expand All @@ -549,7 +568,13 @@ def _latest_query(parameters_dict: dict) -> str:
" WHERE `{{ tagname_column }}` IN ('{{ tag_names | join('\\', \\'') }}') "
"{% endif %}"
"{% endif %}"
"ORDER BY `{{ tagname_column }}` "
"ORDER BY `{{ tagname_column }}` ) "
"{% if display_uom is defined and display_uom == true %}"
"SELECT l.*, m.`UoM` FROM latest l "
"LEFT OUTER JOIN `{{ business_unit|lower }}`.`sensors`.`{{ asset|lower }}_{{ data_security_level|lower }}_metadata` m ON l.`TagName` = m.`TagName` "
"{% else %}"
"SELECT * FROM latest "
"{% endif %}"
"{% if limit is defined and limit is not none %}"
"LIMIT {{ limit }} "
"{% endif %}"
Expand All @@ -565,6 +590,7 @@ def _latest_query(parameters_dict: dict) -> str:
"asset": parameters_dict.get("asset"),
"data_security_level": parameters_dict.get("data_security_level"),
"tag_names": list(dict.fromkeys(parameters_dict["tag_names"])),
"display_uom": parameters_dict.get("display_uom", False),
"limit": parameters_dict.get("limit", None),
"offset": parameters_dict.get("offset", None),
"tagname_column": parameters_dict.get("tagname_column", "TagName"),
Expand Down Expand Up @@ -642,8 +668,12 @@ def _time_weighted_average_query(parameters_dict: dict) -> str:
"{% endif %}"
"))) SELECT * FROM pivot ORDER BY `{{ timestamp_column }}` "
"{% else %}"
"{% if display_uom is defined and display_uom == true %}"
"SELECT p.`EventTime`, p.`TagName`, p.`Value`, m.`UoM` FROM project p LEFT OUTER JOIN `{{ business_unit|lower }}`.`sensors`.`{{ asset|lower }}_{{ data_security_level|lower }}_metadata` m ON p.`TagName` = m.`TagName` ORDER BY `{{ tagname_column }}`, `{{ timestamp_column }}` "
"{% else%}"
"SELECT * FROM project ORDER BY `{{ tagname_column }}`, `{{ timestamp_column }}` "
"{% endif %}"
"{% endif %}"
"{% if limit is defined and limit is not none %}"
"LIMIT {{ limit }} "
"{% endif %}"
Expand Down Expand Up @@ -671,6 +701,7 @@ def _time_weighted_average_query(parameters_dict: dict) -> str:
"include_bad_data": parameters_dict["include_bad_data"],
"step": parameters_dict["step"],
"pivot": parameters_dict.get("pivot", None),
"display_uom": parameters_dict.get("display_uom", False),
"limit": parameters_dict.get("limit", None),
"offset": parameters_dict.get("offset", None),
"time_zone": parameters_dict["time_zone"],
Expand Down Expand Up @@ -742,8 +773,12 @@ def _circular_stats_query(parameters_dict: dict) -> str:
"{% endif %}"
"))) SELECT * FROM pivot ORDER BY `{{ timestamp_column }}` "
"{% else %}"
"{% if display_uom is defined and display_uom == true %}"
"SELECT p.*, m.`UoM` FROM project p LEFT OUTER JOIN `{{ business_unit|lower }}`.`sensors`.`{{ asset|lower }}_{{ data_security_level|lower }}_metadata` m ON p.`TagName` = m.`TagName` ORDER BY `{{ tagname_column }}`, `{{ timestamp_column }}` "
"{% else%}"
"SELECT * FROM project ORDER BY `{{ tagname_column }}`, `{{ timestamp_column }}` "
"{% endif %}"
"{% endif %}"
"{% if limit is defined and limit is not none %}"
"LIMIT {{ limit }} "
"{% endif %}"
Expand All @@ -770,8 +805,12 @@ def _circular_stats_query(parameters_dict: dict) -> str:
"{% endif %}"
"))) SELECT * FROM pivot ORDER BY `{{ timestamp_column }}` "
"{% else %}"
"{% if display_uom is defined and display_uom == true %}"
"SELECT p.*, m.`UoM` FROM project p LEFT OUTER JOIN `{{ business_unit|lower }}`.`sensors`.`{{ asset|lower }}_{{ data_security_level|lower }}_metadata` m ON p.`TagName` = m.`TagName` ORDER BY `{{ tagname_column }}`, `{{ timestamp_column }}` "
"{% else%}"
"SELECT * FROM project ORDER BY `{{ tagname_column }}`, `{{ timestamp_column }}` "
"{% endif %}"
"{% endif %}"
"{% if limit is defined and limit is not none %}"
"LIMIT {{ limit }} "
"{% endif %}"
Expand All @@ -798,6 +837,7 @@ def _circular_stats_query(parameters_dict: dict) -> str:
"time_zone": parameters_dict["time_zone"],
"circular_function": parameters_dict["circular_function"],
"pivot": parameters_dict.get("pivot", None),
"display_uom": parameters_dict.get("display_uom", False),
"limit": parameters_dict.get("limit", None),
"offset": parameters_dict.get("offset", None),
"tagname_column": parameters_dict.get("tagname_column", "TagName"),
Expand Down Expand Up @@ -826,7 +866,7 @@ def _circular_stats_query(parameters_dict: dict) -> str:

def _summary_query(parameters_dict: dict) -> str:
summary_query = (
"SELECT `{{ tagname_column }}`, "
"WITH summary AS (SELECT `{{ tagname_column }}`, "
"count(`{{ value_column }}`) as Count, "
"CAST(Avg(`{{ value_column }}`) as decimal(10, 2)) as Avg, "
"CAST(Min(`{{ value_column }}`) as decimal(10, 2)) as Min, "
Expand All @@ -847,7 +887,12 @@ def _summary_query(parameters_dict: dict) -> str:
"{% if include_status is defined and include_status == true and include_bad_data is defined and include_bad_data == false %}"
"AND `{{ status_column }}` IN ('Good', 'Good, Annotated', 'Substituted, Good, Annotated', 'Substituted, Good', 'Good, Questionable', 'Questionable, Good')"
"{% endif %}"
"GROUP BY `{{ tagname_column }}` "
"GROUP BY `{{ tagname_column }}`) "
"{% if display_uom is defined and display_uom == true %}"
"SELECT s.*, m.`UoM` FROM summary s LEFT OUTER JOIN `{{ business_unit|lower }}`.`sensors`.`{{ asset|lower }}_{{ data_security_level|lower }}_metadata` m ON s.`TagName` = m.`TagName` "
"{% else%}"
"SELECT * FROM summary "
"{% endif %}"
"{% if limit is defined and limit is not none %}"
"LIMIT {{ limit }} "
"{% endif %}"
Expand All @@ -867,6 +912,7 @@ def _summary_query(parameters_dict: dict) -> str:
"end_date": parameters_dict["end_date"],
"tag_names": list(dict.fromkeys(parameters_dict["tag_names"])),
"include_bad_data": parameters_dict["include_bad_data"],
"display_uom": parameters_dict.get("display_uom", False),
"limit": parameters_dict.get("limit", None),
"offset": parameters_dict.get("offset", None),
"time_zone": parameters_dict["time_zone"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def get(connection: object, parameters_dict: dict) -> pd.DataFrame:
upper_bound (int): Upper boundary for the sample range
include_bad_data (bool): Include "Bad" data points with True or remove "Bad" data points with False
pivot (bool): Pivot the data on timestamp column with True or do not pivot the data with False
display_uom (optional bool): Display the unit of measure with True or False. Does not apply to pivoted tables. Defaults to False
limit (optional int): The number of rows to be returned
offset (optional int): The number of rows to skip before returning rows
case_insensitivity_tag_search (optional bool): Search for tags using case insensitivity with True or case sensitivity with False
Expand All @@ -48,10 +49,17 @@ def get(connection: object, parameters_dict: dict) -> pd.DataFrame:
!!! warning
Setting `case_insensitivity_tag_search` to True will result in a longer query time.
!!! Note
`display_uom` True will not work in conjunction with `pivot` set to True.
"""
if isinstance(parameters_dict["tag_names"], list) is False:
raise ValueError("tag_names must be a list")

if "pivot" in parameters_dict and "display_uom" in parameters_dict:
if parameters_dict["pivot"] is True and parameters_dict["display_uom"] is True:
raise ValueError("pivot True and display_uom True cannot be used together")

try:
query = _query_builder(parameters_dict, "circular_average")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def get(connection: object, parameters_dict: dict) -> pd.DataFrame:
upper_bound (int): Upper boundary for the sample range
include_bad_data (bool): Include "Bad" data points with True or remove "Bad" data points with False
pivot (bool): Pivot the data on timestamp column with True or do not pivot the data with False
display_uom (optional bool): Display the unit of measure with True or False. Defaults to False
limit (optional int): The number of rows to be returned
offset (optional int): The number of rows to skip before returning rows
case_insensitivity_tag_search (optional bool): Search for tags using case insensitivity with True or case sensitivity with False
Expand All @@ -48,10 +49,17 @@ def get(connection: object, parameters_dict: dict) -> pd.DataFrame:
!!! warning
Setting `case_insensitivity_tag_search` to True will result in a longer query time.
!!! Note
`display_uom` True will not work in conjunction with `pivot` set to True.
"""
if isinstance(parameters_dict["tag_names"], list) is False:
raise ValueError("tag_names must be a list")

if "pivot" in parameters_dict and "display_uom" in parameters_dict:
if parameters_dict["pivot"] is True and parameters_dict["display_uom"] is True:
raise ValueError("pivot True and display_uom True cannot be used together")

try:
query = _query_builder(parameters_dict, "circular_standard_deviation")

Expand Down
8 changes: 8 additions & 0 deletions src/sdk/python/rtdip_sdk/queries/time_series/interpolate.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def get(connection: object, parameters_dict: dict) -> pd.DataFrame:
interpolation_method (str): Interpolation method (forward_fill, backward_fill, linear)
include_bad_data (bool): Include "Bad" data points with True or remove "Bad" data points with False
pivot (bool): Pivot the data on timestamp column with True or do not pivot the data with False
display_uom (optional bool): Display the unit of measure with True or False. Does not apply to pivoted tables. Defaults to False
limit (optional int): The number of rows to be returned
offset (optional int): The number of rows to skip before returning rows
case_insensitivity_tag_search (optional bool): Search for tags using case insensitivity with True or case sensitivity with False
Expand All @@ -57,10 +58,17 @@ def get(connection: object, parameters_dict: dict) -> pd.DataFrame:
!!! warning
Setting `case_insensitivity_tag_search` to True will result in a longer query time.
!!! Note
`display_uom` True will not work in conjunction with `pivot` set to True.
"""
if isinstance(parameters_dict["tag_names"], list) is False:
raise ValueError("tag_names must be a list")

if "pivot" in parameters_dict and "display_uom" in parameters_dict:
if parameters_dict["pivot"] is True and parameters_dict["display_uom"] is True:
raise ValueError("pivot True and display_uom True cannot be used together")

if "sample_rate" in parameters_dict:
logging.warning(
"Parameter sample_rate is deprecated and will be removed in v1.0.0. Please use time_interval_rate instead."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def get(connection: object, parameters_dict: dict) -> pd.DataFrame:
window_length (int): Add longer window time in days for the start or end of specified date to cater for edge cases.
include_bad_data (bool): Include "Bad" data points with True or remove "Bad" data points with False
pivot (bool): Pivot the data on timestamp column with True or do not pivot the data with False
display_uom (optional bool): Display the unit of measure with True or False. Does not apply to pivoted tables. Defaults to False
limit (optional int): The number of rows to be returned
offset (optional int): The number of rows to skip before returning rows
case_insensitivity_tag_search (optional bool): Search for tags using case insensitivity with True or case sensitivity with False
Expand All @@ -47,13 +48,20 @@ def get(connection: object, parameters_dict: dict) -> pd.DataFrame:
!!! warning
Setting `case_insensitivity_tag_search` to True will result in a longer query time.
!!! Note
`display_uom` True will not work in conjunction with `pivot` set to True.
"""
if isinstance(parameters_dict["tag_names"], list) is False:
raise ValueError("tag_names must be a list")

if isinstance(parameters_dict["timestamps"], list) is False:
raise ValueError("timestamps must be a list")

if "pivot" in parameters_dict and "display_uom" in parameters_dict:
if parameters_dict["pivot"] is True and parameters_dict["display_uom"] is True:
raise ValueError("pivot True and display_uom True cannot be used together")

try:
query = _query_builder(parameters_dict, "interpolation_at_time")

Expand Down
1 change: 1 addition & 0 deletions src/sdk/python/rtdip_sdk/queries/time_series/latest.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def get(connection: object, parameters_dict: dict) -> pd.DataFrame:
asset (str): Asset
data_security_level (str): Level of data security
tag_names (optional, list): Either pass a list of tagname/tagnames ["tag_1", "tag_2"] or leave the list blank [] or leave the parameter out completely
display_uom (optional bool): Display the unit of measure with True or False. Does not apply to pivoted tables. Defaults to False
limit (optional int): The number of rows to be returned
offset (optional int): The number of rows to skip before returning rows
case_insensitivity_tag_search (optional bool): Search for tags using case insensitivity with True or case sensitivity with False
Expand Down
Loading

0 comments on commit 89b4cdd

Please sign in to comment.