基于树莓派的智能家居项目整理

news2024/10/1 21:37:14

一、功能介绍
二、设计框图
三、实物展示
四、程序

一、功能介绍
硬件:树莓派3B、LD3320语音识别模块、pi 摄像头、继电器组、小灯、火焰传感器、蜂鸣器、电             磁锁

项目框架:
    采用了简单工厂模式的一个设计方式。稳定,拓展性更强,在C语言中,因为没有接口、类这一说法,所以这里采用了结构体来“等效替换”。有四个灯,所以我创建了四个灯控制.c程序。每一个程序文件中,都有一个设备结构体,每个程序文件的函数实现方法不同,当有新设备进入只需要在创建一个.c文件,改变函数实现方法即可。初始化的时候,通过链表将各个模块连接起来(头插法)。在要使用某个模块时,只需要使用链表遍历,找到所需模块去调用功能
具体功能是
1、可通过ld3320语音模块的口令模式,口令+具体控制,通过串口把控制指令传给树莓派,来控  制客厅、餐厅、二楼、浴室的灯,以及 人脸识别功能。
2、也可以通过socket客户端来发指令来控制灯的开关,电磁锁
3、火灾报警,当火焰传感器检测到火焰的时候,蜂鸣器会报警。
4、视频监控采用开源mjpg-Streamer来实现的,程序执行时创建一个视频监控的线程,用system函数调用启动脚本运行,监控画面可在http://172.20.10.8:8080去看到
5、人脸识别开锁,人脸识别功能是使用的翔云平台的人脸识别解决方案,需要安装libcurl 和 openSSl库来支持https协议,通过系统调用wget +http://172.20.10.8:8080/?action=snapshot -O ./huyu1.jpg 指令到树莓派的监控页面"去截取一帧保存到本地,获取图片的base64编码,工程文件夹下也有一张照片,huyu.jpg格式,相当于采集的人脸。也是获取图片的base64编码,通过sprintf函数将访问翔云需要的两张图片的base64编码与Key、secret、typeId、format拼接在一起,通过https协议去访问翔云平台, 识别成功后会将识别结果返回,通过回调函数readData将返回的字符串读到readBuff里,通过strstr去readbuff里找有没有字符’是’,如果识别成功就去控制电磁锁打开。

二、设计框图

  请添加图片描述

 四、程序

   control Device

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>



struct Devices
{
   char name[128];
   int status;
   int pinName;
   int (*open)(int pinName);
   int (*close)(int pinName);
   int (*deviceInit)(int pinName);

   void (*justDoOnce)();
   char* (*getFace)();
   char* (*getPicFromOCRBase64)(); 
   
   int (*readStaus)(int pinName);
   int (*changeStatus)(int status);

    
   
   struct Devices* next;
};

struct Devices* addbathroomLink(struct Devices* head);
struct Devices* addupstairLink(struct Devices* head);
struct Devices* addrestaurantLink(struct Devices* head);
struct Devices* addlivingroomLink(struct Devices* head);
struct Devices* addcameraToDeviceLink(struct Devices *head);
struct Devices* addfiretoLink(struct Devices* head);
struct Devices* addBeepToDeviceLink(struct Devices *phead)	;

 inoutcommand

#include <stdlib.h>
#include <wiringPi.h>

struct inputcommander{
   char commandName[128]; 
   char deviceName[128];
   char command[32];
   int (*init)(struct inputcommander*voicer ,char* ipAddress,char* port);
   int (*getCommand)(struct inputcommander* voicer);

   char log[1024];
   int fd;

   char port[12];
   char ipAddress[32];
   int sfd;
   struct inputcommander*next;
   	};
   

 struct inputcommander* addvoiceControlInputLink(struct inputcommander* phead);
 struct inputcommander* addsockControlLink(struct inputcommander* phead);

bathroom

#include "controDevice.h"

int bathroomLightopen(int pinName){
     digitalWrite(pinName,LOW);
  }

int bathroomLightclose(int pinName){
     digitalWrite(pinName,HIGH);
	 
  }

int bathroomLightInit(int pinName){
    
	pinMode(pinName,OUTPUT);
	digitalWrite(pinName,HIGH);
}



