@ovok/native 1.6.47 → 1.6.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/modules/bt-device/constants/baby-sleep-clip-catalog-asset.js +10 -0
- package/lib/commonjs/modules/bt-device/constants/baby-sleep-clip-catalog-asset.js.map +1 -0
- package/lib/commonjs/modules/bt-device/constants/device-instruction-pdfs.js +12 -1
- package/lib/commonjs/modules/bt-device/constants/device-instruction-pdfs.js.map +1 -1
- package/lib/commonjs/modules/bt-device/constants/supported-device-catalog-assets.js +5 -1
- package/lib/commonjs/modules/bt-device/constants/supported-device-catalog-assets.js.map +1 -1
- package/lib/commonjs/modules/bt-device/constants/supported-device-catalog-entries.js +19 -0
- package/lib/commonjs/modules/bt-device/constants/supported-device-catalog-entries.js.map +1 -1
- package/lib/commonjs/modules/bt-device/constants/supported-devices.js +38 -0
- package/lib/commonjs/modules/bt-device/constants/supported-devices.js.map +1 -1
- package/lib/commonjs/modules/bt-management/constants/integrated-devices-map.js +1 -1
- package/lib/commonjs/modules/bt-management/constants/integrated-devices-map.js.map +1 -1
- package/lib/commonjs/modules/bt-management/services/device-classes.js +95 -0
- package/lib/commonjs/modules/bt-management/services/device-classes.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/device-creator.js +5 -82
- package/lib/commonjs/modules/bt-management/services/device-creator.js.map +1 -1
- package/lib/commonjs/modules/bt-management/services/devices/bt-managed-device.js +6 -1
- package/lib/commonjs/modules/bt-management/services/devices/bt-managed-device.js.map +1 -1
- package/lib/commonjs/modules/bt-management/services/devices/viatom/baby-sleep-clip.device.js +57 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/baby-sleep-clip.device.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/baby-sleep-clip.protocol.js +106 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/baby-sleep-clip.protocol.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/baby-sleep-clip.sequencer.js +80 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/baby-sleep-clip.sequencer.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/lpm311.device.js +55 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/lpm311.device.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/lpm311.protocol.js +103 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/lpm311.protocol.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/lpm311.sequencer.js +33 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/lpm311.sequencer.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/oxy-s3.device.js +72 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/oxy-s3.device.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/oxy-s3.protocol.js +103 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/oxy-s3.protocol.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/oxy-s3.sequencer.js +110 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/oxy-s3.sequencer.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/pf10aw1.device.js +53 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/pf10aw1.device.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/pf10aw1.protocol.js +64 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/pf10aw1.protocol.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/pf10aw1.sequencer.js +96 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/pf10aw1.sequencer.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/sp20.device.js +54 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/sp20.device.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/sp20.protocol.js +102 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/sp20.protocol.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/sp20.sequencer.js +115 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/sp20.sequencer.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/viatom-lepu-crypto.js +81 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/viatom-lepu-crypto.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/viatom-r20.device.js +57 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/viatom-r20.device.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/viatom-r20.protocol.js +118 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/viatom-r20.protocol.js.map +1 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/viatom-r20.sequencer.js +95 -0
- package/lib/commonjs/modules/bt-management/services/devices/viatom/viatom-r20.sequencer.js.map +1 -0
- package/lib/commonjs/modules/bt-management/types/clock-sync.js +3 -0
- package/lib/commonjs/modules/bt-management/types/clock-sync.js.map +1 -1
- package/lib/commonjs/modules/bt-management/types/device-measurement-map.js.map +1 -1
- package/lib/commonjs/modules/bt-management/types/integrated-devices.js +11 -0
- package/lib/commonjs/modules/bt-management/types/integrated-devices.js.map +1 -1
- package/lib/module/modules/bt-device/constants/baby-sleep-clip-catalog-asset.js +7 -0
- package/lib/module/modules/bt-device/constants/baby-sleep-clip-catalog-asset.js.map +1 -0
- package/lib/module/modules/bt-device/constants/device-instruction-pdfs.js +12 -1
- package/lib/module/modules/bt-device/constants/device-instruction-pdfs.js.map +1 -1
- package/lib/module/modules/bt-device/constants/supported-device-catalog-assets.js +5 -1
- package/lib/module/modules/bt-device/constants/supported-device-catalog-assets.js.map +1 -1
- package/lib/module/modules/bt-device/constants/supported-device-catalog-entries.js +20 -1
- package/lib/module/modules/bt-device/constants/supported-device-catalog-entries.js.map +1 -1
- package/lib/module/modules/bt-device/constants/supported-devices.js +38 -0
- package/lib/module/modules/bt-device/constants/supported-devices.js.map +1 -1
- package/lib/module/modules/bt-management/constants/integrated-devices-map.js +1 -1
- package/lib/module/modules/bt-management/constants/integrated-devices-map.js.map +1 -1
- package/lib/module/modules/bt-management/services/device-classes.js +92 -0
- package/lib/module/modules/bt-management/services/device-classes.js.map +1 -0
- package/lib/module/modules/bt-management/services/device-creator.js +3 -81
- package/lib/module/modules/bt-management/services/device-creator.js.map +1 -1
- package/lib/module/modules/bt-management/services/devices/bt-managed-device.js +6 -1
- package/lib/module/modules/bt-management/services/devices/bt-managed-device.js.map +1 -1
- package/lib/module/modules/bt-management/services/devices/viatom/baby-sleep-clip.device.js +52 -0
- package/lib/module/modules/bt-management/services/devices/viatom/baby-sleep-clip.device.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/baby-sleep-clip.protocol.js +99 -0
- package/lib/module/modules/bt-management/services/devices/viatom/baby-sleep-clip.protocol.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/baby-sleep-clip.sequencer.js +75 -0
- package/lib/module/modules/bt-management/services/devices/viatom/baby-sleep-clip.sequencer.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/lpm311.device.js +50 -0
- package/lib/module/modules/bt-management/services/devices/viatom/lpm311.device.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/lpm311.protocol.js +98 -0
- package/lib/module/modules/bt-management/services/devices/viatom/lpm311.protocol.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/lpm311.sequencer.js +28 -0
- package/lib/module/modules/bt-management/services/devices/viatom/lpm311.sequencer.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/oxy-s3.device.js +67 -0
- package/lib/module/modules/bt-management/services/devices/viatom/oxy-s3.device.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/oxy-s3.protocol.js +94 -0
- package/lib/module/modules/bt-management/services/devices/viatom/oxy-s3.protocol.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/oxy-s3.sequencer.js +105 -0
- package/lib/module/modules/bt-management/services/devices/viatom/oxy-s3.sequencer.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/pf10aw1.device.js +48 -0
- package/lib/module/modules/bt-management/services/devices/viatom/pf10aw1.device.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/pf10aw1.protocol.js +57 -0
- package/lib/module/modules/bt-management/services/devices/viatom/pf10aw1.protocol.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/pf10aw1.sequencer.js +91 -0
- package/lib/module/modules/bt-management/services/devices/viatom/pf10aw1.sequencer.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/sp20.device.js +49 -0
- package/lib/module/modules/bt-management/services/devices/viatom/sp20.device.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/sp20.protocol.js +94 -0
- package/lib/module/modules/bt-management/services/devices/viatom/sp20.protocol.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/sp20.sequencer.js +110 -0
- package/lib/module/modules/bt-management/services/devices/viatom/sp20.sequencer.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/viatom-lepu-crypto.js +71 -0
- package/lib/module/modules/bt-management/services/devices/viatom/viatom-lepu-crypto.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/viatom-r20.device.js +52 -0
- package/lib/module/modules/bt-management/services/devices/viatom/viatom-r20.device.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/viatom-r20.protocol.js +110 -0
- package/lib/module/modules/bt-management/services/devices/viatom/viatom-r20.protocol.js.map +1 -0
- package/lib/module/modules/bt-management/services/devices/viatom/viatom-r20.sequencer.js +90 -0
- package/lib/module/modules/bt-management/services/devices/viatom/viatom-r20.sequencer.js.map +1 -0
- package/lib/module/modules/bt-management/types/clock-sync.js +3 -0
- package/lib/module/modules/bt-management/types/clock-sync.js.map +1 -1
- package/lib/module/modules/bt-management/types/device-measurement-map.js.map +1 -1
- package/lib/module/modules/bt-management/types/integrated-devices.js +11 -0
- package/lib/module/modules/bt-management/types/integrated-devices.js.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-device/constants/baby-sleep-clip-catalog-asset.d.ts +4 -0
- package/lib/typescript/commonjs/src/modules/bt-device/constants/baby-sleep-clip-catalog-asset.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-device/constants/device-instruction-pdfs.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-device/constants/supported-device-catalog-assets.d.ts +5 -1
- package/lib/typescript/commonjs/src/modules/bt-device/constants/supported-device-catalog-assets.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-device/constants/supported-device-catalog-entries.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-device/constants/supported-devices.d.ts +1 -1
- package/lib/typescript/commonjs/src/modules/bt-device/constants/supported-devices.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/constants/integrated-devices-map.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/device-classes.d.ts +89 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/device-classes.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/device-creator.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bt-managed-device.d.ts +2 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/bt-managed-device.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/baby-sleep-clip.device.d.ts +18 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/baby-sleep-clip.device.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/baby-sleep-clip.protocol.d.ts +27 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/baby-sleep-clip.protocol.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/baby-sleep-clip.sequencer.d.ts +32 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/baby-sleep-clip.sequencer.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/lpm311.device.d.ts +9 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/lpm311.device.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/lpm311.protocol.d.ts +14 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/lpm311.protocol.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/lpm311.sequencer.d.ts +10 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/lpm311.sequencer.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/oxy-s3.device.d.ts +18 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/oxy-s3.device.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/oxy-s3.protocol.d.ts +42 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/oxy-s3.protocol.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/oxy-s3.sequencer.d.ts +31 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/oxy-s3.sequencer.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/pf10aw1.device.d.ts +19 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/pf10aw1.device.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/pf10aw1.protocol.d.ts +30 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/pf10aw1.protocol.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/pf10aw1.sequencer.d.ts +27 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/pf10aw1.sequencer.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/sp20.device.d.ts +20 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/sp20.device.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/sp20.protocol.d.ts +28 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/sp20.protocol.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/sp20.sequencer.d.ts +26 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/sp20.sequencer.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/viatom-lepu-crypto.d.ts +7 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/viatom-lepu-crypto.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/viatom-r20.device.d.ts +20 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/viatom-r20.device.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/viatom-r20.protocol.d.ts +38 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/viatom-r20.protocol.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/viatom-r20.sequencer.d.ts +35 -0
- package/lib/typescript/commonjs/src/modules/bt-management/services/devices/viatom/viatom-r20.sequencer.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/modules/bt-management/types/clock-sync.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/types/device-measurement-map.d.ts +12 -1
- package/lib/typescript/commonjs/src/modules/bt-management/types/device-measurement-map.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/modules/bt-management/types/integrated-devices.d.ts +12 -1
- package/lib/typescript/commonjs/src/modules/bt-management/types/integrated-devices.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-device/constants/baby-sleep-clip-catalog-asset.d.ts +4 -0
- package/lib/typescript/module/src/modules/bt-device/constants/baby-sleep-clip-catalog-asset.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-device/constants/device-instruction-pdfs.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-device/constants/supported-device-catalog-assets.d.ts +5 -1
- package/lib/typescript/module/src/modules/bt-device/constants/supported-device-catalog-assets.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-device/constants/supported-device-catalog-entries.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-device/constants/supported-devices.d.ts +1 -1
- package/lib/typescript/module/src/modules/bt-device/constants/supported-devices.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/constants/integrated-devices-map.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/services/device-classes.d.ts +89 -0
- package/lib/typescript/module/src/modules/bt-management/services/device-classes.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/device-creator.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/bt-managed-device.d.ts +2 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/bt-managed-device.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/baby-sleep-clip.device.d.ts +18 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/baby-sleep-clip.device.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/baby-sleep-clip.protocol.d.ts +27 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/baby-sleep-clip.protocol.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/baby-sleep-clip.sequencer.d.ts +32 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/baby-sleep-clip.sequencer.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/lpm311.device.d.ts +9 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/lpm311.device.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/lpm311.protocol.d.ts +14 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/lpm311.protocol.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/lpm311.sequencer.d.ts +10 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/lpm311.sequencer.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/oxy-s3.device.d.ts +18 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/oxy-s3.device.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/oxy-s3.protocol.d.ts +42 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/oxy-s3.protocol.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/oxy-s3.sequencer.d.ts +31 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/oxy-s3.sequencer.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/pf10aw1.device.d.ts +19 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/pf10aw1.device.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/pf10aw1.protocol.d.ts +30 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/pf10aw1.protocol.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/pf10aw1.sequencer.d.ts +27 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/pf10aw1.sequencer.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/sp20.device.d.ts +20 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/sp20.device.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/sp20.protocol.d.ts +28 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/sp20.protocol.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/sp20.sequencer.d.ts +26 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/sp20.sequencer.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/viatom-lepu-crypto.d.ts +7 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/viatom-lepu-crypto.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/viatom-r20.device.d.ts +20 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/viatom-r20.device.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/viatom-r20.protocol.d.ts +38 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/viatom-r20.protocol.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/viatom-r20.sequencer.d.ts +35 -0
- package/lib/typescript/module/src/modules/bt-management/services/devices/viatom/viatom-r20.sequencer.d.ts.map +1 -0
- package/lib/typescript/module/src/modules/bt-management/types/clock-sync.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/types/device-measurement-map.d.ts +12 -1
- package/lib/typescript/module/src/modules/bt-management/types/device-measurement-map.d.ts.map +1 -1
- package/lib/typescript/module/src/modules/bt-management/types/integrated-devices.d.ts +12 -1
- package/lib/typescript/module/src/modules/bt-management/types/integrated-devices.d.ts.map +1 -1
- package/package.json +6 -4
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { MeasurementTypeKey } from "@ovok/core";
|
|
4
|
+
import { CaseType } from "../../../types/case-type.js";
|
|
5
|
+
import { LepuCommandBuilder } from "../lepu/lepu.command-builder.js";
|
|
6
|
+
import { buildOxyS3LegacyFrame, decodeOxyS3Response, OxyS3Command, parseOxyS3Reading } from "./oxy-s3.protocol.js";
|
|
7
|
+
import { createLepuAccessToken, decryptLepuHandshake, decryptLepuPayload, encryptLepuPayload, parseLepuSessionKey } from "./viatom-lepu-crypto.js";
|
|
8
|
+
const toBytes = value => Array.from(value, character => character.charCodeAt(0));
|
|
9
|
+
const validOxygen = value => value >= 50 && value <= 100;
|
|
10
|
+
const validPulse = value => value > 0 && value <= 300;
|
|
11
|
+
|
|
12
|
+
/** Drives the two Oxy S3 transports documented by ViHealth: legacy Oxy and encrypted A5. */
|
|
13
|
+
export class OxyS3Sequencer {
|
|
14
|
+
commands = new LepuCommandBuilder("a5");
|
|
15
|
+
constructor(params) {
|
|
16
|
+
this.params = params;
|
|
17
|
+
this.phase = params.encrypted ? "authenticate" : "clock";
|
|
18
|
+
}
|
|
19
|
+
initialCommands = () => this.phase === "authenticate" ? [this.command(OxyS3Command.authenticate, createLepuAccessToken(this.now()))] : [this.timeCommand()];
|
|
20
|
+
nextCommand = frame => {
|
|
21
|
+
const response = decodeOxyS3Response(frame, this.params.protocol);
|
|
22
|
+
if (!response) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
if (this.phase === "authenticate") {
|
|
26
|
+
if (response.status !== 1 || this.params.protocol === "v2" && response.command !== OxyS3Command.authenticate) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
const sessionKey = parseLepuSessionKey(decryptLepuHandshake(response.payload));
|
|
30
|
+
if (!sessionKey) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
this.sessionKey = sessionKey;
|
|
34
|
+
this.phase = "clock";
|
|
35
|
+
return [this.timeCommand()];
|
|
36
|
+
}
|
|
37
|
+
if (this.phase === "clock") {
|
|
38
|
+
if (response.status !== 1 || this.params.protocol === "v2" && response.command !== OxyS3Command.syncTime) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
if (this.params.protocol === "v1") {
|
|
42
|
+
this.phase = "ready";
|
|
43
|
+
return [this.readLegacyParameters()];
|
|
44
|
+
}
|
|
45
|
+
this.phase = "stream";
|
|
46
|
+
return [this.command(OxyS3Command.enableRealtimeParameters, [1])];
|
|
47
|
+
}
|
|
48
|
+
if (this.phase === "stream") {
|
|
49
|
+
if (response.command !== OxyS3Command.enableRealtimeParameters || response.status !== 1) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
this.phase = "ready";
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
if (this.params.protocol === "v2" && response.command === OxyS3Command.realtimeParameters && response.status === 1) {
|
|
56
|
+
this.report(this.decrypt(response.payload));
|
|
57
|
+
} else if (this.params.protocol === "v1" && response.status === 1) {
|
|
58
|
+
this.report(this.decrypt(response.payload));
|
|
59
|
+
return [this.readLegacyParameters()];
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
};
|
|
63
|
+
command = (command, payload = []) => {
|
|
64
|
+
const encryptedPayload = this.sessionKey ? encryptLepuPayload(payload, this.sessionKey) : [...payload];
|
|
65
|
+
const frame = this.params.protocol === "v2" ? this.commands.build(command, encryptedPayload) : buildOxyS3LegacyFrame(command, encryptedPayload);
|
|
66
|
+
return {
|
|
67
|
+
...this.params.write,
|
|
68
|
+
frame,
|
|
69
|
+
withoutResponse: true
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
timeCommand = () => {
|
|
73
|
+
const date = this.now();
|
|
74
|
+
if (this.params.protocol === "v1") {
|
|
75
|
+
const time = `${date.getFullYear()}-${this.pad(date.getMonth() + 1)}-${this.pad(date.getDate())},${this.pad(date.getHours())}:${this.pad(date.getMinutes())}:${this.pad(date.getSeconds())}`;
|
|
76
|
+
return this.command(OxyS3Command.legacySyncTime, toBytes(JSON.stringify({
|
|
77
|
+
SetTIME: time
|
|
78
|
+
})));
|
|
79
|
+
}
|
|
80
|
+
const year = date.getFullYear();
|
|
81
|
+
const timezoneOffsetTenthHours = Math.round(-date.getTimezoneOffset() / 6);
|
|
82
|
+
return this.command(OxyS3Command.syncTime, [year & 0xff, year >>> 8, date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), timezoneOffsetTenthHours & 0xff]);
|
|
83
|
+
};
|
|
84
|
+
readLegacyParameters = () => this.command(OxyS3Command.legacyRealtimeParameters);
|
|
85
|
+
decrypt = payload => this.sessionKey ? decryptLepuPayload(payload, this.sessionKey) ?? [] : [...payload];
|
|
86
|
+
report = payload => {
|
|
87
|
+
const reading = parseOxyS3Reading(payload, this.params.protocol);
|
|
88
|
+
if (!reading || !validOxygen(reading.bloodOxygen) || !validPulse(reading.pulseRate)) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
this.params.onResult({
|
|
92
|
+
caseType: CaseType.RESULT,
|
|
93
|
+
measurementTypeKey: MeasurementTypeKey.bloodOxygenPulseRate,
|
|
94
|
+
bloodOxygen: reading.bloodOxygen,
|
|
95
|
+
pulseRate: reading.pulseRate,
|
|
96
|
+
...(reading.perfusionIndex > 0 ? {
|
|
97
|
+
perfusionIndex: reading.perfusionIndex
|
|
98
|
+
} : {}),
|
|
99
|
+
recordedAt: this.now()
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
now = () => this.params.now?.() ?? new Date();
|
|
103
|
+
pad = value => value.toString().padStart(2, "0");
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=oxy-s3.sequencer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["MeasurementTypeKey","CaseType","LepuCommandBuilder","buildOxyS3LegacyFrame","decodeOxyS3Response","OxyS3Command","parseOxyS3Reading","createLepuAccessToken","decryptLepuHandshake","decryptLepuPayload","encryptLepuPayload","parseLepuSessionKey","toBytes","value","Array","from","character","charCodeAt","validOxygen","validPulse","OxyS3Sequencer","commands","constructor","params","phase","encrypted","initialCommands","command","authenticate","now","timeCommand","nextCommand","frame","response","protocol","undefined","status","sessionKey","payload","syncTime","readLegacyParameters","enableRealtimeParameters","realtimeParameters","report","decrypt","encryptedPayload","build","write","withoutResponse","date","time","getFullYear","pad","getMonth","getDate","getHours","getMinutes","getSeconds","legacySyncTime","JSON","stringify","SetTIME","year","timezoneOffsetTenthHours","Math","round","getTimezoneOffset","legacyRealtimeParameters","reading","bloodOxygen","pulseRate","onResult","caseType","RESULT","measurementTypeKey","bloodOxygenPulseRate","perfusionIndex","recordedAt","Date","toString","padStart"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/viatom/oxy-s3.sequencer.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/* eslint-disable import/group-exports */
|
|
4
|
+
|
|
5
|
+
import { MeasurementTypeKey } from "@ovok/core";
|
|
6
|
+
import { BTManagedDevice } from "../bt-managed-device.js";
|
|
7
|
+
import { PF10AW1_NOTIFY, PF10AW1_SERVICE, PF10AW1_WRITE, Pf10Aw1FrameReader } from "./pf10aw1.protocol.js";
|
|
8
|
+
import { Pf10Aw1Sequencer } from "./pf10aw1.sequencer.js";
|
|
9
|
+
const acceptNothing = {
|
|
10
|
+
caseValuePosition: [],
|
|
11
|
+
cases: []
|
|
12
|
+
};
|
|
13
|
+
export const pf10Aw1MainServices = [{
|
|
14
|
+
uuid: PF10AW1_SERVICE,
|
|
15
|
+
monitorUuids: [{
|
|
16
|
+
uuid: PF10AW1_NOTIFY,
|
|
17
|
+
parsingModel: acceptNothing
|
|
18
|
+
}],
|
|
19
|
+
writeUuid: {
|
|
20
|
+
uuid: PF10AW1_WRITE,
|
|
21
|
+
mainCommandUuid: "a5"
|
|
22
|
+
}
|
|
23
|
+
}];
|
|
24
|
+
|
|
25
|
+
/** ViHealth PF10AW-ME, SA10AW-PU, and PF10BW-VE encrypted oximeter driver. */
|
|
26
|
+
export class Pf10Aw1Device extends BTManagedDevice {
|
|
27
|
+
mainServices = pf10Aw1MainServices;
|
|
28
|
+
stuckDataTimeout = 60_000;
|
|
29
|
+
onStreamStart = undefined;
|
|
30
|
+
getSupportedMeasurementTypeKeys() {
|
|
31
|
+
return [MeasurementTypeKey.bloodOxygenPulseRate];
|
|
32
|
+
}
|
|
33
|
+
constructor(device, params) {
|
|
34
|
+
super(device, params);
|
|
35
|
+
this.frameReader = new Pf10Aw1FrameReader();
|
|
36
|
+
this.createCommandSequencer = () => new Pf10Aw1Sequencer({
|
|
37
|
+
write: {
|
|
38
|
+
serviceUuid: PF10AW1_SERVICE,
|
|
39
|
+
characteristicUuid: PF10AW1_WRITE
|
|
40
|
+
},
|
|
41
|
+
onResult: result => this.onResult?.(result)
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
handleSuccessResult() {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=pf10aw1.device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["MeasurementTypeKey","BTManagedDevice","PF10AW1_NOTIFY","PF10AW1_SERVICE","PF10AW1_WRITE","Pf10Aw1FrameReader","Pf10Aw1Sequencer","acceptNothing","caseValuePosition","cases","pf10Aw1MainServices","uuid","monitorUuids","parsingModel","writeUuid","mainCommandUuid","Pf10Aw1Device","mainServices","stuckDataTimeout","onStreamStart","undefined","getSupportedMeasurementTypeKeys","bloodOxygenPulseRate","constructor","device","params","frameReader","createCommandSequencer","write","serviceUuid","characteristicUuid","onResult","result","handleSuccessResult"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/viatom/pf10aw1.device.ts"],"mappings":";;AAAA;;AAEA,SAASA,kBAAkB,QAAQ,YAAY;AAQ/C,SAASC,eAAe,QAAQ,yBAAsB;AAEtD,SACEC,cAAc,EACdC,eAAe,EACfC,aAAa,EACbC,kBAAkB,QACb,uBAAoB;AAC3B,SAASC,gBAAgB,QAAQ,wBAAqB;AAOtD,MAAMC,aAAa,GAAG;EAAEC,iBAAiB,EAAE,EAAE;EAAEC,KAAK,EAAE;AAAG,CAAC;AAE1D,OAAO,MAAMC,mBAA+B,GAAG,CAC7C;EACEC,IAAI,EAAER,eAAe;EACrBS,YAAY,EAAE,CAAC;IAAED,IAAI,EAAET,cAAc;IAAEW,YAAY,EAAEN;EAAc,CAAC,CAAC;EACrEO,SAAS,EAAE;IAAEH,IAAI,EAAEP,aAAa;IAAEW,eAAe,EAAE;EAAK;AAC1D,CAAC,CACF;;AAED;AACA,OAAO,MAAMC,aAAa,SAASf,eAAe,CAAkB;EACxDgB,YAAY,GAAGP,mBAAmB;EAClCQ,gBAAgB,GAAG,MAAM;EACzBC,aAAa,GAAGC,SAAS;EAEhBC,+BAA+BA,CAAA,EAAyB;IACzE,OAAO,CAACrB,kBAAkB,CAACsB,oBAAoB,CAAC;EAClD;EAEOC,WAAWA,CAChBC,MAAc,EACdC,MAA2C,EAC3C;IACA,KAAK,CAACD,MAAM,EAAEC,MAAM,CAAC;IACrB,IAAI,CAACC,WAAW,GAAG,IAAIrB,kBAAkB,CAAC,CAAC;IAC3C,IAAI,CAACsB,sBAAsB,GAAG,MAC5B,IAAIrB,gBAAgB,CAAC;MACnBsB,KAAK,EAAE;QACLC,WAAW,EAAE1B,eAAe;QAC5B2B,kBAAkB,EAAE1B;MACtB,CAAC;MACD2B,QAAQ,EAAGC,MAAM,IACf,IAAI,CAACD,QAAQ,GACXC,MAGF;IACJ,CAAC,CAAC;EACN;EAEUC,mBAAmBA,CAAA,EAAS;IACpC;EACF;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/* eslint-disable import/group-exports */
|
|
4
|
+
|
|
5
|
+
import { calculateCrc8 } from "../../../utils/calculate-crc-8.js";
|
|
6
|
+
import { hexToByte } from "../../../utils/hex-to-byte.js";
|
|
7
|
+
import { le16FromHex } from "../../../utils/le-16-from-hex.js";
|
|
8
|
+
import { LepuFrameReader } from "../lepu/lepu.frame-reader.js";
|
|
9
|
+
export const PF10AW1_SERVICE = "e8fb0001-a14b-98f9-831b-4e2941d01248";
|
|
10
|
+
export const PF10AW1_WRITE = "e8fb0002-a14b-98f9-831b-4e2941d01248";
|
|
11
|
+
export const PF10AW1_NOTIFY = "e8fb0003-a14b-98f9-831b-4e2941d01248";
|
|
12
|
+
export const Pf10Aw1Command = {
|
|
13
|
+
authenticate: 0xff,
|
|
14
|
+
setUtcTime: 0xc0,
|
|
15
|
+
enableParameters: 0x02,
|
|
16
|
+
enableWave: 0x03,
|
|
17
|
+
realtimeParameters: 0x04
|
|
18
|
+
};
|
|
19
|
+
/** PF10AW1 uses the shared Lepu A5 frame and CRC-8/ATM. */
|
|
20
|
+
export class Pf10Aw1FrameReader {
|
|
21
|
+
reader = new LepuFrameReader(["a5"]);
|
|
22
|
+
readFrame = buffer => this.reader.readFrame(buffer);
|
|
23
|
+
}
|
|
24
|
+
export const decodePf10Aw1Response = frame => {
|
|
25
|
+
if (frame.length < 8 || hexToByte(frame[0] ?? "00") !== 0xa5) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
const command = hexToByte(frame[1] ?? "00");
|
|
29
|
+
if (hexToByte(frame[2] ?? "00") !== (~command & 0xff)) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const payloadLength = le16FromHex(frame, 5);
|
|
33
|
+
if (frame.length !== payloadLength + 8) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
const checksumIndex = frame.length - 1;
|
|
37
|
+
if (hexToByte(frame[checksumIndex] ?? "00") !== calculateCrc8([...frame], checksumIndex)) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
command,
|
|
42
|
+
status: hexToByte(frame[3] ?? "00"),
|
|
43
|
+
payload: frame.slice(7, checksumIndex).map(value => hexToByte(value))
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
export const parsePf10Aw1OximeterReading = payload => {
|
|
47
|
+
if (payload.length < 5) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
bloodOxygen: payload[0] ?? 0,
|
|
52
|
+
pulseRate: payload[1] ?? 0,
|
|
53
|
+
perfusionIndex: (payload[2] ?? 0) / 10,
|
|
54
|
+
probeOff: ((payload[3] ?? 0) & 0x02) !== 0
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=pf10aw1.protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["calculateCrc8","hexToByte","le16FromHex","LepuFrameReader","PF10AW1_SERVICE","PF10AW1_WRITE","PF10AW1_NOTIFY","Pf10Aw1Command","authenticate","setUtcTime","enableParameters","enableWave","realtimeParameters","Pf10Aw1FrameReader","reader","readFrame","buffer","decodePf10Aw1Response","frame","length","undefined","command","payloadLength","checksumIndex","status","payload","slice","map","value","parsePf10Aw1OximeterReading","bloodOxygen","pulseRate","perfusionIndex","probeOff"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/viatom/pf10aw1.protocol.ts"],"mappings":";;AAAA;;AAGA,SAASA,aAAa,QAAQ,mCAAgC;AAC9D,SAASC,SAAS,QAAQ,+BAA4B;AACtD,SAASC,WAAW,QAAQ,kCAA+B;AAC3D,SAASC,eAAe,QAAQ,8BAA2B;AAE3D,OAAO,MAAMC,eAAe,GAAG,sCAAsC;AACrE,OAAO,MAAMC,aAAa,GAAG,sCAAsC;AACnE,OAAO,MAAMC,cAAc,GAAG,sCAAsC;AAEpE,OAAO,MAAMC,cAAc,GAAG;EAC5BC,YAAY,EAAE,IAAI;EAClBC,UAAU,EAAE,IAAI;EAChBC,gBAAgB,EAAE,IAAI;EACtBC,UAAU,EAAE,IAAI;EAChBC,kBAAkB,EAAE;AACtB,CAAU;AAeV;AACA,OAAO,MAAMC,kBAAkB,CAAwB;EACpCC,MAAM,GAAG,IAAIX,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC;EAE9CY,SAAS,GAAIC,MAAyB,IAAK,IAAI,CAACF,MAAM,CAACC,SAAS,CAACC,MAAM,CAAC;AACjF;AAEA,OAAO,MAAMC,qBAAqB,GAChCC,KAAwB,IACQ;EAChC,IAAIA,KAAK,CAACC,MAAM,GAAG,CAAC,IAAIlB,SAAS,CAACiB,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE;IAC5D,OAAOE,SAAS;EAClB;EAEA,MAAMC,OAAO,GAAGpB,SAAS,CAACiB,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;EAE3C,IAAIjB,SAAS,CAACiB,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAACG,OAAO,GAAG,IAAI,CAAC,EAAE;IACrD,OAAOD,SAAS;EAClB;EAEA,MAAME,aAAa,GAAGpB,WAAW,CAACgB,KAAK,EAAE,CAAC,CAAC;EAE3C,IAAIA,KAAK,CAACC,MAAM,KAAKG,aAAa,GAAG,CAAC,EAAE;IACtC,OAAOF,SAAS;EAClB;EAEA,MAAMG,aAAa,GAAGL,KAAK,CAACC,MAAM,GAAG,CAAC;EAEtC,IACElB,SAAS,CAACiB,KAAK,CAACK,aAAa,CAAC,IAAI,IAAI,CAAC,KACvCvB,aAAa,CAAC,CAAC,GAAGkB,KAAK,CAAC,EAAEK,aAAa,CAAC,EACxC;IACA,OAAOH,SAAS;EAClB;EAEA,OAAO;IACLC,OAAO;IACPG,MAAM,EAAEvB,SAAS,CAACiB,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IACnCO,OAAO,EAAEP,KAAK,CAACQ,KAAK,CAAC,CAAC,EAAEH,aAAa,CAAC,CAACI,GAAG,CAAEC,KAAK,IAAK3B,SAAS,CAAC2B,KAAK,CAAC;EACxE,CAAC;AACH,CAAC;AAED,OAAO,MAAMC,2BAA2B,GACtCJ,OAA0B,IACa;EACvC,IAAIA,OAAO,CAACN,MAAM,GAAG,CAAC,EAAE;IACtB,OAAOC,SAAS;EAClB;EAEA,OAAO;IACLU,WAAW,EAAEL,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5BM,SAAS,EAAEN,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1BO,cAAc,EAAE,CAACP,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE;IACtCQ,QAAQ,EAAE,CAAC,CAACR,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,MAAM;EAC3C,CAAC;AACH,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { MeasurementTypeKey } from "@ovok/core";
|
|
4
|
+
import { CaseType } from "../../../types/case-type.js";
|
|
5
|
+
import { LepuCommandBuilder } from "../lepu/lepu.command-builder.js";
|
|
6
|
+
import { decodePf10Aw1Response, parsePf10Aw1OximeterReading, Pf10Aw1Command } from "./pf10aw1.protocol.js";
|
|
7
|
+
import { createLepuAccessToken, decryptLepuHandshake, decryptLepuPayload, encryptLepuPayload, parseLepuSessionKey } from "./viatom-lepu-crypto.js";
|
|
8
|
+
const isValidOxygen = value => value >= 50 && value <= 100;
|
|
9
|
+
const isValidPulse = value => value > 0 && value <= 300;
|
|
10
|
+
|
|
11
|
+
/** Drives the vendor-encrypted A5 exchange used by the PF10AW1 oximeter models. */
|
|
12
|
+
export class Pf10Aw1Sequencer {
|
|
13
|
+
commands = new LepuCommandBuilder("a5");
|
|
14
|
+
phase = "authenticate";
|
|
15
|
+
constructor(params) {
|
|
16
|
+
this.params = params;
|
|
17
|
+
}
|
|
18
|
+
initialCommands = () => [this.write(this.commands.build(Pf10Aw1Command.authenticate, createLepuAccessToken(this.params.now?.() ?? new Date())))];
|
|
19
|
+
nextCommand = frame => {
|
|
20
|
+
const response = decodePf10Aw1Response(frame);
|
|
21
|
+
if (!response) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
if (this.phase === "authenticate") {
|
|
25
|
+
return this.acceptHandshake(response.command, response.status, response.payload);
|
|
26
|
+
}
|
|
27
|
+
if (this.phase === "clock" && response.command === Pf10Aw1Command.setUtcTime) {
|
|
28
|
+
if (response.status !== 1) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
this.phase = "parameters";
|
|
32
|
+
return [this.buildEncryptedCommand(Pf10Aw1Command.enableParameters, [1])];
|
|
33
|
+
}
|
|
34
|
+
if (this.phase === "parameters" && response.command === Pf10Aw1Command.enableParameters && response.status === 1) {
|
|
35
|
+
this.phase = "wave";
|
|
36
|
+
return [this.buildEncryptedCommand(Pf10Aw1Command.enableWave, [1])];
|
|
37
|
+
}
|
|
38
|
+
if (this.phase === "wave" && response.command === Pf10Aw1Command.enableWave && response.status === 1) {
|
|
39
|
+
this.phase = "ready";
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
if (this.phase === "ready" && response.command === Pf10Aw1Command.realtimeParameters && response.status === 1) {
|
|
43
|
+
this.report(this.decrypt(response.payload));
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
};
|
|
47
|
+
acceptHandshake = (command, status, payload) => {
|
|
48
|
+
if (command !== Pf10Aw1Command.authenticate || status !== 1) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const key = parseLepuSessionKey(decryptLepuHandshake(payload));
|
|
52
|
+
if (!key) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
this.sessionKey = key;
|
|
56
|
+
this.phase = "clock";
|
|
57
|
+
return [this.buildEncryptedCommand(Pf10Aw1Command.setUtcTime, this.timePayload())];
|
|
58
|
+
};
|
|
59
|
+
buildEncryptedCommand = (command, payload) => {
|
|
60
|
+
const encrypted = encryptLepuPayload(payload, this.sessionKey ?? []);
|
|
61
|
+
return this.write(this.commands.build(command, encrypted));
|
|
62
|
+
};
|
|
63
|
+
decrypt = payload => (this.sessionKey && decryptLepuPayload(payload, this.sessionKey)) ?? [];
|
|
64
|
+
timePayload = () => {
|
|
65
|
+
const date = this.params.now?.() ?? new Date();
|
|
66
|
+
const timezoneOffsetTenthHours = Math.round(-date.getTimezoneOffset() / 6);
|
|
67
|
+
return [date.getFullYear() & 0xff, date.getFullYear() >>> 8 & 0xff, date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), timezoneOffsetTenthHours & 0xff];
|
|
68
|
+
};
|
|
69
|
+
report = payload => {
|
|
70
|
+
const reading = parsePf10Aw1OximeterReading(payload);
|
|
71
|
+
if (!reading || reading.probeOff || !isValidOxygen(reading.bloodOxygen) || !isValidPulse(reading.pulseRate)) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
this.params.onResult({
|
|
75
|
+
caseType: CaseType.RESULT,
|
|
76
|
+
measurementTypeKey: MeasurementTypeKey.bloodOxygenPulseRate,
|
|
77
|
+
bloodOxygen: reading.bloodOxygen,
|
|
78
|
+
pulseRate: reading.pulseRate,
|
|
79
|
+
...(reading.perfusionIndex > 0 ? {
|
|
80
|
+
perfusionIndex: reading.perfusionIndex
|
|
81
|
+
} : {}),
|
|
82
|
+
recordedAt: this.params.now?.() ?? new Date()
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
write = frame => ({
|
|
86
|
+
...this.params.write,
|
|
87
|
+
frame,
|
|
88
|
+
withoutResponse: true
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=pf10aw1.sequencer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["MeasurementTypeKey","CaseType","LepuCommandBuilder","decodePf10Aw1Response","parsePf10Aw1OximeterReading","Pf10Aw1Command","createLepuAccessToken","decryptLepuHandshake","decryptLepuPayload","encryptLepuPayload","parseLepuSessionKey","isValidOxygen","value","isValidPulse","Pf10Aw1Sequencer","commands","phase","constructor","params","initialCommands","write","build","authenticate","now","Date","nextCommand","frame","response","undefined","acceptHandshake","command","status","payload","setUtcTime","buildEncryptedCommand","enableParameters","enableWave","realtimeParameters","report","decrypt","key","sessionKey","timePayload","encrypted","date","timezoneOffsetTenthHours","Math","round","getTimezoneOffset","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","reading","probeOff","bloodOxygen","pulseRate","onResult","caseType","RESULT","measurementTypeKey","bloodOxygenPulseRate","perfusionIndex","recordedAt","withoutResponse"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/viatom/pf10aw1.sequencer.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/* eslint-disable import/group-exports */
|
|
4
|
+
|
|
5
|
+
import { MeasurementTypeKey } from "@ovok/core";
|
|
6
|
+
import { BTManagedDevice } from "../bt-managed-device.js";
|
|
7
|
+
import { SP20_NOTIFY, SP20_SERVICE, SP20_WRITE, Sp20FrameReader } from "./sp20.protocol.js";
|
|
8
|
+
import { Sp20Sequencer } from "./sp20.sequencer.js";
|
|
9
|
+
const acceptNothing = {
|
|
10
|
+
caseValuePosition: [],
|
|
11
|
+
cases: []
|
|
12
|
+
};
|
|
13
|
+
export const sp20MainServices = [{
|
|
14
|
+
uuid: SP20_SERVICE,
|
|
15
|
+
monitorUuids: [{
|
|
16
|
+
uuid: SP20_NOTIFY,
|
|
17
|
+
parsingModel: acceptNothing
|
|
18
|
+
}],
|
|
19
|
+
writeUuid: {
|
|
20
|
+
uuid: SP20_WRITE,
|
|
21
|
+
mainCommandUuid: "aa55"
|
|
22
|
+
}
|
|
23
|
+
}];
|
|
24
|
+
|
|
25
|
+
/** ViHealth SP-20, SP-20-BLE, and SP-20-WPS encrypted realtime oximeter. */
|
|
26
|
+
export class Sp20Device extends BTManagedDevice {
|
|
27
|
+
mainServices = sp20MainServices;
|
|
28
|
+
stuckDataTimeout = 60_000;
|
|
29
|
+
onStreamStart = undefined;
|
|
30
|
+
preferredMtu = 247;
|
|
31
|
+
getSupportedMeasurementTypeKeys() {
|
|
32
|
+
return [MeasurementTypeKey.bloodOxygenPulseRate];
|
|
33
|
+
}
|
|
34
|
+
constructor(device, params) {
|
|
35
|
+
super(device, params);
|
|
36
|
+
this.frameReader = new Sp20FrameReader();
|
|
37
|
+
this.createCommandSequencer = () => new Sp20Sequencer({
|
|
38
|
+
write: {
|
|
39
|
+
serviceUuid: SP20_SERVICE,
|
|
40
|
+
characteristicUuid: SP20_WRITE
|
|
41
|
+
},
|
|
42
|
+
onResult: result => this.onResult?.(result)
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
handleSuccessResult() {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=sp20.device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["MeasurementTypeKey","BTManagedDevice","SP20_NOTIFY","SP20_SERVICE","SP20_WRITE","Sp20FrameReader","Sp20Sequencer","acceptNothing","caseValuePosition","cases","sp20MainServices","uuid","monitorUuids","parsingModel","writeUuid","mainCommandUuid","Sp20Device","mainServices","stuckDataTimeout","onStreamStart","undefined","preferredMtu","getSupportedMeasurementTypeKeys","bloodOxygenPulseRate","constructor","device","params","frameReader","createCommandSequencer","write","serviceUuid","characteristicUuid","onResult","result","handleSuccessResult"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/viatom/sp20.device.ts"],"mappings":";;AAAA;;AAEA,SAASA,kBAAkB,QAAQ,YAAY;AAQ/C,SAASC,eAAe,QAAQ,yBAAsB;AAEtD,SACEC,WAAW,EACXC,YAAY,EACZC,UAAU,EACVC,eAAe,QACV,oBAAiB;AACxB,SAASC,aAAa,QAAQ,qBAAkB;AAOhD,MAAMC,aAAa,GAAG;EAAEC,iBAAiB,EAAE,EAAE;EAAEC,KAAK,EAAE;AAAG,CAAC;AAE1D,OAAO,MAAMC,gBAA4B,GAAG,CAC1C;EACEC,IAAI,EAAER,YAAY;EAClBS,YAAY,EAAE,CAAC;IAAED,IAAI,EAAET,WAAW;IAAEW,YAAY,EAAEN;EAAc,CAAC,CAAC;EAClEO,SAAS,EAAE;IAAEH,IAAI,EAAEP,UAAU;IAAEW,eAAe,EAAE;EAAO;AACzD,CAAC,CACF;;AAED;AACA,OAAO,MAAMC,UAAU,SAASf,eAAe,CAAe;EAClDgB,YAAY,GAAGP,gBAAgB;EAC/BQ,gBAAgB,GAAG,MAAM;EACzBC,aAAa,GAAGC,SAAS;EAChBC,YAAY,GAAG,GAAG;EAClBC,+BAA+BA,CAAA,EAAyB;IACzE,OAAO,CAACtB,kBAAkB,CAACuB,oBAAoB,CAAC;EAClD;EAEOC,WAAWA,CAChBC,MAAc,EACdC,MAAwC,EACxC;IACA,KAAK,CAACD,MAAM,EAAEC,MAAM,CAAC;IACrB,IAAI,CAACC,WAAW,GAAG,IAAItB,eAAe,CAAC,CAAC;IACxC,IAAI,CAACuB,sBAAsB,GAAG,MAC5B,IAAItB,aAAa,CAAC;MAChBuB,KAAK,EAAE;QAAEC,WAAW,EAAE3B,YAAY;QAAE4B,kBAAkB,EAAE3B;MAAW,CAAC;MACpE4B,QAAQ,EAAGC,MAAM,IACf,IAAI,CAACD,QAAQ,GACXC,MAGF;IACJ,CAAC,CAAC;EACN;EAEUC,mBAAmBA,CAAA,EAAS;IACpC;EACF;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/* eslint-disable import/group-exports */
|
|
4
|
+
|
|
5
|
+
import { FrameReadStatus } from "../../../types/frame-read-status.js";
|
|
6
|
+
import { calculateCrc8Pc } from "../../../utils/calculate-crc-8-pc.js";
|
|
7
|
+
import { hexToByte } from "../../../utils/hex-to-byte.js";
|
|
8
|
+
export const SP20_SERVICE = "0000fff0-0000-1000-8000-00805f9b34fb";
|
|
9
|
+
export const SP20_NOTIFY = "0000fff1-0000-1000-8000-00805f9b34fb";
|
|
10
|
+
export const SP20_WRITE = "0000fff2-0000-1000-8000-00805f9b34fb";
|
|
11
|
+
const byte = value => (value & 0xff).toString(16).padStart(2, "0");
|
|
12
|
+
export const buildSp20Frame = (token, type, payload = []) => {
|
|
13
|
+
const frame = ["aa", "55", byte(token), byte(payload.length + 2), byte(type), ...payload.map(byte), "00"];
|
|
14
|
+
frame[frame.length - 1] = byte(calculateCrc8Pc(frame));
|
|
15
|
+
return frame;
|
|
16
|
+
};
|
|
17
|
+
export const decodeSp20Frame = frame => {
|
|
18
|
+
if (hexToByte(frame[0] ?? "00") !== 0xaa || hexToByte(frame[1] ?? "00") !== 0x55 || frame.length < 6 || frame.length !== hexToByte(frame[3] ?? "00") + 4 || calculateCrc8Pc(frame) !== hexToByte(frame.at(-1) ?? "00")) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
token: hexToByte(frame[2] ?? "00"),
|
|
23
|
+
type: hexToByte(frame[4] ?? "00"),
|
|
24
|
+
content: frame.slice(5, -1).map(value => hexToByte(value)),
|
|
25
|
+
cipherText: frame.slice(4, -1).map(value => hexToByte(value))
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export const parseSp20OximeterReading = content => {
|
|
29
|
+
if (content.length < 6) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const flags = content[4] ?? 0;
|
|
33
|
+
return {
|
|
34
|
+
bloodOxygen: content[0] ?? 0,
|
|
35
|
+
pulseRate: (content[1] ?? 0) | (content[2] ?? 0) << 8,
|
|
36
|
+
perfusionIndex: content[3] ?? 0,
|
|
37
|
+
probeOff: (flags & 0x02) !== 0,
|
|
38
|
+
pulseSearching: (flags & 0x04) !== 0,
|
|
39
|
+
checkProbe: (flags & 0x08) !== 0
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/** AA55 frames carry their length at byte 3; notifications may split or batch them. */
|
|
44
|
+
export class Sp20FrameReader {
|
|
45
|
+
readFrame(buffer) {
|
|
46
|
+
const start = this.findHeader(buffer);
|
|
47
|
+
if (start < 0) {
|
|
48
|
+
return {
|
|
49
|
+
status: FrameReadStatus.INCOMPLETE,
|
|
50
|
+
consumedBytes: Math.max(0, buffer.length - 1)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (start + 4 > buffer.length) {
|
|
54
|
+
return {
|
|
55
|
+
status: FrameReadStatus.INCOMPLETE,
|
|
56
|
+
consumedBytes: start
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const length = hexToByte(buffer[start + 3] ?? "00") + 4;
|
|
60
|
+
if (length < 6) {
|
|
61
|
+
return {
|
|
62
|
+
status: FrameReadStatus.CORRUPT,
|
|
63
|
+
consumedBytes: start + 2
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if (start + length > buffer.length) {
|
|
67
|
+
return {
|
|
68
|
+
status: FrameReadStatus.INCOMPLETE,
|
|
69
|
+
consumedBytes: start
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const frame = buffer.slice(start, start + length);
|
|
73
|
+
if (calculateCrc8Pc(frame) !== hexToByte(frame.at(-1) ?? "00")) {
|
|
74
|
+
return {
|
|
75
|
+
status: FrameReadStatus.CORRUPT,
|
|
76
|
+
consumedBytes: start + 2
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
status: FrameReadStatus.COMPLETE,
|
|
81
|
+
consumedBytes: start + length,
|
|
82
|
+
frame
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
findHeader = buffer => {
|
|
86
|
+
for (let index = 0; index < buffer.length - 1; index += 1) {
|
|
87
|
+
if (hexToByte(buffer[index] ?? "00") === 0xaa && hexToByte(buffer[index + 1] ?? "00") === 0x55) {
|
|
88
|
+
return index;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return -1;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=sp20.protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["FrameReadStatus","calculateCrc8Pc","hexToByte","SP20_SERVICE","SP20_NOTIFY","SP20_WRITE","byte","value","toString","padStart","buildSp20Frame","token","type","payload","frame","length","map","decodeSp20Frame","at","undefined","content","slice","cipherText","parseSp20OximeterReading","flags","bloodOxygen","pulseRate","perfusionIndex","probeOff","pulseSearching","checkProbe","Sp20FrameReader","readFrame","buffer","start","findHeader","status","INCOMPLETE","consumedBytes","Math","max","CORRUPT","COMPLETE","index"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/viatom/sp20.protocol.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { MeasurementTypeKey } from "@ovok/core";
|
|
4
|
+
import { CaseType } from "../../../types/case-type.js";
|
|
5
|
+
import { calculateCrc8Pc } from "../../../utils/calculate-crc-8-pc.js";
|
|
6
|
+
import { buildSp20Frame, decodeSp20Frame, parseSp20OximeterReading } from "./sp20.protocol.js";
|
|
7
|
+
import { decryptLepuHandshake, decryptLepuPayload, encryptLepuPayload, parseLepuSessionKey, createLepuAccessToken } from "./viatom-lepu-crypto.js";
|
|
8
|
+
const command = (write, frame) => ({
|
|
9
|
+
...write,
|
|
10
|
+
frame,
|
|
11
|
+
withoutResponse: true
|
|
12
|
+
});
|
|
13
|
+
const validOxygen = value => value >= 50 && value <= 100;
|
|
14
|
+
const validPulse = value => value > 0 && value <= 300;
|
|
15
|
+
|
|
16
|
+
/** Handles the encrypted AA55 exchange used by the ViHealth SP-20 variants. */
|
|
17
|
+
export class Sp20Sequencer {
|
|
18
|
+
phase = "authenticate";
|
|
19
|
+
constructor(params) {
|
|
20
|
+
this.params = params;
|
|
21
|
+
}
|
|
22
|
+
initialCommands = () => {
|
|
23
|
+
const token = createLepuAccessToken(this.params.now?.() ?? new Date());
|
|
24
|
+
return [this.write(buildSp20Frame(0xff, 0x81, token))];
|
|
25
|
+
};
|
|
26
|
+
nextCommand = frame => {
|
|
27
|
+
const raw = decodeSp20Frame(frame);
|
|
28
|
+
if (!raw) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
const response = this.decodePayload(raw);
|
|
32
|
+
if (!response) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
if (this.phase === "authenticate") {
|
|
36
|
+
return this.acceptHandshake(raw, response);
|
|
37
|
+
}
|
|
38
|
+
if (this.phase === "clock" && response.token === 0x0f && response.type === 7) {
|
|
39
|
+
this.phase = "parameters";
|
|
40
|
+
return [this.encryptedCommand(0x84, [1])];
|
|
41
|
+
}
|
|
42
|
+
if (this.phase === "parameters" && response.token === 0x0f && response.type === 4) {
|
|
43
|
+
this.phase = "wave";
|
|
44
|
+
return [this.encryptedCommand(0x85, [1])];
|
|
45
|
+
}
|
|
46
|
+
if (this.phase === "wave" && response.token === 0x0f && response.type === 5) {
|
|
47
|
+
this.phase = "ready";
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
if (this.phase === "ready" && response.token === 0xf0 && response.type === 1) {
|
|
51
|
+
this.report(response.content);
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
};
|
|
55
|
+
decodePayload = response => {
|
|
56
|
+
if (response.token === 0xff && !this.sessionKey) {
|
|
57
|
+
return response;
|
|
58
|
+
}
|
|
59
|
+
if (!this.sessionKey) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
const decrypted = decryptLepuPayload(response.cipherText, this.sessionKey);
|
|
63
|
+
return decrypted?.length ? {
|
|
64
|
+
token: response.token,
|
|
65
|
+
type: decrypted[0] ?? 0,
|
|
66
|
+
content: decrypted.slice(1),
|
|
67
|
+
cipherText: response.cipherText
|
|
68
|
+
} : undefined;
|
|
69
|
+
};
|
|
70
|
+
acceptHandshake = (raw, response) => {
|
|
71
|
+
if (raw.token !== 0xff || raw.type !== 1) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
const key = parseLepuSessionKey(decryptLepuHandshake(response.content));
|
|
75
|
+
if (!key) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
this.sessionKey = key;
|
|
79
|
+
this.phase = "clock";
|
|
80
|
+
return [this.encryptedCommand(0x87, this.timePayload())];
|
|
81
|
+
};
|
|
82
|
+
encryptedCommand = (type, payload) => {
|
|
83
|
+
const encrypted = encryptLepuPayload([type, ...payload], this.sessionKey ?? []);
|
|
84
|
+
const frame = ["aa", "55", "0f", (encrypted.length + 1 & 0xff).toString(16).padStart(2, "0"), ...encrypted.map(value => value.toString(16).padStart(2, "0")), "00"];
|
|
85
|
+
frame[frame.length - 1] = calculateCrc8Pc(frame).toString(16).padStart(2, "0");
|
|
86
|
+
return this.write(frame);
|
|
87
|
+
};
|
|
88
|
+
timePayload = () => {
|
|
89
|
+
const date = this.params.now?.() ?? new Date();
|
|
90
|
+
return [date.getFullYear() >>> 8 & 0xff, date.getFullYear() & 0xff, date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()];
|
|
91
|
+
};
|
|
92
|
+
report = content => {
|
|
93
|
+
const reading = parseSp20OximeterReading(content);
|
|
94
|
+
if (!reading || reading.probeOff || reading.pulseSearching || reading.checkProbe || !validOxygen(reading.bloodOxygen) || !validPulse(reading.pulseRate)) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
this.params.onResult({
|
|
98
|
+
caseType: CaseType.RESULT,
|
|
99
|
+
measurementTypeKey: MeasurementTypeKey.bloodOxygenPulseRate,
|
|
100
|
+
bloodOxygen: reading.bloodOxygen,
|
|
101
|
+
pulseRate: reading.pulseRate,
|
|
102
|
+
...(reading.perfusionIndex > 0 ? {
|
|
103
|
+
perfusionIndex: reading.perfusionIndex
|
|
104
|
+
} : {}),
|
|
105
|
+
recordedAt: this.params.now?.() ?? new Date()
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
write = frame => command(this.params.write, frame);
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=sp20.sequencer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["MeasurementTypeKey","CaseType","calculateCrc8Pc","buildSp20Frame","decodeSp20Frame","parseSp20OximeterReading","decryptLepuHandshake","decryptLepuPayload","encryptLepuPayload","parseLepuSessionKey","createLepuAccessToken","command","write","frame","withoutResponse","validOxygen","value","validPulse","Sp20Sequencer","phase","constructor","params","initialCommands","token","now","Date","nextCommand","raw","undefined","response","decodePayload","acceptHandshake","type","encryptedCommand","report","content","sessionKey","decrypted","cipherText","length","slice","key","timePayload","payload","encrypted","toString","padStart","map","date","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","reading","probeOff","pulseSearching","checkProbe","bloodOxygen","pulseRate","onResult","caseType","RESULT","measurementTypeKey","bloodOxygenPulseRate","perfusionIndex","recordedAt"],"sourceRoot":"../../../../../../../src","sources":["modules/bt-management/services/devices/viatom/sp20.sequencer.ts"],"mappings":"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","ignoreList":[]}
|