Thingsboard экспортирует все данные телеметрии за определенное временное окно - PullRequest
1 голос
/ 24 октября 2019

Я хочу экспортировать телеметрию как необработанные данные для устройства. Так как я должен указать limit в API телеметрии , я разбиваю запросы на страницы. В противном случае система иногда зависала. Так как значения возвращаются начиная с самых последних, я сужаю конец запрошенного периода дальше. Эта процедура работает только в том случае, если, например, в телеметрии нет старых ключей. Когда появляются старые ключи (например, если я не определяю параметр keys), моя логика потерпит неудачу.

Существует ли более простой способ получения данных телеметрии через API (без экспорта в csv) определенного интервала времени?

#!/usr/bin/env python

import datetime
import requests

TB_USERNAME = "<user>"
TB_PASSWORD = "***"
THINGSBOARD_URL = "<url>"
TB_API_AUTH_LOGIN = THINGSBOARD_URL + '/api/auth/login'
TB_API_TELEMETRY_CONTROLLER_getTimeseries = THINGSBOARD_URL + '/api/plugins/telemetry/%(entityType)s/%(deviceId)s/values/timeseries'
TB_API_DC_getDeviceCredentialsByDeviceId = THINGSBOARD_URL + '/api/device/%(deviceId)s/credentials'
TB_API_DEVICE_CONTROLLER_getDeviceById = THINGSBOARD_URL + '/api/device/%(deviceId)s'

DEVICES = ("<uid>", )

def datetime_from_millis(millis, epoch=datetime.datetime(1970, 1, 1)):
    """Return UTC time that corresponds to milliseconds since Epoch."""
    return epoch + datetime.timedelta(milliseconds=millis)

def timestamp_millis(utc_time, epoch=datetime.datetime(1970, 1, 1)):
    """Return milliseconds since Epoch as integer."""
    td = utc_time - epoch
    return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) // 10**3

# retrieve Bearer token
auth_token = requests.post(TB_API_AUTH_LOGIN,
                           json={"username": TB_USERNAME,
                                 "password": TB_PASSWORD},
                           verify=False).json()

f = open("thingsboard.csv", "w")
f.write("device;date;attr;value\n")

START_TS = datetime.datetime(2019,10,10)
END_TS = datetime.datetime(2019,10,17)

for deviceId in DEVICES:
    print("Query device %s" % deviceId)
    jwt_header = {"X-Authorization": "Bearer %s" % auth_token["token"]}
    api_response_device = requests.get(TB_API_DEVICE_CONTROLLER_getDeviceById % {"deviceId": deviceId},
                                         headers=jwt_header,
                                         verify=False).json()
    device_name = api_response_device["name"]
    print("Found %s" % device_name)

    ts_end = END_TS
    while START_TS < ts_end:
        print("%s from %s to %s" % (device_name, START_TS, ts_end))
        api_response_ts = requests.get(TB_API_TELEMETRY_CONTROLLER_getTimeseries % {"entityType": "DEVICE",
                                                                                     "deviceId": deviceId},
                                          headers=jwt_header,
                                          params={#"keys": "***",
                                                  "limit": 2000,
                                                  #"agg": "NONE",
                                                  "startTs": str(timestamp_millis(START_TS)),
                                                  "endTs": str(timestamp_millis(ts_end))},
                                          verify=False).json()
        ts_end = START_TS
        finished = True
        for telemetry_attr, attr_ts in api_response_ts.items():
            for data in attr_ts:
                # ugly but works for now, round float strings to .2
                val = data["value"]
                if "." in val:
                    try:
                        val = "%.2f" % float(val)
                    except:
                        pass
                f.write("%s;%s;%s;%s\n" % (device_name, datetime_from_millis(data["ts"]).strftime("%Y-%m-%d %H:%M:%S"), telemetry_attr, val))
            # substract a fraction of a second in order to have no overlapping entries
            ts_end_value = datetime_from_millis(data["ts"] - 1)

            # search the maximum minima of all keys and start with this next round
            if ts_end < ts_end_value:
                ts_end = ts_end_value

f.close()

Так что мой принцип запросов разбит на страницы в зависимости от значений телеметрии и статического предела.

DEVICE from 2019-10-10 00:00:00 to 2019-10-17 00:00:00
DEVICE from 2019-10-10 00:00:00 to 2019-10-15 14:28:24.497000
DEVICE from 2019-10-10 00:00:00 to 2019-10-14 05:04:25.393000
DEVICE from 2019-10-10 00:00:00 to 2019-10-12 19:32:26.380000
DEVICE from 2019-10-10 00:00:00 to 2019-10-11 10:09:27.350000
DEVICE from 2019-10-10 00:00:00 to 2019-10-10 00:41:28.331000
DEVICE from 2019-10-10 00:00:00 to 2019-10-10 00:00:28.419000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...