yeelink探究

2023-10-08 21:50
文章标签 探究 yeelink

本文主要是介绍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探究的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/168220

相关文章

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

探究零工市场小程序如何改变传统兼职模式

近年来,零工市场小程序正逐渐改变传统的兼职模式,为求职者和雇主提供了一个更为高效、便捷的平台。本文将深入探讨零工市场小程序如何影响传统兼职模式,以及它带来的优势和挑战。 一、背景与挑战 传统的兼职市场往往存在信息不对称的问题,求职者难以快速找到合适的工作,而雇主也难以找到匹配的劳动力。此外,兼职工作的不稳定性和安全性也是求职者关注的焦点。零工市场小程序的兴起,旨在解决这些问题,通过数字化手

apk中签名文件探究(*.SF, *.MF,*.RSA)

文章来源: 作者:嘟嘟小灰 链接:https://www.jianshu.com/p/e07da93acf98 来源:简书 1、取一个apk,然后进行不同签名,生成1.apk、2.apk,并提取META-INF里面的文件进行比对 def calc_sha1(data):sha1obj = hashlib.sha1()if not isinstance(data, (bytear

TRIZ在充电桩安全中的应用探究

在当今电动汽车日益普及的时代,充电桩的安全问题至关重要。TRIZ(发明问题解决理论)可以为提升充电桩的安全性提供强大助力。具体步骤如深圳天行健企业管理咨询公司下文所述: 一、充电桩安全面临的问题 1.电气安全风险:包括过压、过流、短路等电气故障,可能导致设备损坏、火灾甚至人员伤亡。 2.机械安全风险:如充电桩外壳的坚固程度、充电插头的插拔可靠性等,可能影响用户的使用安全。 3.环境安全

Flink on YARN模式下TaskManager的内存分配探究

点击上方蓝色字体,选择“设为星标” 回复”资源“获取更多资源 我们使用如下的参数提交了Flink on YARN作业(per-job模式)。 /opt/flink-1.9.0/bin/flink run \--detached \--jobmanager yarn-cluster \--yarnname "x.y.z" \--yarnjobManagerMemory 2048 \--

BBR 与 AIMD 共存公平性探究

一个古已有之的结论: deep buffer 场景,bbr 相对 reno/cubic 等 aimd 有优势,侵占性强;shallow buffer 场景,aimd 有优势,bbr 带宽被挤占。 本文用实例分析 why 并给出 how。 先看 deep buffer 场景 bbr 单挑 aimd 双流的效果,下图是标准 bbr,被虐成经理: 下图是用 max(bw/delay) 替代 ma

深入Linux轻量级进程管理:线程创建、线程ID解析与进程地址空间页表探究

🍑个人主页:Jupiter. 🚀 所属专栏:Linux从入门到进阶 欢迎大家点赞收藏评论😊 目录 `🚲Linux线程控制``🐏POSIX线程库``🐕创建线程``🐟指令查看轻量级进程``指令:ps -aL` `🐒线程ID及进程地址空间布局`*pthread_t 到底是什么类型呢?* `🦔__thread与线程的局部存储`

「OC」剪不断,理还乱——UIResponder、UIGestureRecognizer、UIControl的响应优先级探究

「OC」剪不断,理还乱——UIResponder、UIGestureRecognizer、UIControl的响应优先级探究 文章目录 「OC」剪不断,理还乱——UIResponder、UIGestureRecognizer、UIControl的响应优先级探究前言介绍UIResponderUIGestureRecognizerUIControl 正文UIGestureRecognizer和

Mac工程动态库配置和加载探究

缘起 最近在做Mac程序的打包,其中涉及到Mac程序引用了Hoops的第三方动态库。在之前的工程配置中,Project的Run Script是这么来处理动态库的: FRAMEWORKS_DIR=${TARGET_BUILD_DIR}/${EXECUTABLE_NAME}.app/Contents/Frameworks/mkdir -p ${FRAMEWORKS_DIR}if [ -f ${T