#include "OSAL.h" #include "ZGlobals.h" #include "AF.h" #include "aps_groups.h" #include "ZDApp.h" //#include "SampleApp.h" #include "demoapp.h" #include "SampleAppHw.h" #include "OnBoard.h" /* HAL */ #include "hal_lcd.h" #include "hal_led.h" #include "hal_key.h" #include "MT_UART.h" #include "DHT11.h" #include "string.h" #include "stdlib.h" #include "MT.h" uint8 my_TaskID; endPointDesc_t my_epDesc; uint8 my_TransID = 0; // This is the unique message ID (counter) afAddrType_t my_DstAddr; devStates_t identity_nwk = DEV_INIT; static struct join_info join_addr[SAMPLEAPP_MAX_CLUSTERS];//假设每种设备网络中只有一个 const cId_t my_ClusterList[SAMPLEAPP_MAX_CLUSTERS] = { SAMPLEAPP_SENSOR_CLUSTERID, SAMPLEAPP_CTRL_CLUSTERID }; //端点描述符 const SimpleDescriptionFormat_t my_SimpleDesc = { MY_ENDPOINT, // int Endpoint; SAMPLEAPP_PROFID, // uint16 AppProfId[2]; SAMPLEAPP_DEVICEID, // uint16 AppDeviceId[2]; SAMPLEAPP_DEVICE_VERSION, // int AppDevVer:4; SAMPLEAPP_FLAGS, // int AppFlags:4; SAMPLEAPP_MAX_CLUSTERS, // uint8 AppNumInClusters; (cId_t *)my_ClusterList, // uint8 *pAppInClusterList; SAMPLEAPP_MAX_CLUSTERS, // uint8 AppNumInClusters; (cId_t *)my_ClusterList // uint8 *pAppInClusterList; }; static struct adjust_info adjust = { TEMPS_ADJUST_MIN_DEF, TEMPS_ADJUST_MAX_DEF, HUMIS_ADJUST_MIN_DEF, HUMIS_ADJUST_MAX_DEF, TEMPS_ADJUST_MIN_DEF, HUMIS_ADJUST_MIN_DEF, SET_TEMP_ADJUST_CLOSE, SET_HUMI_ADJUST_CLOSE, MANUAL_CTRL_MODE, MANUAL_CTRL_MODE, 5, 5}; void send_to_gateway(char *str) { signed char len = strlen(str); if(len > 0){ HalUARTWrite(1,(uint8 *)str,len); HalUARTWrite(1,"\r\n",2); } } //每个终端入网成功后先给协调器发送一个消息以确认身份,只有终端调用 void send_coord_affirm(uint16 cid) { uint8 data[10]; strcpy((char *)data,CLIENT_AFFIRM); my_DstAddr.addr.shortAddr = 0x0000; AF_DataRequest( &my_DstAddr,//目标地址 &my_epDesc, cid, strlen((char const *)data), data, &my_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ); } //协调器对采集到的温湿度数据进行处理 void coord_th_dispose(unsigned char *th) { char *info[10];signed char len=0; info[len] = strtok((char *)th,","); while(info[len]){ info[++len] = strtok(NULL,","); }//get_data/periodic_th,24,29,open,close if(len != 5) return; adjust.temp_curr = atoi((char const *)info[1]); adjust.humi_curr = atoi((char const *)info[2]); strcpy(adjust.temp_c_ops,info[3]);//保存开关状态 strcpy(adjust.humi_c_ops,info[4]);//保存开关状态 debug("温度%d度,湿度%d%%\n",adjust.temp_curr,adjust.humi_curr); char tbuf[16]=""; sprintf(tbuf,"%d,%d\r",adjust.temp_curr,adjust.humi_curr); HalUARTWrite(1,(uint8 *)tbuf,strlen(tbuf)); if(strncmp((char *)(adjust.temp_c_mode),AUTO_CTRL_MODE,strlen(AUTO_CTRL_MODE)) == 0){ if((adjust.temp_curr >= adjust.temp_min)&&(adjust.temp_curr <= adjust.temp_max)&&(strncmp(adjust.temp_c_ops,"open",strlen("open")) == 0)){ my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_TEMP_ADJUST_CLOSE);//温度适宜,关闭所有升降温设备 my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_TEMP_ADJUST_CLOSE); }else if((adjust.temp_curr > adjust.temp_max)&&(strncmp(adjust.temp_c_ops,"close",strlen("close")) == 0)){ my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_TEMP_ADJUST_OPEN);//温度太高,开启降温设备 my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_TEMP_ADJUST_OPEN); }else if((adjust.temp_curr < adjust.temp_min)&&(strncmp(adjust.temp_c_ops,"close",strlen("close")) == 0)){ //温度过低,开启升温设备 } } if(strncmp((char *)(adjust.humi_c_mode),AUTO_CTRL_MODE,strlen(AUTO_CTRL_MODE)) == 0){ if((adjust.humi_curr >= adjust.humi_min)&&(adjust.humi_curr <= adjust.humi_max)&&(strncmp(adjust.humi_c_ops,"open",strlen("open")) == 0)){ my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_HUMI_ADJUST_CLOSE);//湿度适宜,关闭所有加湿除湿设备 my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_HUMI_ADJUST_CLOSE); }else if((adjust.humi_curr > adjust.humi_max)&&(strncmp(adjust.humi_c_ops,"close",strlen("close")) == 0)){ my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_HUMI_ADJUST_OPEN);//湿度太高,开启除湿设备 my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_HUMI_ADJUST_OPEN); }else if((adjust.humi_curr < adjust.humi_min)&&(strncmp(adjust.humi_c_ops,"close",strlen("close")) == 0)){ //湿度过低,开启加湿设备 } } } //采集温湿度并发送 void get_th_send_to_coord(char *head) { uint8 th[6];char curr_t[6],curr_h[6]; char temp[60],count = 100; while(count--){ DHT11(); if((wendu_shi == 0)||(shidu_shi == 0)) continue;//采集结果不正确需要重新采集 else break; } th[0]=wendu_shi+'0'; th[1]=wendu_ge%10+'0'; th[2]=','; th[3]=shidu_shi+'0'; th[4]=shidu_ge%10+'0'; th[5]= 0; if((LOCAL_LED1 == SWITCH_LED_OPEN)) strcpy(curr_t,"open"); else strcpy(curr_t,"close"); if((LOCAL_LED2 == SWITCH_LED_OPEN)) strcpy(curr_h,"open"); else strcpy(curr_h,"close"); sprintf(temp,"%s,%s,%s,%s",head,th,curr_t,curr_h); debug("%s\n",temp); my_SendPointToPointMessage(SAMPLEAPP_COORD_SEND,(uint8 *)temp);//数据格式:periodic_th/get_data,25,60,open,close } //处理两个串口的数据 void serial_dispos(uint8 port,uint8 len,uint8 *str) { if(strstr((char *)str, GET_DATA)!=NULL){//这里没有区分是debug(uart0)还是网关(uart1) my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,GET_DATA);//协调器给传感器发请求数据命令 return; } if(port == 0){//来至调试串口 if(strncmp((char *)str,"open",strlen("open")) == 0){//调试开关可以不受自动手动限制 my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_TEMP_ADJUST_OPEN); my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_HUMI_ADJUST_OPEN); my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_TEMP_ADJUST_OPEN); my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_HUMI_ADJUST_OPEN); LOCAL_LED1 = SWITCH_LED_OPEN; LOCAL_LED2 = SWITCH_LED_OPEN; SWITCH_LED = SWITCH_LED_OPEN; }else if(strncmp((char *)str,"close",strlen("close")) == 0){ my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_TEMP_ADJUST_CLOSE); my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_HUMI_ADJUST_CLOSE); my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_TEMP_ADJUST_CLOSE); my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_HUMI_ADJUST_CLOSE); LOCAL_LED1 = SWITCH_LED_CLOSE; LOCAL_LED2 = SWITCH_LED_CLOSE; SWITCH_LED = SWITCH_LED_CLOSE; } }else if(port == 1){//来至网关的数据 if(strncmp((char *)str,SET_DATA,strlen(SET_DATA)) == 0){ char *info[10];signed char len=0; debug("%s\n",str); info[len] = strtok((char *)str,","); while(info[len]){ info[++len] = strtok(NULL,","); }//set_data,24,29,40,60,auto,manual // 先判断后赋值 if(len != 7) return; adjust.temp_min = atoi(info[1]); adjust.temp_max = atoi(info[2]); adjust.humi_min = atoi(info[3]); adjust.humi_max = atoi(info[4]); strcpy((char *)(adjust.temp_c_mode),info[5]); strcpy((char *)(adjust.humi_c_mode),info[6]); }else if(strncmp((char *)str,SET_TEMP_ADJUST_OPEN,strlen(SET_TEMP_ADJUST_OPEN)) == 0){ if(strncmp((char *)(adjust.temp_c_mode),AUTO_CTRL_MODE,strlen(AUTO_CTRL_MODE)) == 0) return; strcpy(adjust.temp_c_ops,"open"); my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_TEMP_ADJUST_OPEN); my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_TEMP_ADJUST_OPEN); }else if(strncmp((char *)str,SET_TEMP_ADJUST_CLOSE,strlen(SET_TEMP_ADJUST_CLOSE)) == 0){ if(strncmp((char *)(adjust.temp_c_mode),AUTO_CTRL_MODE,strlen(AUTO_CTRL_MODE)) == 0) return; strcpy(adjust.temp_c_ops,"close"); my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_TEMP_ADJUST_CLOSE); my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_TEMP_ADJUST_CLOSE); }else if(strncmp((char *)str,SET_HUMI_ADJUST_OPEN,strlen(SET_HUMI_ADJUST_OPEN)) == 0){ if(strncmp((char *)(adjust.humi_c_mode),AUTO_CTRL_MODE,strlen(AUTO_CTRL_MODE)) == 0) return; strcpy(adjust.humi_c_ops,"open"); my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_HUMI_ADJUST_OPEN); my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_HUMI_ADJUST_OPEN); }else if(strncmp((char *)str,SET_HUMI_ADJUST_CLOSE,strlen(SET_HUMI_ADJUST_CLOSE)) == 0){ if(strncmp((char *)(adjust.humi_c_mode),AUTO_CTRL_MODE,strlen(AUTO_CTRL_MODE)) == 0) return; strcpy(adjust.humi_c_ops,"close"); my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_HUMI_ADJUST_CLOSE); my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_HUMI_ADJUST_CLOSE); } } } //任务初始 void my_Init( uint8 task_id ) { my_TaskID = task_id; MT_UartInit();//串口初始化 MT_UartRegisterTaskID(task_id);//登记任务号 /* GPIO初始化 */ P1DIR |= (1<<0); //P1_0定义为输出 P1DIR |= (1<<1); //P1_1定义为输出 P2INP &= ~(1<<6);//打开上拉 LOCAL_LED1 = SWITCH_LED_CLOSE; LOCAL_LED2 = SWITCH_LED_CLOSE; P1INP &= ~(1<<3); P1SEL &= ~((1<<0)|(1<<1)|(1<<3)); P1DIR |= (1<<0)|(1<<1)|(1<<3); SWITCH_LED = SWITCH_LED_CLOSE; /* 端点初始化 */ my_epDesc.endPoint = MY_ENDPOINT; my_epDesc.task_id = &my_TaskID; my_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&my_SimpleDesc; my_epDesc.latencyReq = noLatencyReqs; if(afRegister(&my_epDesc) == afStatus_INVALID_PARAMETER) debug("端点注册失败\n"); else debug("端点注册成功\n"); /* 地址结构初始化 */ my_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;//点播 my_DstAddr.endPoint = MY_ENDPOINT; my_DstAddr.addr.shortAddr = 0x0000;//默认为协调器地址 } //zigbee发消息接口 void my_SendPointToPointMessage(uint8 obj,uint8 *str) { uint16 cid; if(identity_nwk == DEV_END_DEVICE){ my_DstAddr.addr.shortAddr = 0x0000; cid = SAMPLEAPP_SENSOR_CLUSTERID; }else if(identity_nwk == DEV_ZB_COORD){ if(obj == SAMPLEAPP_SENSOR_CLUSTERID){ my_DstAddr.addr.shortAddr = join_addr[SAMPLEAPP_SENSOR_CLUSTERID-1].addr; cid = SAMPLEAPP_SENSOR_CLUSTERID; }else if(obj == SAMPLEAPP_CTRL_CLUSTERID){ my_DstAddr.addr.shortAddr = join_addr[SAMPLEAPP_CTRL_CLUSTERID-1].addr; cid = SAMPLEAPP_CTRL_CLUSTERID; } }else if(identity_nwk == DEV_ROUTER){ return; } debug("send:0x%x,%d\n",my_DstAddr.addr.shortAddr,cid); AF_DataRequest( &my_DstAddr,//目标地址 &my_epDesc, cid, strlen((char const *)str), str, &my_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } //zigbee收到数据处理函数 void my_MessageMSGCB( afIncomingMSGPacket_t *pkt ) { uint8 data[30]; osal_memcpy(data,pkt->cmd.Data,pkt->cmd.DataLength); data[pkt->cmd.DataLength] = 0;//变成一个字符串 debug("recv:%s\n",data); switch ( pkt->clusterId ) { case SAMPLEAPP_CTRL_CLUSTERID: //控制类 if((identity_nwk == DEV_ZB_COORD)&&(strncmp((char *)pkt->cmd.Data,CLIENT_AFFIRM,6) == 0)){//如果是协调器就收集一下终端地址 debug("控制终端入网地址:0x%x\n",pkt->srcAddr.addr.shortAddr); join_addr[SAMPLEAPP_CTRL_CLUSTERID-1].type = SAMPLEAPP_CTRL_CLUSTERID; join_addr[SAMPLEAPP_CTRL_CLUSTERID-1].addr = pkt->srcAddr.addr.shortAddr; break;//收集完地址退出 }else if(identity_nwk == DEV_END_DEVICE){ if(strncmp((char *)pkt->cmd.Data,SET_TEMP_ADJUST_OPEN,strlen(SET_TEMP_ADJUST_OPEN)) == 0){ SWITCH_LED = SWITCH_LED_OPEN; }else if(strncmp((char *)pkt->cmd.Data,SET_TEMP_ADJUST_CLOSE,strlen(SET_TEMP_ADJUST_CLOSE)) == 0){ SWITCH_LED = SWITCH_LED_CLOSE; }else if(strncmp((char *)pkt->cmd.Data,SET_HUMI_ADJUST_OPEN,strlen(SET_HUMI_ADJUST_OPEN)) == 0){ SWITCH_LED = SWITCH_LED_OPEN; }else if(strncmp((char *)pkt->cmd.Data,SET_HUMI_ADJUST_CLOSE,strlen(SET_HUMI_ADJUST_CLOSE)) == 0){ SWITCH_LED = SWITCH_LED_CLOSE; } } break; case SAMPLEAPP_SENSOR_CLUSTERID://传感器类 if((identity_nwk == DEV_ZB_COORD)&&(strncmp((char *)pkt->cmd.Data,CLIENT_AFFIRM,6) == 0)){//如果是协调器就收集一下终端地址 debug("采集终端入网地址:0x%x\n",pkt->srcAddr.addr.shortAddr); join_addr[SAMPLEAPP_SENSOR_CLUSTERID-1].type = SAMPLEAPP_SENSOR_CLUSTERID; join_addr[SAMPLEAPP_SENSOR_CLUSTERID-1].addr = pkt->srcAddr.addr.shortAddr; break;//收集完地址退出 }else if(strncmp((char *)pkt->cmd.Data,SET_TEMP_ADJUST_OPEN,strlen(SET_TEMP_ADJUST_OPEN)) == 0){ LOCAL_LED1 = SWITCH_LED_OPEN; SWITCH_LED = SWITCH_LED_OPEN; }else if(strncmp((char *)pkt->cmd.Data,SET_TEMP_ADJUST_CLOSE,strlen(SET_TEMP_ADJUST_CLOSE)) == 0){ LOCAL_LED1 = SWITCH_LED_CLOSE; SWITCH_LED = SWITCH_LED_CLOSE; }else if(strncmp((char *)pkt->cmd.Data,SET_HUMI_ADJUST_OPEN,strlen(SET_HUMI_ADJUST_OPEN)) == 0){ LOCAL_LED2 = SWITCH_LED_OPEN; SWITCH_LED = SWITCH_LED_OPEN; }else if(strncmp((char *)pkt->cmd.Data,SET_HUMI_ADJUST_CLOSE,strlen(SET_HUMI_ADJUST_CLOSE)) == 0){ LOCAL_LED2 = SWITCH_LED_CLOSE; SWITCH_LED = SWITCH_LED_CLOSE; }else if(strncmp((char *)pkt->cmd.Data,PERIODIC_REPORT_TH,strlen(PERIODIC_REPORT_TH)) == 0){ if(identity_nwk == DEV_ZB_COORD){ coord_th_dispose(data);//periodic_th,25,60,open,close } }else if(strncmp((char *)pkt->cmd.Data,GET_DATA,strlen(GET_DATA)) == 0){//传感器收到协调器获取数据的请求命令 if(identity_nwk == DEV_END_DEVICE){//传感器发数据 get_th_send_to_coord(GET_DATA); osal_set_event(my_TaskID,DEMO_GET_TH); }else if(identity_nwk == DEV_ZB_COORD){//协调器收数据并转发给网关 char temp[80]; debug("%s\n",data); //get_data,24,29,40,60,25,60,open,close,auto,manual sprintf(temp,"%s,%d,%d,%d,%d,%s,%s,%s",GET_DATA, adjust.temp_min, adjust.temp_max, adjust.humi_min, adjust.humi_max, data+strlen(GET_DATA)+1,//跳过"get_data,"字符,取出"25,60,open,close" adjust.temp_c_mode, adjust.humi_c_mode ); debug("%s\n",temp); send_to_gateway((char *)temp); coord_th_dispose(data);//get_data,25,60,open,close } } break; } } //任务事件处理函数 uint16 my_ProcessEvent( uint8 task_id, uint16 events ) { afIncomingMSGPacket_t *MSGpkt = NULL; if (events & SYS_EVENT_MSG) { MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( my_TaskID ); while(MSGpkt != NULL){ switch ( MSGpkt->hdr.event ) { case ZDO_STATE_CHANGE: identity_nwk = (devStates_t)(MSGpkt->hdr.status); if(identity_nwk == DEV_END_DEVICE){ debug("入网成功\n"); debug("获得地址=0x%x\n",NLME_GetShortAddr()); #if CTRL_OR_GATHER//控制节点/采集节点入网成功后先发一个数据给协调器以确认自己是谁,并让协调器记录这个地址 send_coord_affirm(SAMPLEAPP_CTRL_CLUSTERID);//这是不同终端要改的地方 #else send_coord_affirm(SAMPLEAPP_SENSOR_CLUSTERID);//这是不同终端要改的地方 #endif } break; case AF_INCOMING_MSG_CMD://接收到无线消息 my_MessageMSGCB(MSGpkt); break; case CMD_SERIAL_MSG: { uint8 str[UART_RECV_LEN]; uint8 port = *(((mtOSALSerialData_t *)MSGpkt)->msg);//数据包格式:串口+长度+数据 uint8 len = *(((mtOSALSerialData_t *)MSGpkt)->msg+1); if(len < UART_RECV_LEN) osal_memcpy(str,((mtOSALSerialData_t *)MSGpkt)->msg+2,len); else break; if(len > 1){ *(str+len) = 0; debug("uart%d(%d):%s\n",port,len,str); serial_dispos(port,len,str); } } break; } osal_msg_deallocate( (uint8 *)MSGpkt ); MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(my_TaskID); } return (events ^ SYS_EVENT_MSG); }else if (events & DEMO_KEYBOARD_1){ debug("key1 down\n"); my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_TEMP_ADJUST_OPEN); my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_HUMI_ADJUST_OPEN); my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_TEMP_ADJUST_OPEN); my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_HUMI_ADJUST_OPEN); LOCAL_LED1 = SWITCH_LED_OPEN; LOCAL_LED2 = SWITCH_LED_OPEN; SWITCH_LED = SWITCH_LED_OPEN; return (events ^ DEMO_KEYBOARD_1); }else if (events & DEMO_KEYBOARD_2){ debug("key2 down\n"); my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_TEMP_ADJUST_CLOSE); my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_HUMI_ADJUST_CLOSE); my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_TEMP_ADJUST_CLOSE); my_SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_HUMI_ADJUST_CLOSE); LOCAL_LED1 = SWITCH_LED_CLOSE; LOCAL_LED2 = SWITCH_LED_CLOSE; SWITCH_LED = SWITCH_LED_CLOSE; return (events ^ DEMO_KEYBOARD_2); }else if (events & DEMO_GET_TH){ if(identity_nwk == DEV_END_DEVICE){ get_th_send_to_coord(PERIODIC_REPORT_TH); osal_start_timerEx(my_TaskID,DEMO_GET_TH,SENSOR_PERIODIC_REPORTED); } return (events ^ DEMO_GET_TH); } return 0; }