mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-05 02:30:44 +00:00
Merge branch 'master' into overview
This commit is contained in:
commit
842052addb
@ -1671,53 +1671,53 @@ bool PRS1DataChunk::ParseEventsF5V3(void)
|
||||
// TB events have a duration in 0.1s, based on the review of pressure waveforms.
|
||||
// TODO: Ideally the starting time here would be adjusted here, but PRS1ParsedEvents
|
||||
// currently assume integer seconds rather than ms, so that's done at import.
|
||||
duration = data[pos++];
|
||||
duration = data[pos];
|
||||
this->AddEvent(new PRS1TimedBreathEvent(t, duration));
|
||||
break;
|
||||
case 3: // Statistics
|
||||
// These appear every 2 minutes, so presumably summarize the preceding period.
|
||||
this->AddEvent(new PRS1IPAPEvent(t, data[pos++], GAIN)); // 00=IPAP (average?)
|
||||
this->AddEvent(new PRS1IPAPLowEvent(t, data[pos++], GAIN)); // 01=IAP Low
|
||||
this->AddEvent(new PRS1IPAPHighEvent(t, data[pos++], GAIN)); // 02=IAP High
|
||||
this->AddEvent(new PRS1TotalLeakEvent(t, data[pos++])); // 03=Total leak (average?)
|
||||
this->AddEvent(new PRS1RespiratoryRateEvent(t, data[pos++])); // 04=Breaths Per Minute (average?)
|
||||
this->AddEvent(new PRS1PatientTriggeredBreathsEvent(t, data[pos++])); // 05=Patient Triggered Breaths (average?)
|
||||
this->AddEvent(new PRS1MinuteVentilationEvent(t, data[pos++])); // 06=Minute Ventilation (average?)
|
||||
this->AddEvent(new PRS1TidalVolumeEvent(t, data[pos++])); // 07=Tidal Volume (average?)
|
||||
this->AddEvent(new PRS1SnoreEvent(t, data[pos++])); // 08=Snore count // TODO: not a VS on official waveform, but appears in flags and contributes to overall VS index
|
||||
this->AddEvent(new PRS1EPAPEvent(t, data[pos++], GAIN)); // 09=EPAP (average? see event 1 above)
|
||||
this->AddEvent(new PRS1LeakEvent(t, data[pos++])); // 0A=Leak (average?)
|
||||
this->AddEvent(new PRS1IPAPEvent(t, data[pos+0], GAIN)); // 00=IPAP (average?)
|
||||
this->AddEvent(new PRS1IPAPLowEvent(t, data[pos+1], GAIN)); // 01=IAP Low
|
||||
this->AddEvent(new PRS1IPAPHighEvent(t, data[pos+2], GAIN)); // 02=IAP High
|
||||
this->AddEvent(new PRS1TotalLeakEvent(t, data[pos+3])); // 03=Total leak (average?)
|
||||
this->AddEvent(new PRS1RespiratoryRateEvent(t, data[pos+4])); // 04=Breaths Per Minute (average?)
|
||||
this->AddEvent(new PRS1PatientTriggeredBreathsEvent(t, data[pos+5])); // 05=Patient Triggered Breaths (average?)
|
||||
this->AddEvent(new PRS1MinuteVentilationEvent(t, data[pos+6])); // 06=Minute Ventilation (average?)
|
||||
this->AddEvent(new PRS1TidalVolumeEvent(t, data[pos+7])); // 07=Tidal Volume (average?)
|
||||
this->AddEvent(new PRS1SnoreEvent(t, data[pos+8])); // 08=Snore count // TODO: not a VS on official waveform, but appears in flags and contributes to overall VS index
|
||||
this->AddEvent(new PRS1EPAPEvent(t, data[pos+9], GAIN)); // 09=EPAP (average? see event 1 above)
|
||||
this->AddEvent(new PRS1LeakEvent(t, data[pos+0xa])); // 0A=Leak (average?)
|
||||
break;
|
||||
case 0x04: // Pressure Pulse
|
||||
duration = data[pos++]; // TODO: is this a duration?
|
||||
duration = data[pos]; // TODO: is this a duration?
|
||||
this->AddEvent(new PRS1PressurePulseEvent(t, duration));
|
||||
break;
|
||||
case 0x05: // Obstructive Apnea
|
||||
// OA events are instantaneous flags with no duration: reviewing waveforms
|
||||
// shows that the time elapsed between the flag and reporting often includes
|
||||
// non-apnea breathing.
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos];
|
||||
this->AddEvent(new PRS1ObstructiveApneaEvent(t - elapsed, 0));
|
||||
break;
|
||||
case 0x06: // Clear Airway Apnea
|
||||
// CA events are instantaneous flags with no duration: reviewing waveforms
|
||||
// shows that the time elapsed between the flag and reporting often includes
|
||||
// non-apnea breathing.
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos];
|
||||
this->AddEvent(new PRS1ClearAirwayEvent(t - elapsed, 0));
|
||||
break;
|
||||
case 0x07: // Hypopnea
|
||||
// TODO: How is this hypopnea different from events 0xd and 0xe?
|
||||
// TODO: What is the first byte?
|
||||
pos++; // unknown first byte?
|
||||
elapsed = data[pos++]; // based on sample waveform, the hypopnea is over after this
|
||||
//data[pos+0]; // unknown first byte?
|
||||
elapsed = data[pos+1]; // based on sample waveform, the hypopnea is over after this
|
||||
this->AddEvent(new PRS1HypopneaEvent(t - elapsed, 0));
|
||||
break;
|
||||
case 0x08: // Flow Limitation
|
||||
// TODO: We should revisit whether this is elapsed or duration once (if)
|
||||
// we start calculating flow limitations ourselves. Flow limitations aren't
|
||||
// as obvious as OA/CA when looking at a waveform.
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos];
|
||||
this->AddEvent(new PRS1FlowLimitationEvent(t - elapsed, 0));
|
||||
break;
|
||||
case 0x09: // Vibratory Snore
|
||||
@ -1731,15 +1731,13 @@ bool PRS1DataChunk::ParseEventsF5V3(void)
|
||||
case 0x0a: // Periodic Breathing
|
||||
// PB events are reported some time after they conclude, and they do have a reported duration.
|
||||
duration = 2 * (data[pos] | (data[pos+1] << 8));
|
||||
pos += 2;
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos+2];
|
||||
this->AddEvent(new PRS1PeriodicBreathingEvent(t - elapsed - duration, duration));
|
||||
break;
|
||||
case 0x0b: // Large Leak
|
||||
// LL events are reported some time after they conclude, and they do have a reported duration.
|
||||
duration = 2 * (data[pos] | (data[pos+1] << 8));
|
||||
pos += 2;
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos+2];
|
||||
this->AddEvent(new PRS1LargeLeakEvent(t - elapsed - duration, duration));
|
||||
break;
|
||||
case 0x0d: // Hypopnea
|
||||
@ -1749,7 +1747,7 @@ bool PRS1DataChunk::ParseEventsF5V3(void)
|
||||
// TODO: We should revisit whether this is elapsed or duration once (if)
|
||||
// we start calculating hypopneas ourselves. Their official definition
|
||||
// is 40% reduction in flow lasting at least 10s.
|
||||
duration = data[pos++];
|
||||
duration = data[pos];
|
||||
this->AddEvent(new PRS1HypopneaEvent(t - duration, 0));
|
||||
break;
|
||||
case 0x0f:
|
||||
@ -2441,66 +2439,64 @@ bool PRS1DataChunk::ParseEventsF3V6(void)
|
||||
// TB events have a duration in 0.1s, based on the review of pressure waveforms.
|
||||
// TODO: Ideally the starting time here would be adjusted here, but PRS1ParsedEvents
|
||||
// currently assume integer seconds rather than ms, so that's done at import.
|
||||
duration = data[pos++];
|
||||
duration = data[pos];
|
||||
// TODO: make sure F3 import logic matches F5 in adjusting TB start time
|
||||
this->AddEvent(new PRS1TimedBreathEvent(t, duration));
|
||||
break;
|
||||
case 2: // Statistics
|
||||
// These appear every 2 minutes, so presumably summarize the preceding period.
|
||||
pos++; // TODO: 0 = ???
|
||||
this->AddEvent(new PRS1EPAPEvent(t, data[pos++], GAIN)); // 01=EPAP (average?)
|
||||
this->AddEvent(new PRS1IPAPEvent(t, data[pos++], GAIN)); // 02=IPAP (average?)
|
||||
this->AddEvent(new PRS1TotalLeakEvent(t, data[pos++])); // 03=Total leak (average?)
|
||||
this->AddEvent(new PRS1RespiratoryRateEvent(t, data[pos++])); // 04=Breaths Per Minute (average?)
|
||||
this->AddEvent(new PRS1PatientTriggeredBreathsEvent(t, data[pos++])); // 05=Patient Triggered Breaths (average?)
|
||||
this->AddEvent(new PRS1MinuteVentilationEvent(t, data[pos++])); // 06=Minute Ventilation (average?)
|
||||
this->AddEvent(new PRS1TidalVolumeEvent(t, data[pos++])); // 07=Tidal Volume (average?)
|
||||
this->AddEvent(new PRS1Test2Event(t, data[pos++])); // 08=Flow???
|
||||
this->AddEvent(new PRS1Test1Event(t, data[pos++])); // 09=TMV???
|
||||
this->AddEvent(new PRS1SnoreEvent(t, data[pos++])); // 0A=Snore count // TODO: not a VS on official waveform, but appears in flags and contributes to overall VS index
|
||||
this->AddEvent(new PRS1LeakEvent(t, data[pos++])); // 0B=Leak (average?)
|
||||
//data[pos+0]; // TODO: 0 = ???
|
||||
this->AddEvent(new PRS1EPAPEvent(t, data[pos+1], GAIN)); // 01=EPAP (average?) // TODO: needs to be added second if we decide to calculate PS
|
||||
this->AddEvent(new PRS1IPAPEvent(t, data[pos+2], GAIN)); // 02=IPAP (average?)
|
||||
this->AddEvent(new PRS1TotalLeakEvent(t, data[pos+3])); // 03=Total leak (average?)
|
||||
this->AddEvent(new PRS1RespiratoryRateEvent(t, data[pos+4])); // 04=Breaths Per Minute (average?)
|
||||
this->AddEvent(new PRS1PatientTriggeredBreathsEvent(t, data[pos+5])); // 05=Patient Triggered Breaths (average?)
|
||||
this->AddEvent(new PRS1MinuteVentilationEvent(t, data[pos+6])); // 06=Minute Ventilation (average?)
|
||||
this->AddEvent(new PRS1TidalVolumeEvent(t, data[pos+7])); // 07=Tidal Volume (average?)
|
||||
this->AddEvent(new PRS1Test2Event(t, data[pos+8])); // 08=Flow???
|
||||
this->AddEvent(new PRS1Test1Event(t, data[pos+9])); // 09=TMV???
|
||||
this->AddEvent(new PRS1SnoreEvent(t, data[pos+0xa])); // 0A=Snore count // TODO: not a VS on official waveform, but appears in flags and contributes to overall VS index
|
||||
this->AddEvent(new PRS1LeakEvent(t, data[pos+0xb])); // 0B=Leak (average?)
|
||||
break;
|
||||
case 0x03: // Pressure Pulse
|
||||
duration = data[pos++]; // TODO: is this a duration?
|
||||
duration = data[pos]; // TODO: is this a duration?
|
||||
this->AddEvent(new PRS1PressurePulseEvent(t, duration));
|
||||
break;
|
||||
case 0x04: // Obstructive Apnea
|
||||
// OA events are instantaneous flags with no duration: reviewing waveforms
|
||||
// shows that the time elapsed between the flag and reporting often includes
|
||||
// non-apnea breathing.
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos];
|
||||
this->AddEvent(new PRS1ObstructiveApneaEvent(t - elapsed, 0));
|
||||
break;
|
||||
case 0x05: // Clear Airway Apnea
|
||||
// CA events are instantaneous flags with no duration: reviewing waveforms
|
||||
// shows that the time elapsed between the flag and reporting often includes
|
||||
// non-apnea breathing.
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos];
|
||||
this->AddEvent(new PRS1ClearAirwayEvent(t - elapsed, 0));
|
||||
break;
|
||||
case 0x06: // Hypopnea
|
||||
// TODO: How is this hypopnea different from events 0xd and 0xe?
|
||||
// TODO: What is the first byte?
|
||||
pos++; // unknown first byte?
|
||||
elapsed = data[pos++]; // based on sample waveform, the hypopnea is over after this
|
||||
//data[pos+0]; // unknown first byte?
|
||||
elapsed = data[pos+1]; // based on sample waveform, the hypopnea is over after this
|
||||
this->AddEvent(new PRS1HypopneaEvent(t - elapsed, 0));
|
||||
break;
|
||||
case 0x07: // Periodic Breathing
|
||||
// PB events are reported some time after they conclude, and they do have a reported duration.
|
||||
duration = 2 * (data[pos] | (data[pos+1] << 8));
|
||||
pos += 2;
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos+2];
|
||||
this->AddEvent(new PRS1PeriodicBreathingEvent(t - elapsed - duration, duration));
|
||||
break;
|
||||
case 0x08: // RERA
|
||||
elapsed = data[pos++]; // based on sample waveform, the RERA is over after this
|
||||
elapsed = data[pos]; // based on sample waveform, the RERA is over after this
|
||||
this->AddEvent(new PRS1RERAEvent(t - elapsed, 0));
|
||||
break;
|
||||
case 0x09: // Large Leak
|
||||
// LL events are reported some time after they conclude, and they do have a reported duration.
|
||||
duration = 2 * (data[pos] | (data[pos+1] << 8));
|
||||
pos += 2;
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos+2];
|
||||
this->AddEvent(new PRS1LargeLeakEvent(t - elapsed - duration, duration));
|
||||
break;
|
||||
case 0x0a: // Hypopnea
|
||||
@ -2510,7 +2506,7 @@ bool PRS1DataChunk::ParseEventsF3V6(void)
|
||||
// TODO: We should revisit whether this is elapsed or duration once (if)
|
||||
// we start calculating hypopneas ourselves. Their official definition
|
||||
// is 40% reduction in flow lasting at least 10s.
|
||||
duration = data[pos++];
|
||||
duration = data[pos];
|
||||
this->AddEvent(new PRS1HypopneaEvent(t - duration, 0));
|
||||
break;
|
||||
// case 0x0c?
|
||||
@ -3398,7 +3394,7 @@ bool PRS1DataChunk::ParseEventsF0V6(CPAPMode /*mode*/)
|
||||
// adjustments. E.g. 6 at 28:11 and 7.3 at 29:05 results in the following dots:
|
||||
// 6 at 28:11, 6.5 around 28:30, 7.0 around 28:50, 7(.3) at 29:05. That holds until
|
||||
// subsequent "adjustment" of 7.3 at 30:09 followed by 8.0 at 30:19.
|
||||
this->AddEvent(new PRS1CPAPEvent(t, data[pos++]));
|
||||
this->AddEvent(new PRS1CPAPEvent(t, data[pos]));
|
||||
break;
|
||||
case 0x02: // Pressure adjustment (bi-level)
|
||||
// TODO: Have OSCAR treat pressure adjustment events differently than (average?) stats below.
|
||||
@ -3417,25 +3413,25 @@ bool PRS1DataChunk::ParseEventsF0V6(CPAPMode /*mode*/)
|
||||
//CHECK_VALUE(data[pos], 40);
|
||||
break;
|
||||
case 0x04: // Pressure Pulse
|
||||
duration = data[pos++]; // TODO: is this a duration?
|
||||
duration = data[pos]; // TODO: is this a duration?
|
||||
this->AddEvent(new PRS1PressurePulseEvent(t, duration));
|
||||
break;
|
||||
case 0x05: // RERA
|
||||
elapsed = data[pos++]; // based on sample waveform, the RERA is over after this
|
||||
elapsed = data[pos]; // based on sample waveform, the RERA is over after this
|
||||
this->AddEvent(new PRS1RERAEvent(t - elapsed, 0));
|
||||
break;
|
||||
case 0x06: // Obstructive Apnea
|
||||
// OA events are instantaneous flags with no duration: reviewing waveforms
|
||||
// shows that the time elapsed between the flag and reporting often includes
|
||||
// non-apnea breathing.
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos];
|
||||
this->AddEvent(new PRS1ObstructiveApneaEvent(t - elapsed, 0));
|
||||
break;
|
||||
case 0x07: // Clear Airway Apnea
|
||||
// CA events are instantaneous flags with no duration: reviewing waveforms
|
||||
// shows that the time elapsed between the flag and reporting often includes
|
||||
// non-apnea breathing.
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos];
|
||||
this->AddEvent(new PRS1ClearAirwayEvent(t - elapsed, 0));
|
||||
break;
|
||||
//case 0x08: // never seen
|
||||
@ -3444,15 +3440,15 @@ bool PRS1DataChunk::ParseEventsF0V6(CPAPMode /*mode*/)
|
||||
case 0x0b: // Hypopnea
|
||||
// TODO: How is this hypopnea different from events 0xa, 0x14 and 0x15?
|
||||
// TODO: What is the first byte?
|
||||
pos++; // unknown first byte?
|
||||
elapsed = data[pos++]; // based on sample waveform, the hypopnea is over after this
|
||||
//data[pos+0]; // unknown first byte?
|
||||
elapsed = data[pos+1]; // based on sample waveform, the hypopnea is over after this
|
||||
this->AddEvent(new PRS1HypopneaEvent(t - elapsed, 0));
|
||||
break;
|
||||
case 0x0c: // Flow Limitation
|
||||
// TODO: We should revisit whether this is elapsed or duration once (if)
|
||||
// we start calculating flow limitations ourselves. Flow limitations aren't
|
||||
// as obvious as OA/CA when looking at a waveform.
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos];
|
||||
this->AddEvent(new PRS1FlowLimitationEvent(t - elapsed, 0));
|
||||
break;
|
||||
case 0x0d: // Vibratory Snore
|
||||
@ -3466,33 +3462,30 @@ bool PRS1DataChunk::ParseEventsF0V6(CPAPMode /*mode*/)
|
||||
case 0x0e: // ???
|
||||
// 5 bytes like PB and LL, but what is it?
|
||||
duration = 2 * (data[pos] | (data[pos+1] << 8)); // this looks like a 16-bit value, so may be duration like PB?
|
||||
pos += 2;
|
||||
elapsed = data[pos++]; // this is always 60 seconds unless it's at the end, so it seems like elapsed
|
||||
elapsed = data[pos+2]; // this is always 60 seconds unless it's at the end, so it seems like elapsed
|
||||
CHECK_VALUES(elapsed, 60, 0);
|
||||
//this->AddEvent(new PRS1PeriodicBreathingEvent(t - elapsed - duration, duration));
|
||||
break;
|
||||
case 0x0f: // Periodic Breathing
|
||||
// PB events are reported some time after they conclude, and they do have a reported duration.
|
||||
duration = 2 * (data[pos] | (data[pos+1] << 8));
|
||||
pos += 2;
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos+2];
|
||||
this->AddEvent(new PRS1PeriodicBreathingEvent(t - elapsed - duration, duration));
|
||||
break;
|
||||
case 0x10: // Large Leak
|
||||
// LL events are reported some time after they conclude, and they do have a reported duration.
|
||||
duration = 2 * (data[pos] | (data[pos+1] << 8));
|
||||
pos += 2;
|
||||
elapsed = data[pos++];
|
||||
elapsed = data[pos+2];
|
||||
this->AddEvent(new PRS1LargeLeakEvent(t - elapsed - duration, duration));
|
||||
break;
|
||||
case 0x11: // Statistics
|
||||
this->AddEvent(new PRS1TotalLeakEvent(t, data[pos++]));
|
||||
this->AddEvent(new PRS1SnoreEvent(t, data[pos++]));
|
||||
this->AddEvent(new PRS1TotalLeakEvent(t, data[pos]));
|
||||
this->AddEvent(new PRS1SnoreEvent(t, data[pos+1]));
|
||||
// Average pressure: this reads lower than the current CPAP set point when
|
||||
// a flex mode is on, and exactly the current CPAP set point when off. For
|
||||
// bi-level it's presumably an average of the actual pressures.
|
||||
// TODO: What to do with this average pressure? Actual pressure adjustments are handled above.
|
||||
//this->AddEvent(new PRS1EPAPEvent(t, data[pos++]));
|
||||
//this->AddEvent(new PRS1EPAPEvent(t, data[pos+2]));
|
||||
break;
|
||||
case 0x12: // Snore count per pressure
|
||||
// Some sessions (with lots of ramps) have multiple of these, each with a
|
||||
@ -3516,7 +3509,7 @@ bool PRS1DataChunk::ParseEventsF0V6(CPAPMode /*mode*/)
|
||||
// TODO: We should revisit whether this is elapsed or duration once (if)
|
||||
// we start calculating hypopneas ourselves. Their official definition
|
||||
// is 40% reduction in flow lasting at least 10s.
|
||||
duration = data[pos++];
|
||||
duration = data[pos];
|
||||
this->AddEvent(new PRS1HypopneaEvent(t - duration, 0));
|
||||
break;
|
||||
default:
|
||||
@ -4148,13 +4141,14 @@ bool PRS1DataChunk::ParseSettingsF3V6(const unsigned char* data, int size)
|
||||
// TODO: We probably need additional enums for these modes, the below are just a rough guess mapping for now.
|
||||
switch (data[pos]) {
|
||||
case 1: cpapmode = MODE_BILEVEL_FIXED; break; // "S" mode
|
||||
case 2: cpapmode = MODE_ASV; break; // "S/T" mode; pressure seems variable?
|
||||
case 2: cpapmode = MODE_BILEVEL_FIXED; break; // "S/T" mode; pressure seems variable?
|
||||
case 4: cpapmode = MODE_AVAPS; break; // "PC" mode? Usually "PC - AVAPS", see setting 1 below
|
||||
// TODO: fixed vs. variable PS seems to be independent from ventilator mode, for example
|
||||
// S/T can be fixed (single IPAP pressure) or variable (IPAP min/max).
|
||||
default:
|
||||
UNEXPECTED_VALUE(data[pos], "known device mode");
|
||||
break;
|
||||
}
|
||||
this->AddEvent(new PRS1ParsedSettingEvent(PRS1_SETTING_CPAP_MODE, (int) cpapmode));
|
||||
break;
|
||||
case 1: // ???
|
||||
// How do these interact with the mode above?
|
||||
@ -4174,21 +4168,36 @@ bool PRS1DataChunk::ParseSettingsF3V6(const unsigned char* data, int size)
|
||||
// pressures seem variable on practice, maybe due to ramp or leaks?
|
||||
fixed_ipap = data[pos];
|
||||
this->AddEvent(new PRS1PressureSettingEvent(PRS1_SETTING_IPAP, fixed_ipap, GAIN));
|
||||
// TODO: We need to revisit whether PS should be shown as a setting.
|
||||
this->AddEvent(new PRS1PressureSettingEvent(PRS1_SETTING_PS, fixed_ipap - fixed_epap, GAIN));
|
||||
if (fixed_epap == 0) UNEXPECTED_VALUE(fixed_epap, ">0");
|
||||
break;
|
||||
case 8: // Min IPAP
|
||||
CHECK_VALUE(fixed_ipap, 0);
|
||||
if (cpapmode == MODE_BILEVEL_FIXED) {
|
||||
cpapmode = MODE_BILEVEL_AUTO_VARIABLE_PS; // TODO: this isn't quite right, it's actually fixed EPAP with variable PS
|
||||
}
|
||||
min_ipap = data[pos];
|
||||
this->AddEvent(new PRS1PressureSettingEvent(PRS1_SETTING_IPAP_MIN, min_ipap, GAIN));
|
||||
// TODO: We need to revisit whether PS should be shown as a setting.
|
||||
this->AddEvent(new PRS1PressureSettingEvent(PRS1_SETTING_PS_MIN, min_ipap - fixed_epap, GAIN));
|
||||
if (fixed_epap == 0) UNEXPECTED_VALUE(fixed_epap, ">0");
|
||||
break;
|
||||
case 9: // Max IPAP
|
||||
CHECK_VALUE(fixed_ipap, 0);
|
||||
if (min_ipap == 0) UNEXPECTED_VALUE(min_ipap, ">0");
|
||||
max_ipap = data[pos];
|
||||
this->AddEvent(new PRS1PressureSettingEvent(PRS1_SETTING_IPAP_MAX, max_ipap, GAIN));
|
||||
// TODO: We need to revisit whether PS should be shown as a setting.
|
||||
this->AddEvent(new PRS1PressureSettingEvent(PRS1_SETTING_PS_MAX, max_ipap - fixed_epap, GAIN));
|
||||
if (fixed_epap == 0) UNEXPECTED_VALUE(fixed_epap, ">0");
|
||||
break;
|
||||
case 0x19: // Tidal Volume (AVAPS)
|
||||
//CHECK_VALUE(data[pos], 47); // gain 10.0
|
||||
// TODO: add a setting for this
|
||||
break;
|
||||
case 0x1e: // Backup rate (S/T and AVAPS)
|
||||
CHECK_VALUES(cpapmode, MODE_ASV, MODE_AVAPS);
|
||||
//CHECK_VALUES(cpapmode, MODE_BILEVEL_FIXED, MODE_AVAPS); // TODO: this should be testing for S/T rather than bilevel
|
||||
// TODO: Does mode breath rate off mean this is essentially bilevel? The pressure graphs are confusing.
|
||||
CHECK_VALUES(data[pos], 0, 2); // 0 = Breath Rate off (S), 2 = fixed BPM (1 = auto on F5V3 setting 0x14)
|
||||
//CHECK_VALUE(data[pos+1], 10); // BPM for mode 2
|
||||
@ -4240,6 +4249,8 @@ bool PRS1DataChunk::ParseSettingsF3V6(const unsigned char* data, int size)
|
||||
|
||||
pos += len;
|
||||
} while (ok && pos + 2 <= size);
|
||||
|
||||
this->AddEvent(new PRS1ParsedSettingEvent(PRS1_SETTING_CPAP_MODE, (int) cpapmode));
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user