本文主要是介绍yeelink探究,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
对yeelink服务器上的相应数据进行改写,并用上位机查看。
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")
// 请求缓冲区和响应缓冲区
char http_request[1024] = { 0, };
char http_response[1024] = { 0, };
// 主机IP地址,也可以是主机域名
char remote_server[] = "api.yeelink.net";
// 文件地址 RESTFUL形式
char remote_path[] = "/v1.0/device/写自己的/sensor/写自己的/datapoints";//需要相应更改
// 用户密码
char apikey[] = "写自己的";//需要相应更改
int main(int argc, char **argv)
{WSADATA wsaData;int result;int socket_id;// 传感器检测结果double value = 5.9;// Http属性char http_attribute[64] = { 0, };// Http内容,表单内容char http_content[64] = { 0, };// 确定HTTP表单提交内容 {"value":20}sprintf_s(http_content, "{\"value\":%.2f}", value);// 确定 HTTP请求首部// 例如POST /v1.0/device/1949/sensor/2510/datapoints HTTP/1.1\r\nchar http_header[64] = { 0, };sprintf_s(http_header, "POST %s HTTP/1.1\r\n", remote_path);strcpy_s(http_request, http_header); // 复制到请求缓冲区中// 增加属性 例如 Host: api.yeelink.net\r\nsprintf_s(http_attribute, "Host:%s\r\n", remote_server);strcat_s(http_request, http_attribute);memset(http_attribute, 0, sizeof(http_attribute));// 增加密码 例如 U-ApiKey: ffa3826972d6cc7ba5b17e104ec59fa3sprintf_s(http_attribute, "U-ApiKey:%s\r\n", apikey);strcat_s(http_request, http_attribute);memset(http_attribute, 0, sizeof(http_attribute));// 增加提交表单内容的长度 例如 Content-Length:12\r\nsprintf_s(http_attribute, "Content-Length:%d\r\n", strlen(http_content));strcat_s(http_request, http_attribute);memset(http_attribute, 0, sizeof(http_attribute));// 增加表单编码格式 Content-Type:application/x-www-form-urlencoded\r\n// 该步骤可省略strcat_s(http_request, "Content-Type:application/x-www-form-urlencoded\r\n");memset(http_attribute, 0, sizeof(http_attribute));// HTTP首部和HTTP内容 分隔部分strcat_s(http_request, "\r\n");// HTTP负载内容strcat_s(http_request, http_content);// Winsows下启用socketresult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (result != 0) {printf("WSAStartup failed: %d\n", result);return 1;}// DNS解析 获得远程IP地址struct hostent *remote_host;remote_host = gethostbyname(remote_server);if (remote_host == NULL){printf("DNS failed\r\n");return 1;}// 创建套接字socket_id = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in remote_sockaddr;remote_sockaddr.sin_family = AF_INET;remote_sockaddr.sin_port = htons(80);remote_sockaddr.sin_addr.s_addr = *(u_long *)remote_host->h_addr_list[0];memset(&(remote_sockaddr.sin_zero), 0, sizeof(remote_sockaddr.sin_zero));// 连接远程主机result = connect(socket_id, (struct sockaddr *)&remote_sockaddr, sizeof(struct sockaddr));if (result == SOCKET_ERROR){printf("connect ok\r\n");}// 发送请求printf("Http request:\r\n%s\r\n", http_request);printf("--------------------\r\n");send(socket_id, http_request, strlen(http_request), 0);// 获得响应int bytes_received = 0;bytes_received = recv(socket_id, http_response, 1024, 0);http_response[bytes_received] = '\0';printf("Receive Message:\r\n%s\r\n", http_response);printf("--------------------\r\n");// 判断是否收到HTTP OKchar* presult = strstr(http_response, "200 OK\r\n");if (presult != NULL) printf("Http response OK\r\n");// 关闭套接字closesocket(socket_id);WSACleanup();// 输入任何字符则关闭程序printf("Finish\r\n"); getchar();return 0;
}
上述代码为数据改写代码,在vs2013c/c++上运行可更改yeelink服务器其上相应数据。
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")
// 请求缓冲区和响应缓冲区
char http_request[1024] = { 0, };
char http_response[1024] = { 0, };
// 主机IP地址,也可以是主机域名
char remote_server[] = "api.yeelink.net";
// 文件地址 RESTFUL形式
char remote_path[] = "/v1.0/device/写自己的/sensor/写自己的/datapoints";
// 用户密码
char apikey[] = "写自己的";char test_http[1024] = { 0, };
char test_str[32];
int main(int argc, char **argv)
{WSADATA wsaData;int result;int socket_id;result = WSAStartup(MAKEWORD(2, 2), &wsaData);if (result != 0) {printf("WSAStartup failed: %d\n", result);return 1;}// DNS解析 获得远程IP地址struct hostent *remote_host;remote_host = gethostbyname(remote_server);if (remote_host == NULL){printf("DNS failed\r\n");return 1;}//printf("yeelink address: %s\n", inet_ntop(remote_host->h_addrtype, remote_host->h_addr_list, test_str, sizeof(test_str)));//test_http = "POST / v1.0 / device / 写自己的/ sensor / 写自己的 / datapoints HTTP / 1.1\r\nHost:api.yeelink.net\r\nU - ApiKey:写自己的\r\nContent - Length:14\r\nContent - Type:application / x - www - form - urlencoded\r\n\r\n{ \"value\":5.90}"sprintf_s(test_http, "POST /v1.0/device/写自己的/sensor/写自己的/datapoints HTTP/1.1\r\nHost:api.yeelink.net\r\nU-ApiKey:写自己的\r\nContent-Length:14\r\nContent-Type:application/x-www-form-urlencoded\r\n\r\n{\"value\":3.90}");// 创建套接字socket_id = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in remote_sockaddr;remote_sockaddr.sin_family = AF_INET;remote_sockaddr.sin_port = htons(80);remote_sockaddr.sin_addr.s_addr = *(u_long *)remote_host->h_addr_list[0];memset(&(remote_sockaddr.sin_zero), 0, sizeof(remote_sockaddr.sin_zero));// 连接远程主机result = connect(socket_id, (struct sockaddr *)&remote_sockaddr, sizeof(struct sockaddr));if (result == SOCKET_ERROR){printf("connect ok\r\n");}// 发送请求//printf("Http request:\r\n%s\r\n", http_request);//printf("--------------------\r\n");printf("test_http:\r\n%s\r\n", test_http);//自定义,需要修改printf("--------------------\r\n");send(socket_id, test_http, strlen(test_http), 0);// 获得响应int bytes_received = 0;bytes_received = recv(socket_id, http_response, 1024, 0);http_response[bytes_received] = '\0';printf("Receive Message:\r\n%s\r\n", http_response);printf("--------------------\r\n");// 判断是否收到HTTP OKchar* presult = strstr(http_response, "200 OK\r\n");if (presult != NULL) printf("Http response OK\r\n");// 关闭套接字closesocket(socket_id);WSACleanup();// 输入任何字符则关闭程序printf("Finish\r\n"); getchar();return 0;
}
第二段代码是对于第一段代码的改写。对比可以发现,整个程序的主要分以下几步
result = WSAStartup(MAKEWORD(2, 2), &wsaData);
1 开启windows自带的功能,固定格式。
remote_host = gethostbyname(remote_server);
2 将域名解析成ip,其中解析的ip地址可以用以下的方式打印出来
printf("yeelink address: %s\n", inet_ntop(remote_host->h_addrtype, remote_host->h_addr_list, test_str, sizeof(test_str)));
3 创建套接字,通过这步,我们得到了两个比较重要的东西:socket_id(不知道干啥) remote_sockaddr(remote_sockaddr.sin_addr.s_addr = *(u_long *)remote_host->h_addr_list[0]; 含有刚才解析的域名的ip)
// 创建套接字socket_id = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in remote_sockaddr;remote_sockaddr.sin_family = AF_INET;remote_sockaddr.sin_port = htons(80);remote_sockaddr.sin_addr.s_addr = *(u_long *)remote_host->h_addr_list[0];memset(&(remote_sockaddr.sin_zero), 0, sizeof(remote_sockaddr.sin_zero));
4 连接远程主机。利用上面已经得到的socket_id 和 remote_sockaddr连接主机
result = connect(socket_id, (struct sockaddr *)&remote_sockaddr, sizeof(struct sockaddr));
5 发送请求。
send(socket_id, test_http, strlen(test_http), 0);
这个请求是有一定格式的,控制相应变量的格式如下
POST /v1.0/device/写自己的/sensor/写自己的/datapoints HTTP/1.1
Host:api.yeelink.net
U-ApiKey:写自己的
Content-Length:14//根据设定的数据长度进行改变
Content-Type:application/x-www-form-urlencoded{"value":5.90}
获取相应变量的格式为
GET /v1.0/device/写自己的/sensor/写自己的/datapoints HTTP/1.1
Host:api.yeelink.net
U-ApiKey:写自己的
Accept: */*
Content-Type:application/x-www-form-urlencoded
Connection: close
只要在连接后,通过send函数将相应格式发送到yeelink服务器上,就能得到相应。
6 获得响应
bytes_received = recv(socket_id, http_response, 1024, 0);http_response[bytes_received] = '\0';
运行之后http_reponse这个变量里面就包含了相应结果。对于获取数据,返回字符串里面就包含数据;对于设定数据,返回字符串里面包含数据设定的成功与否。
7 关闭套接字
closesocket(socket_id);
8 关闭第一步是运行的那个玩意儿
WSACleanup();
运行成功后显示如下
改写后yeelink平台也会有相应变化,这里就不展示了。
以上工程详见:控制yeelink服务器变量;控制yeelink服务器变量(原版)
下面是上位机的制作。上位机的主要功能是没一秒刷新一次结果(yeelink平台上的显示需要手动刷新,恨不爽)。下面是一个网上大神发布的上位机(无刷新)的截图,亲测好使。
以上工程详见:查看yeelink服务器变量
下图是我的上位机
我的上位机是自动刷新,每秒刷新一次。
以上工程详见:查看yeelink服务器变量(刷新)
这篇关于yeelink探究的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!