diff --git a/client/src/App.js b/client/src/App.js index 964bfad..7ef951b 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -680,21 +680,18 @@ function MultiLineChart({title, measurement, dataKey, sensors, colors, end, dura const api_key = localStorage.getItem('api_key', 'null'); const params = { end: end.unix(), duration: duration.len.toLowerCase(), window: duration.win, api_key: api_key }; - const responses = await Promise.all( - sensors.map(name => axios.get(`https://sensors-api.dns.t0.vc/history/${measurement}/${name}`, { params })) - ); - - const timeMap = {}; - responses.forEach((res, i) => { - const sensorName = sensors[i]; - res.data.forEach(d => { - if (!timeMap[d.time]) timeMap[d.time] = { time: d.time }; - timeMap[d.time][sensorName] = d[dataKey]; + const names = sensors.join(','); + const res = await axios.get(`https://sensors-api.dns.t0.vc/history/${measurement}/${names}`, { params }); + + const formattedData = res.data.map(d => { + const newObj = { time: d.time }; + sensors.forEach(sensor => { + newObj[sensor] = d[`${sensor}_${dataKey}`]; }); + return newObj; }); - - const merged = Object.values(timeMap).sort((a, b) => a.time.localeCompare(b.time)); - setData(merged); + + setData(formattedData); setLoading(false); } catch (error) { console.log(error); diff --git a/main.py b/main.py index 0db7680..602be59 100644 --- a/main.py +++ b/main.py @@ -445,7 +445,8 @@ async def history(request): authed = api_key == settings.SENSORS_API_KEY measurement = request.match_info.get('measurement') - name = request.match_info.get('name') + name_param = request.match_info.get('name') + names = name_param.split(',') share_start = request.rel_url.query.get('shareStart', '') share_end = request.rel_url.query.get('shareEnd', '') @@ -458,8 +459,9 @@ async def history(request): if not authed and measurement in ['owntracks', 'sleep']: return web.json_response([]) - if name not in [x.name for x in sensors.sensors]: - raise + for name in names: + if name not in [x.name for x in sensors.sensors]: + raise end_unix = request.rel_url.query.get('end', None) if end_unix: @@ -496,13 +498,6 @@ async def history(request): if window not in ['1m', '3m', '10m', '30m', '1h', '2h', '1d', '7d', '30d']: raise - if name == 'Water': - scale = 10 - elif name == 'Gas': - scale = 0.001055*1000 - else: - scale = 1 - start = int(start.timestamp()) end = int(end.timestamp()) @@ -512,47 +507,69 @@ async def history(request): if end >= int(share_end): end = int(share_end) + time_map = {} - if measurement == 'temperature': - client = sensors_client - q = 'select mean("temperature_C") as temperature_C, mean("humidity") as humidity from temperature where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) - elif measurement == 'ertscm': - client = sensors_client - q = 'select derivative(max("consumption_data"))*{} as delta, max("consumption_data")*{} as max from ertscm where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(previous)'.format(scale, scale, name, start, end, window) - elif measurement == 'thermostat': - client = sensors_client - q = 'select first("spacetemp") as spacetemp, first("heattemp") as heattemp, mode("state") as state from thermostat where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(previous)'.format(name, start, end, window) - elif measurement == 'dust': - client = sensors_client - q = 'select max("avg_p10") as max_p10, max("avg_p25") as max_p25 from dust where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) - elif measurement == 'air': - client = sensors_client - q = 'select max("pm10") as max_p10, max("pm25") as max_p25, max("co2") as max_co2, max("voc_idx") as max_voc from air where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) - elif measurement == 'soil': - client = sensors_client - q = 'select mean("soil") as soil, mean("moisture") as moisture from soil where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) - elif measurement == 'lux': - client = sensors_client - q = 'select mean("lux") as lux from air where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) - elif measurement == 'hpa': - client = sensors_client - q = 'select mean("hpa") as hpa from air where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) - elif measurement == 'sleep': - client = sensors_client - q = 'select max("max_mag") as max_mag from sleep where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) - elif measurement == 'solar': - client = solar_client - q = 'select max("actual_total") as actual_total, last("lifetime_energy")-first("lifetime_energy") as lifetime_energy from ecu where time >= {}s and time < {}s group by time({}) fill(linear)'.format(start, end, window) - elif measurement == 'owntracks': - client = sensors_client - q = 'select first("lat") as lat, first("lon") as lon from owntracks where "acc" < 100 and "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(previous)'.format(name, start, end, window) - else: - raise + for name in names: + if name == 'Water': + scale = 10 + elif name == 'Gas': + scale = 0.001055*1000 + else: + scale = 1 - q += ' tz(\'America/Edmonton\')' + if measurement == 'temperature': + client = sensors_client + q = 'select mean("temperature_C") as temperature_C, mean("humidity") as humidity from temperature where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) + elif measurement == 'ertscm': + client = sensors_client + q = 'select derivative(max("consumption_data"))*{} as delta, max("consumption_data")*{} as max from ertscm where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(previous)'.format(scale, scale, name, start, end, window) + elif measurement == 'thermostat': + client = sensors_client + q = 'select first("spacetemp") as spacetemp, first("heattemp") as heattemp, mode("state") as state from thermostat where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(previous)'.format(name, start, end, window) + elif measurement == 'dust': + client = sensors_client + q = 'select max("avg_p10") as max_p10, max("avg_p25") as max_p25 from dust where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) + elif measurement == 'air': + client = sensors_client + q = 'select max("pm10") as max_p10, max("pm25") as max_p25, max("co2") as max_co2, max("voc_idx") as max_voc from air where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) + elif measurement == 'soil': + client = sensors_client + q = 'select mean("soil") as soil, mean("moisture") as moisture from soil where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) + elif measurement == 'lux': + client = sensors_client + q = 'select mean("lux") as lux from air where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) + elif measurement == 'hpa': + client = sensors_client + q = 'select mean("hpa") as hpa from air where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) + elif measurement == 'sleep': + client = sensors_client + q = 'select max("max_mag") as max_mag from sleep where "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(linear)'.format(name, start, end, window) + elif measurement == 'solar': + client = solar_client + q = 'select max("actual_total") as actual_total, last("lifetime_energy")-first("lifetime_energy") as lifetime_energy from ecu where time >= {}s and time < {}s group by time({}) fill(linear)'.format(start, end, window) + elif measurement == 'owntracks': + client = sensors_client + q = 'select first("lat") as lat, first("lon") as lon from owntracks where "acc" < 100 and "name" = \'{}\' and time >= {}s and time < {}s group by time({}) fill(previous)'.format(name, start, end, window) + else: + raise - result = list(client.query(q).get_points()) + q += ' tz(\'America/Edmonton\')' + points = list(client.query(q).get_points()) + + for p in points: + t = p['time'] + if t not in time_map: + time_map[t] = {'time': t} + + if len(names) > 1: + for k, v in p.items(): + if k != 'time': + time_map[t][f"{name}_{k}"] = v + else: + time_map[t].update(p) + + result = sorted(time_map.values(), key=lambda x: x['time']) return web.json_response(result)