struct Devices bathroomLight = {
	  .name="bathroomLight",
	  .pinName=22,	
	  .open=bathroomLightopen,
	  .close=bathroomLightclose,
  	  .deviceInit=bathroomLightInit
  	  
};


struct Devices* addbathroomLink(struct Devices* head){
     if(head==NULL){
         return &bathroomLight;
	 }
	 else
	 {
        bathroomLight.next=head;
		head=&bathroomLight;
		return head;
	   }
}

livinglight

#include "controDevice.h"

int livingroomLightopen(int pinName){
     digitalWrite(pinName,LOW);
  }

int livingroomLightclose(int pinName){
     digitalWrite(pinName,HIGH);
	 
  }

int livingroomLightInit(int pinName){
    
	pinMode(pinName,OUTPUT);
	digitalWrite(pinName,HIGH);
  }

int livingroomLightChangestatus(int status){

  }

struct Devices livingroomLight = {
	  .name="livingroomLight",
	  .pinName=24,	
	  .open=livingroomLightopen,
	  .close=livingroomLightclose,
  	  .deviceInit=livingroomLightInit,
  	  .changeStatus=livingroomLightChangestatus
};

struct Devices* addlivingroomLink(struct Devices* head){
     if(head==NULL){
         return &livingroomLight;
	 }
	 else
	 {
        livingroomLight.next=head;
		head=&livingroomLight;
		return head;
	   }
}

restraut light

#include "controDevice.h"

int restaurantLightopen(int pinName){
     digitalWrite(pinName,LOW);
  }

int restaurantLightclose(int pinName){
     digitalWrite(pinName,HIGH);
	 
  }

int restaurantLighttInit(int pinName){
    
	pinMode(pinName,OUTPUT);
	digitalWrite(pinName,HIGH);
  }

int restaurantLightChangestatus(int status){

  }

struct Devices restaurantLight = {
	  .name="restaurantLight",
	  .pinName=23,	
	  .open=restaurantLightopen,
	  .close=restaurantLightclose,
  	  .deviceInit=restaurantLighttInit,
  	  .changeStatus=restaurantLightChangestatus
};

struct Devices* addrestaurantLink(struct Devices* head){
     if(head==NULL){
         return &restaurantLight;
	 }
	 else
	 {
        restaurantLight.next=head;
		head=&restaurantLight;
		return head;
	   }
}

upstair light

#include "controDevice.h"

int upstairLightopen(int pinName){
     digitalWrite(pinName,LOW);
  }

int upstairLightclose(int pinName){
     digitalWrite(pinName,HIGH);
	 
  }

int upstairLightInit(int pinName){
    
	pinMode(pinName,OUTPUT);
	digitalWrite(pinName,HIGH);
  }

int upstairLightChangestatus(int status){

  }

struct Devices upstairLight = {
	  .name="upstairLight",
	  .pinName=21,	
	  .open=upstairLightopen,
	  .close=upstairLightclose,
  	  .deviceInit=upstairLightInit,
  	  .changeStatus=upstairLightChangestatus
};

struct Devices* addupstairLink(struct Devices* head){
     if(head==NULL){
         return &upstairLight;
	 }
	 else
	 {
        upstairLight.next=head;
		head=&upstairLight;
		return head;
	   }
}

filre

#include "controDevice.h"



int firetoInit(int pinName){           //初始化函数
    
	pinMode(pinName,INPUT);                      	//配置引脚为输入引脚
	digitalWrite(pinName,HIGH);                       //引脚输出高电平,即默认为关闭状态
  }

int firetostatusread(int pinName){                    //读取火焰传感器状态函数
      return digitalRead(pinName);                    	//读取高低电平,返回0或1
  }

struct Devices fireto = {                                 //火焰传感器设备链表节点
	  .name="fire",
	  .pinName=25,	
  	  .deviceInit=firetoInit,
  	  .readStaus=firetostatusread
};

struct Devices* addfiretoLink(struct Devices* head){               //头插法将设备节点加入设备工厂链表函数
     if(head==NULL){
         return &fireto;
	 }
	 else
	 {
        fireto.next=head;
		head=&fireto;
		return head;
	   }
}

