Turns SenML (JSON or CBOR) and LwM2M TLV into one record shape
Turns SenML (JSON or CBOR) and LwM2M TLV into one record shape: resolved name, unit, absolute timestamp, typed value. Optionally puts every series on a shared time axis with a chosen interval and fill rule (last value, bucket mean, linear). Works only on the payload you pass: no device is contacted, nothing is stored, the same request returns the same bytes. TLV carries no type on the wire; unmapped resource ids come back as opaque base64 with a warning instead of a guess.
Paid test badge: not yet. The checks above are free: we call the tool without paying and read the payment request it sends back. The Verified badge needs paid calls whose answers match the promised output, and nobody can buy a badge.
Endpoint
POST https://tools.halowerk.com/v1/telemetry/normalize
| Category | Everything else |
|---|---|
| Provider host | tools.halowerk.com |
| Networks | eip155:8453 |
| Payment schemes | exact |
| Self-reported calls, 30 days | 3 from 3 payers (the provider's figure, not ours) |
Our checks, last 30 days
| Day | Result | HTTP | Asked | Time |
|---|---|---|---|---|
| 2026-10-10 | valid payment request | 402 | $0.002 | 1187 ms |
Example input (from the provider)
{
"body": {
"align": true,
"align_method": "last",
"format": "senml_json",
"interval_s": 60,
"payload": [
{
"bn": "urn:dev:ow:10e2073a:",
"bt": 1786000000,
"bu": "Cel",
"n": "temp",
"v": 21.3
},
{
"n": "temp",
"t": 60,
"v": 21.9
},
{
"n": "hum",
"t": 60,
"u": "%RH",
"v": 48
}
]
},
"bodyType": "json",
"method": "POST",
"type": "http"
}
Promised output schema (from the provider)
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"input": {
"additionalProperties": false,
"properties": {
"body": {
"properties": {
"align": {
"default": false,
"description": "Also return every numeric series on one shared time grid.",
"type": "boolean"
},
"align_method": {
"default": "last",
"description": "How a grid point is filled: last value at or before the point, mean over the bucket, or linear interpolation between neighbours.",
"enum": [
"last",
"mean",
"linear"
],
"type": "string"
},
"base_name": {
"description": "Prefix put in front of every resolved record name. For lwm2m_tlv this is where the device identity goes.",
"maxLength": 200,
"type": "string"
},
"base_time_unix_s": {
"description": "Anchor in seconds since 1970 for records that carry no absolute time. SenML calls times below 2^28 relative to now; this endpoint is stateless and will not invent a now.",
"type": "number"
},
"format": {
"description": "Wire format of payload. senml_cbor and lwm2m_tlv expect base64.",
"enum": [
"senml_json",
"senml_cbor",
"lwm2m_tlv"
],
"type": "string"
},
"interval_s": {
"default": 60,
"description": "Grid spacing in seconds. The grid may not exceed 10000 points.",
"maximum": 86400,
"minimum": 0.001,
"type": "number"
},
"max_records": {
"default": 5000,
"description": "Upper bound on records taken from the payload.",
"maximum": 20000,
"minimum": 1,
"type": "integer"
},
"payload": {
"description": "SenML records as a JSON array (or a JSON string holding one), or base64 for senml_cbor and lwm2m_tlv. At most 1000000 bytes after decoding; the service caps the whole request body at 256 KB."
},
"tolerance_s": {
"default": 0,
"description": "align_method=last only: how stale the carried value may be before the grid point is left empty. 0 means no limit.",
"maximum": 86400,
"minimum": 0,
"type": "number"
},
"value_types": {
"description": "lwm2m_tlv only: resource id as key, one of integer, float, boolean, string, time, opaque as value. Ids left out come back as opaque base64 with a warning instead of a guessed type.",
"type": "object"
}
},
"required": [
"format",
"payload"
],
"type": "object"
},
"bodyType": {
"enum": [
"json",
"form-data",
"text"
],
"type": "string"
},
"method": {
"enum": [
"POST"
],
"type": "string"
},
"type": {
"const": "http",
"type": "string"
}
},
"required": [
"type",
"method",
"bodyType",
"body"
],
"type": "object"
},
"output": {
"properties": {
"example": {
"type": "object"
},
"type": {
"type": "string"
}
},
"required": [
"type"
],
"type": "object"
}
},
"required": [
"input"
],
"type": "object"
}