#物联网征文#【FFH】基于 OpenHarmony 的水流量监测系统(二) 原创 精华
Z·y
发布于 2022-8-8 21:33
浏览
6收藏
承接上文:基于 OpenHarmony 的实时水流量监测管理系统(一)
三、实战
1.2.2管
主要代码:
1)创建 socket 和初始化
创建 socket 配置服务器 ip 和端口
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in sock_addr = {0};
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons(4000);
sock_addr.sin_addr.s_addr = inet_addr("114.116.10.71");
char sendbuf[1024]={0};
2)将数据通过 socket UDP 发送云端
sprintf(sendbuf,"%d",data)
sendto(sockfd, sendbuf, sizeof(sendbuf), 0,
(struct sockaddr*)&sock_addr,sizeof(sock_addr));
sleep(1);
在点led灯上的业务代码上稍作修改即可将数据发送出去。
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include "hdf_sbuf.h"
#include "hdf_io_service_if.h"
//导入相应的头文件
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#define LED_WRITE_READ 1
#define LED_SERVICE "hdf_led"
static int SendEvent(struct HdfIoService *serv, uint8_t eventData)
{
int ret = 0;
struct HdfSBuf *data = HdfSBufObtainDefaultSize();
if (data == NULL)
{
printf("fail to obtain sbuf data!\r\n");
return 1;
}
struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
if (reply == NULL)
{
printf("fail to obtain sbuf reply!\r\n");
ret = HDF_DEV_ERR_NO_MEMORY;
goto out;
}
/* 写入数据 */
if (!HdfSbufWriteUint8(data, eventData))
{
printf("fail to write sbuf!\r\n");
ret = HDF_FAILURE;
goto out;
}
/* 通过Dispatch发送到驱动 */
ret = serv->dispatcher->Dispatch(&serv->object, LED_WRITE_READ, data, reply);
if (ret != HDF_SUCCESS)
{
printf("fail to send service call!\r\n");
goto out;
}
int replyData = 0;
/* 读取驱动的回复数据 */
if (!HdfSbufReadInt32(reply, &replyData))
{
printf("fail to get service call reply!\r\n");
ret = HDF_ERR_INVALID_OBJECT;
goto out;
}
printf("\r\nGet reply is: %d\r\n", replyData);
sprintf(sendbuf,"%d",replyData);
sendto(sockfd, sendbuf, sizeof(sendbuf), 0, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
out:
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
int main(int argc, char **argv)
{
int i;
//1.创建socket
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
//2.配置端口和地址
struct sockaddr_in sock_addr = {0};
sock_addr.sin_family = AF_INET; // 设置地址族为IPv4
sock_addr.sin_port = htons(4000); // 设置地址的端口号信息
sock_addr.sin_addr.s_addr = inet_addr("114.116.10.71"); // 设置IP地址
//3.创建发送缓冲器字符串数组
char sendbuf[1024]={0}; //发送数据
/* 获取服务 */
struct HdfIoService *serv = HdfIoServiceBind(LED_SERVICE);
if (serv == NULL)
{
printf("fail to get service %s!\r\n", LED_SERVICE);
return HDF_FAILURE;
}
for (i=0; i < argc; i++)
{
printf("\r\nArgument %d is %s.\r\n", i, argv[i]);
}
while(1){
SendEvent(serv, atoi(argv[1]));
sprintf(sendbuf,"%d",replyData); //发送数据
sendto(sockfd, sendbuf, sizeof(sendbuf), 0, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
sleep(1);
}
// 4. 关闭套接字
close(sockfd);
HdfIoServiceRecycle(serv);
printf("exit");
return HDF_SUCCESS;
}
用python编写一个简单的udp服务器,测试能否接收到数据
import socket, time
def main():
# 1、创建一个UDP套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2. 绑定本地的相关信息,如果不绑定,则系统会随机分配一个端口号
local_addr = ('', 50001) # ip地址和端口号,ip一般不用写,表示本机的任何一个ip
udp_socket.bind(local_addr)
while 1:
# 3. 等待接收对方发送的数据
data, addr = udp_socket.recvfrom(1024) # 1024表示本次接收的最大字节数
# 4、打印接收到的数据
#print(data)
print(data.decode('utf-8'))
# 5. 关闭套接字
udp_socket.close()
if __name__ == '__main__':
main()
成功接收到来在小熊派开发板的数据。
1.2.3云
云端分为两部分,一部分是作为服务器接收小熊派上传的数据,另一部分作为 HTTP 服务器对外提供 API
主要代码:
UDP 服务器
global values
while True:
data, addr = udp_socket.recvfrom(1024)
print(data.decode('utf-8'))
values=int(data.decode('utf-8'))
udp_socket.close()
HTTP 服务器
global values
while True:
ios_connection, ios_address = ios.accept()
data = ios_connection.recv(1024).decode('UTF-8')
print(data)
print(ios_address)
ios_connection.send(b"HTTP/1.1 200 OK\r\nContentType:text/html;charset=utf-8\r\n\r\n")
ios_connection.send(str(values).encode('utf-8'))
datalist = data.split("\n")
for i in datalist:
if i == "key: open\r":
pass
elif i == "key: close\r":
pass
else:
pass
ios_connection.close()
1.2.4用(北向)
接口调用
(1) 添加接口定义 由于只需要读取水流量和实现命令,这里简化了定义内容,只需要定义 一个 res 返回对象和一个 code 命令
//自定义接口 static water_rate(options: {
code: number;
success?: (res: string) => void;
fail?: (res: string, code: number) => void;
complete?: () => void; }): void;
(2) 修改 config.json 配置文件
编写页面
参考官方点灯的index.js文件修改
change_per_second(e){
const ShowRate = ()=>
{
let that=this
app.ledcontrol({
code:1,
success(res){console.log("data show1")
that.rate = res.led_status
test_value = JSON.stringify(res.led_status)
},
fail(res,code){
},
complete(){
}
})
console.log("data show2")
// console.log("data show1")
// this.rate=app.water_rate.code;
// console.log("data show2")
}
const a= setInterval(function(){ShowRate()},1000);
/*这里有一个关于类里This的指向问题,这里使用匿名函数处理 ()=>{}
不可以使用function(),因为由于类特性,在function里的this指向change_per_second的rate变量,而无法访问到default类的rate变量
但是匿名函数里this会逐层上找
*/
},
重中之重:北向如何通过接口调用南向的数据
先console.log(JSON.stringify(res)),在屏幕上打印出使用南向的接口后会传递哪些数据
接口中传递过来的数据是led_status,值为1.
然后,就可以直接赋值了
test_value = JSON.stringify(res.led_status)
四、演示
【本文正在参加物联网有奖征文活动】,活动链接:https://ost.51cto.com/posts/14758;
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-8-9 11:23:36修改
赞
11
收藏 6
回复
相关推荐
演示视频楼主有兴趣的话可以上传到社区中更好的展示,发布链接:https://ost.51cto.com/show/add
这个项目可以叫智能水表了。
为实战派点赞
硬核楼主