阿里云边缘计算使用学习

前提准备

本文主要介绍基于阿里云边缘C版本SDK的使用,使传感器接入边缘计算网关并上传数据到阿里云。

编译环境搭建

Ubuntu开发环境下载链接:Ubuntu18.04

C版本SDK下载链接:GitHub地址

在linux终端使用以下命令下载环境检测脚本,安装必须文件:
下载脚本:
wget http://iotedge-web.oss-cn-shanghai.aliyuncs.com/public/testingTool/link-iot-edge_env-check.sh
修改权限:
sudo chmod +x ./link-iot-edge_env-check.sh
执行脚本:
sudo ./link-iot-edge_env-check.sh
ps
PS:当依赖项或缺少相关组件时最好使用使用aptitude

aptitude与 apt-get 一样,是 Debian 及其衍生系统中功能极其强大的包管理工具。与 apt-get 不同的是,aptitude在处理依赖问题上更佳一些。举例来说,aptitude在删除一个包时,会同时删除本身所依赖的包。这样,系统中不会残留无用的包,整个系统更为干净。

sudo aptitude install libmysqlclient-dev
当出现无法安装情形参考此处:点击查看
运行后,不接受未安装方案接受降级方案搞定。

开发环境依赖项

本SDK的开发编译环境使用如下软件: make-4.1, git-2.7.4, gcc-5.4.0, gcov-5.4.0, lcov-1.12, bash-4.3.48, tar-1.28, mingw-5.3.1

先安装以下工具

sudo apt-get install -y aptitude
sudo aptitude  install -y build-essential make git gcc

本工程依赖库的版本要保证和表格中列举版本一致或更高版本,否则将编译可能会失败
标识区重点检查是否安装

ToolVersion
gcc4.8.5+
make3.82+
ld2.17+
cmake3.11.1+
autoconf2.69+
libtool2.4.6+
zip3.0+

依赖组件

ComponetVersion
cjson1.5.5+
expat2.2.0+
dbus1.2.1+

在边缘计算网关中部署实例…
边缘计算实例下载网关
在这里插入图片描述
1.进入虚拟机,打开SDK文件:cd linkedge-thing-access-sdk-c/
cd sdk
2.复制以下代码保存名为:maintain.sh文件
调试编译

#!/bin/bash
RED_COLOR='\E[1;31m'   #红
GREEN_COLOR='\E[1;32m' #绿
YELOW_COLOR='\E[1;33m' #黄
BLUE_COLOR='\E[1;34m'  #蓝
PINK='\E[1;35m'        #粉红
RES='\E[0m'
pid=""
check_root_user() {
    if [ -z "$FC_NO_ISOLATION" ]; then
        local effective_uid=$("id" | grep -o "uid=[0-9]*" | cut -d= -f2)

        if [ $effective_uid -ne 0 ]
        then
            echo -e "\033[1;31mThe script needs to be run as root.\033[0m"
            exit 1;
        fi
    fi
}
usageFunc(){
    echo -e "${RED_COLOR}======input parameter error!======${RES}"
    echo -e "[ ${GREEN_COLOR}fctl${RES} ]==view the properties"
    echo -e "[ ${GREEN_COLOR}auto${RES} ]==make&&install"
    echo -e "[ ${GREEN_COLOR}check${RES} ]==check the build"
    echo -e "[ ${GREEN_COLOR}down${RES} ]==down the sample sdk"
    echo -e "[ ${GREEN_COLOR}driver${RES} ]==了解驱动运行状态"
    echo -e "[ ${GREEN_COLOR}dimu${RES} ]==了解设备上线异常"
    echo -e "[ ${GREEN_COLOR}data${RES} ]==了解设备上线成功后,如果设备数据上报有异"
	echo -e "[ ${GREEN_COLOR}restart 'pid'${RES} ]==重新启动驱动"
}

use_fctl(){
	echo -e "[ ${GREEN_COLOR}==view the properties==${RES} ]"
	cd /linkedge/gateway/build/bin/
	./fctl show
}
use_auto(){
	echo -e "[ ${GREEN_COLOR}==make&&install==${RES} ]"
	make clean
	make prepare && make && make install
}
use_check(){
	echo -e "[ ${GREEN_COLOR}==check the build==${RES} ]"
	ls -l build/bin/demo/led/
}
use_down(){
   if [[ -d ./linkedge-thing-access-sdk-c ]] ; then
     echo -e "${RED_COLOR}directory_exist!${RES}"
     echo -e "${PINK}======GO-->View======${RES}"
	   ls
	else
		git clone https://github.com/aliyun/linkedge-thing-access-sdk-c.git
		cd linkedge-thing-access-sdk-c/
	fi
}
use_driver(){
	echo -e "[ ${GREEN_COLOR}==了解驱动运行状态==${RES} ]"
	cd /linkedge/run/logger/fc-base/demo_driver
	ls -l
}
use_dimu(){
	echo -e "[ ${GREEN_COLOR}==了解设备上线异常==${RES} ]"
	cd /linkedge/run/logger/dimu
	ls -l
}
use_cloud_proxy(){
	echo -e "[ ${GREEN_COLOR}==了解设备上线成功后,如果设备数据上报有异==${RES} ]"
	cd /linkedge/run/logger/cloud-proxy
	ls -l
}
use_restart(){
	echo -e "[ ${GREEN_COLOR}==依据pid:$pid重新启动驱动==${RES} ]"
	kill -9 $pid
}
check_root_user	
if [[ $1 == "down" ]] ; then
	use_down
elif [[ $1 == "fctl" ]] ; then
	use_fctl
