Project Overview
Some students may have been exposed to soft bus application development on standard systems, but have you played soft bus applications on lightweight systems? Now it's here. We use the light-weight system soft bus capability of OpenAtom OpenHarmony 3.1 Release (hereinafter referred to as "OpenHarmony") to form a light-weight distributed network of smart gas detection equipment and smart window ventilation equipment to achieve mutual control between the devices.
The schematic diagram is as follows:
When the gas in the home is alarmed, it can directly control the motor in the window ventilation system without any operation.
Development Notes
As can be seen from the above video, the application interface of the relevant case equipment can be divided into two parts: the peripheral interaction page and the soft bus operation page. The relevant pages and the associated lightweight system capabilities they depend on can be seen in the system block diagram below. For example, the peripheral interface interacts with the device hardware through a custom JSI interface, and the soft bus operation interface realizes the discovery, authentication, transmission and other soft bus operations between devices through the device management capabilities and soft bus capabilities of the lightweight system.
In the following content, we will take the intelligent gas alarm device as an example, and divide the relevant development process into three parts: JS application-side development, custom JSI implementation, and development board-side code:
JS application development <br>The gas alarm JS application is a distributed safe kitchen application developed in JS language based on the 3.1 release version, combined with the features of the Ark development framework (ArkUI) and distributed networking. In order to reflect the lightweight distributed characteristics of OpenHarmony, it is not only necessary to consider how to design the page and how the application interacts with the peripherals, but also how to perform device authentication between two lightweight devices and how to communicate between the devices.
Therefore, the operation page, alarm page and device authentication page are designed in related applications. The home page is to set the gas concentration threshold and display the current gas concentration; the alarm page is to jump from the home page to the alarm interface when the home page detects that the current gas concentration reaches or exceeds the threshold we set; the equipment authentication page is to two devices for distributed networking.
The code structure is as follows:
Peripheral interactive page development
The relevant interface is shown in the figure above. We divide the home page into three parts: the top label, the gas concentration display, and the setting of the alarm threshold. The following is the specific analysis content:
1) Top label analysis <br>In addition to the relevant text interface, the top label is mainly two buttons at the top, which are used to display the current Wi-Fi connection status and jump to the device authentication page.
GetKey() {
com.get({ // 获取wifi状态
key: 'storage_key',
success: (data)=> {
let res = JSON.parse(data)
if (res.wifi) {
if(res.wifi == 'connected') {
this.isWifi = true;
} else {
this.isWifi = false;
}
}
.....
},
});
},
changePage(operation) {
router.replace({
uri:"pages/dm/dm" // 跳转到设备认证页面
});
}
2) The gas concentration display <br> is mainly to obtain the current gas concentration and refresh it on the relevant interface in real time.
onInit() {
setTimeout(()=>{
setInterval(()=>this.GetKey(),500) // 每500ms 获取一次
},3000);
},
GetKey() {
com.get({
key: 'storage_key',
success: (data)=> {
let res = JSON.parse(data)
if (res.CurrentGasCONC) {
this.currentValue = res.CurrentGasCONC;
this.progressPercent = ((this.currentValue ) /300) * 100
if(this.currentValue >this.PresetValue && !this.isChange){
this.isChange = true;
router.replace({
uri:"pages/warn/warn" // 燃气数值超标后自动跳转告警页面
});
}
}
},
......
});
},
3) Setting the alarm threshold <br>The processing of the alarm threshold in the home page interface mainly includes reducing the preset threshold and increasing the preset threshold, which are all completed by calling the relevant SetKey operation.
reduceProgress(){ //减小预设阈值
if (this.PresetValue <= 0) {
this.PresetValue = 0
}else{
this.PresetValue = parseInt(this.PresetValue) - 20
}
this.isChange = false;
this.setProgress = ((this.PresetValue ) /300) * 100
this.SetKey( 'GasThreshold', this.PresetValue );
},
addProgress(){ //增大预设阈值
if (this.PresetValue >= 300) {
this.PresetValue = 300
}else{
this.PresetValue = parseInt(this.PresetValue) + 20
}
this.isChange = false;
this.setProgress = ((this.PresetValue ) /300) * 100
this.SetKey( 'GasThreshold', this.PresetValue );
},
SetKey(key1, value1) {
com.set({
key: key1 + '',
value: value1 + '',
// success or failed 状态打印
});
},
Device authentication page development
The relevant interface is shown in the figure above. We divide the device authentication steps into four steps: discovering the device, initiating authentication, allowing authentication, and entering PIN code. The following is the specific analysis content:
1) Discovery device analysis <br>Device authentication displays the corresponding UI due to different device states. The UI shown in the figure above corresponds to the device state "status = start".
startDevice(){
this.subscribeId = Math.floor(Math.random() * 10000 + 1000)
var info = {
"subscribeId": this.subscribeId, // 特定随机的
"mode": 0xAA, // 设置主动发现模式,除此之外还有被动模式DISCOVER_MODE_PASSIVE
"medium": 0, // 自动选择发现介质,目前用的是coap
"freq": 2, // 发送发现消息的频率,目前用的是HIGH 还有LOW/MID/SUPER_HIGH
"isSameAccount": false, // 取消同一账号下才能发现的限制
"isWakeRemote": false, // 目前轻量系统没有睡眠模式,所以不用睡眠唤醒功能
"capability": 0 // 目前使用DDMP
devicemanager.startDeviceDiscovery(info); // 开始设备发现
},
2) Initiate authentication analysis
AuthenticateDevice(){ // 发起认证
let extraInfo = {
targetPkgName: 'test',
appName: "Newname",
appDescription: "testAPP",
business: '0',
displayOwner: 0
};
let AuthParam = {
authType: 1, // 以PIN 码方式进行认证校验
appIcon:null,
appThumbnail:null,
extraInfo: extraInfo
};
let _this = this;
devicemanager.authenticateDevice(this.statusInfo, AuthParam, {
// 省略了相关success 和fail 回调处理,完整代码见参考链接
},
3) Allow authentication parsing
When the device status is "status = join-pin", the relevant authentication actions are allowed and the relevant PIN code is displayed.
joinAuthOk() {
this.joinPin() //切换显示PIN码界面
this.initStatue() //获取PIN码并显示
devicemanager.setUserOperation(0)
},
initStatue() {
this.log('initStatue')
const data = devicemanager.getAuthenticationParam()
// 参数值转换为 JSON 字符串写入data
this.log('getAuthenticationParam:' + JSON.stringify(data))
// Authentication type, 1 for pin code.
// ode ==1,pin码
if (data && data.authType == 1) {
// 完整代码见参考链接
}
},
4) Input PIN code analysis <br>When the device status is "status = main-pin", enter the relevant PIN code input and verification interface.
mainInputPin(s) { // 输入六位数字
if (this.pinNumb == 6) return
if (this.pinNumb < 6) {
this.pin[this.pinNumb] = s
++this.pinNumb
}
if (this.pinNumb == 6) {
console.log("verifyAuthInfo ok")
this.verifyAuthInfo(this.pin.join('')) // PIN码校验
}
},
Custom JSI principle and implementation
JSI is a JS API implementation mechanism for OpenHarmony's lightweight and small systems. It is suitable for encapsulating IO, CPU-intensive, and OS bottom-level capabilities for JS application calls. Through JSI, JS and C/C++ code can access each other. Similar to the audio, device, sensor and other JSI modules involved in the OpenHarmony lightweight system that need to deal with hardware, the CommunicationKit and DeviceManager modules also need to be added to the relevant configuration files first. ace_lite_engine maps keywords used in JS applications to C++ functions through JSI::SetModuleAPI. The specific operations are as follows:
OHOS_MODULES in foundation/ace/ace_engine_lite/frameworks/module_manager/ohos_module_config.h adds the following fields:
{"CommunicationKit", InitNativeApiCommunicationKit},
{"devicemanager", InitDeviceManagerModule},
Loading a custom module <br>As shown above, the CommunicationKit module is introduced when reading data and issuing commands in the JS application peripheral control interface. Now let's take a look at the relevant details:
The contents of the InitNativeApiCommunicationKit function are as follows:
vendor/team_x/common/communicationkit/native_utils/src/nativeapi_communication_kit.cpp
void InitNativeApiCommunicationKit(JSIValue exports) {
JSI::SetModuleAPI(exports, "get", NativeapiCommunicationKit::Get); // 与JS应用中的关键字一致
JSI::SetModuleAPI(exports, "set", NativeapiCommunicationKit::Set);
}
The related C++ implementations of NativeapiCommunicationKit::Get and Set are similar. We refer to the implementation of other modules in the lightweight system source code and use the ExecuteAsyncWork function. Creates an asynchronous job based on the given parameters and dispatches it to the main application task handler. The logic for obtaining the gas concentration is implemented in ExecuteGet, and the setting of the light-weight system gas alarm threshold is implemented in ExecuteSet. The function args parameter is used to receive the parameters (JSIValue array) passed from the JS side, and argsNum represents the length of the array.
ExecuteAsyncWork(thisVal, args, argsNum, ExecuteGet, false);
ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSet, false);
Loading the device management module <br>Similar to the custom module, when the JS application uses the soft bus interface, the device management module needs to be loaded before the application is executed. The device management module is also an important part of the OpenHarmony system. In the standard system, we load related modules through NAPI, while in our lightweight system, the device management module is loaded through JSI. First, see the relevant content of the InitDeviceManagerModule function as follows:
foundation/distributedhardware/devicemanager/interfaces/kits/js_mini/src/native_devicemanager_js.cpp
void InitDeviceManagerModule(JSIValue exports) {
JSI::SetModuleAPI(exports, "createDeviceManager", DeviceManagerModule::CreateDeviceManager);
......
JSI::SetModuleAPI(exports, "startDeviceDiscovery", DeviceManagerModule::StartDeviceDiscoverSync);
JSI::SetModuleAPI(exports, "stopDeviceDiscovery", DeviceManagerModule::StopDeviceDiscoverSync);
JSI::SetModuleAPI(exports, "authenticateDevice", DeviceManagerModule::AuthenticateDevice);
JSI::SetModuleAPI(exports, "verifyAuthInfo", DeviceManagerModule::VerifyAuthInfo);
JSI::SetModuleAPI(exports, "setUserOperation", DeviceManagerModule::SetUserOperationSync);
JSI::SetModuleAPI(exports, "getAuthenticationParam", DeviceManagerModule::GetAuthenticationParamSync);
......
}
Development board-side code development instructions <br>As shown in the figure below, we start from the system startup process of the light-weight system soft-bus device to analyze the key points of soft-bus application execution. Step 1: Initialize the soft bus server; Step 2: Register services related to the soft bus, such as PRC, device management DeviceManager service; Step 3: JS engine loads the DeviceManager interface declaration; Step 4: Specific RPC communication operations process.
Initialize Soft Bus Service <br>During the startup process of the light-weight system device, the relevant initialization soft bus service thread will be registered. The main content in this thread is to call the InitSoftBusServer function. This function will initialize the configuration, discovery, authentication and other related operations related to the soft bus.
Softbus -related service registration <br>Service is an important concept in OpenHarmony system. Different functional modules and calling interfaces between different threads/processes are unified and abstracted into services. Using the service mechanism, the capabilities provided by the operating system, driver framework, etc. can be packaged into services and provided to application calls. The following is a detailed introduction to the details and key points of the service registration related to the soft bus.
SAMGR: As an intermediary, it manages the capabilities provided by the Provider and helps the Consumer to discover the capabilities of the Provider.
Provider: The provider of the service, providing capabilities (external interface) for the system.
PRC service registration
RPC: (Remote Procedure Call) is used for cross-device and cross-process communication. In the light-weight system soft bus application, we use the RPC capability to realize the associated control of two devices in the safe kitchen project. The details of the RPC service registration are as follows :
1. Create related static service objects;
static MiniService g_miniService = {
.GetName = GetName, // 相关服务名为mini_sa_rpc
.Initialize = Initialize,
.MessageHandle = MessageHandle,
.GetTaskConfig = GetTaskConfig,
SERVER_IPROXY_IMPL_BEGIN,
.Invoke = FeatureInvoke, // 对外提供Invoke方法,供RPC相关client端程序调用
IPROXY_END,
};
2. Register related services and default objects;
SAMGR_GetInstance()->RegisterService((Service *)&g_miniService);
SAMGR_GetInstance()->RegisterDefaultFeatureApi(MINI_SERVICE, GET_IUNKNOWN(g_miniService));
Device management service registration <br>If the device management service is not registered, then the related soft bus capabilities will not be discussed. When the lightweight system starts, perform initialization actions of related device management services, the details are as follows:
1) Create related static service objects;
static DeviceManagerSamgrService service = {
.GetName = GetName, // 相关服务名为dev_mgr_svc
.Initialize = Initialize,
.MessageHandle = MessageHandle,
.GetTaskConfig = GetTaskConfig,
};
2) Register related services and default objects;
SAMGR_GetInstance()->RegisterService((Service *)&service)) ;
SAMGR_GetInstance()->RegisterDefaultFeatureApi(DEVICE_MANAGER_SERVICE_NAME, GET_IUNKNOWN(service));
3) Execute relevant initialization actions. The initialization function of the DeviceManager service will complete the relevant status callback registration and transmission channel initialization, and then execute the relevant Publish action to prepare for receiving the discovery message.
RPC communication between devices <br>In standard system application development, we can realize the communication between devices by means of distributed database and starting remote Ability, and in the lightweight system, we can realize it by RPC method. In the previous content, we talked about the concept of service. The following is the related schematic diagram of the expansion:
Consumer: The consumer of the service, calling the function (external interface) provided by the service.
After completing the soft bus networking, if it is detected that the gas degree exceeds the standard, the intelligent ventilation equipment can be controlled by the following steps:
1. Obtain the relevant node information in the soft bus network;
GetAllNodeDeviceInfo("com.ohos.devicemanagerui", &nodeInfo, &infoNum);
2. Obtain the corresponding IUnknown method in the mini_sa_rpc service published by the remote node;
IUnknown *miniDefApi = SAMGR_GetInstance()->GetRemoteDefaultFeatureApi(nodeInfo[0]->networkId, "mini_sa_rpc");
3. Query the relevant capabilities published by the service, and obtain the pointer miniInterface pointing to the specific API interface;
miniDefApi->QueryInterface(miniDefApi, 0, (void **) &miniInterface);
4. Call the Invoke capability provided by the related mini_sa_rpc;
miniInterface->Invoke(miniInterface, 1, &reply, NULL, NULL);
Operation experience
- Prepare the smart window ventilation equipment and smart gas alarm equipment in the safe kitchen scene in advance, and complete the relevant compilation and application installation actions;
- Prepare a working wireless routing device in advance (please ensure the default hotspot name: test_wifi password: 12345678; whether it can connect to the Internet or not)
- Power on the gas detection equipment and the window ventilation equipment, and confirm that the two equipment applications start and operate normally;
- The ventilation equipment and gas detection equipment are formed into a soft bus network according to the following steps:
● Click the soft bus configuration icon in the upper right corner of the application interface of the two devices respectively to enter the soft bus configuration interface;
● Click the application discovery icon of the smart gas detection equipment, and click the initiate authentication icon after an interval of 3S;
● Click the allow authentication icon under the soft bus configuration interface of the smart ventilation device, a 6-digit PIN code will be displayed under normal circumstances;
● Click on the smart gas detection device application to enter the PIN code button, enter the numeric keypad to enter the PIN code;
● Click the return button in the upper left corner of the two application software bus configuration icons to enter the device control interface. Set the threshold value of the gas detection device to be lower than the actual gas value read. When the gas detection application enters the alarm interface, it will control the motor to work, automatically ventilate and ventilate, and ensure the safety of the home. When the actual gas value is lower than the set threshold, the motor is turned off.
Reference link
The reference materials and related document paths involved in this project are as follows: Ouzhitong BES2600WM development board quick start learning path:
https://growing.openharmony.cn/mainPlay/learnPathMaps?id=17
Lightweight System Application Development Soft Bus Video Course:
https://www.bilibili.com/video/BV1BS4y1A7ry/?vd_source=fa133082ba4f0aaa5d2dae4f0a981ab3
Device Management Module Documentation:
https://gitee.com/openharmony/device_manager/blob/master/README_en.md
Example of intelligent gas detection system:
https://growing.openharmony.cn/mainPlay/detail?sampleId=3935
Example of a smart window ventilation system:
https://growing.openharmony.cn/mainPlay/detail?sampleId=3936Summarize
It can be seen from this article that the same application as the standard system calls the relevant interfaces provided by the device management module to realize functions such as soft bus discovery and authentication, but the difference is that the standard system uses the prefabricated DeviceManager_UI.hap to display the PIN code , enter the PIN code. In the light-weight system soft bus application, the related PIN code display and PIN code input need to call the related interface by themselves.
Compared with the standard system soft bus application, the current lightweight system soft bus application only realizes the previous data transfer function of the lightweight system equipment, and the functions such as distributed pull-up and distributed database of the lightweight system need to be updated and iterated later. The next step will be to study how to use soft bus to connect lightweight systems and standard systems, so please look forward to it.
The rich and diverse OpenHarmony development samples are inseparable from the contributions of partners and developers. If you want to share your own development samples, you are welcome to submit them to the OpenHarmony Knowledge System SIG repository.
Co-construct development sample reference https://gitee.com/openharmony-sig/knowledge/blob/master/docs/co-construct_demos/README_zh.md
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。