|
1 | | -from typing import List |
2 | 1 | import requests as req |
3 | | -import pandas as pd |
4 | | -import time as timelib |
5 | | -from functools import reduce |
6 | | - |
7 | | -# TODO add typing |
8 | | - |
9 | | -uploadDataset = "/api/deviceApi/uploadDataset" |
10 | | -initDatasetIncrement = "/api/deviceApi/initDatasetIncrement" |
11 | | -addDatasetIncrement = "/api/deviceApi/addDatasetIncrement" |
12 | | -addDatasetIncrementBatch = "/api/deviceApi/addDatasetIncrementBatch" |
13 | | -getProjectEndpoint = "/api/deviceApi/getProject" |
14 | | - |
15 | | -# |
16 | | -# Uploads a whole dataset to a specific project |
17 | | -# @param {string} url - The url of the backend server |
18 | | -# @param {string} key - The Device-Api-Key |
19 | | -# @param {object} dataset - The dataset to upload |
20 | | -# @returns A Promise indicating success or failure |
21 | | -# |
22 | | - |
23 | | -def sendDataset(url: str, key: str, dataset: dict): |
24 | | - try: |
25 | | - res = req.post(url + uploadDataset, json = {"key": key, "payload": dataset}) |
26 | | - except req.exceptions.RequestException: |
27 | | - raise "error" #TODO |
28 | | - |
29 | | -# |
30 | | -# Returns the all datasets and labels belonging to a project |
31 | | -# Can be used for further processing |
32 | | -# @param {string} url - The url of the backend server |
33 | | -# @param {string} key - The Device-Api-Key |
34 | | -# |
35 | | - |
36 | | -def getProject(url: str, key: str): |
37 | | - print('fetching project...') |
38 | | - res = req.post(url + getProjectEndpoint, json = {"key": key}) |
39 | | - if res.ok: |
40 | | - return res.json() |
41 | | - if res.status_code == 403: |
42 | | - raise RuntimeError("Invalid key") |
43 | | - raise RuntimeError(res.reason) |
44 | | - |
45 | | -def __extractLabels(dataset, labeling: str=None): |
46 | | - labelingSets = dataset['labels'] |
47 | | - matchedSet = None |
48 | | - for labelingSet in labelingSets: |
49 | | - if labelingSet and labelingSet[0] and (labelingSet[0]['labelingName'] == labeling or labeling == None): |
50 | | - labeling = labelingSet[0]['labelingName'] |
51 | | - matchedSet = labelingSet |
52 | | - break |
53 | | - if matchedSet == None: |
54 | | - return (None, None, None) |
55 | | - labelSet = {} # stores different start and end times (intervals) belonging to a label |
56 | | - labelIds = {} # assing distinct ids to labels, required for training with data |
57 | | - labelId = 0 |
58 | | - for label in labelingSet: |
59 | | - name = label['name'] |
60 | | - start = label['start'] |
61 | | - end = label['end'] |
62 | | - if not name in labelSet: |
63 | | - labelSet[name] = [] |
64 | | - labelIds[name] = labelId # assign id to the label |
65 | | - labelId = labelId + 1 |
66 | | - labelSet[name].append((start, end)) # add interval to the label |
67 | | - return (labeling, labelSet, labelIds) |
68 | | - |
69 | | -# |
70 | | -# Returns a list of Pandas.DataFrames generated from the datasets in the project |
71 | | -# Each dataframe corresponds to a single dataset in the project |
72 | | -# For each dataset only with the given labeling labeled parts are included in the dataframes |
73 | | -# If no labeling is provided, first labeling with a valid label on part of the dataset will be used for that dataset |
74 | | -# In this case different datasets may have different labelings as a result in the returned list |
75 | | -# @param {string} url - The url of the backend server |
76 | | -# @param {string} key - The Device-Api-Key |
77 | | -# @param {string} labeling - Labeling used to generate the dataframes |
78 | | - |
79 | | -def getDataFrames(url: str, key: str, labeling: str=None) -> List[pd.DataFrame]: |
80 | | - datasets = getProject(url, key)['datasets'] |
81 | | - df_project: List[pd.DataFrame] = [] |
82 | | - for dataset in datasets: |
83 | | - (labeling, labelSet, labelIds) = __extractLabels(dataset, labeling) |
84 | | - if labelSet == None: # dataset is not labeled |
85 | | - continue |
86 | | - sensors = dataset['sensors'] |
87 | | - df_dataset = [] |
88 | | - for sensor in sensors: |
89 | | - sensorName = sensor['name'] |
90 | | - data = sensor['data'] |
91 | | - df_sensor = {'timestamp': [], 'label': [], sensorName: []} |
92 | | - for dataPoint in data: |
93 | | - timestamp = dataPoint['timestamp'] |
94 | | - value = dataPoint['datapoint'] |
95 | | - for label, intervals in labelSet.items(): |
96 | | - for start, end in intervals: |
97 | | - if timestamp >= start and timestamp <= end: |
98 | | - df_sensor['timestamp'].append(timestamp) |
99 | | - df_sensor[sensorName].append(value) |
100 | | - df_sensor['label'].append(label) |
101 | | - # can break here if it is ensured that labels are not overlapping |
102 | | - df_sensor = pd.DataFrame(df_sensor) |
103 | | - df_dataset.append(df_sensor) |
104 | | - if not df_dataset: |
105 | | - continue |
106 | | - df_dataset = reduce( |
107 | | - lambda left, right: pd.merge( |
108 | | - left, right, on=['timestamp', 'label'], how='outer'), df_dataset |
109 | | - ).sort_values('timestamp').reset_index(drop=True) |
110 | | - df_project.append(df_dataset) |
111 | | - return df_project |
| 2 | +from edgeml.consts import getProjectEndpoint |
| 3 | +from edgeml.Dataset import Dataset |
| 4 | +import timelib |
| 5 | + |
| 6 | + |
| 7 | +class edgeml: |
| 8 | + |
| 9 | + def __init__(self, backendURL, readKey=None, writeKey=None): |
| 10 | + self.backendURL = backendURL |
| 11 | + self._readKey=readKey |
| 12 | + self._writeKey=writeKey |
| 13 | + res = req.get(backendURL + getProjectEndpoint + readKey) |
| 14 | + if res.status_code == 403: |
| 15 | + raise RuntimeError("Invalid key") |
| 16 | + elif res.status_code >= 300: |
| 17 | + raise RuntimeError(res.reason) |
| 18 | + self.datasets = [] |
| 19 | + res_data = res.json() |
| 20 | + datasets = res_data["datasets"] |
| 21 | + self.labeligns = res_data["labelings"] |
| 22 | + for d in datasets: |
| 23 | + tmp_dataset = Dataset(backendURL, self._readKey, self._writeKey) |
| 24 | + tmp_dataset.parse(d, self.labeligns) |
| 25 | + self.datasets.append(tmp_dataset) |
| 26 | + |
| 27 | + def loadData(self): |
| 28 | + for d in self.datasets: |
| 29 | + d.loadData() |
112 | 30 |
|
113 | 31 | # |
114 | 32 | # @param {string} url - The url of the backend server |
|
0 commit comments