2.1. 手环初次上电

手环初次上电开机之后会执行下列操作:

  1. 简单自检。

  2. 关闭所有传感器。

  3. 初始化NFC芯片,存储BLE的MAC地址(6个字节)和自检结果(1字节)。手机可以从NFC的天线端读取该数据。

  4. 开启BLE广播。

注意

为了节省电量,BLE广播是按照广播1秒,关闭1s这个循环工作的。负面影响是连接时间可能会变长,因为在广播关闭时手环是不能被连接的。后续可能会改变这个策略,但是对网关没有什么影响。

网关扫描并连接手环,然后通过 CougarRequest.settings 命令设置手环。

手环工作时会遵循以下原则。如果两条原则冲突,则以前一个原则为准。

  1. 充电时 传感器关闭,停止扫描beacon,打开ble广播

  2. 休眠时 传感器关闭,停止扫描beacon,关闭ble广播

  3. 唤醒时 传感器打开,开始扫描beacon,打开ble广播

  4. 已设置广播设置,断开ble连接时,若无新数据待上传 关闭ble广播

  5. 已设置广播设置,断开ble连接后,达到指定时间 打开ble广播

以下是手环广播和传感器采集的状态机(和最终版本略有不同,下次再更新最终版),仅供参考。

hide empty description

state STATE_INITIAL #FFFF77
[*] --> STATE_INITIAL

STATE_INITIAL --> joinBleAdvertise : EV_SERVICE_ADDED
state joinBleAdvertise <<join>>

joinBleAdvertise --> entryBleAdvertise

state BleAdvertise #LightBlue {
  state entryBleAdvertise <<entryPoint>>

  state bs as "BLE Advertise Start" <<start>>
  state bh as "H" <<history>>
  state sas1 as "start_advertise_scheduler" #Beige
  sas1 : 启动BLE广播scheduler
  sas1 : 超时时间为1s
  sas1 : BLE广播1s,停止1s

  bs --> sas1
  sas1  --> STATE_ADVERTISE_STOP

  state STATE_ADVERTISE_STOP #FFFF77
  state STATE_ADVERTISING #FFFF77
  STATE_ADVERTISE_STOP -->  STATE_ADVERTISING : EV_ADVERTISE_SCHEDULE_TIMEOUT
  STATE_ADVERTISING  --> STATE_ADVERTISE_STOP : EV_ADVERTISE_SCHEDULE_TIMEOUT
  state exitBleAdvertise <<exitPoint>>
}

state forkExitBleAdvertise <<fork>>

exitBleAdvertise --> forkExitBleAdvertise

state checkPendingData1 <<choice>>
state stopr1 as "stop_record" #lightsteelblue
forkExitBleAdvertise -up-> stopr1 : EV_SLEEP
state checkChargState1 <<choice>>

stopr1 -up-> checkChargState1

checkChargState1 -up-> checkPendingData1 : 没有在充电
checkChargState1 -up-> ssf1 : 在充电

state sbs1 as "stop_advertise_scheduler" #Coral
checkPendingData1 -up-> sbs1 : 没有未发送数据
sbs1 -up-> stop_advertise
stop_advertise -up-> STATE_SLEEP

state ssf1 as "set_sleep_flag" #LawnGreen
checkPendingData1 -up-> ssf1 : 有未发送的数据
ssf1 -up-> bh

state sartr1 as "start_record" #cornflowerblue
state usf1 as "unset_sleep_flag" #BurlyWood
forkExitBleAdvertise -up-> usf1: EV_WAKEUP

state checkChargState2 <<choice>>

usf1 -up-> checkChargState2
checkChargState2 -up-> sartr1 : 没有在充电
sartr1 -up-> bh
checkChargState2 -up-> bh : 在充电

state sbs2 as "stop_advertise_scheduler" #Coral
forkExitBleAdvertise --> sbs2 : EV_CONNECTED

state stopr2 as "stop_record" #lightsteelblue
forkExitBleAdvertise -up-> stopr2 : EV_PLUG_IN
stopr2 -up-> bh

state checkSleepFlag2 <<choice>>
forkExitBleAdvertise -up-> checkSleepFlag2 : EV_PLUG_OUT
state checkPendingData3 <<choice>>
checkSleepFlag2 -up-> checkPendingData3 : sleep标记为true
checkPendingData3 -up-> sbs1 : 没有未发送数据
checkPendingData3 -up-> bh : 有未发送的数据
checkSleepFlag2 -up-> sartr1 : sleep标记为false


