Add Devices

Introduce several ways of binding devices, including Ble, QrCode, etc.

In our current product, devices can be added via ble, qrcode and LAN multicast.

Adding by BLE

Adding by Ble support: X1,Aegis,Gatweay.

Adding process introduction

1. Check Bluetooth permission

// Is Ble Enable
if (!BleHelper.isBleEnable()) {
     ViseLog.e("BlueTooth not enable");
     return;
}

if (!BleHelper.checkBlePermission(context)) {
     ViseLog.e("Location for ble scan");
     return;
}

//GPS is needed for auto unlock
if (!LocationOperateUtils.isLocationServiceEnable(context)) {
     ViseLog.e("BlueTooth not enable");
     return;
}

2. implement the Bluetooth Listener interface

OnScanListener:For listening to Bluetooth search callbacks
OnConnectListener:For listening to Bluetooth connection callbacks
OnParserListener:For Bluetooth data parsing callback listening
OnBleBusinessListener:For listening to Bluetooth command callbacks

3. Scan BLE devices

//Start searching ble device
BleScanHelper.getInstance().startSearch(macAddress, deviceName, rule, uuid, minRSsi, BleScanHelper.TIME_OUT, false);

//Stop searching ble device
BleScanHelper.getInstance().dispose()

//Register ble scaning callback
BleScanHelper.getInstance().registerScanCB(this@BleViewModel)
 
//unRegister ble scaning callback
BleScanHelper.getInstance().unRegisterScanCB()

The scanning results are called back in the onScanResult method

//Scan result
public void onScanResult(@Nullable ScanResult scanResult) 

//Scan timeout
public void onScanTimeOut()    

//Scan failure
public void onScanFailure(@NotNull Throwable throwable)

4. Connect BLE Devices

To connect Bluetooth devices, you need to start the service BleService

Register Bluetooth service in AndroidManifest.xml, and bind the service in Activity to keep Bluetooth connection during Activity switching.

<service android:name="com.bosma.blemodule.connect.BleService" />
// register ble connection receiver
fun registerBleConnectionReceiver() {
 val filterBle = IntentFilter()
     filterBle.addAction(BleConst.FILTER_ACTION_BLE_CONNECT_ERROR)
     filterBle.addAction(BleConst.FILTER_ACTION_BLE_CONNECT_STATUS)
     filterBle.addAction(BleConst.FILTER_ACTION_BLE_DATA_READY)
     filterBle.addAction(BleConst.FILTER_ACTION_BLE_DATA_CHANGE_OTA)
     if (mBleReceiver != null) {
         unRegisterBleConnectionReceiver()
     }
  mBleReceiver = BleReceiver(this)
  MyApplication.getApplication().registerReceiver(mBleReceiver, filterBle)
}

//unregister ble connection receiver
fun unRegisterBleConnectionReceiver() {
 try {
     MyApplication.getApplication().unregisterReceiver(mBleReceiver)
 } catch (ex: Exception) {
 }
}

//start connect ble device
mServiceBinder.connect(scanResult.getBleDevice().getMacAddress());

//Disconnect ble device
BleConnectHelper.getInstance().disconnect()

When the device is connected, onDataReady callback, initialize the command callback listener

 @Override
    public void onDataReady() {
        // Device is connected and is ready to send data
        AddBleBusinessHelper.onDataReady(mModelCode, getScanResult().getBleDevice().getMacAddress());
    }

5. Command data parser call back

// register data parser
 BleDataParserHelper.registerParserCB(this)
// unregister data parser
BleDataParserHelper.unregisterParserCB(this)
     
// data callbac
@Override
public void onParseResp(int code, @Nullable Object value) {
     //Ble Data receive here
     ViseLog.i("onParseResp code = " + code + " value = " + value);
     if (value instanceof BaseModel) {
         if (((BaseModel) value).getConfirm() != 0) {
             getUpdateBleDataErrorMD().postValue(ErrorCode.ERROR_CODE_BLE_DATA_ERROR);
             return;
         }
     }
     // Start to parse data
     AddBleBusinessHelper.onParseResp(code, value);

 }