bee

#include "controDevice.h"


int beepInit(int pinName)					//初始化函数
{
	pinMode(pinName,OUTPUT);					//配置引脚为输出引脚
	digitalWrite(pinName,HIGH);				//引脚输出高电平,即默认为关闭状态
}

int beepOpen(int pinName)					//打开蜂鸣器函数
{
	digitalWrite(pinName,LOW);
}

int beepClose(int pinName)					//关闭蜂鸣器函数
{
	digitalWrite(pinName,HIGH);
}




struct Devices beep = {			//蜂鸣器设备链表节点
	.name = "beep",
	.pinName = 7,					//树莓派gpio引脚29
	.deviceInit = beepInit,
	.open = beepOpen,
	.close = beepClose
};


	


struct Devices* addBeepToDeviceLink(struct Devices *phead)			//头插法将设备节点加入设备工厂链表函数
{
	if(phead == NULL){
		return &beep;
	}else{
		beep.next = phead;
		phead = &beep;
		return phead;
	}
}

camera

#include "controDevice.h"
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <curl/curl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#define SWITCH1 21


char ocrRetBuf[1024] = {'\0'};//全局变量,用来接收从OCR后台返回的数据

size_t readData1(void *ptr, size_t size, size_t nmemb, void *stream)
//回调函数,把从后台的数据拷贝给ocrRetBuf
{
        strncpy(ocrRetBuf,ptr,1024);
		printf("data reviver\n");
}





char *getPicFromOCRBase641(char *Filepath)
{
        int fd;
        int filelen;
        char cmd[128]={'\0'};

        sprintf(cmd,"base64 %s > tmpFile",Filepath);
        system(cmd);
        fd=open("./tmpFile",O_RDWR);
        filelen=lseek(fd,0,SEEK_END);
        lseek(fd,0,SEEK_SET);
        char *bufpic=(char *)malloc(filelen+2);
        memset(bufpic,'\0',filelen+2);
        read(fd,bufpic,filelen+128);
        system("rm -rf tmpFile");
        close(fd);

        return bufpic;

}


char*getFace1(){
     printf("pai zhao zhong\n");
	system("raspistill -q 5 -t 1 -o pic.jpg");
	
	while(access("./pic.jpg",F_OK) != 0); //判断是否拍照完毕
	
	printf("paizhao wan bi\n");
	
	char* base64BufFaceRec = getPicFromOCRBase641("./pic.jpg");

	system("rm pic.jpg");
	
	return base64BufFaceRec;   //返回刚才拍照的base64


}

void postUrl()
	{
			CURL *curl;
			CURLcode res;
	
			//分开定义,然后字符串拼接
			char* key	 = "P5bruv7dU4YRH7JHNxuCeb";	//翔云平台购买人脸识别后的key
			char* secret = "0c4c02a1161e43bf9de539d6487260c8";	//翔云平台购买人脸识别后的secret
			int   typeId = 21;	
			char* format = "xml";
	
			char* base64BufPic1 = getFace1();
	
			char* base64BufPic2 = getPicFromOCRBase641("PYD.jpg");
	
			int len = strlen(key)+strlen(secret)+strlen(base64BufPic1)+strlen(base64BufPic2)+128;//分配空间不够会导致栈溢出
			char* postString = (char* )malloc(len);
			memset(postString,'\0',len);//因为postString是一个指针,不能用sizeof来计算其指向的大小
	
			sprintf(postString,"img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s",base64BufPic1,base64BufPic2,key,secret,typeId,format);//根据平台的传参格式编写
	
			curl = curl_easy_init();
	
			if(curl){
					curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postString);  //指定post内容,传入参数  
					curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do");// 指定url
					curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,readData1);  //回调函数readDate读取返回值
					res = curl_easy_perform(curl);			//类似于状态码
					printf("OK:%d\n",res);
	
					if(strstr(ocrRetBuf,"是") != NULL){    //判断翔云后台返回的字符串中有没有“是”
							printf("the same person\n");
							pinMode(SWITCH1,OUTPUT);
			                digitalWrite(SWITCH1,LOW);
					}
					else{
							printf("different person\n");
							
			                digitalWrite(SWITCH1,HIGH);
					}
					curl_easy_cleanup(curl);
			}
	
	}


