01DEA611-EFE9-4A3A-AA30-ED10C3C84F5501DEA611-EFE9-4A3A-AA30-ED10C3C84F5501DEA612-EFE9-4A3A-AA30-ED10C3C84F5501DEA612-EFE9-4A3A-AA30-ED10C3C84F5501DEA617-EFE9-4A3A-AA30-ED10C3C84F5501DEA617-EFE9-4A3A-AA30-ED10C3C84F5501DEA614-EFE9-4A3A-AA30-ED10C3C84F5501DEA614-EFE9-4A3A-AA30-ED10C3C84F5501DEA619-EFE9-4A3A-AA30-ED10C3C84F5501DEA619-EFE9-4A3A-AA30-ED10C3C84F5501DEA61A-EFE9-4A3A-AA30-ED10C3C84F5501DEA61A-EFE9-4A3A-AA30-ED10C3C84F5501DEA61E-EFE9-4A3A-AA30-ED10C3C84F5501DEA61E-EFE9-4A3A-AA30-ED10C3C84F5501DEA618-EFE9-4A3A-AA30-ED10C3C84F5501DEA618-EFE9-4A3A-AA30-ED10C3C84F5501DEA615-EFE9-4A3A-AA30-ED10C3C84F5501DEA615-EFE9-4A3A-AA30-ED10C3C84F5501DEA613-EFE9-4A3A-AA30-ED10C3C84F5501DEA613-EFE9-4A3A-AA30-ED10C3C84F5501DEA621-EFE9-4A3A-AA30-ED10C3C84F5501DEA622-EFE9-4A3A-AA30-ED10C3C84F5501DEA623-EFE9-4A3A-AA30-ED10C3C84F5501DEA624-EFE9-4A3A-AA30-ED10C3C84F5501DEA625-EFE9-4A3A-AA30-ED10C3C84F5501DEA626-EFE9-4A3A-AA30-ED10C3C84F5501DEA627-EFE9-4A3A-AA30-ED10C3C84F5501DEA628-EFE9-4A3A-AA30-ED10C3C84F5501DEA621-EFE9-4A3A-AA30-ED10C3C84F5501DEA622-EFE9-4A3A-AA30-ED10C3C84F5501DEA623-EFE9-4A3A-AA30-ED10C3C84F5501DEA624-EFE9-4A3A-AA30-ED10C3C84F5501DEA625-EFE9-4A3A-AA30-ED10C3C84F5501DEA626-EFE9-4A3A-AA30-ED10C3C84F5501DEA627-EFE9-4A3A-AA30-ED10C3C84F5501DEA628-EFE9-4A3A-AA30-ED10C3C84F55const mac: string = '<DEVICE_MAC>';
const service: string = '01DEA611-EFE9-4A3A-AA30-ED10C3C84F55';
read = async (frequency: string): Promise<Uint16Array> => {
const data: DataView = await BleClient.read(mac, service, frequency);
return new Uint16Array(data.buffer);
}
const f1: string = '01DEA621-EFE9-4A3A-AA30-ED10C3C84F55';
// Operation - 操作控制
const BLE_OP_CONTROL = '01DEA613-EFE9-4A3A-AA30-ED10C3C84F55';
const BLE_OP_CONTROL_VALUE = 0x04;
const op: Uint8Array = new Uint8Array([BLE_OP_CONTROL_VALUE]);
await BleClient.write(mac, BLE_LFT_POC, BLE_OP_CONTROL, new DataView(op.buffer));
// Reading - 读取数据
await BleClient.startNotifications(mac, service, f1, async () => {
// Notification received, reading values are ready
// 收到通知,读取值已就绪
const reading: Record<string, number[]> = {};
// Array of characteristics, from F1 to F8
// 光谱特征数组,从 F1 到 F8
for (let frequency of frequencies) {
const values: Uint16Array = read(frequency)
// Values is an array of 250 unsigned integers of this certain frequency
// values 是该频率对应的 250 个无符号整数数组
reading[frequency] = values;
}
console.log(reading);
});
01DEA617-EFE9-4A3A-AA30-ED10C3C84F55https://s3.eu-west-3.amazonaws.com/qassay.pre.public/firmwares/index.json01DEA617-EFE9-4A3A-AA30-ED10C3C84F55 获取硬件 ID 和软件 IDhttps://s3.eu-west-3.amazonaws.com/qassay.pre.public/firmwares/index.jsoninterface FirmwareIndex {
entries: FirmwareIndexEntry[];
}
interface FirmwareIndexEntry {
id: number;
code: number;
name: string;
uuid: string;
hardwareCodes: number[];
createdAt: Date;
}interface FirmwareIndex {
entries: FirmwareIndexEntry[];
}
interface FirmwareIndexEntry {
id: number;
code: number;
name: string;
uuid: string;
hardwareCodes: number[];
createdAt: Date;
}https://s3.eu-west-3.amazonaws.com/qassay.pre.public/firmwares/${firmware.uuid}/data.binhttps://s3.eu-west-3.amazonaws.com/qassay.pre.public/firmwares/${firmware.uuid}/data.bin2046a492-6798-422d-8dc6-0cf7d77299402046a492-6798-422d-8dc6-0cf7d77299402046a495-6798-422d-8dc6-0cf7d7729940 to check it matches the size of the original binary (optional, recommended especially for iOS)2046a492-6798-422d-8dc6-0cf7d7729940 无响应写入2046a492-6798-422d-8dc6-0cf7d7729940 的 Indicate 通知2046a495-6798-422d-8dc6-0cf7d7729940 检查是否与原始固件大小一致 (可选,iOS 平台强烈建议)const BLE_INSTALL_FIRMWARE_CHUNK_SIZE: number = 240;
const BLE_INSTALL_FIRMWARE_BLOCK_SIZE: number = 16;
enum BleFirmwareUpdateBaseAddressActionEnum {
StopAllUpload = 0x00,
StartUserDataUpload = 0x01,
StartApplicationFileUpload = 0x02,
EndOfFileTransfer = 0x06,
FileUploadFinish = 0x07,
CancelUpload = 0x08
}
export interface InstallFirmwareProgressInterface {
step: InstallFirmwareStepEnum;
total: number;
uploaded: number;
}
export enum InstallFirmwareStepEnum {
'START', // 开始
'WRITE_START_FILE_UPLOAD', // 写入启动文件上传
'WAITING_FOR_CONFIRMATION', // 等待确认
'UPLOAD_FIRMWARE', // 上传固件
'WRITE_END_OF_FILE_TRANSFER', // 写入结束文件传输
'WAITING_FOR_REBOOT', // 等待重启
'FINISHED', // 完成
'FAILED' // 失败
}
GET /calibration-stick/by-code/:code01DEA613-EFE9-4A3A-AA30-ED10C3C84F5GET /calibration-stick/by-code/:code01DEA613-EFE9-4A3A-AA30-ED10C3C84F5 依次写入 0x07 和 0x0301DEA616-EFE9-4A3A-AA30-ED10C3C84F5501DEA616-EFE9-4A3A-AA30-ED10C3C84F5501DEA616-EFE9-4A3A-AA30-ED10C3C84F55 写入字节 0x05 和 0x0001DEA616-EFE9-4A3A-AA30-ED10C3C84F55 写入字节 0x05 和 0x01{
"data": {
"F1": { ... },
"F2": { ... },
"F3": { ... },
"F4": { ... },
"F5": { ... },
"F6": { ... },
"F7": { ... },
"F8": { ... }
},
"normalizationData": {
"white": { "F1": xx, "F2": xx, "F3": xx, "F4": xx, "F5": xx, "F6": xx, "F7": xx, "F8": xx },
"black": { "F1": xx, "F2": xx, "F3": xx, "F4": xx, "F5": xx, "F6": xx, "F7": xx, "F8": xx }
},
"calibrationStick": { "id": 0 },
"reader": { "id": 0 }
}
POST /readers/:id/quality-checksPOST /readers/:id/check-calibrationPOST /readers/:id/quality-checksPOST /readers/:id/check-calibration| EN - Description | 中文 - 描述 | EN - Feedback | 中文 - 反馈 |
|---|---|---|---|
| USB/Charging Check: • If USB characteristic is enabled, device is charging • If USB characteristic is disabled, device is not charging |
USB/充电检查: • 若 USB 特征已启用,表示设备正在充电 • 若 USB 特征已禁用,表示设备未在充电 |
Error - Please contact your distributor | 错误 - 请联系您的经销商 |
| Low Battery Check: • Check device is not in low battery |
低电量检查: • 检查设备不处于低电量状态 |
Low battery - Please charge the device | 低电量 - 请给设备充电 |
| Normalization Data Check: • Check values are different to 0 and 32767 |
归一化数据检查: • 检查值不等于 0 和 32767 |
Error - Please contact your distributor | 错误 - 请联系您的经销商 |
| 1.8V Check: • Check voltage is okay |
1.8V 电压检查: • 检查电压是否正常 |
Error - Please contact your distributor | 错误 - 请联系您的经销商 |
| Product ID Check: • Hardware ID, SW ID and HW ID is not 0x00 |
产品 ID 检查: • 硬件 ID、软件 ID 及硬件 ID 不为 0x00 |
Error - Please contact your distributor | 错误 - 请联系您的经销商 |
| OTP Memory Free Space Check | OTP 内存可用空间检查 | Error - Please contact your distributor | 错误 - 请联系您的经销商 |
| EN - Description | 中文 - 描述 | EN - Feedback | 中文 - 反馈 |
|---|---|---|---|
| Device won't turn on | 设备无法开机 | Low battery - Please charge the device. If the LED does not switch on after the USB-C cable is connected, please contact your distributor. | 低电量 - 请给设备充电。若连接 USB-C 线缆后 LED 仍未亮起,请联系经销商。 |
| QR read is not available in the platform | 平台中无法读取该 QR 码 | Test not available - Please check the correct QR code is being read | 检测不可用 - 请确认正在读取的是正确的 QR 码 |
| Read UV QR with a White device | 用白色版设备读取紫外线检测卡 QR 码 | Test not available - Please check the correct QR code is being read | 检测不可用 - 请确认正在读取的是正确的 QR 码 |
| Bluetooth permission not granted | 未授予蓝牙权限 | Bluetooth permission required - Please grant permission to use the Bluetooth | 需要蓝牙权限 - 请授予使用蓝牙的权限 |
| Bluetooth is turned off | 蓝牙已关闭 | Bluetooth disabled - Please turn on the Bluetooth on your phone | 蓝牙已禁用 - 请在手机上开启蓝牙 |
| Camera permission not granted | 未授予相机权限 | Camera permission required - Please grant permission to use the camera | 需要相机权限 - 请授予使用相机的权限 |
| Device connection failed (wrong PIN) | 设备连接失败 (PIN 码错误) | Connection failed - Connection failed, make sure you introduced the correct PIN | 连接失败 - 请确认输入了正确的 PIN 码 |
| Device connection failed (device is off) | 设备连接失败 (设备已关机) | Connection failed - Make sure your device is on | 连接失败 - 请确认设备已开机 |
| Test removed too fast | 检测卡拔出过快 | Repeat reading - Please remove the test slower at a steady speed | 重新读取 - 请以稳定速度较慢地拔出检测卡 |
| Test removed too slow | 检测卡拔出过慢 | Repeat reading - Please remove the test faster at a steady speed | 重新读取 - 请以稳定速度较快地拔出检测卡 |
| Reading error (other) | 读取错误 (其他) | Repeat reading - Please remove the test at a steady speed | 重新读取 - 请以稳定速度拔出检测卡 |
| Read expired batch QR code | 读取了已过期的批次 QR 码 | Batch expired - Batch expired, please use a valid batch | 批次已过期 - 请使用有效批次的检测卡 |
| Test deemed invalid due to: (1) Long time after reaction time (2) Missing control line (3) Unexpected signal |
检测判定无效,原因: (1) 超出反应时间 (2) 缺少质控线 (3) 非预期信号 |
Invalid test - (1) The reaction time was exceeded, please repeat the process with a new test. (2) (3) Repeat procedure with a new test. | 无效检测 - (1) 反应时间已超过,请使用新的检测卡重新检测。(2)(3) 请使用新的检测卡重新检测。 |
| QC fails | 质控检查失败 | QC failed - Please contact your distributor | 质控失败 - 请联系您的经销商 |
| MAC does not exist in the database | MAC 地址不在数据库中 | Device not found - Please contact your distributor | 未找到设备 - 请联系您的经销商 |
| Failed update | 更新失败 | Update failed - Update failed, please retry the process | 更新失败 - 请重试更新流程 |
| The user gets out of the reading process mid process | 用户在读取过程中退出 | You are about to leave - You will receive a notification when the test is ready. Reading is discarded. | 您即将离开 - 检测就绪时将收到通知。当前读数将被丢弃。 |
| Resume test | 恢复检测 | You have a pending test, do you want to resume? If discarded, it won't appear on dashboard nor app if no readings exist. | 您有一个待处理的检测,是否恢复?若丢弃且无读数记录,则不会显示在仪表盘和 App 中。 |
| Internet connection lost | 网络连接丢失 | Please make sure you are connected to the internet to use the device | 请确保已连接互联网以使用设备 |
GET https://api.qassay.com/documentation#/Strips/StripController_getByCodeGET https://api.qassay.com/documentation#/Strips/StripController_getByCodePOST https://api.qassay.com/documentation#/Samples/SampleController_createPOST https://api.qassay.com/documentation#/Samples/SampleController_createGET https://api.qassay.com/documentation#/Samples/SampleController_getTimerGET https://api.qassay.com/documentation#/Samples/SampleController_getTimerGET https://api.qassay.com/documentation#/Readers/ReaderController_getByMacGET https://api.qassay.com/documentation#/Readers/ReaderController_getByMacPOST /samples/{id}/validate{
"id": 0,
"attemptNumber": 0,
"key": "string",
"result": {
"id": 0,
"status": "Error", // Error or OK
"error": "ExtractionTooFast" // Error codes
},
"createdAt": "2025-06-16T09:57:23.766Z",
"updatedAt": "2025-06-16T09:57:23.766Z"
}POST /samples/{id}/validate{
"id": 0,
"attemptNumber": 0,
"key": "string",
"result": {
"id": 0,
"status": "Error", // Error 或 OK
"error": "ExtractionTooFast" // 错误码
},
"createdAt": "2025-06-16T09:57:23.766Z",
"updatedAt": "2025-06-16T09:57:23.766Z"
}| EN - Error | 中文 - 错误 | EN - Description / Action | 中文 - 描述 / 操作 |
|---|---|---|---|
| ExtractionTooFast | 拔出过快 | Extraction was done too fast. Action: Repeat reading slower, as shown in the video. If encountered TooFast/TooSlow 10 times in a row, ask the user to use another test. | 拔出速度过快。操作: 如视频所示以较慢速度重新读取。若连续 10 次出现过快/过慢,提示用户更换检测卡。 |
| ExtractionTooSlow | 拔出过慢 | Extraction was done too slow. Action: Repeat reading faster, as shown in the video. If encountered TooFast/TooSlow 10 times in a row, ask the user to use another test. | 拔出速度过慢。操作: 如视频所示以较快速度重新读取。若连续 10 次出现过快/过慢,提示用户更换检测卡。 |
| MissingControlLine | 缺少质控线 | The control line on the test was not found. Action: Invalid test, ask the user to repeat the test. If encountered 3 times in a row, ask the user to use another test. | 未检测到质控线。操作: 无效检测,提示用户重新检测。若连续 3 次出现,提示用户更换检测卡。 |
| Other | 其他错误 | Used when non-parsed errors are detected. Action: Repeat reading. If encountered 3 times in a row, ask the user to use another test. | 用于未解析的错误。操作: 重新读取。若连续 3 次出现,提示用户更换检测卡。 |
POST https://api.qassay.com/documentation#/Samples/SampleController_uploadPOST https://api.qassay.com/documentation#/Samples/SampleController_upload| Property / 属性 | FSH | LH | Progesterone / 孕酮 | AMH | β-HCG | Vitamin D / 维生素D | TSH | Estradiol / 雌二醇(E2) |
|---|---|---|---|---|---|---|---|---|
| strip-type-id / 检测卡类型ID | 502 | 430 | 368 | 369 | 485 | 494 | 457 | 494 |
| Light / 光源类型 | Ultra-violet / 紫外线 | |||||||
| sampleTypes / 样本类型 (校正因子) |
Serum/血清: 1 Plasma/血浆: 1 Blood/全血: 1.5 |
Serum: 1 Plasma: 1 Blood: 2 |
Serum: 1 Plasma: 1 Blood: 1.5 / 1.3 |
Serum: 1 Plasma: 1 Blood: 1.5 |
||||
| Sampling / 反应时间 (秒) | 900 | |||||||
| maxReactionTime / 最大允许读数时间 (秒) | 180 | |||||||
| sampleWellOrientation / 样本孔方向 | analytes-control / 分析物-质控 | |||||||
| Property / 属性 | FSH | LH | Progesterone | AMH | β-HCG | Vitamin D | TSH | E2 |
|---|---|---|---|---|---|---|---|---|
| Analyte ID | 31 | 26 | 7 | 8 | 24 | 22 | 28 | 23 |
| Analyte Name / 分析物名称 | FSH | LH | Progesterone / 孕酮 | AMH | β-HCG | Vitamin D / 维生素D | TSH | E2 / 雌二醇 |
| rangeMin / 最小范围 | 0.2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| rangeMax / 最大范围 | 150 | 100 | 60 | 16 | 20000 | 100 | 100 | 3000 |
| cutOff / 截断值 | 0.2 | 5 | 0.5 | 0.1 | 5 | 5 | 0.1 | 5 |
| Unit / 单位 | mIU/mL | mIU/L | ng/mL | ng/mL | mIU/mL | ng/mL | uIU/mL | pg/mL |
| assayMethod / 检测方法 | Sandwich / 夹心法 | |||||||
| EN - Property | 中文 - 属性 | EN - Description | 中文 - 描述 |
|---|---|---|---|
| strip-type-id | 检测卡类型 ID | strip-type-id information is gathered | 收集检测卡类型 ID 信息 |
| manufacturingDate (timestamp) | 生产日期 (时间戳) | Timestamp of manufacturing date | 生产日期时间戳 |
| expiryDate (timestamp) | 有效期 (时间戳) | Timestamp of expiration date | 有效期时间戳 |
| Traceability / 可追溯性 | 可追溯性 |
- Individual traceability: Serial number applied to the manufacturing batch (e.g., VD 28374648 0000). These codes can only be read once. - Lot traceability: Lot number can be read indefinitely. |
- 个体追溯: 应用于生产批次的序列号 (例如: VD 28374648 0000)。这些编码仅可读取一次。 - 批次追溯: 批号可无限次读取。 |
| Rev 版本 | Date 日期 | Author 作者 | EN - Description | 中文 - 描述 |
|---|---|---|---|---|
| A | 2025-12-09 | I. Aurrekoetxea | New document | 新建文档 |
| B | 2025-12-10 | I. Aurrekoetxea | Added QC and FUOTA | 新增 QC 质控流程和 FUOTA 固件更新章节 |
| B-CN-MGMT-001 | 2026-06-22 | Claude / 项目协作 | Added local document management log and recovery reference for later command-integration requirement analysis. The source technical content remains unchanged. | 新增本地文档管理记录与恢复参考,供后续指令对接需求分析使用。原始技术内容未变更。 |
| B-CN-COMMENT-001 | 2026-06-22 | Claude / 项目协作 | Added self-contained local Word-like comment and reply feature. | 新增本地自包含批注与回复功能。 |
| B-CN-COMMENT-002 | 2026-06-22 | Claude / 项目协作 | Upgraded comment persistence from browser-local localStorage to embedded HTML comment data for repository-shareable multi-person review. Added explicit updated-HTML export/save workflow and legacy localStorage migration. | 将批注持久化方式由浏览器本地 localStorage 升级为 HTML 内嵌批注数据,支持随文件进入仓库进行多人共享;新增导出/保存更新后 HTML 的显式流程,并支持旧版本地批注迁移。 |
| B-CN-COMMENT-003 | 2026-06-23 | Claude / 项目协作 | Changed the comment system to Cloudflare Pages Functions with KV persistence and shared password validation for adding comments and replies. | 将批注系统调整为 Cloudflare Pages Functions + KV 持久化,并新增添加批注/回复时的共享密码校验。 |
| 日期 | 记录类型 | 文件/位置 | 说明 | 恢复方式 |
|---|---|---|---|---|
| 2026-06-22 | 基线备份 | 文档备份/CN_D006-PIB21001_revB_Qassay SDK_baseline_20260622.html | 在新增管理记录前保存当前 HTML 文档基线,便于后续需求分析、指令对接和差异比对。 | 如需恢复,可用该备份文件覆盖当前 HTML 文档;覆盖前建议先另存当前版本。 |
| 2026-06-22 | 管理机制建立 | 本文档底部:文档修订历史、文档管理记录 | 明确后续所有基于本文档的需求分析、指令对接说明、翻译校正、接口含义补充,都需要在“文档修订历史”中新增记录;涉及文件级变更或备份/恢复动作时,同时维护“文档管理记录”。 | 查看本表定位可恢复文件;若需精确恢复某次变更,请优先使用最近一次备份,再结合修订历史确认差异。 |
| 2026-06-22 | 批注功能实施前备份 | 文档备份/CN_D006-PIB21001_revB_Qassay SDK_before_comments_20260622.html | 在新增 Word 式批注与回复功能前保存当前 HTML,便于回退到无批注功能版本。 | 恢复前先备份当前文件,再用该备份覆盖当前 HTML。 |
| 2026-06-22 | 批注功能实现 | 本文档:批注 CSS、批注面板、运行时脚本;legacy localStorage key: qassay-sdk-comments:CN_D006-PIB21001_revB | 新增本地自包含批注功能,支持选择正文添加批注、回复、解决/重新打开、删除、JSON 导出/导入。该版本最初使用浏览器 localStorage;后续已升级为 HTML 内嵌批注数据。 | HTML 功能可通过实施前备份恢复;旧 localStorage 批注可由升级后的页面检测并迁移到 HTML 内嵌数据。 |
| 2026-06-22 | 内嵌批注升级前备份 | 文档备份/CN_D006-PIB21001_revB_Qassay SDK_before_embedded_comments_20260622.html | 在将批注持久化从浏览器 localStorage 升级为 HTML 内嵌数据前保存当前版本,便于回退到本地批注版本。 | 恢复前先备份当前文件,再用该备份覆盖当前 HTML。 |
| 2026-06-22 | 批注持久化升级 | 本文档:HTML 内嵌批注数据块、批注面板、运行时脚本、导出更新后的 HTML | 批注以 HTML 内嵌 JSON 为主数据源,支持随文件进入外部仓库多人共享。新增/修改批注后需点击“导出更新后的 HTML”或“保存 HTML 文件”,再替换原文件并提交仓库。 | HTML 可通过升级前备份恢复;批注可从 HTML 内嵌 JSON 或“备份 JSON”恢复。 |
| 2026-06-23 | Cloudflare KV 密码批注升级前备份 | 文档备份/CN_D006-PIB21001_revB_Qassay SDK_before_cloudflare_kv_password_comments_20260623.html | 在将批注系统调整为 Cloudflare Pages Functions + KV + 共享密码前保存当前 HTML 版本。 | 恢复前先备份当前文件,再用该备份覆盖当前 HTML。 |
| 2026-06-23 | Cloudflare KV 批注功能实现 | 本文档、comment-system.js、functions/api/comments/*、comments.schema.json、comments.seed.json | 批注数据改由 Cloudflare KV 持久保存;新增/回复批注需输入共享密码,默认 SZY123;KV binding 名称为 COMMENTS_KV;comments.json 可通过 /api/comments/export 导出。 | HTML 可通过升级前备份恢复;批注数据以 Cloudflare KV 为准,可通过导出 comments.json 备份。 |