# myAithinker_obj **Repository Path**: seahi007/my-aithinker_obj ## Basic Information - **Project Name**: myAithinker_obj - **Description**: 爱星云测试仓库 - **Primary Language**: C - **License**: GPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-12-26 - **Last Updated**: 2024-01-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Ai-WB2 中间件爱星云基本代码 ## 前期教程 [Ai-WB2-12F使用安信可中间件接入爱星云,远程点个灯——第一篇](https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=43935&extra=page%3D1) [Ai-WB2-12F使用安信可中间件接入爱星云,远程点个灯——第二篇](https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=43942&extra=page%3D1) ## 文件结构 ``` ├── components ------>组件文件夹,存放所有代码 │ ├── aiio_cloud ------>爱星云相关源码文件夹 │ │ ├── aiio_common.c ------>flash 操作源码 │ │ ├── aiio_common.h │ │ ├── cloud_config.h ------>爱星云设备信息声明源码 │ │ ├── cloud_mutual ------>爱星云信息交互文件 │ │ │ ├── cloud_mutual.c │ │ │ └── cloud_mutual.h │ │ ├── clou_rtc ------>rtc系统时钟同步文件 │ │ │ ├── aiio_cloud_rtc.c │ │ │ └── aiio_cloud_rtc.h │ │ ├── wifi_config ------>爱星云BLE配网源码文件 │ │ │ ├── ble_config.c │ │ │ └── ble_config.h │ │ └── wifista ------>爱星云网络连接源码文件 │ │ ├── staWiFiConnect.c │ │ └── staWiFiConnect.h │ ├── config_buttom ------>配网按键驱动文件 │ │ ├── config_buttom.c │ │ └── config_buttom.h │ └── led ------>led灯驱动文件,包括网络灯和被控灯 │ ├── led_dev.c │ └── led_dev.h └── main.c ``` ## 一、产品名和三元组声明 在`src/components/aiio_cloud/cloud_config.h`文件中,声明了爱星云产品的几个信息: ``` #define DEVICE_FW_VERSION "1.0.0" //固件版本 // /* 开发平台创建产品后生成的产品ID,用户可根据创建不同产品而获得不同的产品ID,可在该处进行修改*/ #define PRODUCT_ID "PKcbCxhO" //产品ID // /* 产品标识,该标识是用户在创建不同产品时将自定义的产品标识 */ #define PRODUCT_FLAG "LIGH" //产品标识 #define DEVICE_ID "" //三元组的设备ID #define USER_NAME "" //三元组的用户名 #define PASSWORD "" //三元组的密码 ``` 如果你没有提前在爱星云开放平台创建自己的产品,你可以展示使用我提供的App,三元组进行本代码的测试: - 爱星云开放平台:https://open.iot-aithings.com/user/login?redirect=%2Fdashboard%2Findex - App 连接: [./test/AiPi-R286.apk](./test/AiPi-R286.apk) - 三元组: [./test/三元组.csv](./test/三元组.csv) ## 二、 编译 ``` ./build.sh bl602 my-aithinker_obj cn debug ``` ## 三、配网功能和重新配网 ### 3.1 配网的启动和停止 配网功能集中在`aiio_cloud/wifi_config`文件夹中,`ble_config.c`主要介绍BLE 配网,主要功能是两个函数: - **bleConfigStart()**:启动配网 - **bleConfigStop()**:停止配网 启动配网只需要在需要启动配网的时候调用即可,比如: > - 系统启动的时候,读取Flash 中的连接信息,当读取不到时,则启动配网 > - 配网按键长按达到配网时长时,启动配网。 我这里在`main.c`中的启动配网代码: ``` //读取成功则发起连接, if (config_len>0) { //判断是wifi 名称和 token 是否存在,存在则连接 if (wifi_config_data.ssid&&wifi_config_data.token) { cloud_data_s.device_token = wifi_config_data.token; cloud_data_s.mqtt_host = wifi_config_data.mqttip; cloud_data_s.mqtt_port = wifi_config_data.port; staWiFiConnect(wifi_config_data.ssid, wifi_config_data.password); } else { //不存在则配网 bleConfigStart(); } } else { //读取不到信息也进入配网 bleConfigStart(); } ``` 停止配网则是等待爱星云连接成功之后停止配网,该函数在*src/components/aiio_cloud/cloud_mutual/cloud_mutual.c*中的"**AIIO_SERVICE_ONLINE_EVENT**"事件中调用: ``` #ifdef CONFIG_BLE_DISTRIBUTION_NETWORK_ENABLE if (ble_config_start) { aiio_ble_config_response_status(AIIO_BLE_CODE_ONLINE_REQ); aiio_os_tick_dealy(aiio_os_ms2tick(100)); aiio_ble_config_response_status(AIIO_BLE_CODE_OK); aiio_os_tick_dealy(aiio_os_ms2tick(100)); bleConfigStop(); aiio_flash_save_wifi_config_data(&wifi_config_data); } #endif ``` ### 3.2 配网交互内容 配网的交互,都执行在*cloud_mutual.c*的事件中有调用: ``` aiio_ble_config_response_status(AIIO_BLE_CODE_UTC_REQ); //回复UTC成功 aiio_ble_config_response_status(AIIO_BLE_CODE_ACTIVITY_REQ);//回复设备激活 aiio_ble_config_response_status(AIIO_BLE_CODE_MQTT_CONN_OK);//回复MQTT 连接成功 aiio_ble_config_response_status(AIIO_BLE_CODE_MQTT_CONNING);//回复MQTT正在连接 aiio_ble_config_response_status(AIIO_BLE_CODE_MQTT_CONN_ERR);//回复MQTT 连接失败 aiio_ble_config_response_status(AIIO_BLE_CODE_FAIL);//回复BLE错误 aiio_ble_config_response_status(AIIO_BLE_CODE_ONLINE_REQ);//回复设备在线 aiio_ble_config_response_status(AIIO_BLE_CODE_OK);//回复OK代码 ``` ## 四、WiFi和爱星云连接 ### 4.1 WiFi的连接 在配网成功,并且得到配网数据之后,即可在配网结果事件中连接WiFi,在*src/components/aiio_cloud/wifi_config/ble_config.c*当中的**AIIO_BLE_CONFIG_OK** 事件里: ``` case AIIO_BLE_CONFIG_OK: /*The BLE distribution network is successful, and the successful events and distribution network data are sent through the queue */ { aiio_log_i("AIIO_BLE_CONFIG_OK"); if (ble_data->ble_data->ssid) { aiio_log_d("ssid = %s ", ble_data->ble_data->ssid); } if (ble_data->ble_data->passwd) { aiio_log_d("passwd = %s", ble_data->ble_data->passwd); } if (ble_data->ble_data->mqttip) { aiio_log_d("mqttip = %s ", ble_data->ble_data->mqttip); } memset(&wifi_config_data, 0, sizeof(wifi_config_data)); /************* 复制连接信息 ********/ strcpy(wifi_config_data.ssid, ble_data->ble_data->ssid); strcpy(wifi_config_data.password, ble_data->ble_data->passwd); strcpy(wifi_config_data.token, ble_data->ble_data->token); strcpy(wifi_config_data.mqttip, ble_data->ble_data->mqttip); strcpy(wifi_config_data.wificc, ble_data->ble_data->wificc); strcpy(wifi_config_data.tz, ble_data->ble_data->tz); wifi_config_data.port = ble_data->ble_data->port; wifi_config_data.ts = ble_data->ble_data->ts; cloud_data_s.device_token = wifi_config_data.token; cloud_data_s.mqtt_host = wifi_config_data.mqttip; cloud_data_s.mqtt_port = wifi_config_data.port; //开始连接路由 staWiFiConnect(ble_data->ble_data->ssid, ble_data->ble_data->passwd); } break; ``` 剩下的,就交给WiFi 事件来处理。 ### 4.2 爱星云连接 当WiFi 连接成功之后,就可以调用服务器连接函数来连接服务器,在*src/components/aiio_cloud/wifista/staWiFiConnect.c*中的**AIIO_WIFI_EVENT_STA_GOT_IP** 事件,解析了相对应的连接参数之后,就可以发起连接,函数:**cloudConnectInit(false, &cloud_data_s)**: ``` case AIIO_WIFI_EVENT_STA_GOT_IP: { aiio_log_d("<<<<<<<<< CONNECTED GOT IP <<<<<<<<<<<"); devLedNetWorkdChangeState(LED_DEV_NETWORKD_STATE_CONNECTED); wifi_is_connect = true; aiio_wifi_rssi_get(&rssi); aiio_log_d("wifi cur_rssi = %d!!", rssi); aiio_wifi_sta_mac_get(mac); aiio_log_d("wifi mac = %02x%02x%02x%02x%02x%02x!!", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); aiio_wifi_sta_connect_ind_stat_get(&wifi_ind_stat); aiio_log_d("wifi sta_bssid = %02x%02x%02x%02x%02x%02x", wifi_ind_stat.bssid[0], wifi_ind_stat.bssid[1], wifi_ind_stat.bssid[2], wifi_ind_stat.bssid[3], wifi_ind_stat.bssid[4], wifi_ind_stat.bssid[5]); aiio_wifi_ip_params_t wifi_sta_ip_praram = { 0 }; aiio_wifi_sta_ip_get(&wifi_sta_ip_praram.ip, &wifi_sta_ip_praram.gateway, &wifi_sta_ip_praram.netmask); memset(&ap_info, 0, sizeof(ap_info)); if (ap_info.ssid) { memset(ap_info.ssid, 0, strlen(wifi_ind_stat.ssid) + 1); memcpy(ap_info.ssid, wifi_ind_stat.ssid, strlen(wifi_ind_stat.ssid)); } ap_info.bssid = malloc(sizeof(wifi_ind_stat.bssid) * 2 + 1); if (ap_info.bssid) { memset(ap_info.bssid, 0, sizeof(wifi_ind_stat.bssid) * 2 + 1); snprintf(ap_info.bssid, sizeof(wifi_ind_stat.bssid) * 2 + 1, "%02x%02x%02x%02x%02x%02x", wifi_ind_stat.bssid[0], wifi_ind_stat.bssid[1], wifi_ind_stat.bssid[2], wifi_ind_stat.bssid[3], wifi_ind_stat.bssid[4], wifi_ind_stat.bssid[5]); } sprintf(ap_info.bssid, "%02x%02x%02x%02x%02x%02x", wifi_ind_stat.bssid[0], wifi_ind_stat.bssid[1], wifi_ind_stat.bssid[2], wifi_ind_stat.bssid[3], wifi_ind_stat.bssid[4], wifi_ind_stat.bssid[5]); structureWiFiConnectInfo(&ap_info, &wifi_sta_ip_praram); cloud_data_s.wifi_info = &ap_info; cloudConnectInit(false, &cloud_data_s); } break; ``` 剩下的逻辑全部都在爱星云的事件回调中处理。 ## 五、爱星云信息交互 爱星云的交互代码都集中在*src/components/aiio_cloud/cloud_mutual/cloud_mutual.c* 当中,在回调函数**service_receive_data** 你可以看到爱星云互交的所有事件: ``` AIIO_SERVICE_LANCH_FAIL_EVNET //连接失败事件 AIIO_SERVICE_SUBSCRIBE_TIMEOUT //订阅超时事件 AIIO_SERVICE_MQTT_DISCONNECT //断开连接事件 AIIO_SERVICE_MQTT_CONNECTING //正在连接事件 AIIO_SERVICE_MQTT_CONNECTED //连接成功事件 AIIO_SERVICE_ACTIVITY_EVENT //激活成功事件 AIIO_SERVICE_RESTORE_EVENT //恢复出厂设置事件 AIIO_SERVICE_REBOOT_EVENT //复位消息下发事件 AIIO_SERVICE_INFO_EVENT //信息请求事件 AIIO_SERVICE_CONFIG_EVENT //配置结果事件 AIIO_SERVICE_UPGRADE_EVENT //OTA升级通知 AIIO_SERVICE_QUERY_EVENT //发布结果通知 AIIO_SERVICE_CONTROL_EVENT //控制消息下发通知 AIIO_SERVICE_UTC_EVENT //UTC时间同步通知 AIIO_SERVICE_ONLINE_EVENT //设备在线通知 ``` ### 5.1 控制消息读取 由上面的事件可以知道,服务器下发控制时,也就是APP控制信息下发时,会触发**AIIO_SERVICE_CONTROL_EVENT** 事件,所以在这个事件当中,给LED做相应的控制就行了. 爱星云消息数据协议:**{"control":{"1":true}}** >- **"control"**:代表消息类型为控制 >- **"1"**:爱星云规定的开关类型的消息ID >- **true**:bool的结果,true为开,false 为关 ``` case AIIO_SERVICE_CONTROL_EVENT: { aiio_log_i("AIIO_SERVICE_CONTROL_EVENT patload=%s\r\n", rev_event->data); devLedCtrlValueFromPayload(rev_event->data); } break; ``` 当然,也可以控制完成之后,上报控制结果: ``` case AIIO_SERVICE_CONTROL_EVENT: { aiio_log_i("AIIO_SERVICE_CONTROL_EVENT patload=%s\r\n", rev_event->data); devLedCtrlValueFromPayload(rev_event->data); char* payload_t = malloc(128); memset(payload_t, 0, 128); sprintf(payload_t, "{\"1\":%s}", devLedCtrlGetValue()?"true":"false"); cloudPublishPayload(payload_t); free(payload_t); } break; ``` ### 5.2 消息的上报 只需要调用这个函数: **cloudPublishPayload(char\* payload)** >如:cloudPublishPayload("{\"1\":false}"):发布开光状态为关