elif [[ $1 == "auto" ]] ; then
	use_auto
elif [[ $1 == "check" ]] ; then
  use_check
elif [[ $1 == "driver" ]] ; then
	use_driver
elif [[ $1 == "dimu" ]] ; then
	use_dimu
elif [[ $1 == "data" ]] ; then
	use_cloud_proxy
elif [[ $1 == "restart" ]] ; then
	if [[ $2 -ne "" ]] ; then
		pid="$2"
		use_restart
	else
		echo -e "${RED_COLOR}ERROR:pid为空!${RES}"
	fi
else
	usageFunc
fi

3.以上步骤完成后在此文件夹,鼠标右键选择在terminal打开
2
4.使用图中框选命令熟悉脚本功能,这里的功能可以参考阿里给个设备接入驱动开发文档。
浏览地址:调试与发布
3
4.1假设未下载SDK文件可以,直接使用脚本进行下载:sudo ./maintain.sh down
就可以在当前文件夹看到下载的SDK文件夹linkedge-thing-access-sdk-c
4.2下载完成后再将miantain.sh文件移动到linkedge-thing-access-sdk-c里面
(可能新文件需要扩展权限:Linux 给文件夹或者文件增加权限chmod -R 777 文件夹)来参考以上步骤运行脚本~
在这里插入图片描述

调试驱动

1.云端添加驱动
debug
1.1.云端添加驱动
add driver
1.2.云端添加驱动
add driver2
1.3.设置哪些设备使用此驱动
select
1.4.部署
以上设置完成后,点击部署,这步需确定边缘计算网关在线
部署
2.启动边缘计算网关,使其在线
启动
部署成功!
2.1意外情况,边缘计算网关无法在线问题–>导致–>无法部署新驱动
通过命令ifconfig查看网络情况
ping www.baidu.com 查看外网连接情况!

  • 当前虚拟机中外网连接有问题,而主机无问题,这时候最好重启下电脑,或者虚拟机尝试是否解决!
  • 单独重启网络命令:
$ /etc/init.d/network-manager restart
  • 非边缘计算网关在线问题,其他问题导致的无法部署,建议直接查看部署日志,查看出错原因及时解决!
    erro1
    error2

SDK功能解释及应用

详细请参考github上官方手册地址

服务功能

温湿度设备物模型如下:

{
  "services": [
    {
      "outputData": [
        {
          "identifier": "Result",
          "dataType": {
            "type": "bool"
          }
        }
      ],
      "identifier": "Power_Switch",
      "inputData": [
        {
          "identifier": "Power_Switch",
          "dataType": {
            "type": "bool"
          }
        }
      ]
    },
    {
      "outputData": [
        {
          "identifier": "Result_Time",
          "dataType": {
            "type": "bool"
          }
        }
      ],
      "identifier": "Setting_Period",
      "inputData": [
        {
          "identifier": "Period_Time",
          "dataType": {
            "type": "int"
          }
        }
      ]
    },
    {
      "outputData": [
        {
          "identifier": "result",
          "dataType": {
            "type": "bool"
          }
        }
      ],
      "identifier": "Env_Control",
      "inputData": [
        {
          "identifier": "Alarm_Temp",
          "dataType": {
            "type": "double"
          }
        }
      ]
    },
    {
      "outputData": [
        {
          "identifier": "result",
          "dataType": {
            "type": "bool"
          }
        }
      ],
      "identifier": "Env_Control_Humi",
      "inputData": [
        {
          "identifier": "Alarm_Humi",
          "dataType": {
            "type": "double"
          }
        }
      ]
    },
    {
      "outputData": [
        {
          "identifier": "result",
          "dataType": {
            "type": "enum"
          }
        }
      ],
      "identifier": "Over_Timeout",
      "inputData": [
        {
          "identifier": "Over_Timeout",
          "dataType": {
            "type": "int"
          }
        }
      ]
    }
  ],
  "properties": [
    {
      "identifier": "CurrentTemperature",
      "dataType": {
        "type": "double"
      }
    },
    {
      "identifier": "CurrentHumidity",
      "dataType": {
        "type": "double"
      }
    }
  ],
  "events": [
    {
      "outputData": [
        {
          "identifier": "error",
          "dataType": {
            "type": "enum"
          }
        }
      ],
      "identifier": "Faultreport",
      "type": "error"
    },
    {
      "outputData": [
        {
          "identifier": "AlarmType",
          "dataType": {
            "type": "enum"
          }
        },
        {
          "identifier": "CurrentTemperature",
          "dataType": {
            "type": "double"
          }
        }
      ],
      "identifier": "Temperature_Alarm",
      "type": "alert"
    },
    {
      "outputData": [
        {
          "identifier": "AlarmType",
          "dataType": {
            "type": "enum"
          }
        },
        {
          "identifier": "CurrentHumidity",
          "dataType": {
            "type": "double"
          }
        }
      ],
      "identifier": "Humidity_Alarm",
      "type": "alert"
    }
  ]
}

在这里插入图片描述
网关设备物模型如下:

{
  "services": [
    {
      "outputData": [
        {
          "identifier": "result",
          "dataType": {
            "type": "enum"
          }
        }
      ],
      "identifier": "Over_Timeout",
      "inputData": [
        {
          "identifier": "Over_Timeout",
          "dataType": {
            "type": "int"
          }
        }
      ]
    },
    {
      "outputData": [
        {
          "identifier": "Result_Time",
          "dataType": {
            "type": "bool"
          }
        }
      ],
      "identifier": "Gateway_Setting_Period",
      "inputData": [
        {
          "identifier": "Period_Time",
          "dataType": {
            "type": "int"
          }
        }
      ]
    },
    {
      "outputData": [
        {
          "identifier": "Result",
          "dataType": {
            "type": "bool"
          }
        }
      ],
      "identifier": "Switch_Filtration",
      "inputData": [
        {
          "identifier": "Main_Switch_Filtration",
          "dataType": {
            "type": "bool"
          }
        }
      ]
    },
    {
      "outputData": [
        {
          "identifier": "Result",
          "dataType": {
            "type": "bool"
          }
        }
      ],
      "identifier": "Gateway_Power_Switch",
      "inputData": [
        {
          "identifier": "Power_Switch",
          "dataType": {
            "type": "int"
          }
        }
      ]
    },
    {
      "identifier": "Manul",
      "inputData": [
        {
          "identifier": "Manul",
          "dataType": {
            "specs": {
              "item": {
                "type": "int"
              },
              "size": "15"
            },
            "type": "array"
          }
        }
      ]
    }
  ]
}

在这里插入图片描述