struct Devices camera = {

	.name = "camera",
	.justDoOnce = postUrl,
	.getFace = getFace1,
	.getPicFromOCRBase64 = getPicFromOCRBase641,
	//.readData = readData1

};

struct Devices* addcameraToDeviceLink(struct Devices *head)
{
	if(head == NULL){
		return &camera;
	}
	else{
		camera.next = head;
		head = &camera;
	}
}

socket

#include <wiringSerial.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "inoutCommand.h"




int SocketInit(struct inputcommander* Socketlnits,char*ipAddress,char*port){  
    int s_fd;
	
	struct sockaddr_in s_addr;

	memset(&s_addr,0,sizeof(struct sockaddr_in));
	
    s_fd = socket(AF_INET, SOCK_STREAM,0);
	if(s_fd == -1){
           perror("socket");
		   exit(-1);
            	  }
	
    s_addr.sin_family =AF_INET;
	s_addr.sin_port = htons(atoi(Socketlnits->port));
	inet_aton(Socketlnits->ipAddress , &s_addr.sin_addr);
 
   bind(s_fd , (struct sockaddr*)&s_addr , sizeof(struct sockaddr_in));
  

  listen(s_fd,10);
  printf("socket server Listening >>>\n");
  Socketlnits->sfd=s_fd;

  return s_fd;
	

	  
}



struct inputcommander socketControl = {
  .commandName="socketserver",
  .command={'\0'},
  .port = "8124",
  .ipAddress ="192.168.43.165",
  .init = SocketInit,
  .log = {'\0'},
  .next = NULL
};


struct inputcommander* addsockControlLink(struct inputcommander* phead){
   if(phead==NULL){
         return &socketControl;
	 }
	 else
	 {
        socketControl.next=phead;
		phead=&socketControl;
		return phead;
	   }
  

}

voice control

#include "inoutCommand.h"
#include <wiringSerial.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <string.h>

int voicegetCommand(struct inputcommander* voicer){
	int nread =0;

	memset(voicer->command,'\0',sizeof(voicer->command));
    nread = read(voicer->fd, voicer->command, sizeof(voicer->command));
	if(nread==0){
          printf(" voice device read over times\n");
	    }
	else{
        return nread;
	    }
}


int voiceInit(struct inputcommander* voicer,char*ipAddress,char*port){
    
   int fd;
   if((fd = serialOpen(voicer->deviceName,9600))<0){
   	printf("voicelnit open error\n");
       return (-1);
    }
   printf("voicelnit...contun...\n");
   voicer->fd=fd;
   return fd;

}




struct inputcommander voiceControl = {
  .commandName="voice",
  .deviceName="/dev/ttyAMA0",
  .command={'\0'},
  .init = voiceInit,
  .getCommand = voicegetCommand,
  .log = {'\0'},
  .next = NULL
};


struct inputcommander* addvoiceControlInputLink(struct inputcommander* phead){
   if(phead==NULL){
         return &voiceControl;
	 }
	 else
	 {
        voiceControl.next=phead;
		phead=&voiceControl;
		return phead;
	   }
}

main

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "inoutCommand.h"
#include "controDevice.h"
#include<unistd.h>
#include<pthread.h>
#include<wiringPi.h>
#include<wiringSerial.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>

#define SWITCH1 21		//四盏灯对应的引脚
#define SWITCH2 22
#define SWITCH3 23
#define SWITCH4 24
#define SWITCH5 25


struct Devices* tem=NULL;
struct inputcommander* commandhead=NULL; 

struct inputcommander*socketHeadler = NULL;
     int c_fd;


struct Devices* findDeviceByName(char* name,struct Devices* phead){

struct Devices*tmp=phead;

if(phead==NULL){
     return NULL;
   }
 else{
     while(tmp!=NULL){
         if(strcmp(tmp->name,name)==0){
             return tmp;
		    }  
		   tmp=tmp->next;
	       }
	    return NULL;
     }
}

