Teach you how to use Hongmeng OS to realize smart home LOT cloud project

Teach you how to use Hongmeng OS to realize smart home LOT cloud project

Teach you how to use Hongmeng OS to realize smart home LOT cloud project

I. Introduction

Today, I use Hongmeng OS to make a smart home project on the cloud by LOT. The scenario we want to achieve is this: Cloud WEB has a control interface that can control the lights and fans in the room, and display the temperature, humidity, and light intensity in the room in real time.

2. Case ideas

Let's talk about the general idea first, which can be divided into two parts: first configure the cloud server, and then write the business code of the underlying MCU to realize data collection and online reporting. There is nothing complicated in logic, but it is more important to walk through the entire process. It is similar to the solution of common RTOS to go to the cloud, and the specific difference lies in the software.

1. Preparation

The configuration of the cloud server is not complicated, mainly the front-end processing and display, which can be adjusted on the server first, and then accessed according to the API provided by the cloud service.

The hardware environment uses the bearpai hongmengji development board and the E53_IA1 expansion board (with temperature, humidity, light intensity sensor and motor).

For details on how to create a project, you can refer to my last article, which uses the development method in the Windows environment. Whether it is based on HPM or Docker environment to obtain Hongmeng source code to create a project, it is very simple.

In this demo, we will use the kernel subsystem and driver subsystem of Hongmeng OS. The kernel subsystem mainly uses thread-related API (based on CMSIS-2.0) and network service-related API (socket); the driver subsystem mainly calls the underlying GPIO and hardware I2C to control external devices.

In the kernel subsystem and driver subsystem, we also need a component (package), the Internet of Things communication protocol MQTT, which can be used for cloud services.

List the main resources and tools:


  • Cubs Pie Hongmengji Development Board
  • E53_IA1 expansion board

Source code:

  • Source code of Hi3861 development board, source Hb, suitable for windows environment


  • vscode (IDE platform)
  • DevEco Device Tool (IDE component, optional)
  • RaiDrive

Local environment:

  • windows10 64 bit
  • ubuntu18.04

Cloud environment:

  • HUAWEI-LoTCloud (cloud server platform)
  • CloudIDE (optional, used for online debugging API interface)

Below, follow my specific operations to implement the entire program step by step, with a lot of content, and be sure to install the environment in advance. You can read the previous article first to set up the environment.

2. Cloud operation

Let me talk about the cloud server first. In order to facilitate verification, we prefer Huawei Cloud Server (Tencent Cloud and Alibaba Cloud are also available, with similar principles).

The operation process is roughly as follows:

Before the device is connected to the HUAWEI CLOUD platform, it needs to be registered on the platform. If you have already registered, you can ignore this step. Huawei Cloud Address: www.huaweicloud.com/

After logging in, click on the HUAWEI CLOUD homepage

, Enter the product control terminal, which contains a variety of cloud service products.

Choose the location of the cloud server

Huawei-Beijing IV

Click on the left

,turn up
Internet of Things
Device access IoTDA
And use it immediately. Or enter in the search
Device access IoTDA
Jump over. Next time you choose this service, you can directly click on the recently visited service under the search bar to quickly enter the corresponding service, which is very convenient.

Click on

Create a product
, Fill in the product information. "Owned Resource Space" is selected by default, "Product Name" fill in a Smart_House (write one according to your preference), "Protocol Type" select MQTT, "Data Format" is JSON, "Vendor Name" fill in Linux, "Device" Type" fill in sensor. Click OK to complete the creation of the product.

After the creation is completed, a window message that the product has been created successfully will pop up.

Click "View" in the product list to perform equipment related operations. Define a service model. Name the "Service ID", fill in Agriculture here, and fill in sensor for "Service Type". Click OK to complete the service addition. Next, set the attributes and commands for the service. The basic format of data communication is specified here.

Click "Add Attribute", take temperature as an example, fill in Temperature in "Attribute Name", fill in Temperature in "Attribute Description", "Data Type" as Integer, "Access Permission" as Readable, and the rest can be the default. The content of the "attribute name" must be consistent with the information we send in the MCU later, here is a mention. Similar to temperature, we fill in the following in order, the difference is the lamp and the motor, the two "data type" is a character string, and the "length" is 3. The following figure lists the properties of the lamp and an overview of other device properties. Then add a service command, click "Add Command", enter the "Command Name" in turn, and then click "Add Input Parameters".

The new input parameter is similar to the service attribute, here is the data type of the string, enter the enumerated value, separated by English commas. Let's take a look at all the attributes and commands, almost like this:

Let's go down, click "Device", select "Register Device" and fill in the device attributes, select the default account for "Resource Space", select the product created above for "Product", and fill in sensor for "Device ID" Fill in house for "device name", keep the others as default, click OK to complete the creation.

After the device is successfully created, there are two important pieces of information that need to be saved, namely the device ID and the device key.

Device ID: 60cdaf505f880902bcaa161c_senser Device key: 4a423f69b41806de0d8ed77e145534e7 Copy code

Then we use the obtained key to generate the ClentID required for direct connection to MQTT, and jump through this link: iot-tool.obs-website.cn-north-4.myhuaweicloud.com/ iot-tool.obs-website.cn -north-4.myhuaweicloud.com/

Above, the configuration of our cloud server ends here, and the next step is to write the software on the MCU terminal. After we finish the software writing, we will conduct joint debugging tests on both sides.

3. software writing

The Hongmeng OS source code that we use already contains commonly used modules such as MQTT, which can be easily found in the sample project. Let's briefly talk about the directory structure first, and get familiar with the details of the entire Hongmeng OS on the source code framework.

The Hongmeng source code project used here is obtained by the HPM package manager. The specific source code structure is as follows: Let's make a table to see which functions each folder undertakes:

file namedescription
applicationsBearPi-HM_Nano development board application case
baseBasic services of the system, mainly using the DFX subsystem, startup files, hardware adaptation interfaces, etc.
kernelKernel subsystem
ohos_bundlesSome components and services provided by the manufacturer
third_partyThird-party components
foundationSystem service framework subsystem, WAN development
headersStore the main header file
srcStore main source files
utilsPublic base library
testXTS authentication subsystem
vendorHardware abstraction layer
buildCompile and build subsystem
outStore compiled files
binStore binary files

The code example suitable for this project is in the applications folder, and the specific directory is:

. Here is a list of the directory file structure:

file namedescription
E53_IA1.cExpansion board driver
oc_mqtt_profile_package.cPackage and configure MQTT data
oc_mqtt.cMQTT connection service
wifi_connet.cwifi connection service
iot_cloud_oc_sample.cBusiness logic code

The APIs we mainly need to use are as follows, the specific implementation details can be read in the source file. It can be divided into two parts: initialization and data upload.

1. Initialization

1) Equipment information

void device_info_init(char *client_id, char * username, char *password);

Set the device information, you must set the device information before calling oc_mqtt_init()

-1Failed to obtain device information
-2mqtt client initialization failed

2) Initialization of Huawei IoT platform

int oc_mqtt_init(void);

The initialization function of Huawei IoT platform needs to be called before using the functions of Huawei IoT platform.

-1Failed to obtain device information
-2mqtt client initialization failed

3) Set the command response function

void oc_set_cmd_rsp_cb(void(*cmd_rsp_cb)(uint8_t *recv_data, size_t recv_size, uint8_t **resp_data, size_t *resp_size));

Set the command response callback function.

recv_dataReceived data
recv_sizeThe length of the data
resp_dataResponse data
resp_sizeThe length of the response data

2. Data upload

1) Device information reporting

int oc_mqtt_profile_msgup(char *deviceid,oc_mqtt_profile_msgup_t *payload);

This means that when the device cannot report data according to the attribute format defined in the product model, this interface can be called to report the device's customized data to the platform, and the platform forwards the message reported by the device to the application server or other cloud services of Huawei Cloud for storage And processing.

deviceidDevice id
payloadMessage to upload
0Uploaded successfully
1upload failed

2) Attribute data reported by the device

int oc_mqtt_profile_propertyreport(char *deviceid,oc_mqtt_profile_service_t *payload);

It is used by the device to report attribute data to the platform in the format defined in the product model.

deviceidDevice id
payloadMessage to upload
0Uploaded successfully
1upload failed

For the difference between attribute reporting and message reporting, please refer to the message communication description

3) The gateway reports attribute data in batches

int oc_mqtt_profile_gwpropertyreport(char *deviceid,oc_mqtt_profile_device_t *payload);

Used for batch devices to report attribute data to the platform. The gateway device can use this interface to report the attribute data of multiple sub-devices at the same time.

deviceidDevice id
payloadMessage to upload
0Uploaded successfully
1upload failed

4) Response result of attribute setting

int oc_mqtt_profile_propertysetresp(char *deviceid,oc_mqtt_profile_propertysetresp_t *payload);

deviceidDevice id
0Uploaded successfully
1upload failed