/*
*演示:接收云端服务调用
*/
static int call_service_callback_cb(device_handle_t dev_handle, 
                               const char *service_name, 
                               const leda_device_data_t data[], 
                               int data_count, 
                               leda_device_data_t output_data[], 
                               void *usr_data)
{
	const char *Service_dat1[]= {  //服务标识符匹配
	"Power_Switch",
	"Gateway_Power_Switch",
	"Gateway_Setting_Period",
	"Setting_Period",
	"Env_Control",
	"Env_Control_Humi",
	"Over_Timeout",
	"Switch_Filtration",
	"Manul"
								    };
	const char *Service_dat2[]= { //参数标识符匹配
	"Power_Switch",
	"Period_Time",
	"Alarm_Temp",
	"Alarm_Humi",
	"Alarm_Boiler",
	"Alarm_Negative_pressure",
	"Alarm_Co2",
	"Alarm_NH3",
	"Alarm_iLLumination",
	"Alarm_Position_Value",
	"Alarm_Water",
	"Alarm_Co",
	"Over_Timeout",
	"Main_Switch_Filtration",
	"Manul"
												};
    int i = 0;
		SNAI_Config *cnf = SNAI_cnf_read_config("/linkedge/run/SNAI_cnf.ini", '#', '=');
		char config_dev_n[12];								
		sprintf(config_dev_n,"485_DEV_%u",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]);
    /* service_name为该驱动物模型自定义方法名称 */
    log_i(LED_TAG_NAME, "service_name: %s\r\n", service_name);
    SNAI_DEBUG_INFO("service_name:【%s】",service_name);
    /* 获取service_name方法的参数名称和值信息 */
    for (i = 0; i < data_count; i++)
    {
        log_i(LED_TAG_NAME, "input_data %s: %s\r\n", data[i].key, data[i].value);
        SNAI_DEBUG_INFO("input_data:【%s】【%s】",data[i].key,data[i].value);
		for(int Service_N_c = 0;Service_N_c < 9;Service_N_c++)
			{
				if (!strcmp(service_name, Service_dat1[Service_N_c]))//匹配到服务名称
        		{
					for (int Service_K_c = 0;Service_K_c < 15;Service_K_c++)
					{
						if (!strcmp(data[i].key, Service_dat2[Service_K_c]))//匹配到输入参数名称
        				{
							if(Service_K_c == 0)
							{
								if(Service_N_c == 0)
								{
									SNAI_ALL_DEVICE_REPORT.SNAI_DEVICE_EXIST[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]] = atoi(data[i].value);//停止轮询
									SNAI_cnf_add_option(cnf, config_dev_n, Service_dat2[Service_K_c], data[i].value);									
									SNAI_DEBUG_INFO("设备:【%u】开关状态:【%d】",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle],SNAI_ALL_DEVICE_REPORT.SNAI_DEVICE_EXIST[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]]);
								}
								if(Service_N_c == 1)
								{
									SNAI_Gateway_Power_Switch_Flag = atoi(data[i].value);//为0 /停止轮询,停止上报,停止解析一切数据 //=2停止主动轮寻
									SNAI_cnf_add_option(cnf, "485_Gateway", Service_dat2[Service_K_c], data[i].value);
									SNAI_DEBUG_INFO("网关开关状态:【%d】",SNAI_Gateway_Power_Switch_Flag);
								}
								if(SNAI_ALL_DEVICE_REPORT.SNAI_DEVICE_EXIST[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]] == 0)record_delete(SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]);
								
							}
							if(Service_K_c == 1)
							{
								if (Service_N_c == 2)//网关的周期/s
								{
									sscanf(data[i].value,"%u",&SNAI_Period_Set.SNAI_Gateway_Report_Period);
									SNAI_cnf_add_option(cnf, "485_Gateway", Service_dat2[Service_K_c], data[i].value);
									SNAI_DEBUG_INFO("网关上报周期:【%uS】",SNAI_Period_Set.SNAI_Gateway_Report_Period);
								}
								if (Service_N_c == 3)//设备轮询周期/*1000=us
								{
									sscanf(data[i].value,"%u",&SNAI_Period_Set.SNAI_485dev_Polling_Period[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]]);
									SNAI_cnf_add_option(cnf, config_dev_n, Service_dat2[Service_K_c], data[i].value);
									SNAI_DEBUG_INFO("设备:【%u】轮询周期:【%ums】",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle],SNAI_Period_Set.SNAI_485dev_Polling_Period[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]]);
								}
								record_update(SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle],SNAI_Period_Set.SNAI_485dev_Polling_Period[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]],0);
							}
							if(Service_K_c == 2 || Service_K_c == 3 || Service_K_c == 4)//报警值
							{
								if(Service_N_c == 5)//湿度报警值
								{
									SNAI_Alarm_value.SNAI_485dev_Alarm_DATA_Humi[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]] = atof(data[i].value);//485地址区分 -每个地址报警值
									SNAI_cnf_add_option(cnf, config_dev_n, Service_dat2[Service_K_c], data[i].value);
									SNAI_DEBUG_INFO("设备:【%u】湿度报警设定:【%.1f%%】",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle],SNAI_Alarm_value.SNAI_485dev_Alarm_DATA_Humi[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]]);
								}
								else
								{
								SNAI_Alarm_value.SNAI_485dev_Alarm_DATA_TMP[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]] = atof(data[i].value);//485地址区分 -每个地址报警值
								SNAI_cnf_add_option(cnf, config_dev_n, Service_dat2[Service_K_c], data[i].value);
								SNAI_DEBUG_INFO("设备:【%u】温度报警设定:【%.1f℃】",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle],SNAI_Alarm_value.SNAI_485dev_Alarm_DATA_TMP[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]]);
								}							
							}
							if(Service_K_c == 5 || Service_K_c == 6 || Service_K_c == 7 || Service_K_c == 8 || Service_K_c == 9 || Service_K_c == 11)//报警值
							{
								sscanf(data[i].value,"%u",&SNAI_Alarm_value.SNAI_485dev_Alarm_DATA_INT[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]]);
								if(SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle] == 11)
								{
									SNAI_cnf_add_option(cnf, config_dev_n, "Alarm_Position_Value_L", data[i].value);
								}
								else if(SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle] == 12)
								{
									SNAI_cnf_add_option(cnf, config_dev_n, "Alarm_Position_Value_R", data[i].value);
								}
								else
								{
									SNAI_cnf_add_option(cnf, config_dev_n, Service_dat2[Service_K_c], data[i].value);
								}
								SNAI_DEBUG_INFO("设备:【%u】报警设定:【%u】",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle],SNAI_Alarm_value.SNAI_485dev_Alarm_DATA_INT[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]]);
							}
							if(Service_K_c == 10)
							{
								SNAI_Alarm_value.SNAI_485dev_Alarm_DATA_Water = atof(data[i].value);//485地址区分 -水表报警值
								SNAI_cnf_add_option(cnf, config_dev_n, Service_dat2[Service_K_c], data[i].value);
								SNAI_DEBUG_INFO("设备:【%u】水量报警设定:【%.2f】",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle],SNAI_Alarm_value.SNAI_485dev_Alarm_DATA_Water);
							}

							if(Service_K_c == 12)
							{
								SNAI_Period_Set.SNAI_485dev_Filtration_Timeout_Period[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]] = atoi(data[i].value);//每个设备的过滤超时时间设置
								SNAI_cnf_add_option(cnf, config_dev_n, Service_dat2[Service_K_c], data[i].value);
								SNAI_DEBUG_INFO("设备:【%u】过滤超时设定:【%dmin】",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle],SNAI_Period_Set.SNAI_485dev_Filtration_Timeout_Period[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[dev_handle]]);
							}
							if(Service_K_c == 13)
							{
								SNAI_Period_Set.SNAI_Main_Filtration_Flag = atoi(data[i].value);//启用网关过滤
								SNAI_cnf_add_option(cnf, "485_Gateway", Service_dat2[Service_K_c], data[i].value);
								SNAI_DEBUG_INFO("网关过滤启用状态:【%d】",SNAI_Period_Set.SNAI_Main_Filtration_Flag);
							}
							if(Service_K_c == 14)
							{
								int temp = 0;
								unsigned char temp_value[16] = {0};
								char temp_ch[1024] = {0};
								strcpy(temp_ch,data[i].value);
								SNAI_DEBUG_INFO("源数据:【%s】",temp_ch);
								if(SNAI_strip_comments(temp_ch, '#'))//去掉空格
								{
									SNAI_DEBUG_INFO("修剪后数据:【%s】",data[i].value);
									if ('[' == data[i].value[0] && ']' == data[i].value[strlen(data[i].value)-1]) {
										for(int count = 1; count < strlen(data[i].value)-1;count++)
											{
												if(data[i].value[count] == ',' || data[i].value[count] == 0x20)continue;
												temp_value[temp] = SNAI_hexCharToValue(data[i].value[count]);
												temp_value[temp] <<= 4;//MSB
												temp_value[temp] += SNAI_hexCharToValue(data[i].value[count+1]);
												count += 1;
												SNAI_DEBUG_INFO("接收自定义数据:【%02X】",temp_value[temp]);
												temp++;//数组下标
											}
									}
								}
								usart_tx(temp_value ,temp+1);//send;					
							}
							break;
						}
					}
				}
		}
    }
		SNAI_cnf_write_file(cnf, "/linkedge/run/SNAI_cnf.ini", "SNAI 485 DEVICE DRIVER CONFIG INFO"); // 将配置信息写入/linkedge/run/SNAI_cnf.ini文件
		SNAI_delete_config(cnf);
		free(cnf);
		cnf = NULL;
		SNAI_DEBUG_INFO("写入完成!");//调试用
    return LE_SUCCESS;
}

数据上报