struct inputcommander* findcommandByName(char* name,struct inputcommander* phead){

struct inputcommander*tmp=phead;

if(phead==NULL){
     return NULL;
   }
 else{
     while(tmp!=NULL){
         if(strcmp(tmp->commandName,name)==0){
             return tmp;
		    }  
		   tmp=tmp->next;
	       }
	    return NULL;
     }
}



void *fireAlarmThread(void *data)				//“火灾报警器线程”执行的函数
{
	int status;
	struct Devices *firetmp = NULL;
	struct Devices *buztmp = NULL;

	firetmp = findDeviceByName("fire",tem);		//寻找“火焰传感器”链表节点,返回给firetmp
	buztmp = findDeviceByName("beep",tem);				//寻找“蜂鸣器”链表节点,返回给buztmp
      
	while(1){
		status = firetmp->readStaus(firetmp->pinName);			//读取“火焰传感器”状态
	        buztmp->deviceInit(buztmp->pinName);
		if(status == 0){			   //检测到火焰或强光源
		        printf("have fire\n");
			buztmp->open(buztmp->pinName);		//打开蜂鸣器
			delay(1000);						//延时1000毫秒=1秒
		}

		if(status == 1){						//未检测到火焰、强光源或解除警报
			buztmp->close(buztmp->pinName);		//关闭蜂鸣器
		}
	}
}





void *cameraThread_func(void* data)//起线程的函数有格式要求
{
	struct Devices *cameraTemp;
	cameraTemp = findDeviceByName("camera", tem); 	//设备都要从工厂里面取出来
      
	if(cameraTemp == NULL){  //防止段错误的必需判断,当给指针赋值是,一定要考虑NULL的情况,否则后续操作都是空谈
		printf("find camera error\n");
		pthread_exit(NULL); //在线程中不用return
	}
	printf("222\n");
	cameraTemp->justDoOnce(); //调用postUrl函数
}



void* read_Thread(void* datas){
     int n_read;
	 memset(socketHeadler->command,'\0',sizeof(socketHeadler->command));
     n_read = read(c_fd,socketHeadler->command,sizeof(socketHeadler->command));
    if(n_read == -1){
         perror("read");
	    }
	else if(n_read>0){
         printf("\n socker read number:%d , contixt:%s\n",n_read,socketHeadler->command);
		     if(strstr(socketHeadler->command,"KS") != NULL){
			    printf("open lock\n");
	            pinMode(SWITCH1,OUTPUT);
			    digitalWrite(SWITCH1,LOW);
			 }
		    if(strstr(socketHeadler->command,"KYS") != NULL){		
                 pinMode(SWITCH2,OUTPUT);
				 digitalWrite(SWITCH2,LOW);
			  }
			if(strstr(socketHeadler->command,"GYS") != NULL){
				digitalWrite(SWITCH2,HIGH);
			 }
			if(strstr(socketHeadler->command,"KKT") != NULL){		//对socket收到的指令进行分析,并执行对应的操作
                 pinMode(SWITCH4,OUTPUT);
				 digitalWrite(SWITCH4,LOW);
			  }
			if(strstr(socketHeadler->command,"GKT") != NULL){
				digitalWrite(SWITCH4,HIGH);
			 }
			if(strstr(socketHeadler->command,"KCT") != NULL){		//对socket收到的指令进行分析,并执行对应的操作
                 pinMode(SWITCH3,OUTPUT);
				 digitalWrite(SWITCH3,LOW);
			  }
			if(strstr(socketHeadler->command,"GCT") != NULL){
				digitalWrite(SWITCH3,HIGH);
			 }
			if(strstr(socketHeadler->command,"GS") != NULL){
                 digitalWrite(SWITCH1,HIGH);
			  }
		else{
          printf("Input error! \n");
		}
			
			
			
			
			
			
	 }
}




