{ "version": 1, // version of the protocol, major number only "msg_type": "telemetry", // telemetry only for now // optional, defaults to "descriptive" // // for strict mode, no `metadata` in fields is allowed // all fields must be well defined in separate documentation (e.g. JSON schema) // // for descriptive mode, everything should self contained (like unit, sample interval, etc.) "mode": "descriptive", "dev_id": "2B1oj2S5k7kS8mL_QaCs", // NanoID, unique for each device "dev_type": "device_type_name", // "dev_type field supports: // string: designated by a unique string // {"type_id": "2B1oj2S5k7kS8mL_QaCs"} // NanoID, unique for each device type // {"type_name": "device_type_name"} // unique string, same as the string above "timestamp": 1715145600, // UNIX timestamp in seconds // timestamp fields supports: // number: UNIX timestamp in seconds (default) // {"unix_ns": 1715145600000000000} // {"unix_us": 1715145600000000} // {"unix_ms": 1715145600000} // {"unix_s": 1715145600} // same as the number above // {"iso8601": "2025-01-01T00:00:00Z"} "fields": [ // note the name of the field must be unique in the array // discrete fields { // `id` MUST be unique in the `fields` array // should be ASCII string, no whitespace, no special characters, only underscore is allowed "id": "field_1", "value": "field_value", // string, number, boolean or enum value // field specific metadata "metadata": { // required // primitive types are // // type Primitive = number | string | boolean | enum // where `enum` is new type alias of number with well defined values // type DataType = Primitive | // [Primitive] | // array // {v: [Primitive], t: [Timestamp]} // irregular // // - `null` is not allowed // - nesting (array of array or irregular of array) is not allowed "data_type": "string", // optional // timestamp of the time of sampling // which might differ from the timestamp of uplink message // if not provided, the timestamp of uplink message is used "timestamp": 1715145600, // optional // recommended to use UCUM (unified code for units of measure) // but arbitrary string is supported "unit": "unit_name", // optional // confidence of sampling, 0-1, 1 means 100% confidence "confidence": 0.95, // optional // user defined fields (arbitrary key-value pairs) "user": { "user_defined_field_1": "user_defined_value_1", "user_defined_field_2": "user_defined_value_2" } } }, // batch fields, for continuous data { "id": "field_2", // unique string "value": [ 1, 2, 3 ], // array of numbers, strings, booleans or enum values "metadata": { // required // "array", "array", "array", or "array" // no nesting is allowed "data_type": "array", "timestamp": 1715145600, // timestamp of the time of sampling "sample_interval": 0.5, // sample interval in seconds, 0.5 means 2 samples per second // sample_interval fields also supports: // {"ms": 0, "s": 0, "m": 0, "h": 0, "d": 0, "w": 0} // the total sample interval is the sum of each field's sample interval in each unit // optional // recommended to use UCUM (unified code for units of measure) // but arbitrary string is supported "unit": "unit_name", // optional // array of confidence, or single scalar confidence // confidence of each sample, 0-1, 1 means 100% confidence // if it's array, its length must be same as the length of the value array "confidence": [ 0.95, 0.95, 0.95 ] } }, // batch fields, with enum { "id": "air_quality", // interpreted as: // good, good, moderate, good, unhealthy, very_unhealthy, hazardous // for each hour past from `timestamp`, the value is sampled "value": [ 1, 1, 2, 1, 3, 4, 5 ], "metadata": { // refer to global enum definitions in `root.metadata.enums` "data_type": "array", "timestamp": 1715145600, // indicate sample interval in 1 hour "sample_interval": { "h": 1 } } }, // irregular batch fields, with inline enum { "id": "water_quality", // the length of v and t must be the same "value": { "v": [ 1, 2, 2, 1, 1, 3 ], // any legal timestamp format is supported "t": [ 1715145600, 1715145602, 1715145604, 1715145606, 1715145608, 1715145610 ] }, "metadata": { // refer to local enum definitions in current `metadata.enum` "data_type": "irregular", "enum": { "good": 1, "moderate": 2, "bad": 3 }, "timestamp": 1715145600 // `sample_interval` would be ignored for irregular field } }, // an example of sensor with invalid reading { "id": "temperature", "value": 0, "metadata": { // optional // any UTF-8 string is allowed // data consumer would decide whether or how to display this label "label": "温度", "data_type": "number", // required when error occurs, SHOULD NOT appear in non-error cases // defaults to 0 for non-error cases // // well-defined error codes are in separate documentation "error_code": 64, // optional // a custom error message "error_msg": "sensor disconnected", "confidence": 0, "unit": "Cel" } } ], // message level metadata "metadata": { // optional // global enum definitions "enums": [ { // unique string in enums array "id": "air_quality", "value": { "good": 1, "moderate": 2, "unhealthy": 3, "very_unhealthy": 4, "hazardous": 5 } } ], // optional "location": { "coordinates": [ 120.123456, 24.123456 ], // longitude and latitude in degrees // optional, defaults to "gcj02" "coordinate_system": "wgs84", // "wgs84", "gcj02", "bd09" // optional "accuracy": 10, // accuracy in meters // optional "altitude": 100 // altitude in meters }, // optional // battery in percentage, 0-100 "battery": 99, // optional, // for each sample, increase by 1 // defaults to uint32 cyclic counter "seq": 12345, "user": { "user_defined_global_field_1": "user_defined_global_value_1", "user_defined_global_field_2": "user_defined_global_value_2" } } }