Allwell Connect SDK

Version 1.0.0 Android API 29+

1. แนะนำ SDK (Introduction)

Allwell Connect SDK เป็นไลบรารีสำหรับนักพัฒนา (Android) เพื่อใช้ในการค้นหาและเชื่อมต่อกับอุปกรณ์ตรวจวัดสุขภาพแบบไร้สาย (Bluetooth LE) ของแบรนด์ Allwell เช่น เครื่องชั่งน้ำหนัก, เครื่องวัดความดัน, เครื่องวัดน้ำตาล ฯลฯ โดย SDK นี้ได้ซ่อนความซับซ้อนของการเชื่อมต่อระดับล่างเอาไว้ ทำให้พัฒนาแอปพลิเคชันได้รวดเร็วและปลอดภัยยิ่งขึ้น

2. การติดตั้ง (Installation)

2.1 นำไฟล์ SDK เข้าโปรเจกต์

นำไฟล์ AllwellConnectSDK-release.aar ไปวางไว้ในโฟลเดอร์ app/libs/ และเพิ่ม Dependencies:

dependencies {
    // นำเข้า Allwell Connect SDK
    implementation(files("libs/AllwellConnectSDK-release.aar"))
    
    // ไลบรารีพื้นฐานที่ SDK จำเป็นต้องใช้งาน
    implementation("androidx.core:core-ktx:1.12.0")
    implementation("androidx.appcompat:appcompat:1.6.1")
}

2.2 การขอสิทธิ์ (Permissions)

เพิ่มสิทธิ์การใช้งาน Bluetooth ใน AndroidManifest.xml:

<!-- สำหรับ Android 11 ลงไป -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<!-- สำหรับ Android 12 (API 31) ขึ้นไป -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
⚠️
ข้อควรระวัง: บน Android 6.0 ขึ้นไป คุณต้องเขียนโค้ดเพื่อขอสิทธิ์ Runtime Permissions จากผู้ใช้ก่อนเรียกใช้งาน SDK เสมอ

3. การเตรียมตัวก่อนใช้งาน (Initialization)

ก่อนเรียกใช้งานคำสั่งใดๆ จะต้องทำการ Initialize ด้วย Secret Key ก่อนเสมอ

import com.allwell.connectsdk.AllwellSDK

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // กำหนด Secret Key ที่ Generate มาสำหรับ Application ID ของคุณ
        val secretKey = "YOUR_BASE64_SECRET_KEY_HERE"
        val isSuccess = AllwellSDK.initialize(this, secretKey)
        
        if (isSuccess) {
            println("SDK พร้อมใช้งาน")
        }
    }
}

4. การสแกนหาอุปกรณ์ (Scanning)

val scanCallback = object : AllwellSDK.AllwellScanCallback {
    override fun onDeviceScanned(device: AllwellDevice) {
        println("พบอุปกรณ์: ${device.name} [${device.macAddress}]")
    }

    override fun onScanFailed(errorCode: Int, message: String) {
        println("การสแกนล้มเหลว: $message")
    }
}

AllwellSDK.registerScanCallback(scanCallback)
AllwellSDK.scanDevices(10000) // สแกน 10 วินาที

5. การเชื่อมต่อและรูปแบบข้อมูล (Connection & Data Models)

เมื่อสแกนเจออุปกรณ์ ให้สร้าง Controller ตามประเภทของอุปกรณ์เพื่อทำการเชื่อมต่อ

5.1 เครื่องชั่งน้ำหนักอัจฉริยะ (Weight Scale)

ออบเจกต์ WeightData จะคืนค่า weightKg และ bmi แต่จุดสำคัญคือ rawData ซึ่งเป็นออบเจกต์ของ ICWeightData ที่บรรจุค่าเชิงลึกทั้งหมด ดังนี้:

ค่าวัดพื้นฐาน (Basic Metrics):
  • weight_kg: น้ำหนัก (กิโลกรัม)
  • bmi: ดัชนีมวลกาย
  • bodyFatPercent: ไขมันในร่างกาย (%)
  • subcutaneousFatPercent: ไขมันใต้ผิวหนัง (%)
  • visceralFat: ไขมันในช่องท้อง
  • musclePercent: มวลกล้ามเนื้อ (%)
  • smPercent: กล้ามเนื้อลาย Skeletal Muscle (%)