void* status_report(void* data)
{
    int i = 0;
    int Para_num = 0,temp = 0,Event_Name_num = 0,Event_Name_temp = 0,Event_Name_offset = 0;
		unsigned int Event_Para_offset = 0,Event_Par_temp = 0,Event_Para_count_temp = 0;//偏移--参数数量--末尾地址
    SNAI_circular_buffer *cb = (SNAI_circular_buffer *)(data);//调试用
    signal(SIGKILL,SNAI_driver_exit);
    /* 对已上线设备每隔2秒钟上报一次温度数据和事件 */
    while (1)
    {
			//SNAI_DEBUG_INFO("加锁!");//调试用
			pthread_mutex_lock(&SNAI_Decode_mutex_lock);
			//SNAI_DEBUG_INFO("挂起线程!");//调试用
			pthread_cond_wait(&SNAI_cond, &SNAI_Decode_mutex_lock);
			//SNAI_DEBUG_INFO("等待条件变量激活...");//调试用
    	if(SNAI_Gateway_Power_Switch_Flag != 0)
    	{
					//SNAI_DEBUG_INFO("条件变量激活!");//调试用
	        for (i = 0; i < g_dev_handle_count; i++)
	        {
							if(SNAI_ALL_DEVICE_REPORT.SNAI_DEVICE_EXIST[SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[i]] == 1)
					{
	            if(SNAI_ALL_DEVICE_REPORT.SNAI_device_ready[i] == 1)
	            {
			      /* report device properties */
	              temp = SNAI_ALL_DEVICE_REPORT.Parameter_ptr[i]+SNAI_ALL_DEVICE_REPORT.Parameter_count[i];
					SNAI_DEBUG_INFO(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
				  //SNAI_DEBUG_INFO("设备【%u】【数据】最大偏移至数组下标【%d】",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[i],temp-1);//调试用
	              for(Para_num = SNAI_ALL_DEVICE_REPORT.Parameter_ptr[i];Para_num < temp;Para_num++)
			      {
					if(0 < strlen(dev_proper_data[Para_num].value))
					{
			            SNAI_DEBUG_INFO("上传时设备数值【%s】",dev_proper_data[Para_num].value);
			            SNAI_DEBUG_INFO("上传时设备字符数【%u】",strlen(dev_proper_data[Para_num].value));//交叉编译不同long unsigned
					}
	              }
				 SNAI_DEBUG_INFO("上传数据首地址:【%d】数量:【%d】",SNAI_ALL_DEVICE_REPORT.Parameter_ptr[i],SNAI_ALL_DEVICE_REPORT.Parameter_count[i]);
	             leda_report_properties(g_dev_handle_list[i],dev_proper_data+SNAI_ALL_DEVICE_REPORT.Parameter_ptr[i], SNAI_ALL_DEVICE_REPORT.Parameter_count[i]);
	             
				 //memset(dev_proper_data+SNAI_ALL_DEVICE_REPORT.Parameter_ptr[i],0,sizeof(dev_proper_data[0])*SNAI_ALL_DEVICE_REPORT.Parameter_count[i]);//不可瞎用,导致乱码!
	            
	            /* report device event */
					SNAI_DEBUG_INFO("|------------------设备号【%u】事件参数------------------|",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[i]);
					Event_Name_temp = SNAI_DEVICE_EVN_REPOR.Event_Name_ptr[i]+SNAI_DEVICE_EVN_REPOR.Event_Name_count[i];//首地址+参数个数=尾地址+1
					for(Event_Name_num = SNAI_DEVICE_EVN_REPOR.Event_Name_ptr[i]; Event_Name_num < Event_Name_temp; Event_Name_num++)//依据事件名个数循环
					{
						if(Event_Name_num == SNAI_DEVICE_EVN_REPOR.Event_Name_ptr[i])//如果第一个事件触发那么参数只有1个
						{
							Event_Name_offset += 1;
							Event_Par_temp = 1;
						}
						else //其他事件参数都为2个
						{
							Event_Name_offset += 2;
							Event_Par_temp = 2;
						}
						SNAI_DEBUG_INFO("设备号【%u】事件名轮寻次数+1",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[i]);
						if((SNAI_DEVICE_EVN_REPOR.SNAI_DEVICE_EVENT_TRIGGER[i] & 0x01) == 1)//从第一个事件开始检测,决定是否上报
						{
							SNAI_DEBUG_INFO("设备号【%u】事件任务轮进入+1",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[i]);
							Event_Para_count_temp = SNAI_DEVICE_EVN_REPOR.Event_Parameter_ptr[i]+Event_Name_offset;//加上事件变化偏移量
							SNAI_DEBUG_INFO("设备号【%u】原始【%u】当前总偏移至【%u】",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[i],Event_Para_count_temp-Event_Par_temp,Event_Para_count_temp-1);
							SNAI_DEBUG_INFO("设备号【%u】事件名【%s】参数数量【%u】",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[i],SNAI_DEVICE_EVN_REPOR.SNAI_DEVICE_EVENT_NAME[Event_Name_num],Event_Par_temp);
							
							for(Event_Para_offset = (Event_Para_count_temp-Event_Par_temp); Event_Para_offset < Event_Para_count_temp; Event_Para_offset++)//循环调试-->展示数据用
							{
							          SNAI_DEBUG_INFO("事件参数名【%s】事件上传时数值【%s】",dev_event_data[Event_Para_offset].key,dev_event_data[Event_Para_offset].value);
							         
							}
							//leda_report_event(g_dev_handle_list[i], SNAI_DEVICE_EVN_REPOR.SNAI_DEVICE_EVENT_NAME[SNAI_DEVICE_EVN_REPOR.Event_Name_ptr[i]+Event_Name_offset], dev_event_data, Event_Para_offset);//上报名称
							leda_report_event(g_dev_handle_list[i], SNAI_DEVICE_EVN_REPOR.SNAI_DEVICE_EVENT_NAME[Event_Name_num], dev_event_data+(Event_Para_count_temp-Event_Par_temp), Event_Par_temp);//上报名称	
							SNAI_DEBUG_INFO("上传事件首地址:【%d】偏移【%d】总数量:【%d】",Event_Para_count_temp-Event_Par_temp,Event_Par_temp-1,Event_Par_temp);
						}
						SNAI_DEVICE_EVN_REPOR.SNAI_DEVICE_EVENT_TRIGGER[i] >>= 1;//下一个事件检测
				          
					}
					Event_Name_offset = 0;
					SNAI_DEVICE_EVN_REPOR.SNAI_DEVICE_EVENT_TRIGGER[i] = 0;
					SNAI_ALL_DEVICE_REPORT.SNAI_device_ready[i] = 0;
			}
      else
      {
          //SNAI_DEBUG_INFO("*********设备【%u】未准备好数据,不上传!【线程号“%d”】*********",SNAI_ALL_DEVICE_REPORT.SNAI_485dev_ADDR[i],i);//调试用
      }
		}
			}
    	}
				//SNAI_DEBUG_INFO("解锁!");//调试用
				pthread_mutex_unlock(&SNAI_Decode_mutex_lock);
				
        if(SNAI_Period_Set.SNAI_Gateway_Report_Period == 0)
		{
			//SNAI_DEBUG_INFO("挂起本线程150ms!");//调试用
			usleep(150000);//最快上报频率
		}
		else
		{
					//SNAI_DEBUG_INFO("挂起本线程%us!",SNAI_Period_Set.SNAI_Gateway_Report_Period);//调试用
        	sleep(SNAI_Period_Set.SNAI_Gateway_Report_Period);//Origin_2s
		}
    }
}

自定义驱动功能实现顺序

July August September October November December 2020 February March April May June 串口驱动 数据解析上报 报警信息上报 交互服务功能实现 配置文件保存 本地设备信息数据库 接入其他平台 功能名称 功能模块实现顺序
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
重磅,史上最全的阿里云分享的云原生技术学习资料合集,共120份。 一、阿里云开源书合集 2020微服务领域开源数字化报告 阿里巴巴云原生技术与实践13讲 阿里巴巴云原生实践15讲 不一样的双11技术:阿里巴巴经济体云原生实践 深入浅出Kubernetes 云原生架构白皮书 Knative云原生应用开发指南 二、思维图合集 分布式系统大图 分布式系统知识体系大图 架构图思考路径 Go指南大图 三、大咖演讲 阿里巴巴 DevOps 的三架马车:基础设施、运维编排、监控 阿里巴巴 K8s 超大规模实践经验 阿里巴巴 Kubernetes 应用管理实践中的经验与教训 阿里巴巴超大规模神龙裸金属 Kubernetes 集群运维实践 阿里巴巴核心应用落地 Service Mesh 的挑战与机遇 阿里巴巴云原生开源探索与实践司徒放(姬风) 阿里云文件存储:K8s 云原生场景下的共享高性能存储 安全容器的发展与思考 拐点已至, 云原生引领数字化转型升级 拐点已至,云原生引领数字化转型升级易立 函数计算在 双11 小程序场景中的应用 基于 K8s 扩展机制实现 PaaS 平台云原生演进 金融级云原生 PaaS 探索与实践 客如云容器化改造经验 蚂蚁金服双十一 Service Mesh 超大规模落地揭秘 全民双十一:基于容器服务的大促备战 容器混合云趋势与展望 容器上云的攻与守 三维家的 Paas 平台建设与微服务架构 深入 Kubernetes 的“无人区”-蚂蚁金服双十一的调度系统 使用 Kubernetes 运行 MXNet 和 AutoTVM 谐云科技阿里云联合新品解读 云原生应用分发协同实践 Distributed Database on Cloud Edge Kubernetes - 构建边缘云计算基础设施 Improving Resource Efficiency in Kubernetes Clusters Kata Containers 云原生服务的一块坚定基石 OpenKruise — 助力阿里巴巴集团落地 Kubernetes的核心开源技术 OpenKruise — 自动化部署 Kubernetes 应用的新方法 Serverless 弹性容器实例:设计、实现和性能优化 Serverless autoscaling in kubernetes Serverless Deep Learning Inference Service Mesh 在『路口』的产品思考与实践 TiDB Operator 实现原理解析 四、架构师成长系列直播 10分钟高质量完成应用容器化迁移 从 2019 到 2020,Apache Dubbo 年度总结与展望 从代码到部署,云原生应用 DevSecOps 实践 攻克痛点:如何保证复杂微服务架构下的数据一致性 构建安全可靠的微服务 Nacos 在颜铺 SaaS 平台的应用实践 函数计算最佳实践:搭建基于 Serverless 的在线转换工具 函数计算最佳实践:基于函数计算实现 Serverless 自动化运维 函数计算最佳实践:快速开发一个分布式 Puppeteer 网页截图服务 函数计算最佳实践:如何轻松构建弹性高可用的音视频处理系统? 基于 DLedger 构建高可用的 Apache RocketMQ 集群 基于 RocketMQ + Knative 驱动云原生 Serverless 应用 基于 RocketMQ Prometheus Exporter 打造定制化 DevOps 平台 快速交付云原生应用的 3 种发布策略详解 流量太大容易挂?接入 Sentinel 让 N 个 9 成为可能! 容器化应用痛点剖析:问题诊断、监控及运维 如何借助 Serverless 技术降低闲置计算资源成本 十分钟上线-使用函数计算构建支付宝小程序服务 为什么 RocketMQ 是业务消息的首选 消息队列 Kafka 版差异化特性 云原生时代的在线教育 DevOps 之道 中小企业如何实现在家研发软件 Apache RocketMQ 未来展望 Arthas 在线应用诊断实践 Dubbo 2.7.6 新特性 GitOps之应用安全发布模型实践 Nacos 全新权限控制系统介绍 OAM:云原生时代的应用模型与下一代 DevOps 技术 RocketMQ 新特性揭秘-Request-Reply 模式 RocketMQ Connect 平台的搭建与实践 RocketMQ Go 客户端实践 RocketMQ Operator-K8s 平台自动化部署工具 Serverless 工作流适用场景及最佳实践 Serverless 开发实战--十分钟上线一个 Web 应用 Service Mesh 实践及落地风险控制
2021智能云边开源峰会是VMware联合了Intel、PingCAP、灵雀云等多家VMware创新网络合作伙伴,联合举办本次“智能云边开源峰会”。 2021智能云边开源峰会演讲PPT汇总,共30份。 云原生Commonwealth学习平台、实践与应用-vmware TiDB Cloud 云原生数据库未来规划-PingCAP Harbor企业级落地实践PPT-灵雀云 Commonwealth学习企业级实现 KubeVela云原生时代的应用交付 与管理控制平面-阿里云 Clusternet-云边一体化多集群管理实践-腾讯云 Milvus探索云原生的向量数据库-Zilliz Antrea项目介绍-VMware Velero-intro-VMware 共同创新 向善而行-VMware 数据要素与Commonwealth学习-微众银行 边缘计算及可持续性计算-VMware 云原生隐私计算平台-VMware 云原生技术的未来-PingCAP Data Infrastructure for IoT-EMQ 企业级开源:数字化转型加速剂-灵雀云 开源云原生数据分析平台-Kyligence EdgeX社区简介及发展近况 CNCF 边缘计算云原生项目OpenYurt介绍-阿里云 使用Baetyl连接云、边缘和智能-百度智能云 SuperEdge的新特性和未来之路-容器云 EMQ 边缘计算解决方案-EMQ 边缘计算技术创新与应用实践-中科创达 边缘计算助力碳中和 DeepCooling提高用能效率 TVM backend的机器学习推理加速 双碳目标下的边缘计算和虚拟电厂-江行智能 赋能全场景,构建芯生态 周易AIPU的创新与演进-安谋科技 5G万物互联时代的边缘实时计算 Kube-OVN一个非著名K8s CNI 网络插件-灵雀云 面向城市物联网的边缘网络算例覆盖-电子科技大学
KubeCon 2020 阿里巴巴云原生专场PPT汇总,共28份。 一、微服务技术与实践论坛 托管式服务网格:多种类型计算服务统一管理的基础设施 Dubbo3.0 的演进及多语言解决方案的实践 Nacos 内核构建及演进方向 Service Mesh 在超大规模场景下的落地挑战 Spring Cloud Alibaba 在 Kubernetes 下的微服务治理最佳实践 二、K8s 技术与实践论坛 一种基于硬多租的大数据 serverless 解决方案 Alluxio 助力 Kubernetes,加速云端深度学习 KubeNode:阿里巴巴云原生容器基础设施运维实践 OpenKruise:云原生应用全生命周期自动化的实战 OpenYurt:让云原生和边缘计算无缝融合的奥秘 三、KubeCon 议题 containerd 的现状 面向 SLO 的资源估计调度以优化利用率 企业云原生应用上云最佳实践 通过 Kubernetes 与 OAM 管理应用 为 Kubernetes 的秘密披上无形的盾牌 我们在阿里巴巴是如何管理各种各样的 Kubernetes 基础设施 云原生-数字经济技术创新基石 在大规模 Kubernetes 集群上实现高 SLO 的方法 主题演讲:应用交付的五大挑战以及我们如何解决它们 Dragonfly:在云原生高效、安全的进行镜像分发 Kubernetes WebAssembly:无服务器的新架构 Kubernetes 异常配置检测的DSL框架 四、Serverless 技术与实践论坛 深入浅出剖析 Knative Serverless 架构 FaaS & Cloud Native 函数计算的云原生之旅 Infrastructure As Code 在阿里巴巴的初步实践 Serverless 场景下 Pod 创建效率优化 Serverless Kubernetes - 理想,现实和未来
2021阿里云开发者大会涵盖开发与运维、云原生、大数据、人工智能、数据库、低代码等领域,本资料供大家学习参考。 阿里云开发者大会主论坛: 云原生推动全云开发与实践 云上大数据与AI开发范式的演进 AIoT云端一体加速设备智能论坛: 企业物联网设备上云 解决方案 云原生的云边一体化框架和边缘容器 从1到无穷:极致原生安全论坛: 云原生环境下的安全开发 从云上开发角度 思考个人信息保护 安全开发最佳实践 云上容器一体化 云原生网络安全开发应用 基于阿里云可信云产品的高等级安全环境研发 大数据与AI一体化开发平台论坛: 实时计算 Flink 版 和 Hologres 全域实时数仓实践 云原生数据湖构建、分析与开发治理最佳实践 统一召回引擎在搜索推荐场景的应用实践 基于实时深度学习的推荐系统 架构设计和技术演进 基于MaxCompute快速打通数仓和数据湖: 湖仓一体实践 面向云原生可观测性的平台架构实践 云原生技术与最佳实践论坛: 云原生应用新边界 基于OpenYurt和EdgeXFoudry的云边端一体化实践 KubeVela:阿里巴巴新一代易用可扩展的 应用交付管理引擎 基于消息队列RocketMQ的大型分布式应用 上云最佳实践 Serverless趋势及规模化落地实践 Serverless 开发者工具Serverless Devs介绍 基于ECI的ACK集群高弹性架构 双管齐下: Servicemesh和Dapr的实践与展望 云原生数据库:一站式数据服务: 云原生分布式数据库 PolarDB技术深度解密 阿里巴巴集团数据库最佳实践 数据库大数据一体化: 加速数智化创新 新科技达摩院Ganos时空数据库与大数据处理 云原生多模数据库Lindorm: 物联网的数据处理平台 云原生演进趋势下传统数据库升级实践 云原生与智能化的RDS 智能开发与高效运维论坛: 智能开发 高效运维 云开发解决方案和代码智能技术 最大化阿里云 OpenAPI 能力的方法和实践 卓越三项:阿里巴巴代码平台技术揭秘 云原生基础设施下的开发、调测及可靠发布的解决方案 基于Terraform的自动化管理云上资源实践 代码即服务-让开发者快速上云 如何保证移动应用的稳定性 应用开发的云基础设施优化论坛: 海量订单系统优化实践 无影办公新体验与实现揭秘 云化时代的海量算力成本优化利器 云上资源自动化部署新模式 云网络端到端保障应用平滑上云 云网络加速云原生应用交付
2020人工智能与机器学习创新峰会PPT汇总,24个专题共73份资料。供大家学习参考。 一、测试新趋势 业务数据监控从0-1脱敏 AI在游戏数值与平衡性分析中的应用 微众研发效能改进之数据度量体系 敏捷测试团队转型实践 二、大规模机器学习算法 快速深度学习训练优化算法 三、高效运维 构建全链路数据度量体系、实现DevOps数据驱动闭环 既快又好 DevOps为小红书全员质量保障赋能 浙江移动AIOpsDev运维转型实践-脱敏版 四、工业4.0 AI赋能医药工业发展案例 五、机器学习框架 Volcano加速AI云原生迁移之路 基于分布式机器学习的通信网络资源协同优化和分配 如何做智能边缘计算 六、计算机视觉 深度学习Depth预测--在2d-to-3d项目中的应用 PaddleOCR产业实践之路:如何打造8.6M超轻量模型,一条龙解决训练部署问题 视觉问答与对话系统的新技术进展 视觉技术赋能高效淘宝素材质量巡检 七、架构演进 边缘计算的缘起、价值和实践 AI人脸识别应用技术方案选型与架构落地 爱奇艺 K8S GPU 共享虚拟化实践和优化 菜鸟运力平台架构演进 八、流式计算 美团点评实时计算平台 小米实时计算平台构建 超大规模 Flink 调度优化实践 九、落地"大中台"战略 有赞数据中台降本治理 演进式的大规模业务中台体系落地实践 京东B2B中台化实践A2M 十、企业级大数据架构演进 基于阿里云数据湖分析服务DLA快速构建数据湖解决方案 Delta Lake在实时数仓中的应用实践 滴滴数据平台建设实践 美图PB级大数据基础架构升级之路 十一、区块链 新基建下可信区块链网络建设 基于区块链的药品溯源体系建设 区块链+电子合同 确保效力 放飞效率 千里之堤溃于蚁穴 十二、数据库的未来 PB级结构化日志数据的高效处理 TBase多中心多活应用实践 使用 TiDB 列存引擎进行实时数据分析 十三、图神经网络、知识图谱 知识图谱在内容安全中的实践应用 百度事件图谱技术与应用 华为云知识图谱平台技术及案例分享 知识图谱在腾讯AI医疗的应用实践-脱敏版 十四、推荐系统 多模态内容理解在推荐系统的应用 小红书推荐系统的架构演进 知乎搜索排序模型实践 十五、微服务的2.0时代 如何优雅的步入微服务2.0时代(脱敏版) 微服务之后,分层架构该如何演进 微服务网关(2) 十六、云原生构建之路 从0到1构建云原生智能金融电商-脱敏版 Tars与k8s如何结合,助力阅文海外业务 云原生应用性能优化之道 Dubbo 基于 MOSN 在 Service Mesh 场景下的落地实践-曹春晖 十七、智慧金融 智慧金融的新基础设施-数据中台-A2M 自然语言处理在金融实时事件监测和财务快讯生成中的应用 联邦学习在金融安全领域的研究与应用 人工智能Fairness在金融行业的研究:基于Pipeline的方法 十八、智能数据分析 闲鱼纳米镜--人人都是数据分析师 大数据分析系统在游戏领域的实践 十九、智能语音 智能语音交互 面向自然交互的多模态人机交互解决方案 二十、AI基础设施建设 飞桨开源模型库与行业应用 基于飞桨的深度学习全流程开发实战 NLP定制化训练实践1.3 二十一、AIOps AItest 百度AIOps解决方案及行业落地案例--脱敏 邱化峰-使用AI从业务测试走向业务验证 面向人工智能的测试体系建设 - 脱敏 二十二、FinTech 恒生银行DevOps实践和探索 数字化转型:从内部一体走向内外一体 基于区块链的隐私支付分析与比较 二十三、IOT 数字化转型升级 AIoT在工业水处理中的应用和实践及对永续发展的意义 二十四、NLP 阿里小蜜DeepQA算法平台化大规模提效实践 多模态内容生成在京东商品营销中的探索与实践

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aron566

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值