void* voiceThread(void* datas){
	int nread;
    struct inputcommander* voiceHead=findcommandByName("voice",commandhead);
	if(voiceHead==NULL){
		printf(" no voice \n");
		pthread_exit(NULL);
		}
	else{
		printf("%s find voice \n",voiceHead->commandName);
		if(voiceHead->init(voiceHead, NULL ,NULL)<0){
             printf("voice init error!!!\n");
			 pthread_exit(NULL);
		    }
		else{
            printf(" %s init successful!\n",voiceHead->commandName);
		    }
	   while(1){
		      nread = voiceHead->getCommand(voiceHead);
                 if(nread == 0){
                    printf("waiting...\n");
		                      }
		         else{
			        printf("do divece control : %s\n",voiceHead->command);
					if(strstr(voiceHead->command,"XJ") != NULL){		//一级指令,
					   printf("收到:\n");	
			    }else if(strstr(voiceHead->command,"KYSD") != NULL){		
			         pinMode(SWITCH2,OUTPUT);
				    digitalWrite(SWITCH2,LOW);
				}else if(strstr(voiceHead->command,"GYSD") != NULL){
					digitalWrite(SWITCH2,HIGH);
				}else if(strstr(voiceHead->command,"KCTD") != NULL){
				    pinMode(SWITCH3,OUTPUT);
					digitalWrite(SWITCH3,LOW);
				}else if(strstr(voiceHead->command,"GCTD") != NULL){
					digitalWrite(SWITCH3,HIGH);
				}else if(strstr(voiceHead->command,"KKTD") != NULL){
				     pinMode(SWITCH4,OUTPUT);
					digitalWrite(SWITCH4,LOW);
				}else if(strstr(voiceHead->command,"GKTD") != NULL){
					digitalWrite(SWITCH4,HIGH);
				}else if(strstr(voiceHead->command,"KS") != NULL){
				    pthread_t cameraThread;
				     printf("1111\n");
				     system("sudo killall -TERM motion");
				     delay(3000);	
	                  pthread_create(&cameraThread,NULL,cameraThread_func,NULL);
					 }
		         	}
		      }  
	  }
}


void* socketThread(void* datas){
     int n_read = 0;
	 pthread_t readThread;
	 struct sockaddr_in c_addr;
	 
	 
	 memset(&c_addr,0,sizeof(struct sockaddr_in));
	 int clen = sizeof(struct sockaddr_in);

     socketHeadler=findcommandByName("socketserver",commandhead);
	 if(socketHeadler ==NULL){
           printf("NO find socketserver!\n");
		   pthread_exit(NULL);
	     }
	  else{
          printf("find socketserver!\n");          
    	   	}
 
	 socketHeadler->init(socketHeadler,NULL,NULL);
	 while(1){
        c_fd=accept(socketHeadler->sfd,(struct sockaddr*)&c_addr,&clen);
     
         pthread_create(&readThread,NULL,read_Thread,NULL);  
	   }
}


void * video_thread(void *datas){

system("sudo motion");
printf(" chest ... \n");
	//pthread_exit(NULL);	

}





int main(){

if(wiringPiSetup() == -1){				  
	printf("wiringPiSetup failed!\n");
	return -1; 
	}

char name[128];

pthread_t voice_thread;
pthread_t socket_thread;
pthread_t fireAlarm_thread;
pthread_t videoThread;


//设备工厂初始化
tem=addbathroomLink(tem);
tem=addupstairLink(tem);
tem=addrestaurantLink(tem);
tem=addlivingroomLink(tem);

tem= addfiretoLink(tem);
tem=addBeepToDeviceLink(tem);		
	

tem=addcameraToDeviceLink(tem);


commandhead=addvoiceControlInputLink(commandhead);
commandhead=addsockControlLink(commandhead);



pthread_create(&voice_thread , NULL , voiceThread , NULL);
pthread_create(&socket_thread , NULL , socketThread , NULL);
pthread_create(&fireAlarm_thread,NULL,fireAlarmThread,NULL);

pthread_create(&videoThread, NULL, video_thread, NULL);




pthread_join(voice_thread,NULL);
pthread_join(socket_thread,NULL);
pthread_join(fireAlarm_thread,NULL);





pthread_join(videoThread,NULL);

        
return 0;
}


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/352758.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023美赛ABCDEF题思路+参考文献+代码