state STATE_CONNECTED #FFFF77
sbs2 --> STATE_CONNECTED

state stopr3 as "stop_record" #lightsteelblue
STATE_CONNECTED --> stopr3 : EV_PLUG_IN
stopr3 --> STATE_CONNECTED

state checkSleepFlag3 <<choice>>
STATE_CONNECTED --> checkSleepFlag3 : EV_PLUG_OUT
checkSleepFlag3 --> STATE_CONNECTED : sleep标记为true
state sartr2 as "start_record" #cornflowerblue
checkSleepFlag3 --> sartr2 : sleep标记为false
sartr2 --> STATE_CONNECTED

state stopr4 as "stop_record" #lightsteelblue
STATE_CONNECTED --> stopr4 : EV_SLEEP
state ssf2 as "set_sleep_flag" #LawnGreen
stopr4 --> ssf2
ssf2 --> STATE_CONNECTED


state usf2 as "unset_sleep_flag" #BurlyWood
STATE_CONNECTED --> usf2 : EV_WAKEUP
state checkChargState3 <<choice>>
usf2 --> checkChargState3
state sartr3 as "start_record" #cornflowerblue
checkChargState3 --> sartr3 : 没有在充电

sartr3 --> STATE_CONNECTED

checkChargState3 --> STATE_CONNECTED : 在充电

STATE_CONNECTED -up-> try_perform_sleep_setting : EV_DISCONNECTED

state checkSleepFlag <<choice>>
try_perform_sleep_setting -up-> checkSleepFlag
state checChargeState1 <<choice>>
checkSleepFlag -up-> checChargeState1 : sleep标记为true
checChargeState1 -up-> checkPendingData2 : 没有在充电
checChargeState1 -up-> joinBleAdvertise : 在充电

checkSleepFlag -up-> checChargeState2 : sleep标记为false
state checChargeState2 <<choice>>
checChargeState2 -up-> joinBleAdvertise : 在充电


state checkPendingData4 <<choice>>
checChargeState2 -up-> try_perofrm_beacon_setting : 没有在充电
try_perofrm_beacon_setting -up-> try_start_record
try_start_record -up-> checkPendingData4

checkPendingData4 -up-> try_perform_adv_setting : 没有未发送的数据
checkPendingData4 -up-> joinBleAdvertise : 有未发送的数据

state STATE_IDLE #FFFF77
try_perform_adv_setting -up-> STATE_IDLE

state ssf3 as "set_sleep_flag" #LawnGreen
STATE_IDLE -up-> ssf3 : EV_SLEEP
ssf3 -up-> stopr5
state stopr5 as "stop_record" #lightsteelblue

state srs1 as "stop_re_advertise_schedule" #Orange
stopr5 -up-> srs1
srs1 -up-> checkPendingData2

state checkPendingData2 <<choice>>
checkPendingData2 -up-> joinBleAdvertise : 有未发送的数据
state STATE_SLEEP #FFFF77
checkPendingData2 -up-> STATE_SLEEP : 没有未发送数据

state usf3 as "unset_sleep_flag" #BurlyWood
STATE_SLEEP -up-> usf3 : EV_WAKEUP
state sartr4 as "start_record" #cornflowerblue
usf3 -up-> sartr4
sartr4 -up-> joinBleAdvertise
STATE_SLEEP -up-> joinBleAdvertise : EV_PLUG_IN
STATE_SLEEP --> checkPendingData2 : EV_NEED_RE_ADVERTISE


STATE_IDLE -up-> srs2 : EV_NEED_RE_ADVERTISE
state stops3 as "stop_sensors" #lightsteelblue
STATE_IDLE -up-> stops3 : EV_PLUG_IN
stops3 -up-> srs2

state usf4 as "unset_sleep_flag" #BurlyWood
STATE_IDLE -up-> usf4 : EV_WAKEUP
state sartr6 as "start_record" #cornflowerblue
usf4 -up-> sartr6
state srs2 as "stop_re_advertise_schedule" #Orange
sartr6 -up-> srs2
srs2 -up-> joinBleAdvertise