ค่าวัดเชิงลึก (Advanced Metrics):
  • bmr: อัตราการเผาผลาญ (kcal)
  • boneMass: มวลกระดูก (กิโลกรัม)
  • moisturePercent: น้ำในร่างกาย (%)
  • proteinPercent: โปรตีน (%)
  • physicalAge: อายุร่างกาย (ปี)
  • hr: อัตราการเต้นหัวใจ (หากเครื่องรองรับ)
  • bodyScore: คะแนนร่างกายรวม (0-100)

ค่าการประเมินและการควบคุม (Evaluation & Control):

ℹ️
หมายเหตุ: เครื่องชั่งน้ำหนักจำเป็นต้องใช้ข้อมูล User Profile (อายุ, ส่วนสูง, เพศ) ในการสั่ง connect() เพื่อคำนวณค่าเหล่านี้ออกมาให้ถูกต้อง
val weightController = AllwellSDK.createWeightScaleController()
weightController.registerCallback(object : AllwellCallback {
    override fun onConnectionResult(response: AllwellResponse<AllwellDevice>) { }
    override fun onBatteryResult(response: AllwellResponse<Int>) { }

    override fun onDataResult(response: AllwellResponse<AllwellData>) {
        if (response.data is AllwellData.WeightData) {
            val data = response.data as AllwellData.WeightData
            val raw = data.rawData
            
            if (raw != null) {
                println("--- ค่าพื้นฐาน ---")
                println("น้ำหนัก: ${raw.weight_kg} kg, BMI: ${raw.bmi}")
                println("ไขมัน: ${raw.bodyFatPercent}%, ไขมันใต้ผิวหนัง: ${raw.subcutaneousFatPercent}%")
                println("ไขมันช่องท้อง: ${raw.visceralFat}, กล้ามเนื้อ: ${raw.musclePercent}%")
                
                println("--- ค่าเชิงลึก ---")
                println("กล้ามเนื้อลาย: ${raw.smPercent}%, น้ำ: ${raw.moisturePercent}%")
                println("กระดูก: ${raw.boneMass}kg, โปรตีน: ${raw.proteinPercent}%")
                println("BMR: ${raw.bmr} kcal, อายุร่างกาย: ${raw.physicalAge} ปี")
                println("คะแนนร่างกาย: ${raw.bodyScore}, ชีพจร (HR): ${raw.hr} bpm")
                
                println("--- การประเมิน ---")
                println("ประเภทร่างกาย: ${raw.bodyType}, ระดับความอ้วน: ${raw.obesityDegree}")
                println("เป้าหมาย: ${raw.targetWeight}kg, ปรับน้ำหนัก: ${raw.weightControl}kg")
            }
        }
    }
})

// สร้างโปรไฟล์ผู้ใช้
val profile = AllwellUserProfile(age = 25, heightCm = 170, isMale = true)
weightController.connect(scannedDevice, profile)

5.2 เครื่องวัดความดันโลหิต (Blood Pressure Monitor)

val bpController = AllwellSDK.createBloodPressureController()
bpController.registerCallback(object : AllwellCallback {
    override fun onConnectionResult(response: AllwellResponse<AllwellDevice>) { }
    override fun onBatteryResult(response: AllwellResponse<Int>) { }
    
    override fun onDataResult(response: AllwellResponse<AllwellData>) {
        if (response.data is AllwellData.BloodPressureData) {
            val bp = response.data as AllwellData.BloodPressureData
            println("ความดันตัวบน (Systolic): ${bp.systolic} mmHg")
            println("ความดันตัวล่าง (Diastolic): ${bp.diastolic} mmHg")
            println("อัตราการเต้นหัวใจ (Pulse): ${bp.pulse} bpm")
        }
    }
})
bpController.connect(scannedDevice)

5.3 เครื่องตรวจวัดน้ำตาลในเลือด (Glucose Meter)

val glucoseController = AllwellSDK.createGlucoseMeterController()
glucoseController.registerCallback(object : AllwellCallback {
    override fun onConnectionResult(response: AllwellResponse<AllwellDevice>) { }
    override fun onBatteryResult(response: AllwellResponse<Int>) { }
    
    override fun onDataResult(response: AllwellResponse<AllwellData>) {
        if (response.data is AllwellData.GlucoseData) {
            val glucose = response.data as AllwellData.GlucoseData
            println("ระดับน้ำตาลในเลือด: ${glucose.glucoseMgDl} mg/dL")
            println("ช่วงเวลาที่วัด: ${glucose.mealContext}")
        }
    }
})
glucoseController.connect(scannedDevice)