6. Registering command business callbacks

// register Add device command business callback
AddBleBusinessHelper.registerBusinessListener(this)
AddBleBusinessHelper.unRegisterBusinessListener(this)

//register Aegis command business callback
AegisBusinessHelper.registerBusinessListener(this)
AegisBusinessHelper.unRegisterBusinessListener(this)

Adding X1 Device(BLE Camera)

Overall process: search for devices -> connect devices -> initialize data -> configure network -> bind to server -> complete

When X1 is connected,onDataReady() will callback,then initialize the business call back:

AddBleBusinessHelper.onDataReady(mModelCode, getScanResult().getBleDevice().getMacAddress());

When a command is received from a device, the following method is called to parse it.

 // Start to parse data
AddBleBusinessHelper.onParseResp(code, value);

Get WiFi List to select:

public static void getWiFiList()

Set wifi ssid and password to device:

public static void setSSidAndPassword(String sSid, String password)

Adding Aegis devices

Overall process: search for devices -> connect devices -> initialize data -> bind to server -> complete

Adding Aegis , the device is connected, it will automatically interact with data and bind to the server, please refer to Demo details

Add Keypad device

The overall process: initialize data -> search device -> connect device -> bind to server -> complete

Pass in Aegis related data for initialization

/**
* @param lockPid Aegis's PId
* @param lockMac Aegis's mac address
*/
AddBleBusinessHelper.initParamsForAddKeypad(String lockPid, String lockMac);

After initializing the data, it will automatically interact with the data and bind to the server. Please refer to Demo for details

Add HomeStation Device

Overall process: Get sessionId -> connect devices -> bind to server -> complete

1. Get SessionId

First get the SessionId and save it locally for subsequent processes. This interface is in the AddDeviceHttpHelper.java class

/**
 * Get session id for device adding
 *
 * @param familyId your current family id, can be empty.
 */
public static Call<BaseTResp<String>> getApplyBindSession(String familyId)

Then search and connect the device, enter the WiFi and password that needs to be connected and send it to the device side, the device will automatically interact with the data and bind to the server.

App side will query the device binding result according to the previous SessionId. Please refer to Demo for details.

Adding deivce by QRCode

Step1: input WiFi ssid and password

Step2: apply session id for binding

