/
ice.idl
474 lines (437 loc) · 19.5 KB
/
ice.idl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
/**
* @author Jeff Plourde
* These are the data types and topic names used by the OpenICE system.
*
* A nominal level of namespacing. In java this will create an ice
* package. In C++ this will create a namespace. In C this will create
* a name prefix. Type names will also be scoped with an "ice::" prefix.
* We do not use such a prefix in topic names because colons are not legal
* characters for use in DDS topics per section A.2 of the DDS spec version 1.2
* http://www.omg.org/spec/DDS/1.2/
*
* Excerpted...
* TOPICNAME - A topic name is an identifier for a topic, and is defined as any
* series of characters ‘a’, ..., ‘z’, ‘A’, ..., ‘Z’, ‘0’, ..., ‘9’, ‘-’ but may
* not start with a digit.
*
* Note: the #pragma syntax for specifying key fields is used by PrismTech OpenSplice.
* The RTI Connext code generator currently uses the //@key syntax and will generate
* harmless warnings about the #pragma definitions in its preprocessing step.
*
* The stability of each data model element will be ranked on a scale 0 to 5.
* For more information on the stability levels.
* http://nodejs.org/api/documentation.html#documentation_stability_index
* A better definition of backward-compatibility is required here with respect to the
* Extensible Types Addendum to DDS. i.e. backward compatibility is influenced
* by the use of markers for extensible types (indicating parameterized CDR)
* http://www.omg.org/spec/DDS-XTypes/
*
*/
module ice {
/**
* A placeholder type for evolving FDA work on UDI. Thus far 64 ISO-8859-1 characters
* is sufficient for holding FDA mandated unique device identifiers but we should
* monitor for changes.
*
* http://www.fda.gov/MedicalDevices/DeviceRegulationandGuidance/UniqueDeviceIdentification/
*/
typedef string<64> UniqueDeviceIdentifier;
/**
* A type for representing nomenclature codes from the ISO/IEEE 11073-10101 along with
* further work by the Rosetta Terminology Mapping project as maintained by NIST:
* https://rtmms.nist.gov/rtmms/index.htm
* 64 ISO-8859-1 characters is sufficient to utilize any "MDC" code currently accepted
* in harmonized rosetta.
*
*/
typedef string<64> MetricIdentifier;
/**
* A type for representing identifying information from a proprietary vendor nomenclature.
*/
typedef string<64> VendorMetricIdentifier;
/**
* For multiple instances of the same sensor this type is used for disambiguation.
* TODO Must these always begin at 0?
*/
typedef long InstanceIdentifier;
/**
* A type for representing unit codes from the ISO/IEEE 11073-10101 along with further
* work by the Rosetta Terminology Mapping project as maintained by NIST:
* https://rtmms.nist.gov/rtmms/index.htm
*/
typedef string<64> UnitIdentifier;
/**
* A type for "long" string fields such as those descriptive of persons, places, and
* things. These are UTF32 encoded to support international use.
*/
typedef wstring<128> LongString;
/**
* For a connected device these are the valid targets the device adapter might connect
* to. These are often the names of serial (RS-232) ports available on the adapter.
*/
typedef sequence<LongString, 128> ValidTargets;
/**
* Contains image data with the type specified externally.
*/
typedef sequence<octet, 65530> ImageData;
/**
* A sequence of values sampled at a high data rate (> 3Hz)
*/
typedef sequence<float, 1024> Values;
/**
* Definition for absolute time since the epoch in nanosecond resolution in the spirit
* of the built-in DDS type and the "struct timespec" structure.
* http://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html
*/
struct Time_t {
long sec;
long nanosec;
}; //@top-level false
/**
* At regular intervals (currently every 2 seconds) every OpenICE participant should
* publish to this topic. When the instance of HeartBeat associated with a device is
* no longer alive that device should be considered disconnected from the system. The
* Type description indicates whether the heartbeat came from a Device or Supervisor.
*
* Stability: 2 - Unstable
* An emitted sample from a particular uniquely identified device is
* necessary to determine device presence; however the particulars may
* change.
*/
struct HeartBeat {
UniqueDeviceIdentifier unique_device_identifier; //@key
string<32> type;
}; //@top-level true //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist HeartBeat unique_device_identifier
const string HeartBeatTopic = "HeartBeat";
/**
* Upon receipt of a HeartBeat sample an OpenICE participant should publish to this
* topic the original source timestamp of that heartbeat as well as the reception
* time. When this TimeSync message arrives back at the participant which originated
* the heartbeat enough information has been gathered to ascertain clock
* synchronization. So a Supervisory participant can determine whether any device
* clocks are out of sync.
*
* Stability: 1 - Experimental
* It is unclear whether the overhead created by this exceeds the benefit
* of detecting a lack of clock synchronization.
*/
struct TimeSync {
UniqueDeviceIdentifier heartbeat_source; //@key
UniqueDeviceIdentifier heartbeat_recipient; //@key
Time_t source_source_timestamp;
Time_t recipient_receipt_timestamp;
}; //@top-level true //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist TimeSync heartbeat_source heartbeat_recipient
const string TimeSyncTopic = "TimeSync";
/**
* Structure that includes binary image data encoded in the specified MIME type.
*/
struct Image {
string<64> content_type;
ImageData image;
}; //@top-level false
/**
* DeviceIdentity allows a device to share identifying information. A device generally
* publishes this information only once. A device with a further connection, perhaps a
* serial RS-232 link, might publish details like serial number only after they become
* available.
*
* Stability: 2 - Unstable
*/
struct DeviceIdentity {
UniqueDeviceIdentifier unique_device_identifier; //@key
LongString manufacturer;
LongString model;
LongString serial_number;
Image icon;
string<128> build;
string<128> operating_system;
}; //@top-level true //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist DeviceIdentity unique_device_identifier
const string DeviceIdentityTopic = "DeviceIdentity";
/**
* For a further connected device (device 'adapter') this enumerates the possible
* states of the further connection to a device.
*/
enum ConnectionState {
/** Connection is initialized and data is flowing normally */
Connected,
/** Connection has been physically made (perhaps an open socket or serial port) but
no information has been exchanged */
Connecting,
/** Information exchange has commenced to establish the connection. Some devices may
skip this state. */
Negotiating,
/** Disconnection has been requested and is being processed. */
Disconnecting,
/** The connection is not active. */
Disconnected
};
/**
* For a further connected device (device 'adapter') this enumerates the possible
* natures of the further connection.
*/
enum ConnectionType {
/** An RS-232 connection */
Serial,
/** A simulator that emulates connected device behaviors. */
Simulated,
/** A network connection (typically IP/Ethernet) */
Network
};
/**
* DeviceConnectivity shares information about a device that has a further connection
* to another device, such as a serial RS-232 link. The status of that further
* connection is published as well as additional information about the connection
* (often details about the connection process). Targets are also provided for an
* associated objective topic whereby establishment of the further connection can
* be requested by another participant. All current OpenICE device adapters attempt
* to establish such a connection by default.
*
* Stability: 2 - Unstable
*/
struct DeviceConnectivity {
UniqueDeviceIdentifier unique_device_identifier; //@key
ConnectionState state;
ConnectionType type;
LongString info;
ValidTargets valid_targets;
}; //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist DeviceConnectivity unique_device_identifier
const string DeviceConnectivityTopic = "DeviceConnectivity";
/**
* This topic allows a participant to instruct a further connected device adapter
* to establish the further connection to the specified target.
*
* Stability: 0 - Deprecated
*/
struct DeviceConnectivityObjective {
UniqueDeviceIdentifier unique_device_identifier; //@key
boolean connected;
LongString target;
}; //@top-level true //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist DeviceConnectivityObjective unique_device_identifier
const string DeviceConnectivityObjectiveTopic = "DeviceConnectivityObjective";
/**
* A number of speculative nomenclature codes not (yet) included in the
* harmonized rosetta.
*/
const string MDC_PRESS_CUFF_NEXT_INFLATION = "MDC_PRESS_CUFF_NEXT_INFLATION";
const string MDC_PRESS_CUFF_INFLATION = "MDC_PRESS_CUFF_INFLATION";
const string MDC_HR_ECG_MODE = "MDC_HR_ECG_MODE";
const string MDC_RR_APNEA = "MDC_RR_APNEA";
const string MDC_SPO2_C_LOCK = "MDC_SPO2_C_LOCK";
const string MDC_TIME_PD_INSPIRATORY = "MDC_TIME_PD_INSPIRATORY";
const string MDC_START_INSPIRATORY_CYCLE = "MDC_START_INSPIRATORY_CYCLE";
const string MDC_START_EXPIRATORY_CYCLE = "MDC_START_EXPIRATORY_CYCLE";
const string MDC_END_OF_BREATH = "MDC_END_OF_BREATH";
const string MDC_VENT_TIME_PD_PPV = "MDC_VENT_TIME_PD_PPV";
const long MDC_EVT_STAT_NBP_DEFL_AND_MEAS_BP = 6250;
const long MDC_EVT_STAT_NBP_INFL_TO_MAX_CUFF_PRESS = 6222;
const long MDC_EVT_STAT_OFF = 6226;
// These leads appear in 11073-10101-2004
// but are absent from Rosetta
const string MDC_ECG_LEAD_I = "MDC_ECG_LEAD_I";
const string MDC_ECG_LEAD_II = "MDC_ECG_LEAD_II";
const string MDC_ECG_LEAD_III = "MDC_ECG_LEAD_III";
const string MDC_ECG_LEAD_V1 = "MDC_ECG_LEAD_V1";
const string MDC_ECG_LEAD_V2 = "MDC_ECG_LEAD_V2";
const string MDC_ECG_LEAD_V3 = "MDC_ECG_LEAD_V3";
const string MDC_ECG_LEAD_V4 = "MDC_ECG_LEAD_V4";
const string MDC_ECG_LEAD_V5 = "MDC_ECG_LEAD_V5";
const string MDC_ECG_LEAD_V6 = "MDC_ECG_LEAD_V6";
const string MDC_ECG_LEAD_AVR = "MDC_ECG_LEAD_AVR";
const string MDC_ECG_LEAD_AVF = "MDC_ECG_LEAD_AVF";
const string MDC_ECG_LEAD_AVL = "MDC_ECG_LEAD_AVL";
/**
* Numerics are values observed by sensors at a relatively slow rate; generally <=3Hz.
* Multiple sensors may exist for the same metric so the instance_id serves to
* distinguish between them. If a timestamp is available from the device's internal
* clock it is specified as device_time. A device ought to register an instance of
* Numeric when the associated sensor might provide observations. If the sensor is
* physically disconnected or otherwise certain not to provide samples then the
* associated instance should be unregistered. Sensors are encouraged to publish a
* new sample whenever a new observation is made even when the same value is observed.
* In this way subscribers are made aware of the timeliness of the observation.
*
* vendor_metric_id is informational only, may be left blank, and must not be expected.
* If non-blank it contains a nomenclature code from a proprietary interface.
*
* Stability: 2 - Unstable
*/
struct Numeric {
UniqueDeviceIdentifier unique_device_identifier; //@key
MetricIdentifier metric_id; //@key
VendorMetricIdentifier vendor_metric_id; //@key
InstanceIdentifier instance_id; //@key
UnitIdentifier unit_id; //@key
float value;
Time_t device_time;
}; //@top-level true //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist Numeric unique_device_identifier metric_id vendor_metric_id instance_id unit_id
const string NumericTopic = "Numeric";
/**
* SampleArrays are values observed by sensors at a relatively high rate; generally
* >3Hz. Multiple sensors may exist for the same metric so the instance_id serves to
* distinguish between them. If a timestamp is available from the device's internal
* clock it is specified as device_time. A device ought to register an instance of
* SampleArray when the associated sensor might provide observations. If the sensor
* is physically disconnected or otherwise certain not to provide samples then the
* associated instance should be unregistered. Sourcetimestamp and device_time should
* both represent the point in time at the end of the sample array.
*
* vendor_metric_id is informational only, may be left blank, and must not be expected.
* If non-blank it contains a nomenclature code from a proprietary interface.
*
* Stability: 2 - Unstable
*/
struct SampleArray {
UniqueDeviceIdentifier unique_device_identifier; //@key
MetricIdentifier metric_id; //@key
VendorMetricIdentifier vendor_metric_id; //@key
InstanceIdentifier instance_id; //@key
UnitIdentifier unit_id; //@key
long frequency; //@key
Values values;
Time_t device_time;
}; //@top-level true //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist SampleArray unique_device_identifier metric_id instance_id unit_id frequency
const string SampleArrayTopic = "SampleArray";
/**
* Speculative topic used for the PCA demonstration. The supervisory safety app
* publishes a sample with stopInfusion=1 to indicate the infusion pump may not
* infuse. Currently a third topic, indicating that the pump has acknowledged
* the safety interlock, has not yet been included. We should also explore the
* possibility of a setup whereby the pump receives periodic 'ok to infuse'
* information and stops when that information is not received.
*
* Stability: 1 - Experimental
*/
struct InfusionObjective {
UniqueDeviceIdentifier unique_device_identifier; //@key
LongString requestor;
boolean stopInfusion;
}; //@top-level true //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist InfusionObjective unique_device_identifier
const string InfusionObjectiveTopic = "InfusionObjective";
/**
* Speculative topic used for the PCA demonstration. Only currently used by infusion
* pump simulators. But this is meant to represent the current state of an infusion
* pump holistically and coherently. While this is an early guess at some appropriate
* fields it does make it evident that many of these fields are not safely
* separable and should be part of the same data sample.
*
* Stability: 0 - Deprecated
*/
struct InfusionStatus {
UniqueDeviceIdentifier unique_device_identifier; //@key
// is the pump actively infusing?
boolean infusionActive;
// it's entirely unclear if patient id, care area, BSA, etc. should be here
// measurement units are standardized to avoid inconsistent states
// derived values are omitted to avoid inconsistent states
// what's in the bag
wstring<128> drug_name;
long drug_mass_mcg;
long solution_volume_ml;
// concentration can be derived
// what's the program
long volume_to_be_infused_ml;
long infusion_duration_seconds;
// rate can be derived
// what is the progress through the program?
float infusion_fraction_complete;
}; //@top-level true //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist InfusionStatus unique_device_identifier
const string InfusionStatusTopic = "InfusionStatus";
/**
* The current alarm thresholds for a particular metric on a particular device.
*
* Stability: 1 - Experimental
*/
struct AlarmSettings {
UniqueDeviceIdentifier unique_device_identifier; //@key
MetricIdentifier metric_id; //@key
float lower;
float upper;
}; //@top-level true //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist AlarmSettings unique_device_identifier metric_id
const string AlarmSettingsTopic = "AlarmSettings";
/**
* This objective is published by a Supervisory participant to request that all
* participants use the specified thresholds for alarms on a particular metric.
*
* Stability: 1 - Experimental
*/
struct GlobalAlarmSettingsObjective {
MetricIdentifier metric_id; //@key
float lower;
float upper;
}; //@top-level true //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist GlobalAlarmSettingsObjective metric_id
const string GlobalAlarmSettingsObjectiveTopic = "GlobalAlarmSettingsObjective";
/**
* This objective is published by a device to acknowledge that it has received the
* global alarm settings objective for a metric. Eventually its AlarmSettings should
* indicate that the change has been made. So the three AlarmSettingsXXX topics form
* an objective-state form of command and control. At any time any participant can see
* the current state of request, acknowledgment of the request, and implementation of
* the requested change.
*
* Stability: 1 - Experimental
*/
struct LocalAlarmSettingsObjective {
UniqueDeviceIdentifier unique_device_identifier; //@key
MetricIdentifier metric_id; //@key
float lower;
float upper;
}; //@top-level true //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist LocalAlarmSettingsObjective unique_device_identifier metric_id
const string LocalAlarmSettingsObjectiveTopic = "LocalAlarmSettingsObjective";
/**
* In the current iteration this is status text associated with the device globally.
* Meant for the global alarm state of the device. For example is the device audibly
* alarming, visibly alarming, alarming but silenced, etc.
*
* Stability: 1 - Experimental
*/
struct DeviceAlertCondition {
UniqueDeviceIdentifier unique_device_identifier; //@key
string<256> alert_state;
}; //@top-level true //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist DeviceAlertCondition unique_device_identifier
const string DeviceAlertConditionTopic = "DeviceAlertCondition";
/**
* This type is used by several topics.
*
*/
struct Alert {
UniqueDeviceIdentifier unique_device_identifier; //@key
// This is a placeholder for something more harmonized
string<256> identifier; //@key
string<256> text;
}; //@top-level true //@Extensibility MUTABLE_EXTENSIBILITY
#pragma keylist Alert unique_device_identifier identifier
/**
* PatientAlert is an alert message related to patient state. In the current iteration
* publishers may use any identifier they would like to uniquely identify patient
* alerts. The instance ought to be registered and a sample published when the alarm
* is triggered. If the associated text changes during the alarm another sample should
* be published. When the alarm is cancelled the instance should be unregistered. It's
* still an open question whether alarm samples should be published at regular intervals
* during the alarm condition. This, unfortunately, might be necessary to assert the
* liveliness of the alarm instance to late joiners. This is something to investigate
* with DDS vendors.
*
* Stability: 1 - Experimental
*/
const string PatientAlertTopic = "PatientAlert";
/**
* TechnicalAlert is similar to PatientAlert but is meant for technical alarms about
* the operation of the device.
*
* Stability: 1 - Experimental
*/
const string TechnicalAlertTopic = "TechnicalAlert";
};