5.4 เครื่องวัดออกซิเจนปลายนิ้ว (Pulse Oximeter)

val oxiController = AllwellSDK.createPulseOximeterController()
oxiController.registerCallback(object : AllwellCallback {
    override fun onConnectionResult(response: AllwellResponse<AllwellDevice>) { }
    override fun onBatteryResult(response: AllwellResponse<Int>) { }
    
    override fun onDataResult(response: AllwellResponse<AllwellData>) {
        if (response.data is AllwellData.PulseOximeterData) {
            val oxi = response.data as AllwellData.PulseOximeterData
            println("ระดับออกซิเจนในเลือด (SpO2): ${oxi.spo2}%")
            println("อัตราการเต้นหัวใจ (Pulse Rate): ${oxi.pulseRate} bpm")
        }
    }
})
oxiController.connect(scannedDevice)

5.5 ปรอทวัดไข้ / เครื่องวัดอุณหภูมิ (Thermometer)

val thermoController = AllwellSDK.createThermometerController()
thermoController.registerCallback(object : AllwellCallback {
    override fun onConnectionResult(response: AllwellResponse<AllwellDevice>) { }
    override fun onBatteryResult(response: AllwellResponse<Int>) { }
    
    override fun onDataResult(response: AllwellResponse<AllwellData>) {
        if (response.data is AllwellData.ThermometerData) {
            val thermo = response.data as AllwellData.ThermometerData
            println("อุณหภูมิร่างกาย: ${thermo.temperatureCelsius} °C")
        }
    }
})
thermoController.connect(scannedDevice)

5.6 สายวัดสัดส่วนร่างกายอัจฉริยะ (Smart Body Tape)

val tapeController = AllwellSDK.createBodyTapeController()
tapeController.registerCallback(object : AllwellCallback {
    override fun onConnectionResult(response: AllwellResponse<AllwellDevice>) { }
    override fun onBatteryResult(response: AllwellResponse<Int>) { }
    
    override fun onDataResult(response: AllwellResponse<AllwellData>) {
        if (response.data is AllwellData.BodyTapeData) {
            val tape = response.data as AllwellData.BodyTapeData
            println("ความยาวสัดส่วนที่วัดได้: ${tape.lengthCm} cm")
        }
    }
})
tapeController.connect(scannedDevice)

5.7 เครื่องวัดความเค็ม / โซเดียมในอาหาร (Salinity Meter)

val saltController = AllwellSDK.createSalinityMeterController()
saltController.registerCallback(object : AllwellCallback {
    override fun onConnectionResult(response: AllwellResponse<AllwellDevice>) { }
    override fun onBatteryResult(response: AllwellResponse<Int>) { }
    
    override fun onDataResult(response: AllwellResponse<AllwellData>) {
        if (response.data is AllwellData.SalinityData) {
            val salt = response.data as AllwellData.SalinityData
            println("ความเค็ม/โซเดียม: ${salt.salinityPercentage}%")
            println("อุณหภูมิอาหาร: ${salt.temperatureCelsius} °C")
        }
    }
})
saltController.connect(scannedDevice)

5.8 การยกเลิกการเชื่อมต่อ (Disconnect)

เมื่อใช้งานเสร็จสิ้น หรือเปลี่ยนหน้าจอ ควรยกเลิกการเชื่อมต่อเสมอเพื่อประหยัดแบตเตอรี่และเคลียร์แคช

controller.disconnect()
controller.unregisterCallback(deviceCallback)

6. โหมดจำลอง (Simulator Mode)

สำหรับนักพัฒนาที่ต้องการทดสอบการจัด Layout หรือเขียนโค้ดโดยที่ยังไม่มีฮาร์ดแวร์จริงอยู่กับตัว สามารถเปิด Simulator Mode ได้ โดยเมื่อสั่งสแกนหรือเชื่อมต่อ SDK จะตอบกลับด้วยข้อมูลจำลอง (Mock Data) เสมือนกำลังทำงานกับอุปกรณ์จริง

// เปิดโหมดจำลอง (ควรเรียกหลัง initialize)
AllwellSDK.enableSimulator(true)