5) Attribute query response results

int oc_mqtt_profile_propertygetresp(char *deviceid,oc_mqtt_profile_propertygetresp_t *payload);

deviceidDevice id
0Uploaded successfully
1upload failed

6) Return the execution result of the command to the platform

int oc_mqtt_profile_cmdresp(char *deviceid,oc_mqtt_profile_cmdresp_t *payload); After the platform issues a command, the device needs to return the execution result of the command to the platform in time. If the device does not respond, the platform will consider the command execution timeout.

deviceidDevice id
payloadMessage to upload
0Uploaded successfully
1upload failed

3. Write business logic

1) Connect the platform

Prepare the connection information (ClientId, Username, Password) we obtained above, a WIFI (account and password) that can access the Internet, and be careful not to use the 5G frequency band.

# define CLIENT_ID "60cdaf505f880902bcaa161c_senser_0_0_2021062002" # define USERNAME "60cdaf505f880902bcaa161c_senser" # define PASSWORD "e7f839333a8d3618a975e2626df1462f67202f3f4103080fe8d6f05df0fa7ce3" WifiConnect( "TP-LINK_65A8" , "0987654321" ); device_info_init(CLIENT_ID,USERNAME,PASSWORD); oc_mqtt_init(); oc_set_cmd_rsp_cb(oc_cmd_rsp_cb); Copy code

2) Push data

When you need to upload data, you need to assemble the data first, and then report the data through oc_mqtt_profile_propertyreport. The code example is as follows:

/** * @brief processes the reported data. * @details Process the reported data. * @param[in] report The data to be reported. The data to be reported. * @return None ***/ static void deal_report_msg ( report_t *report) { /** Define service ID handle*/ oc_mqtt_profile_service_t service; /** Define temperature report data handle*/ oc_mqtt_profile_kv_t temperature; /** Define humidity report data handle*/ oc_mqtt_profile_kv_t humidity; /** Define the report data handle of brightness*/ oc_mqtt_profile_kv_t luminance; /** Define the report data handle of the electric lamp*/ oc_mqtt_profile_kv_t led; /** Define the report data handle of the motor */oc_mqtt_profile_kv_kv ; /** Initialize the service ID data to be reported*/ service.event_time = NULL ; service.service_id = "Agriculture" ; service.service_property = &temperature; service.nxt = NULL ; /** Initialize the temperature data to be reported*/ temperature.key = "Temperature" ; temperature.value = &report->temp; temperature.type = EN_OC_MQTT_PROFILE_VALUE_INT; temperature.nxt = &humidity; /** Initialize the humidity data to be reported*/ humidity.key = "Humidity" ; humidity.value = &report->hum; humidity.type = EN_OC_MQTT_PROFILE_VALUE_INT; humidity.nxt = &luminance; /** Initialize the luminance data to be reported*/ luminance.key = "Luminance" ; luminance.value = &report->lum; luminance.type = EN_OC_MQTT_PROFILE_VALUE_INT; luminance.nxt = &led; /** Initialize the light data to be reported*/ led.key = "LightStatus" ; led.value = g_app_cb.led? "ON" : "OFF" ; led.type = EN_OC_MQTT_PROFILE_VALUE_STRING; led.nxt = &motor; /** Initialize the motor data to be reported*/ motor.key = "MotorStatus" ; motor.value = g_app_cb.motor? "ON" : "OFF" ; motor.type = EN_OC_MQTT_PROFILE_VALUE_STRING; motor.nxt = NULL ; /** Report the attribute data to the platform*/ oc_mqtt_profile_propertyreport(USERNAME,&service); return ; } Copy code

3) Command reception

Huawei IoT platform supports issuing commands, and commands are user-defined. After receiving the command, the command data will be sent to the queue. The task_main_entry function reads the queue data and calls the deal_cmd_msg function for processing. The code example is as follows:

/** * @brief sends the command data to the queue. * @details Send command data to the queue. * @param[in] recv_data received data * @param[in] recv_size The size of the received data * @param[in] report data received by resp_data * @param[in] resp_size The size of the reported data received * @return None ***/ void oc_cmd_rsp_cb ( uint8_t *recv_data, size_t recv_size, uint8_t **resp_data, size_t *resp_size) { app_msg_t *app_msg; int ret = 0 ; app_msg = malloc ( sizeof ( app_msg_t )); app_msg->msg_type = en_msg_cmd; app_msg->msg.cmd.payload = ( char *)recv_data; printf ( "recv data is %.*s\n" , recv_size, recv_data); /** into queue */ RET = osMessageQueuePut (mid_MsgQueue, & app_msg, Zero U , Zero U ); if (ret != 0 ){ free (recv_data); } *resp_data = NULL ; *resp_size = 0 ; } /** * @brief thread entry, read queue data and process. * @details Thread entry, read queue data and process. * @param[in] None * @return None ***/ static int task_main_entry ( void ) { app_msg_t *app_msg; /** Connect to WIFI */ WifiConnect( "TP-LINK_65A8" , "0987654321" ); /** Register the connection information of the device*/ device_info_init(CLIENT_ID,USERNAME,PASSWORD); /** Initialize MQTT*/ oc_mqtt_init(); oc_set_cmd_rsp_cb(oc_cmd_rsp_cb); while ( 1 ){ app_msg = NULL ; ( Void ) osMessageQueueGet (mid_MsgQueue, ( void **) & app_msg, NULL , Zero U ); IF ( NULL ! = App_msg) { Switch (app_msg-> MSG_TYPE) { Case en_msg_cmd: deal_cmd_msg(&app_msg->msg.cmd); break ; case en_msg_report: deal_report_msg(&app_msg->msg.report); break ; default : break ; } free (app_msg); } } return 0 ; } /** * @brief parses the command and gives the result of the processing. * @details Thread entry, read queue data and process. * @param[in] cmd command. * @return None ***/ static void deal_cmd_msg ( cmd_t *cmd) { cJSON *obj_root; cJSON *obj_cmdname; cJSON *obj_paras; cJSON *obj_para; int cmdret = 1 ; oc_mqtt_profile_cmdresp_t cmdresp; obj_root = cJSON_Parse(cmd->payload); if ( NULL == obj_root){ goto EXIT_JSONPARSE; } obj_cmdname = cJSON_GetObjectItem(obj_root, "command_name" ); if ( NULL == obj_cmdname){ goto EXIT_CMDOBJ; } if ( 0 == strcmp (cJSON_GetStringValue(obj_cmdname), "Agriculture_Control_light" )){ obj_paras = cJSON_GetObjectItem(obj_root, "paras" ); if ( NULL == obj_paras){ goto EXIT_OBJPARAS; } obj_para = cJSON_GetObjectItem(obj_paras, "light" ); if ( NULL == obj_para){ goto EXIT_OBJPARA; } ///< operate the LED here if ( 0 == strcmp (cJSON_GetStringValue(obj_para), "ON" )){ g_app_cb.led = 1 ; Light_StatusSet(ON); printf ( "Light On!" ); } else { g_app_cb.led = 0 ; Light_StatusSet(OFF); printf ( "Light Off!" ); } cmdret = 0 ; } else if ( 0 == strcmp (cJSON_GetStringValue(obj_cmdname), "Agriculture_Control_Motor" )){ obj_paras = cJSON_GetObjectItem(obj_root, "paras" ); if ( NULL == obj_paras){ goto EXIT_OBJPARAS; } obj_para = cJSON_GetObjectItem(obj_paras, "motor" ); if ( NULL == obj_para){ goto EXIT_OBJPARA; } ///< operate the Motor here if ( 0 == strcmp (cJSON_GetStringValue(obj_para), "ON" )){ g_app_cb.motor = 1 ; Motor_StatusSet(ON); printf ( "Motor On!" ); } else { g_app_cb.motor = 0 ; Motor_StatusSet(OFF); printf ( "Motor Off!" ); } cmdret = 0 ; } EXIT_OBJPARA: EXIT_OBJPARAS: EXIT_CMDOBJ: cJSON_Delete(obj_root); EXIT_JSONPARSE: ///< do the response cmdresp.paras = NULL ; cmdresp.request_id = cmd->request_id; cmdresp.ret_code = cmdret; cmdresp.ret_name = NULL ; ( void )oc_mqtt_profile_cmdresp( NULL ,&cmdresp); return ; } Copy code

4. Compile and debug


BUILD.gn file under the path, specify
Participate in compilation.

# "D1_iot_wifi_sta: wifi_sta", # "D2_iot_wifi_sta_connect: wifi_sta_connect", # "D3_iot_udp_client: udp_client", # "D4_iot_tcp_server: tcp_server", # "D5_iot_mqtt: iot_mqtt", "D6_iot_cloud_oc: oc_mqtt" , # "D7_iot_cloud_onenet: onenet_mqtt", copy the code

After the sample code is compiled and burned, press the RESET button of the development board, view the log through the serial port assistant, and print the temperature, humidity and light intensity information.

sdk ver:Hi3861V100R001C00SPC025 2020 -09 -03 18 : 10 : 00 FileSystem mount ok. wifi init success! 00 00 : 00 : 00 0 68 D 0/HIVIEW: hilog init success. 00 00 : 00 : 00 0 68 D 0/HIVIEW: log limit init success. 00 00 : 00 : 00 0 68 I 1/SAMGR: Bootstrap core services (count: 3 ) . 00 00:00:00 0 68 I 1/SAMGR: Init service:0x4b8040 TaskPool:0xfa9a4 00 00:00:00 0 68 I 1/SAMGR: Init service:0x4b8064 TaskPool:0xfb014 00 00:00:00 0 68 I 1/SAMGR: Init service:0x4b81c8 TaskPool:0xfb1d4 00 00:00:00 0 100 I 1/SAMGR: Init service 0x4b8064 <time: 0ms> success! 00 00:00:00 0 0 I 1/SAMGR: Init service 0x4b8040 <time: 0ms> success! 00 00:00:00 0 200 D 0/HIVIEW: hiview init success. 00 00:00:00 0 200 I 1/SAMGR: Init service 0x4b81c8 <time: 0ms> success! 00 00:00:00 0 200 I 1/SAMGR: Initialized all core system services! 00 00:00:00 0 0 I 1/SAMGR: Bootstrap system and application services (count: 0 ) . 00 00:00:00 0 0 I 1/SAMGR: Initialized all system and application services! 00 00:00:00 0 0 I 1/SAMGR: Bootstrap dynamic registered services (count: 0 ) . SENSOR:lum:107.50 temp:33.34 hum:63.95 <--System Init--> <--Wifi Init--> register wifi event succeed! callback function for wifi scan:0, 0 +NOTICE:SCANFINISH callback function for wifi scan:1, 24 WaitSacnResult:wait success[1]s ******************** no:001, ssid: raise a dog named Ruibang, rssi: -53 no:002, ssid: telecommunications 302, rssi: -63 no:003, ssid:412, rssi: -64 no:004, ssid:DIRECT-IXLAPTOP-O3K3OKASmsUK, rssi: -69 ... ******************** Select: 2 wireless, Waiting... +NOTICE:CONNECTED SENSOR:lum:67.50 temp:33.17 hum:68.33 WaitConnectResult:wait success[1]s WiFi connect succeed! begain to dhcp <-- DHCP state:Inprogress --> <-- DHCP state:Inprogress --> <-- DHCP state:OK --> server: server_id: mask:, 1 gw: T0: 7200 T1: 3600 T2: 6300 clients <1>: mac_idx mac addr state lease tries rto 0 e81131641696 10 0 1 3 SENSOR:lum:79.17 temp:32.77 hum:60.45 SENSOR:lum:38.33 temp:32.51 hum:52.88 SENSOR:lum:42.50 temp:32.30 hum:50.59 SENSOR:lum:42.50 temp:32.11 hum:49.73 SENSOR:lum:40.00 temp:31.91 hum:49.74 SENSOR:lum:41.67 temp:31.75 hum:49.96 Copy code

Back to the HUAWEI CLOUD platform, the devices on the platform are displayed as online

Click "View" on the right side of the device to enter the device details page, and you can see the reported data

On the HUAWEI CLOUD platform device details page, click "Command", select the synchronization command to issue, select the created command attribute, and click "OK" to send the issued command to control the device.

Take a look at the phenomenon: The serial port prints the data received by the cloud and executes the instruction to light the lamp.


Click "API Search and Debugging" to enter the API debugging interface.

Currently, Java, python, node.js, php, etc. are open, and the front-end can be built according to personal needs. Here we first debug the API, select a device command, and operate as shown. Note that the parameters in the Body are the same as the attributes of our products above. For the parameter of paras, fill in the specifications given in the picture, which is the JSON format.

Finally, click on the mode to give the debugging result, and the light on our development board is also lit!

4. summary

  1. For cloud operations, pay attention to the same information as the information written by the terminal software. One is that the MQTT connection information cannot be wrong, and the other is that the capitalization of the names should be the same;
  2. When compiling the terminal MCU software, pay attention to the layered design, first write the respective functional modules, and finally implement the related business logic;
  3. Pay attention to commissioning and make good use of the serial port and cloud MQTT information tracking service;
  4. Overall, the workload is still quite large, and there are many places to pay attention to, so be very careful.
  5. Source code background reply
    Obtain, the project file can be obtained by referring to the previous article.