基于BOA的嵌入式Web项目机房温度监控

Posted MangataTS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于BOA的嵌入式Web项目机房温度监控相关的知识,希望对你有一定的参考价值。

文章目录

一、需求分析

我们的需求很简单,采集端不断的通过温度传感器采集温度,然后传输到web前端页面进行显示,超过一定温度进行预警或者变化操作,如果后续还有什么需求可以直接添加。

二、项目结构

采集端采集数据 ==> CGI进程 ==> Web服务器 ==> 浏览器显示

更加详细的结构参考下图:

三、效果图


我们动态加载机房温度,并且当机房的温度超过90°的时候我们的监控就会出现红条警告,右边我们内嵌了一个空调

四、数据传输

4.1 采集端数据传输到CGI进程

对于这两个端口的数据传输,我们选择使用共享内存的方式,此时我们的数据采集端就作为了写入端,不断的往共享内存中写入数据,然后我们的CGI进程就不断的读取数据,这里目前不考虑原子性操作,于是没有写入信号量相关的代码限制

这里可以查看我之前写的关于共享内存的简单解析:https://acmer.blog.csdn.net/article/details/124708423

4.2 CGI进程数据传输到Web服务器

这里的话就是前端知识了,我们的CGI每次调用返回一个json数据,然后用ajax解析这个数据,并且通过jquery.js的动态制图绘制出机房五台电脑的温度变化

4.3 Web服务器传输给浏览器

这里的这一步就是Boa服务器帮我们完成的啦,这里只需要简单配置一下Boa服务器就好了,可以跟着我的这篇博客配置:
https://acmer.blog.csdn.net/article/details/124388148

注意的是这里CGI路径并未配置,当然你也可以将你的cgi程序放在它默认的地方,但为了方便管理我们还是更改了一下cgi的读取位置,在最后一行的cgi-bin:ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ 将后面的位置改为你项目存放cgi程序的位置,我这里的话是存放在/home/mangata/webpro/cgi

五、 采集端

5.1 思路

对于采集端,由于没有硬件的设备,我们这里就造一些随机数字就好了,于是我们只需要随机化五个机房的温度,并且写入共享内存中即可

5.2 代码

我们这里给这个命名为sim_catch.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "task.h"

static struct task_infos *tasks;
static char* task_lables[]="机房1","机房2","机房3","机房4","机房5";
//获取随机数据
void get_data(int num)
    tasks->num = num;//设置机房的数量
    for(int i = 0;i < num; ++i) 
        tasks->data[i].temp = (rand() % 9000 + 1000)/100.0;//将数据限制在(0,100.0)的浮点数据
        snprintf(tasks->data[i].label,sizeof(tasks->data[i].label),"%s",task_lables[i]);//像共享内存写入数据
    

//数据打印在控制台显示
void show_data()
    for(int i = 0;i < tasks->num; ++i) 
        printf("the label is: %s,the temp is %.2lf\\n",tasks->data[i].label,tasks->data[i].temp);
    


int main()

    srand(time(NULL));//随机数播种
    tasks = (struct task_infos *)init_shm();//初始化共享内存
    while(1)//每隔2s获取一次温度数据
        get_data(5);
        sleep(2);
    
    return 0;

六、CGI进程

6.1 思路

通过共享内存我们可以获取到sim_catch.c在共享内存中写入的温度数据,这里要构造成json字符串,我们需要借助一个外部的库,cJSON

通过这个文件我们就能很容易构造出我们想要的JSON字符串了,这里想要学习如何构造可以去网上搜一些资料,当然也可直接看项目中的readme文件,通过官方的几个小例子也可以快速学会(这里留个坑,后面有时间精读一下项目)

6.2 代码

然后我们就能构造出我们需要的JSON字符串了,这个CGI进程我们取名temo_cgi.c

//
// Created by Mangata on 2022/5/10.
//

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "task.h"
#include "cJSON.h"

static task_infos *tasks;

void send_json()
    int num;
    char temp[32];
    char *string;
    cJSON *infos = NULL;
    cJSON  *info = NULL;
    cJSON *monitor = cJSON_CreateObject();

    if (monitor == NULL)
    
        goto end;
    
    num = tasks->num;
    cJSON_AddItemToObject(monitor,"num", cJSON_CreateNumber(num));

    infos = cJSON_CreateArray();
    if(infos == NULL)
        goto end;
    
    cJSON_AddItemToObject(monitor,"data",infos);
    for(int i = 0;i < num; ++i) 
        info = cJSON_CreateObject();
        if(info == NULL) 
            goto end;
        
        cJSON_AddItemToArray(infos,info);

        cJSON_AddItemToObject(info,"label", cJSON_CreateString(tasks->data[i].label));
        snprintf(temp,sizeof temp,"%.2lf",tasks->data[i].temp);
        cJSON_AddItemToObject(info,"temp", cJSON_CreateString(temp));
    
    string = cJSON_Print(monitor);
    if (string == NULL)
    
        fprintf(stderr, "Failed to print monitor.\\n");
     else 
        printf("%s",string);
    
    free(string);
end:
    cJSON_Delete(monitor);
    return;


