Nasıl yapılır · Geliştiriciler için
Telemetry API
Geçmiş veri deposundaki veri noktası değerlerini HTTP üzerinden tek bir SQL SELECT ile sorgulayın ve sonucu JSON satırları olarak okuyun.
Bu kılavuzu tamamladığınızda betiğiniz, bir cihazın saklanan veri noktası değerleri üzerinde SQL sorgusu çalıştırır. Sonuçta her satır ayrı bir JSON nesnesi olarak gelir.
Başlamadan önce
Şunlar gereklidir:
- Merkez sunucudan alınmış bir erişim anahtarı. Nasıl alınacağı REST API sayfasında anlatılır.
- Merkez sunucunun adresi, örneğin
http://localhost:8080. - Telemetri verisini ClickHouse'ta saklayan bir merkez sunucu. Ürünle gelen Docker kurulumu bu veritabanını kullanır (yapılandırmanın
[Database]bölümündeTelemetryDB = "clickhouse").
İstek
POST /api/Telemetry/execute?maxRows=10000
Authorization: Bearer <token>
Content-Type: application/json
{ "query": "SELECT ..." }| Bölüm | Anlamı |
|---|---|
query | ClickHouse SQL söz dizimiyle yazılmış tek bir ifade. |
maxRows | Döndürülecek en çok satır sayısı. 1 ile 50.000 arasında olabilir, varsayılan değer 10.000'dir. Sorgudaki LIMIT bu değeri aşarsa bu değere indirilir. LIMIT içermeyen sorgulara otomatik olarak eklenir. |
Yanıtın içerik türü application/x-ndjson olur: her sonuç satırı ayrı bir satırda, tek bir JSON nesnesi olarak gelir. Sorgu bir FORMAT ifadesiyle bitmiyorsa sonuna otomatik olarak FORMAT JSONEachRow eklenir.
Saklanan değerler tablosu
Proxus'un sakladığı her değer, DeviceRawData tablosunda bir satırdır:
| Sütun | Tür | Anlamı |
|---|---|---|
Time | DateTime64(3) | Değerin okunduğu an. UTC olarak, milisaniye hassasiyetinde tutulur. |
DeviceId | UInt32 | Cihazın ID'si. REST API'deki Oid değeriyle aynıdır. |
DeviceName | String | Okuma anında cihazın taşıdığı ad. |
Key | String | Veri noktasının adı. |
DataType | Enum8 | Bool, Short, UShort, Int, UInt, Float, Long, ULong, Double, String, Byte, DateTime. |
Unit | String | Veri noktasının birimi. Birim tanımlı değilse boştur. |
NumericValue | Float64 | Sayısal ve Boolean veri noktalarının değeri. |
StringValue | String | Metin türündeki veri noktalarının değeri. |
Satırlar cihaz, ad, veri noktası ve zaman sırasıyla dizilir. Bu yüzden en hızlı sorgular, DeviceId veya DeviceName, Key ve bir zaman aralığıyla süzülen sorgulardır.
Adım 1: Bir sorgu çalıştırın
TOKEN=$(curl -s -X POST http://localhost:8080/api/Authentication/Authenticate \
-H "Content-Type: application/json" -d '{"userName":"Admin","password":""}')
curl -s -X POST "http://localhost:8080/api/Telemetry/execute?maxRows=100" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d "{\"query\": \"SELECT DeviceName, Key, round(avg(NumericValue), 2) AS avg_value, count() AS samples FROM DeviceRawData WHERE Time >= now() - INTERVAL 1 HOUR AND DeviceName = 'LYS_PACKER_04' GROUP BY DeviceName, Key ORDER BY Key\"}"Yanıt şöyle görünür:
{"DeviceName":"LYS_PACKER_04","Key":"BatchCount","avg_value":1522.98,"samples":"2262"}
{"DeviceName":"LYS_PACKER_04","Key":"MotorCurrent","avg_value":28.91,"samples":"2262"}
{"DeviceName":"LYS_PACKER_04","Key":"Speed","avg_value":81.68,"samples":"2262"}
{"DeviceName":"LYS_PACKER_04","Key":"Temperature","avg_value":24.64,"samples":"2262"}
{"DeviceName":"LYS_PACKER_04","Key":"Vibration","avg_value":1.85,"samples":"2262"}Adım 2: Koddan kullanın
import json
import requests
HUB = "http://localhost:8080"
token = requests.post(
f"{HUB}/api/Authentication/Authenticate",
json={"userName": "Admin", "password": ""},
timeout=30,
).text.strip()
sql = """
SELECT Key, round(avg(NumericValue), 2) AS avg_value, max(NumericValue) AS max_value
FROM DeviceRawData
WHERE DeviceName = 'LYS_PACKER_04'
AND Time >= now() - INTERVAL 1 HOUR
GROUP BY Key
ORDER BY Key
"""
response = requests.post(
f"{HUB}/api/Telemetry/execute",
params={"maxRows": 1000},
json={"query": sql},
headers={"Authorization": f"Bearer {token}"},
timeout=60,
)
response.raise_for_status()
for line in response.text.splitlines():
row = json.loads(line)
print(row["Key"], row["avg_value"], row["max_value"]) using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
var hub = new HttpClient { BaseAddress = new Uri("http://localhost:8080/") };
var login = await hub.PostAsJsonAsync("api/Authentication/Authenticate",
new { userName = "Admin", password = "" });
login.EnsureSuccessStatusCode();
hub.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", await login.Content.ReadAsStringAsync());
// Bir cihazın her veri noktasının son değeri
var query = new {
query = """
SELECT Key, argMax(NumericValue, Time) AS last_value, max(Time) AS last_time
FROM DeviceRawData
WHERE DeviceName = 'LYS_PACKER_04' AND Time >= now() - INTERVAL 1 HOUR
GROUP BY Key ORDER BY Key
"""
};
var response = await hub.PostAsJsonAsync("api/Telemetry/execute?maxRows=100", query);
response.EnsureSuccessStatusCode();
foreach (var line in (await response.Content.ReadAsStringAsync()).Split('\n', StringSplitOptions.RemoveEmptyEntries)) {
using var row = JsonDocument.Parse(line);
Console.WriteLine($"{row.RootElement.GetProperty("Key")} = {row.RootElement.GetProperty("last_value")}");
} Uzun bir zaman aralığını okuyun
Tek bir çağrı en çok 50.000 satır döndürür. Daha fazla veri okumak için sonucu zamana göre sayfalara bölün. Sonucu Time ve DeviceId ile sıralayın, son satırı not edin ve sonraki sorguyu o satırın ardından başlatın.
SELECT Time, DeviceId, Key, NumericValue
FROM DeviceRawData
WHERE DeviceName = 'LYS_PACKER_04'
AND Time >= toDateTime64('2026-10-01 00:00:00', 3)
AND Time < toDateTime64('2026-10-02 00:00:00', 3)
AND (Time > toDateTime64('2026-10-01 06:12:40.250', 3)
OR (Time = toDateTime64('2026-10-01 06:12:40.250', 3) AND DeviceId > 69))
ORDER BY Time ASC, DeviceId ASC
LIMIT 50000Bir sayfa, istenenden az satır döndürdüğünde okuma tamamlanmıştır.
Reddedilen sorgular
Sorgu, veritabanına gönderilmeden önce denetlenir. Aşağıdaki yanıtlar 400 durum koduyla döner:
| Mesaj | Nedeni |
|---|---|
Query cannot be empty | İstek gövdesinde query alanı yok. |
Invalid query: Only SELECT/CTE (WITH), comments, or 'SET TIMEZONE' are allowed at the beginning. | İfade izin verilmeyen bir komutla başlıyor, örneğin SHOW veya DESCRIBE. |
Invalid query: Multiple statements are not allowed. | Sorguda ; ile ayrılmış birden çok ifade var. |
Invalid query: After CTEs, only a SELECT statement is allowed. | WITH bloğundan sonra SELECT dışında bir ifade geliyor. |
Invalid query: Security violation: The SQL keyword 'SYSTEM' is not permitted. | Sorgu, veriyi veya sunucuyu değiştiren bir sözcük içeriyor: UPDATE, DELETE, INSERT, MERGE, UPSERT, DROP, CREATE, ALTER, TRUNCATE, RENAME, ATTACH, DETACH, OPTIMIZE, SYSTEM, KILL, GRANT, REVOKE, COPY, CALL, EXEC, EXECUTE. Denetim tablo ve sütun adlarını da kapsar, bu yüzden system.tables de reddedilir. Tırnak içindeki sözcükler denetlenmez. |
Diğer yanıtlar:
| Durum | Anlamı |
|---|---|
401 | Erişim anahtarı gönderilmemiş ya da süresi dolmuş. |
403 | Kullanıcının yönetici rolü yok. |
Veritabanının döndürdüğü durum kodu ve Query failed: ... | Veritabanı sorguyu reddetti, örneğin bir sütun veya tablo adı yanlış yazılmış. Metin, veritabanının kendi hata mesajıdır. |
500 ve ClickHouse connection failed: ... | Merkez sunucu telemetri veritabanına ulaşamıyor. Çözüm için Veri sorunlarını giderme sayfasına bakın. |
Sonraki adımlar
- MQTT ve UNS konuları: değerleri sorgulamak yerine canlı olarak alın.
- Geçmiş veri aktarımı: aynı tabloya eski değerleri ekleyin.
- Raporlar: aynı veriden hazırlanmış hazır raporları kullanın.
Bu sayfa işinize yaradı mı?
Proxus'u değerlendiriyor musunuz? 30 dakikalık teknik görüşmede kendi makinelerinizle görün.