Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DS-898: Switch SDK Line data from datatab to lineviz endpoint #81

Merged
merged 3 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
223 changes: 223 additions & 0 deletions docs/entities/lines.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,226 @@ print(len(df))
# 14
```

### Get Line Data Lineviz
This function allows you to pull data from our line model via lineviz API. This function can be called using either of the two methods of calling:

#### Using Positional Arguments
```
cli.get_line_data_lineviz(assets, d_vars, i_vars, time_selection, asset_time_offset, filters)
```

#### Using Keyword Arguments
```
cli.get_line_data_lineviz(assets=assets, d_vars=d_vars, i_vars=i_vars, time_selection=time_selection, asset_time_offset=asset_time_offset, filters=filters)
```

It will return something like:
```
[
{
"i_vals": [
{
"name": "offset_endtime",
"asset": "SHARED",
"i_pos": 0,
"value": {
"bin_no": 0,
"bin_min": "2024-07-06T00:00:00+00:00",
"bin_max": "2024-07-06T00:00:00+00:00",
"bin_avg": "2024-07-06T00:00:00+00:00"
}
}
],
"d_vals": [
{
"name": "quality",
"asset": "F3_Paper_Mill_PM1_Production_Status",
"d_pos": 0,
"value": {
"avg": 90.5265124361114
},
"kpi": {
"dependencies": {
"reject_tons": 0.9635,
"good_tons": 1380818.9,
"random": 1445.0002659794823
},
"formula": "good_tons / (good_tons + (reject_tons + (random * 100))) * 100 if (good_tons + (reject_tons + (random * 100))) > 0 else None",
"aggregates": {
"reject_tons": "sum",
"good_tons": "sum",
"random": "sum"
}
},
"type": "kpi"
},
{
"name": "stats__32RL1BWTACT__val",
"asset": "F1_Paper_Mill_PM2_Production_Status",
"d_pos": 1,
"value": {
"avg": 70.23743333551619
},
"type": "continuous"
}
],
"_count": 2880
},
{
"i_vals": [
{
"name": "offset_endtime",
"asset": "SHARED",
"i_pos": 0,
"value": {
"bin_no": 1,
"bin_min": "2024-07-07T00:00:00+00:00",
"bin_max": "2024-07-07T00:00:00+00:00",
"bin_avg": "2024-07-07T00:00:00+00:00"
}
}
],
"d_vals": [
{
"name": "quality",
"asset": "F3_Paper_Mill_PM1_Production_Status",
"d_pos": 0,
"value": {
"avg": 92.36746206062107
},
"kpi": {
"dependencies": {
"reject_tons": 313.66733,
"good_tons": 1177192.4,
"random": 969.6047504117041
},
"formula": "good_tons / (good_tons + (reject_tons + (random * 100))) * 100 if (good_tons + (reject_tons + (random * 100))) > 0 else None",
"aggregates": {
"reject_tons": "sum",
"good_tons": "sum",
"random": "sum"
}
},
"type": "kpi"
},
{
"name": "stats__32RL1BWTACT__val",
"asset": "F1_Paper_Mill_PM2_Production_Status",
"d_pos": 1,
"value": {
"avg": 72.70377143305424
},
"type": "continuous"
}
],
"_count": 1954
}
]
```

Both methods of calling the API are functionally equivalent. The first method exclusively uses positional arguments, while the second method employs named arguments. Providing both positional and keyword values for the same argument in an API call is not allowed. It will throw an error, causing the API call to fail.

#### assets
A required field, this is a list of strings where the strings used are all machine_names. You can use machines from different lines.
```
["F3_Paper_Mill_PM1_Production_Status", "F1_Paper_Mill_PM2_Production_Status"]
```

#### d_vars
The Dependent variables. These will change depending on the entity you are trying to access. But will always be a list in the following form:
```
[
{
"name": "quality",
"asset": "F3_Paper_Mill_PM1_Production_Status",
"aggregate": [
"avg"
],
"type": "kpi"
},
{
"name": "stats__32RL1BWTACT__val",
"asset": "F1_Paper_Mill_PM2_Production_Status",
"aggregate": [
"avg"
],
"type": "continuous"
}
]
```


#### i_vars
The indepent variables. These should typically be time based values that are stored on the machine_type you are using. They will always be a list in the following form:
```
[
{
"name": "offset_endtime",
"asset": "SHARED",
"time_resolution": "day",
"query_tz": "UTC",
"output_tz": "UTC",
"bin_strategy": "user_defined2",
"bin_count": 50
}
]
```


#### time_selection
This is the same time selection we use in other places more details can be found [here](/docs/commonly_used_data_types/data_viz_query.md#time_selection). It defaults to one day if none is given and can look like this:
```
{
"time_type": "relative",
"relative_start": 7,
"relative_unit": "day",
"ctime_tz": "America/Los_Angeles"
}
```


#### asset_time_offset
This is used to set offsets between machines in a line. This is optional and will defualt to no offset if not given. This is a dictionary that looks like this:
```
{
"F3_Paper_Mill_PM1_Production_Status": {
"interval": 0,
"period": "minutes"
},
"F1_Paper_Mill_PM2_Production_Status": {
"interval": 0,
"period": "minutes"
}
}
```


#### filters
This is optional and a way to to filter the data. This a list of objects that each look like the following:
```
{
"asset": "F2_010_BodyMaker_1",
"name": "stats__0_BM 008: Cans Out__val",
"op": "gt",
"value": 35200.0
}
```

##### asset
The name of the asset this filter is looking at. This will be a machine_name.

##### name
The name of the field you are looking at for this machine.

##### op
The operation you are filtering with. Options inclue:
lt: less than
gt: greater than
lte: less than or equal to
gte: greater than or equal to
eq: equal to
in: in
ne: not equal to

##### value
The value you are comparing the field to.
63 changes: 57 additions & 6 deletions smsdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ def dict_to_df(data, normalize=True):
"endtime": "End Time",
"total": "Duration",
"shift": "Shift",
"metadata__reason": "Downtime Reason",
"metadata__category": "Downtime Category",
"metadata__downtime_type": "Downtime Type",
"reason": "Downtime Reason",
"category": "Downtime Category",
"downtime_type": "Downtime Type",
}

downmapinv = {
Expand All @@ -116,9 +116,9 @@ def dict_to_df(data, normalize=True):
"End Time": "endtime",
"Duration": "total",
"Shift": "shift",
"Downtime Reason": "metadata__reason",
"Downtime Category": "metadata__category",
"Downtime Type": "metadata__downtime_type",
"Downtime Reason": "reason",
"Downtime Category": "category",
"Downtime Type": "downtime_type",
}


Expand Down Expand Up @@ -630,6 +630,57 @@ def get_line_data(
limit=limit, offset=offset, **kwargs
)

@version_check_decorator
def get_line_data_lineviz(
self,
assets=None,
d_vars=None,
i_vars=None,
time_selection=ONE_DAY_RELATIVE,
asset_time_offset={},
filters=[],
**kwargs,
):
"""
Returns all the lines for the facility
:param assets: A list of assets you wish to get data for
:param asset_time_offset: A dictionary of the time offsets to use for assets
:param d_vars: A list of data viz d_var objects
:param i_vars: A list of data viz i_var objects
:param time_selection: A time selection for your query defaults to one day relative
:param filter: A list of filters on the data
"""
lines = smsdkentities.get("line")
base_url = get_url(
self.config["protocol"],
self.tenant,
self.config["site.domain"],
self.config["port"],
)

if i_vars:
kwargs["d_vars"] = d_vars
if i_vars:
kwargs["i_vars"] = i_vars
if time_selection:
kwargs["time_selection"] = time_selection
if assets:
for asset in assets:
if asset_time_offset.get(asset) == None:
asset_time_offset[asset] = {"interval": 0, "period": "minutes"}

where = []
if len(filters) > 0:
for filter in filters:
where.append({"nested": [filter]})

kwargs["d_vars"] = d_vars
kwargs["i_vars"] = i_vars
kwargs["asset_time_offset"] = asset_time_offset
kwargs["time_selection"] = time_selection
kwargs["where"] = where
return lines(self.session, base_url).get_line_data_lineviz(**kwargs)

@version_check_decorator
def create_share_link(
self,
Expand Down
12 changes: 6 additions & 6 deletions smsdk/client_v0.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ def convert_to_valid_url(
"endtime": "End Time",
"total": "Duration",
"shift": "Shift",
"metadata__reason": "Downtime Reason",
"metadata__category": "Downtime Category",
"metadata__downtime_type": "Downtime Type",
"reason": "Downtime Reason",
"category": "Downtime Category",
"downtime_type": "Downtime Type",
}

downmapinv = {
Expand All @@ -144,9 +144,9 @@ def convert_to_valid_url(
"End Time": "endtime",
"Duration": "total",
"Shift": "shift",
"Downtime Reason": "metadata__reason",
"Downtime Category": "metadata__category",
"Downtime Type": "metadata__downtime_type",
"Downtime Reason": "reason",
"Downtime Category": "category",
"Downtime Type": "downtime_type",
}


Expand Down
3 changes: 2 additions & 1 deletion smsdk/config/api_endpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
"current_value": "/v1/recipe/current_value"
},
"Line": {
"url": "/v1/datatab/line"
"url": "/v1/datatab/line",
"task": "/v1/linevis/task/async"
},
"RawData": {
"url": "/v1/datatab/raw_data"
Expand Down
9 changes: 7 additions & 2 deletions smsdk/ma_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
import logging

log = logging.getLogger(__name__)
try:
NPINFINITY = np.Inf
except AttributeError:
# numpy 2.0
NPINFINITY = np.inf


class MaSession:
Expand All @@ -45,7 +50,7 @@ def _get_records(
self,
endpoint: str,
method: str = "get",
_limit: float = np.Inf,
_limit: float = NPINFINITY,
_offset: int = 0,
**url_params: t_.Any,
) -> t_.List[t_.Dict[str, t_.Any]]:
Expand Down Expand Up @@ -150,7 +155,7 @@ def _get_records_v1(
self,
endpoint: str,
method: str = "post",
limit: float = np.Inf,
limit: float = NPINFINITY,
offset: float = 0,
db_mode: str = "sql",
results_under: str = "results",
Expand Down
8 changes: 7 additions & 1 deletion smsdk/smsdk_entities/cycle/cycleV1.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@

ENDPOINTS = json.loads(pkg_resources.read_text(config, "api_endpoints.json"))

try:
NPINFINITY = np.Inf
except AttributeError:
# numpy 2.0
NPINFINITY = np.inf


@smsdkentities.register("cycle_v1")
class Cycle(SmsdkEntities, MaSession):
Expand Down Expand Up @@ -136,7 +142,7 @@ def modify_input_params(self, **kwargs):

new_kwargs["select"] = [{"name": i} for i in kwargs["_only"]]
new_kwargs["offset"] = kwargs.get("_offset", 0)
new_kwargs["limit"] = kwargs.get("_limit", np.Inf)
new_kwargs["limit"] = kwargs.get("_limit", NPINFINITY)
new_kwargs["where"] = where

if kwargs.get("_order_by", ""):
Expand Down
Loading