String mSession; 
public void applySession(View view) {
        EditText etWifiSSID = findViewById(R.id.et_wifi_ssid);
        EditText etWifiPassword = findViewById(R.id.et_wifi_password);
        String wifiSSID = etWifiSSID.getText().toString();
        String wifiPassword = etWifiPassword.getText().toString();
        if (TextUtils.isEmpty(wifiSSID) || TextUtils.isEmpty(wifiPassword)) {
            Toast.makeText(this, "please enter WiFi information", Toast.LENGTH_SHORT).show();
            return;
        }
        DeviceHttpHelper.getApplyBindSession().enqueue(new Callback<BaseTResp<String>>() {
            @Override
            public void onResponse(Call<BaseTResp<String>> call, Response<BaseTResp<String>> response) {
                if (response.isSuccessful() && response.body() != null) {
                    mSession = response.body().getData();
                    generateQrCode(wifiSSID, wifiPassword);
                }
            }

            @Override
            public void onFailure(Call<BaseTResp<String>> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }

Step3: Assemble session and WiFi name password and other information into QrCodeData, serialize it into a json string, and use the string to generate QR code images.

public void generateQrCode(String wifiSSID, String wifiPassword) {
    String sessionDecoded = new String(Base64.decode(mSession, Base64.DEFAULT));
    String identity = BosmaFramework.getInstance().getTicket().getIdentity();
    String countryCode = identity != null ? identity : Locale.getDefault().getCountry();
    int serverCode = 3;//release environment by default
    if (BosmaFramework.getInstance().isDebug()) {
        //1 - dev  2 - uat
        if (countryCode.equals("CN")) {
            serverCode = 2;
        } else {
            serverCode = 1;
        }
    }
    QRCodeData qrCodeData = new QRCodeData();
    qrCodeData.setS(wifiSSID);
    qrCodeData.setP(wifiPassword);
    qrCodeData.setT(sessionDecoded);
    qrCodeData.setC(identity);
    qrCodeData.setR(serverCode);
    String qrCodeString = new Gson().toJson(qrCodeData);
    QrCodeDialogFragment instance = QrCodeDialogFragment.getInstance(qrCodeString);
    instance.show(getSupportFragmentManager(), QrCodeDialogFragment.class.getSimpleName());
}

Step4: Prompt the user to use the device to scan the QR code to read the session as well as the WiFi account password, and the device will automatically connect to WiFi and bind the data after reading the information.

Step5: Prompt the user when they hear "Connecting to WiFi" from the device, then click Next to poll for the binding result.

private void startQueryBindingResult() {
    if (null != mRxTimeUtil) {
        mRxTimeUtil.cancel();
    } else {
        mRxTimeUtil = new RxTimerUtil();
    }
    mRxTimeUtil.interval(1000, 5000, number -> {
        Call<BaseTResp<DeviceModel>> call = DeviceHttpHelper.getApplyBindResult(mSession);
        call.enqueue(new Callback<BaseTResp<DeviceModel>>() {
            @Override
            public void onResponse(Call<BaseTResp<DeviceModel>> call, Response<BaseTResp<DeviceModel>> response) {
                if (response.isSuccessful() && response.body() != null) {
                    if (response.body().getData() != null) {
                        ViseLog.i(response.body().getData());
                        mRxTimeUtil.cancel();
                        dismissDialog();
                        Toast.makeText(getBaseContext(), "BindDevice Success", Toast.LENGTH_SHORT).show();
                    }
                }
                if (number > 30) {
                    mRxTimeUtil.cancel();
                    dismissDialog();
                }
            }

            @Override
            public void onFailure(Call<BaseTResp<DeviceModel>> call, Throwable t) {
                t.printStackTrace();
                if (number > 30) {
                    mRxTimeUtil.cancel();
                    dismissDialog();
                }
            }
        });
    });
}

Adding device by LAN multicast

Add EverView Dewvice

You need to add HomeStation before adding EverView,Select the HomeStation you want to add EverView to and initialize AiBoxCommander.

1. Check HomeStation Status

Check if HomeStation is in pair mode, if it is, stop first, then continue to start

/***
 * Get the current pairing mode of aibox
 */
public BosmaCall<APP_SET_AIBOX_PAIR_STATUS> queryAiBoxPairStatus()

2.Set HomeStation Status

Set HomeStation into pair mode

/***
 * Set aibox into pairing mode
 * @param status    0=start 1=stop
 * @param timeout   0-120 seconds
 */
public BosmaCall<FWCommonResponse> setAiBoxPairStatus(short status, short timeout)

3.Check if the device has been added

This interface is asynchronous, just send it and wait for the response from the device

/***
 * Get devices waiting to be paired
 */
public BosmaCall<APP_DEVICE_PAIR_DEVICE_RESP> queryAiBoxPairingDevices()

4. Register the device and respond to device

This API is in AddEverViewHelper.java class

/***
 * register device
 *
 * @param homeStationModel HomeStation Device
 * @param pairDeviceResp  HomeStation pair result information
 */
public static void registerResult(DeviceModel homeStationModel, APP_DEVICE_PAIR_DEVICE_RESP pairDeviceResp)

After successful registration, respond to device the result. This API is in AiBoxCommander.java.

/***
 * Notify the binding result to aibox (0=Failed,1 = Success)
 */
public BosmaCall<FWCommonResponse> notifyAiBoxBindIpc(short result, String mac)

Add Subdevice

Coming soon

Updated at November 17th, 2022