wildlifeai / wildlife-watcher-mobile-app

Mobile app to communicate with the Wildlife Watchers
Other
3 stars 1 forks source link

Add capability to display the device's battery status #11

Closed victor-wildlife closed 7 months ago

victor-wildlife commented 9 months ago

@Burzo should try to follow the steps provided by Charles in section 7 of the architectures_for_app_developer_24_nov_23.

I am open to discussion but I believe the first task the mobile app should achieve is to display the device's battery status. This will prove the app connects to the device. Once we have the BLE connection milestone we can add the LoRaWAN capabilities.

acutetech commented 9 months ago

Right now I am unable to try a real WW120.D00 with BLE comms, to test the messages. However the attached C function shows the source code of the messages that the WW120.D00 (behaving as a predator trap) responds to.

If you can follow the code, the STM32WL32 processor checks if the string arriving from the BLE chip is "enable" - if so it sets the flag enable_triggers true and responds with "PH Sensor messages are enabled\n". The BLE processor recognises the "PH " characters as a messages that it should send to the phone. It sends the rest of the string ("Sensor messages are enabled\n") via a BLE message to the phone.

In the same way you can see the other messages that the current WW120.D00 boards process - including the "disable" and "battery"

`/**

void app_rewild_process_ph_message(char msg) { uint8_t eui; uint16_t vbat; // for calculating and printing Vbat uint8_t decimal; // decimal part of volatge. ble_sm_event_t bump; // buffer for BLE Tx output char outBuffer[PHTXMSGLENGTH]; char * params; //pointer to substring uint8_t value[PARAMETERAPPKEYLENGTH]; // for AppKey and AppEui char byteChars[3]; // 2 characters plus trailing \0

memset (outBuffer, 0, PHTXMSGLENGTH);

if (strncmp(msg, "enable", 6) == 0) {
    enable_triggers = true;

    snprintf(outBuffer, PHTXMSGLENGTH, "PH Sensor messages are enabled\n");
}

else if (strncmp(msg, "disable", 7) == 0) {
    enable_triggers = false;

    snprintf(outBuffer, PHTXMSGLENGTH, "PH Sensor messages are disabled\n");
}

else if (strncmp(msg, "status", 6) == 0) {
    snprintf(outBuffer, PHTXMSGLENGTH, "PH Trap is %s. Sensor is %s. Seq = %d\n",
            ((sensorIsTriggered) ? "sprung" : "set"), (enable_triggers ? "enabled": "disabled"), sequence);
}

else if (strncmp(msg, "battery", 7) == 0) {
    vbat = (uint16_t) GetBatteryLevel();    // apparenty a value between 1 and 254 - TODO find out how this is calculated
    vbat = vbat * 33;
    vbat = vbat / 256;  // now converted to a value between 0 and 33
    decimal = vbat % 10;    // This is the decimal part
    vbat = vbat / 10;
    snprintf(outBuffer, PHTXMSGLENGTH, "PH Battery = %d.%dV\n", vbat, decimal);
}

else if (strncmp(msg, "id", 2) == 0) {
    // DevEui
    eui = SecureElementGetDevEui();

    snprintf(outBuffer, PHTXMSGLENGTH, "PH DevEui: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
            eui[0], eui[1], eui[2], eui[3], eui[4], eui[5], eui[6], eui[7]);
}

else if (strncmp(msg, "ver", 3) == 0) {

ifdef BOARD_WW120_C00

    snprintf(outBuffer, PHTXMSGLENGTH, "PH WW120-C00 %s %s\n", __TIME__, __DATE__);

endif // BOARD_WW120_C00

ifdef BOARD_WW120_D00

    snprintf(outBuffer, PHTXMSGLENGTH, "PH WW120-D00 %s %s\n", __TIME__, __DATE__);

endif // BOARD_WW120_C00

    // TODO CONSIDER SENDING THIS
    //      sprintf(outBuffer, "LoRa V%X.%X.%X RC %X\n",
    //          (uint8_t)(APP_VERSION_MAIN),
    //          (uint8_t)(APP_VERSION_SUB1),
    //          (uint8_t)(APP_VERSION_SUB2),
    //          (uint8_t)(APP_VERSION_RC));
}
else if (strncmp(msg, "get heartbeat", 13) == 0) {
    // Get ping period
    snprintf(outBuffer, PHTXMSGLENGTH,
            "PH heartbeat is %s\n", pingIntervalString(getPingInterval(pingPeriod, pingUnits)));
}

else if (strncmp(msg, "heartbeat ", 10) == 0) {
    // set ping period
    params = &msg[10];

    APP_LOG(TS_OFF, VLEVEL_M, "DEBUG: params '%s'\r\n", params);

    if (setPingFrom(params)) {
        snprintf(outBuffer, PHTXMSGLENGTH, "PH heartbeat %s = OK\n", params);
    }
    else {
        snprintf(outBuffer, PHTXMSGLENGTH, "PH heartbeat %s = error\n", params);
    }
}

else if (strncmp(msg, "get appeui", 10) == 0) {
    // print AppEui
    flash_getParameter(Flash_parameter_joinEui, value, PARAMETERAPPEUILENGTH);
    snprintf(outBuffer, PHTXMSGLENGTH, "PH AppEui ");
    for (uint8_t i=0; i< PARAMETERAPPEUILENGTH; i++) {
        snprintf(byteChars, 3, "%02X", value[i]);   // One byte as hex characters
        strncat(outBuffer, byteChars, PHTXMSGLENGTH - strlen(outBuffer) - 1);
    }
    strncat(outBuffer, "\n", PHTXMSGLENGTH - strlen(outBuffer) - 1);
    APP_LOG(TS_OFF, VLEVEL_M, "DEBUG: sending '%s'\r\n", outBuffer);
}

else if (strncmp(msg, "get appkey", 10) == 0) {
    // print AppEui
    flash_getParameter(Flash_parameter_appKey, value, PARAMETERAPPKEYLENGTH);
    snprintf(outBuffer, PHTXMSGLENGTH, "PH AppKey ");
    for (uint8_t i=0; i< PARAMETERAPPKEYLENGTH; i++) {
        snprintf(byteChars, 3, "%02X", value[i]);   // One byte as hex characters
        strncat(outBuffer, byteChars, PHTXMSGLENGTH - strlen(outBuffer) - 1);
    }
    strncat(outBuffer, "\n", PHTXMSGLENGTH - strlen(outBuffer) - 1);
    APP_LOG(TS_OFF, VLEVEL_M, "DEBUG: sending '%s'\r\n", outBuffer);
}

else if (strncmp(msg, "appeui ", 7) == 0) {
    // set AppEui
    params = &msg[7];

    if (setAppEuiFrom(params)) {
        snprintf(outBuffer, PHTXMSGLENGTH, "PH AppEui updated.\n");
    }
    else {
        snprintf(outBuffer, PHTXMSGLENGTH, "PH AppEui %s = error.\n", params);
    }
}

else if (strncmp(msg, "appkey ", 7) == 0) {
    // set AppKey
    params = &msg[7];

    if (setAppKeyFrom(params)) {
        snprintf(outBuffer, PHTXMSGLENGTH, "PH AppKey updated.\n");
    }
    else {
        snprintf(outBuffer, PHTXMSGLENGTH, "PH AppKey %s = error\n", params);
    }
}

else if (strncmp(msg, "reset", 5) == 0) {
    // Reset the LoRa-e5 - needed after changing appKey or AppEui
    snprintf(outBuffer, PHTXMSGLENGTH, "PH Device will reset after disconnecting.\n");
    ble_stateMachine_requestReset();
}

else if (strncmp(msg, "erase", 5) == 0) {
    // Reset the LoRa-e5 - needed after changing appKey or AppEui
    snprintf(outBuffer, PHTXMSGLENGTH, "PH NVM will be erased after disconnecting.\n");
    ble_stateMachine_requestErase();
}

else if (strncmp(msg, "ping", 4) == 0) {
    // Request a ping message now.
    // It might be useful to report the result of the ping
    app_rewild_restart_ping_timer();
    bumpFromPing();
    snprintf(outBuffer, PHTXMSGLENGTH, "PH Sending ping\n");
}

// TODO figure out a way to send multiple lines...

// else if (strncmp(uart_msg, "help", 4) == 0) { // // print help messages // snprintf(outBuffer, PHTXMSGLENGTH, "PH Available commands:\n"); // snprintf(outBuffer, PHTXMSGLENGTH, "PH enable - enables sensor messages\n"); // snprintf(outBuffer, PHTXMSGLENGTH, "PH disable - disables sensor messages\n"); // snprintf(outBuffer, PHTXMSGLENGTH, "PH heartbeat - sets heartbeat period. e.g.:\n"); // snprintf(outBuffer, PHTXMSGLENGTH, "PH '10 minutes', '4 hours', '1 day' \n"); // snprintf(outBuffer, PHTXMSGLENGTH, "PH ver - prints software version\n"); // }

else {
    // command not recognised
}

if (strlen(outBuffer) > 0) {
    bump.event = Ble_Event_Phone_Transmit;
    bump.p_parameter = outBuffer;
    ble_stateMachine_bump(bump);
}

}`

Burzo commented 7 months ago

This is now completed from v0.0.2 onward.