选题建议、ABCDEF题参考文献、ABCDEF题思路&#xff08;后续更新视频和代码&#xff09;、D题数据、数据集及处理方式已更新&#xff0c;其他日内更新。下文包含&#xff1a;2023年美国大学生数学建模竞赛&#xff08;以下简称美赛&#xff09;A - F题思路解析、选题建议、代码…

插件开发版|Authing 结合 APISIX 实现统一可配置 API 权限网关

当开发者在构建网站、移动设备或物联网应用程序时&#xff0c;API 网关作为微服务架构中不可或缺的控制组件&#xff0c;是流量的核心进出口。通过有效的权限管控&#xff0c;可以实现认证授权、监控分析等功能&#xff0c;提高 API 的安全性、可用性、拓展性以及优化 API 性能…

【郭东白架构课 模块一:生存法则】06|法则二:拼多多是如何通过洞察用户人性脱颖而出的?

你好&#xff0c;我是郭东白。上节课我们学习了怎么利用马斯洛理论去指导架构设计&#xff0c;尤其是该如何考虑和顺应研发人员的人性。 我们都知道&#xff0c;软件这个虚拟的存在最终是要服务于用户的&#xff0c;所以在软件设计的过程中也要考虑用户的人性。也就是说&#…

二进制中1的个数-剑指Offer-java位运算

一、题目描述编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 1 的个数&#xff08;也被称为 汉明重量).&#xff09;。提示&#xff1a;请注意&#xff0c;在某些语言&#xff08;如 Java&…

chatGPT在软件测试中七大应用方式

chatGPT火得不能再火了&#x1f525;过去两周&#xff0c;国内chatGPT概念股很疯狂&#xff0c;不只是百度、讯飞&#xff0c;有些默默无闻且业绩亏损的公司股价大涨&#xff0c;有1-2个公司连续7个涨停板&#xff0c;不可思议&#xff01;上周&#xff0c;因为微软Bing发布新版…

postman-enterprise-API

Postman 是一个用于构建和使用 API 的 API 平台。Postman 简化了 API 生命周期的每个步骤并简化了协作&#xff0c;因此您可以更快地创建更好的 API。 API存储库 在一个中央平台上围绕您的所有 API 工件轻松存储、编目和协作。Postman 可以存储和管理 API 规范、文档、工作流配…

【Unity资源下载】POLYGON Dungeon Realms - Low Poly 3D Art by Synty

$149.99 Synty Studios 一个史诗般的低多边形资产包&#xff0c;包括人物、道具、武器和环境资产&#xff0c;用于创建一个以奇幻为主题的多边形风格游戏。 模块化的部分很容易在各种组合中拼凑起来。 包包含超过1,118个详细预制件。 主要特点 ◼ ◼ 完全模块化的地下城!包…

“消息驱动、事件驱动、流 ”的消息模型

文章目录背景消息驱动 Message-Driven事件驱动 Event-Driven流 Streaming事件规范标准简介&#xff1a; 本文旨在帮助大家对近期消息领域的高频词“消息驱动&#xff08;Message-Driven&#xff09;&#xff0c;事件驱动&#xff08;Event-Driven&#xff09;和流&#xff08;S…

基于Java+Swing+Mysql实现通讯录管理系统

基于JavaSwingMysql实现通讯录管理系统一、系统介绍二、功能展示1.用户登陆2.查询信息3.新增信息4.修改信息5.删除信息三、数据库四、其他系统实现五、获取源码一、系统介绍 1.登录系统 2.查询信息 3.新增信息 4.修改信息 5.删除信息 运行环境&#xff1a;idea/eclipse、mysq…

erupt框架Ueditor富文本编辑器图片上传出现405异常

最近在研究erupt框架(v1.11.2),当字段使用Ueditor富文本编辑器,在图片上传的时候出现405异常,接口不支持POST请求方式: 根据错误提示找到对应的源码,发现Handler方法只支持GET请求,而图片上传的时候是以POST方式发起请求的; 此时需要修改源码,用自定义的类覆盖jar包中同名的…

Qt系列:调用Edge浏览器示例