int main()

    printf("Content-Type:text/html;charset=utf-8\\r\\n");
    printf("\\r\\n");
    tasks = (task_infos*)init_shm();
    if(tasks == NULL) 
        return -1;
    
    send_json();
    return 0;

七、Web界面

7.1 思路

这里使用了bootstrap 框架,简单绘制了一下,只用到了几个控件,就没有什么好讲的,中间有一些注释的语句,那些是另一种刷新方式,手动刷新,没有使用定时器,另外界面的右侧,嵌入了一个在线空调(虽然感觉没什么用)

7.2 代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Home</title>
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <script src="js/bootstrap.min.js"></script>
    <script src="js/jquery.min.js"></script>
    <script src="js/echarts.common.min.js"></script>
</head>
<body>
<nav class="navbar navbar-inverse">
    <div class="container-fluid container">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">xxx机房监控</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">温度监控<span class="sr-only">(current)</span></a></li>
                <li><a href="#">机房电脑</a></li>

            </ul>


        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>

<!--<div class="container">-->
<!--    <h1 class="text-center">机房管理</h1>-->
<!--    <table class="table table-bordered table-hover" id="tab_ctx">-->
<!--        <thead>-->
<!--            <tr>-->
<!--                <td>编号</td>-->
<!--                <td>机器名</td>-->
<!--                <td>温度</td>-->
<!--            </tr>-->
<!--        </thead>-->
<!--        <tbody>-->
<!--        </tbody>-->
<!--    </table>-->
<!--    <hr>-->
<!--    <button type="button" id="bt1">添加任务</button>-->

<!--</div>-->
<!--<script>-->
<!--    $(document).ready(function ()-->
<!--        $("#bt1").click(function ()-->
<!--            $.getJSON("cgi-bin/temp_cgi",function (info)-->
<!--                $("#tab_ctx tbody").html('');-->
<!--                // console.log(info);-->
<!--                for(let idx in info.data)-->
<!--                    let context = "<tr><td>"+idx+"</td>"-->
<!--                        +"<td>" + info.data[idx].label + "</td>"-->
<!--                        +"<td>" + info.data[idx].temp +"&#8451;"+ "</td></tr>";-->
<!--                    $("#tab_ctx tbody").append(context);-->
<!--                -->

<!--            );-->
<!--        );-->
<!--    );-->
<!--</script>-->


<iframe height="740" src="https://ac.yunyoujun.cn" align="right"></iframe>
<div id="main" style="width: 1000px;height:600px;"></div>

<script type="text/javascript">
    // 基于准备好的dom,初始化echarts实例
    let myChart = echarts.init(document.getElementById('main'));
    let data = [];
    for (let i = 0; i < 5; ++i) 
        data.push(Math.round(Math.random() * 100));
    

    option = 
        color: [
            '#dd6b66',
            '#759aa0',
            '#e69d87',
            '#8dc1a9',
            '#ea7e53',
            '#eedd78',
            '#73a373',
            '#73b9bc',
            '#7289ab',
            '#91ca8c',
            '#f49f42',
            '#129'
        ],
        xAxis: 
            max: 100.0
        ,
        yAxis: 
            type: 'category',
            data: ['机房一', '机房二', '机房三', '机房四', '机房五'],
            inverse: true,
            animationDuration: 300,
            animationDurationUpdate: 300,
            max: 4 // only the largest 3 bars will be displayed
        ,
        series: [
            
                realtimeSort: true,
                name: '机房温度实时监控℃',
                type: 'bar',
                data: data,
                label: 
                    borderRadius: 14,
                    show: true,
                    position: 'right',
                    valueAnimation: true
                ,
                itemStyle: 
                    borderRadius: [0, 5, 5, 0],
                    color: '#129',
                    opacity: 0.5
                
            
        ],
        legend: 
            show: true
        ,
        animationDuration: 2000,
        animationDurationUpdate: 2000,
        animationEasing: 'linear',
        animationEasingUpdate: 'linear'
    ;

    function update() 
        let data = option.series[0].data;
        $.getJSON("cgi-bin/temp_cgi",function (info)
            let fg = Number(0);
            for(let idx = 0;idx < data.length; ++idx)
                let temp = Number(info.data[idx].temp);
                if(parseFloat(temp) > parseFloat(90.0))
                    fg = Number(1);
                    console.log("temp ok");
                
                data[idx] = temp;//Math.round(Math.random() * 2000);// Number(info.data[idx].temp);
            
            // console.log(option.series[0].itemStyle.color);
            if(fg === 1) 
                option.series[0].itemStyle.color = option.color[0];
             else 
                option.series[0].itemStyle.color = option.color[11];
            
        )
        myChart.setOption(option);
    

    setInterval(function() 
        update();
    , 2000);
</script>

</body>
以上是关于基于BOA的嵌入式Web项目机房温度监控的主要内容,如果未能解决你的问题,请参考以下文章

Linux下 基于Boa的应用资源管理系统 SMS

Linux下 基于Boa的应用资源管理小系统 SMS

Linux下 基于Boa的应用资源管理小系统 SMS

Linux下 基于Boa的应用资源管理小系统 SMS

如何安全的实现远程监控机房里的温度?

“机房环境监控系统”机房建设必不可少的一环!