11#if DETWS_ENABLE_MTCONNECT
17void put(DetwsMtcStreams *s,
const char *text)
21 size_t tl = strnlen(text, s->cap + 1);
22 if (s->len + tl >= s->cap)
27 memcpy(s->buf + s->len, text, tl);
31void put_escaped(DetwsMtcStreams *s,
const char *text)
35 for (
const char *p = text; *p; p++)
37 const char *rep =
nullptr;
59 if (s->len + 1 >= s->cap)
64 s->buf[s->len++] = *p;
70void put_u64(DetwsMtcStreams *s, uint64_t v)
76 tmp[n++] = (char)(
'0' + (
int)(v % 10));
80 for (
int i = 0; i < n; i++)
81 out[i] = tmp[n - 1 - i];
86const char *mtc_cat_str(DetwsMtcCategory cat)
88 if (cat == DetwsMtcCategory::DETWS_MTC_SAMPLE)
90 if (cat == DetwsMtcCategory::DETWS_MTC_EVENT)
96void detws_mtc_streams_begin(DetwsMtcStreams *s,
char *buf,
size_t cap, uint64_t instance_id, uint64_t next_seq,
97 const char *device_name)
102 s->ok = (buf !=
nullptr && cap > 0);
104 put(s,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
105 put(s,
"<MTConnectStreams xmlns=\"urn:mtconnect.org:MTConnectStreams:1.4\">");
106 put(s,
"<Header instanceId=\"");
107 put_u64(s, instance_id);
108 put(s,
"\" version=\"1.4\" nextSequence=\"");
109 put_u64(s, next_seq);
111 put(s,
"<Streams><DeviceStream name=\"");
112 put_escaped(s, device_name ? device_name :
"");
116void detws_mtc_streams_add(DetwsMtcStreams *s, DetwsMtcCategory cat,
const char *type,
const char *data_id,
117 uint64_t seq,
const char *timestamp,
const char *value)
123 put(s,
"<ComponentStream component=\"Device\">");
126 const char *wrap =
"Condition";
127 if (cat == DetwsMtcCategory::DETWS_MTC_SAMPLE)
129 else if (cat == DetwsMtcCategory::DETWS_MTC_EVENT)
134 if (cat == DetwsMtcCategory::DETWS_MTC_CONDITION)
137 const char *sub = value ? value :
"Normal";
141 put_escaped(s, type ? type :
"");
142 put(s,
"\" dataItemId=\"");
143 put_escaped(s, data_id ? data_id :
"");
144 put(s,
"\" sequence=\"");
146 put(s,
"\" timestamp=\"");
147 put_escaped(s, timestamp ? timestamp :
"");
154 put(s, type ? type :
"");
155 put(s,
" dataItemId=\"");
156 put_escaped(s, data_id ? data_id :
"");
157 put(s,
"\" sequence=\"");
159 put(s,
"\" timestamp=\"");
160 put_escaped(s, timestamp ? timestamp :
"");
162 put_escaped(s, value ? value :
"");
164 put(s, type ? type :
"");
172size_t detws_mtc_streams_end(DetwsMtcStreams *s)
175 put(s,
"</ComponentStream>");
176 put(s,
"</DeviceStream></Streams></MTConnectStreams>");
179 s->buf[s->len] =
'\0';
183size_t detws_mtc_error(uint64_t instance_id,
const char *error_code,
const char *message,
char *out,
size_t cap)
189 s.ok = (out !=
nullptr && cap > 0);
191 put(&s,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
192 put(&s,
"<MTConnectError xmlns=\"urn:mtconnect.org:MTConnectError:1.4\">");
193 put(&s,
"<Header instanceId=\"");
194 put_u64(&s, instance_id);
195 put(&s,
"\" version=\"1.4\"/>");
196 put(&s,
"<Errors><Error errorCode=\"");
197 put_escaped(&s, error_code ? error_code :
"");
199 put_escaped(&s, message ? message :
"");
200 put(&s,
"</Error></Errors></MTConnectError>");
203 if (!s.ok || out ==
nullptr)
211void detws_mtc_devices_begin(DetwsMtcStreams *s,
char *buf,
size_t cap, uint64_t instance_id,
const char *device_id,
212 const char *device_name,
const char *uuid)
217 s->ok = (buf !=
nullptr && cap > 0);
219 put(s,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
220 put(s,
"<MTConnectDevices xmlns=\"urn:mtconnect.org:MTConnectDevices:1.4\">");
221 put(s,
"<Header instanceId=\"");
222 put_u64(s, instance_id);
223 put(s,
"\" version=\"1.4\"/>");
224 put(s,
"<Devices><Device id=\"");
225 put_escaped(s, device_id ? device_id :
"");
226 put(s,
"\" name=\"");
227 put_escaped(s, device_name ? device_name :
"");
228 put(s,
"\" uuid=\"");
229 put_escaped(s, uuid ? uuid :
"");
230 put(s,
"\"><DataItems>");
233void detws_mtc_devices_add_item(DetwsMtcStreams *s, DetwsMtcCategory cat,
const char *
id,
const char *type,
234 const char *name,
const char *units)
238 put(s,
"<DataItem category=\"");
239 put(s, mtc_cat_str(cat));
241 put_escaped(s,
id ?
id :
"");
242 put(s,
"\" type=\"");
243 put_escaped(s, type ? type :
"");
248 put_escaped(s, name);
251 if (units && units[0])
254 put_escaped(s, units);
260size_t detws_mtc_devices_end(DetwsMtcStreams *s)
262 put(s,
"</DataItems></Device></Devices></MTConnectDevices>");
265 s->buf[s->len] =
'\0';
271void detws_mtc_assets_begin(DetwsMtcStreams *s,
char *buf,
size_t cap, uint64_t instance_id, uint32_t asset_count,
272 uint32_t asset_buffer_size)
277 s->ok = (buf !=
nullptr && cap > 0);
279 put(s,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
280 put(s,
"<MTConnectAssets xmlns=\"urn:mtconnect.org:MTConnectAssets:1.4\">");
281 put(s,
"<Header instanceId=\"");
282 put_u64(s, instance_id);
283 put(s,
"\" version=\"1.4\" assetBufferSize=\"");
284 put_u64(s, asset_buffer_size);
285 put(s,
"\" assetCount=\"");
286 put_u64(s, asset_count);
291void detws_mtc_assets_cutting_tool_begin(DetwsMtcStreams *s,
const char *asset_id,
const char *serial_number,
292 const char *tool_id,
const char *device_uuid,
const char *timestamp)
294 put(s,
"<CuttingTool assetId=\"");
295 put_escaped(s, asset_id ? asset_id :
"");
297 if (serial_number && serial_number[0])
299 put(s,
" serialNumber=\"");
300 put_escaped(s, serial_number);
303 if (tool_id && tool_id[0])
305 put(s,
" toolId=\"");
306 put_escaped(s, tool_id);
309 if (device_uuid && device_uuid[0])
311 put(s,
" deviceUuid=\"");
312 put_escaped(s, device_uuid);
315 if (timestamp && timestamp[0])
317 put(s,
" timestamp=\"");
318 put_escaped(s, timestamp);
321 put(s,
"><CuttingToolLifeCycle>");
324void detws_mtc_assets_tool_life(DetwsMtcStreams *s,
const char *type,
const char *count_direction,
const char *limit,
328 put(s,
"<ToolLife type=\"");
329 put_escaped(s, type ? type :
"");
330 put(s,
"\" countDirection=\"");
331 put_escaped(s, count_direction ? count_direction :
"");
333 if (limit && limit[0])
336 put_escaped(s, limit);
340 put_escaped(s, value ? value :
"");
341 put(s,
"</ToolLife>");
344void detws_mtc_assets_cutting_tool_end(DetwsMtcStreams *s)
346 put(s,
"</CuttingToolLifeCycle></CuttingTool>");
349size_t detws_mtc_assets_end(DetwsMtcStreams *s)
351 put(s,
"</Assets></MTConnectAssets>");
354 s->buf[s->len] =
'\0';
363void mtc_copy_str(
char *dst,
size_t cap,
const char *src)
369 for (; i < cap - 1 && src[i] !=
'\0'; i++)
375void mtc_streams_begin_windowed(DetwsMtcStreams *s,
char *buf,
size_t cap, uint64_t instance_id, uint64_t first_seq,
376 uint64_t last_seq, uint64_t next_seq, uint32_t buffer_size,
const char *device_name)
381 s->ok = (buf !=
nullptr && cap > 0);
383 put(s,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
384 put(s,
"<MTConnectStreams xmlns=\"urn:mtconnect.org:MTConnectStreams:1.4\">");
385 put(s,
"<Header instanceId=\"");
386 put_u64(s, instance_id);
387 put(s,
"\" version=\"1.4\" bufferSize=\"");
388 put_u64(s, buffer_size);
389 put(s,
"\" firstSequence=\"");
390 put_u64(s, first_seq);
391 put(s,
"\" lastSequence=\"");
392 put_u64(s, last_seq);
393 put(s,
"\" nextSequence=\"");
394 put_u64(s, next_seq);
396 put(s,
"<Streams><DeviceStream name=\"");
397 put_escaped(s, device_name ? device_name :
"");
402void detws_mtc_sample_buffer_init(DetwsMtcSampleBuffer *b, uint64_t start_seq)
406 b->next_seq = start_seq ? start_seq : 1;
407 b->first_seq = b->next_seq;
410uint64_t detws_mtc_sample_buffer_add(DetwsMtcSampleBuffer *b, DetwsMtcCategory cat,
const char *type,
411 const char *data_id,
const char *timestamp,
const char *value)
413 DetwsMtcObservation *o = &b->obs[b->head];
415 o->seq = b->next_seq;
416 mtc_copy_str(o->type,
sizeof(o->type), type);
417 mtc_copy_str(o->data_id,
sizeof(o->data_id), data_id);
418 mtc_copy_str(o->timestamp,
sizeof(o->timestamp), timestamp);
419 mtc_copy_str(o->value,
sizeof(o->value), value);
425 return b->next_seq++;
428size_t detws_mtc_sample_query(DetwsMtcSampleBuffer *b,
char *buf,
size_t cap, uint64_t instance_id,
429 const char *device_name, uint64_t from, uint32_t count)
431 uint64_t first = b->first_seq;
432 uint64_t next = b->next_seq;
433 uint64_t last = next - 1;
434 uint64_t start = from < first ? first : from;
436 uint32_t avail = (start < next) ? (uint32_t)(next - start) : 0;
437 uint32_t to_emit = (count < avail) ? count : avail;
439 uint64_t next_report = (start >= next) ? next : start + to_emit;
448 for (uint32_t e = 0; e < to_emit; e++)
450 uint32_t k = (uint32_t)((start - first) + e);
452 detws_mtc_streams_add(&s, o->cat, o->type, o->data_id, o->seq, o->timestamp, o->value);
454 return detws_mtc_streams_end(&s);
#define DETWS_MTC_SAMPLE_BUFFER
MTConnect rolling sample buffer sizing (DETWS_ENABLE_MTCONNECT).
MTConnect agent response codec (DETWS_ENABLE_MTCONNECT).