背景 需要解决以下几个问题 政府项目新浏览器兼容老系统ActiveX控件&#xff0c;Qt WebEngineView没有直接的实现方案&#xff0c;需要利用Qt的ActiveX兼容模块与浏览器往返多次交互Qt ActiveX未实现COM事件通知官方Win32示例存在滥用lambda函数的嫌疑&#xff0c;lambda函数…

2023年保健饮品行业分析:市场规模不断攀升,年度销额增长近140%

随着人们健康意识的不断增强&#xff0c;我国保健品市场需求持续增长&#xff0c;同时&#xff0c;保健饮品的市场规模也在不断攀升。 根据鲸参谋电商数据显示&#xff0c;2022年度&#xff0c;京东平台上保健饮品的年度销量超60万件&#xff0c;同比增长了约124%&#xff1b;该…

flutter-第1章-配置环境

flutter-第1章-配置环境 本文针对Windows系统。 一、安装Android Studio 从Android Studio官网下载最新版本&#xff0c;一直默认安装就行。 安装完成要下载SDK&#xff0c;可能会需要科学上网。 打开AS&#xff0c;随便创建一个新项目。 点击右上角的SDK Manager 找到SDK…

c#: NetTopologySuite凹凸多边形计算

环境&#xff1a; .net 6.0NetTopologySuite 2.5.0vs2022平面二维 一、夹角计算 1.1 计算向量与x轴正方向的夹角 方法: AngleUtility.Angle(Coordinate p) 下图上的t2即为p&#xff0c;之所以这么写是为了和AngleUtility.AngleBetweenOriented做比较 注意&#xff1a; 结果…

MySQL 服务正在启动.MySQL 服务无法启动.服务没有报告任何错误。请键入 NET HELPMSG 3534 以获得更多的帮助。总结较全 (已解决)

输入以下命令启动mysql&#xff1a; net start mysql出现以下错误提示&#xff1a; MySQL 服务正在启动 .MySQL 服务无法启动。服务没有报告任何错误。请键入 NET HELPMSG 3534 以获得更多的帮助。 出现这个问题的话&#xff0c;一般有几个情况&#xff1a; 一、MySQL安装文…

面试7分看能力,3分靠嘴皮,剩下90分就靠这份Java面试八股文

有句话说的好&#xff0c;面试中7分靠能力&#xff0c;3分靠嘴皮刚开始面试的时候&#xff0c;介绍项目一般都是凸显我们技能的重中之重&#xff0c;它对一次面试的成败可以说具有决定性作用&#xff0c;这就涉及到我们的表达能力了&#xff0c;有人说我其实水平都在线&#xf…

大学生开学买什么,返校必备数码好物推荐

开学还不知道需要准备些什么&#xff0c;这篇开学数码好物&#xff0c;希望能够对你在开学购买的好物有一些帮助&#xff0c;一款好的数码装备&#xff0c;可以让我们在学校学习当中能够用最少的时间&#xff0c;最大的产出&#xff0c;节省时间&#xff0c;提高学习效率&#…

2023-02-17 学习记录--TS-邂逅TS(一)

TS-邂逅TS&#xff08;一&#xff09; 不积跬步&#xff0c;无以至千里&#xff1b;不积小流&#xff0c;无以成江海。&#x1f4aa;&#x1f3fb; 一、TypeScript在线编译器 https://www.typescriptlang.org/play/ 二、类型 1、普通类型 number&#xff08;数值型&#xff…

零信任-360连接云介绍(9)

​360零信任介绍 360零信任又称360连接云安全访问平台(下文简称为&#xff1a;360连接云)&#xff0c;360连接云&#xff0c;是360基于零信任安全理念&#xff0c;以身份为基础、动态访问控制为核心打造的安全访问平台。 通过收缩业务暴露面、自适应增强身份认证、终端持续检…

操作系统(day11)--快表,两级页表

具有快表的地址变换机构 时间局限性&#xff1a;会有大量连续的指令需要访问同一个内存块的数据的情况&#xff08;程序中的循环&#xff09; 空间局限性&#xff1a;一旦程序访问了某个存储单元&#xff0c;在不久之后&#xff0c;其附近的存储单元也很有可能被访问。&#xf…