首页 > 其他分享 >闲来无事-树莓派控制风扇启停

闲来无事-树莓派控制风扇启停

时间:2023-06-27 09:13:59浏览次数:44  
标签:树莓 闲来无事 get self controlFan 风扇 启停 query fanStatus

扯淡时间

端午放假,本想注册个美团众包骑自行车送外卖体验一下生活,奈何这几天北京热的要死,只能作罢,还是苟在屋里空调续命吧。
无事干的时候,想着给我花盆监控升个级,换个电容的土壤检测(之前的腐蚀了gg了)但是电容的是3v的,esp8266只能检测1v的,所以买了一个新的esp32-cam,正好带个摄像头,间隔5分钟拍个照片,一天下来还能拼接一个延时摄影的效果,奈何这个板子有点毛病,跑不起来,如下图(商家也无法解决)

无奈退货(有大哥知道这个怎么解决麻烦指导一下小弟),想着下雨天打孩子,闲着也是闲着,这条路走不通了,换个其他的玩玩了。
我的树莓派有个风扇,成天在转,给他加一个控制,超出设定的温度再启动,最好在给个页面去控制一下,开搞
还有就是这个树莓派我买的时候400,我靠这玩意还涨价了,无语了,当时400我都觉得贵,还不如买个单片机30块就能玩

思路

  1. 设备控制-远程控制启停
  2. 后台定时任务-定时记录温度,根据设定的温度控制风扇启停
  3. 服务处理请求-展示温度曲线

来个流程图吧

graph TB subgraph 服务器 id1[页面控制指令]-.http请求.->id2{开关控制/最大温度} id2-.开关控制.->id3[控制风扇] id3-.风扇状态写入.->id4 id2-.最大温度写入.->id4[数据库] end subgraph 定时任务 id5[定时任务]<-.读取信息.->id4 id5-.定时任务.->id7[控制启停] end

需要考虑的问题

  1. 当前的实现是用python来写的,我不想每次重启设备后都要ssh上去再使用命令行启动,问了公司大神给了个解决方案:systemctl,可以实现开机自启,使用方式如下,想了解更多可以看:https://ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html
    当人为了防止程序挂掉,或者我退出以后停了,使用了nohup让python脚本一直在后太运行
  2. 如何控制风扇启停呢?树莓派上带了不少Gpio的接口,但是输出的电流只能点亮个led带不动风扇,所以我们需要一个三极管,我买的是s8050NPN的有两种别买错了,pnp是接在地线上的,用流程图画一个接线图吧,意思一下得了markdown不知道怎么画电路图

1. 配置方式和使用方法(当前的解决方案)

/etc/systemd/system 增加对应的文件

fanServer.service

[Unit]
Description=test deamon
After=rc-local.service

[Service]
Type=simple
User=root
Group=root
WorkingDirectory=文件的路径
ExecStart=nohup python3 -u processRequest.py > service.log 2>&1 &
Restart=always

[Install]
WantedBy=multi-user.target

fan.service

[Unit]
Description=test deamon
After=rc-local.service

[Service]
Type=simple
User=root
Group=root
WorkingDirectory=文件所在的路径
ExecStart=nohup python3 -u index.py > fan.log 2>&1 &
Restart=always

[Install]
WantedBy=multi-user.target

启动

sudo systemctl start  fan.service
sudo systemctl start  fanServer.service

添加到开机自启

sudo systemctl enable fan.service
sudo systemctl enable fanServer.service

2. 接线图

graph LR zheng[正极] zheng-.正极.->yongdianqi yongdianqi[风扇] yongdianqi-.地线.->sanjiguan sanjiguan[三极管] sanjiguan-.地线.->dixian dixian[接地] gpio[gpio]-.高电开/低电关.->sanjiguan

意思一下得了哈,效果看图片

现在看一下效果吧

图片名称 图片名称 > 接线的效果图如图二

正片干货结束无聊的实现时间

全部代码地址:https://github.com/dadademo/piFan

设备控制(网页端)

设备控制主要就是:1. 展示数据 2. 发送设备控制指令

写个vue的页面,用脑子设计一下:开关按钮得有,温度设定得有,还得有个图表,还得加个筛选时间,根据时间来筛选数据。就酱式的吧

代码如下(太多了给个链接吧)

https://github.com/dadademo/piFan/blob/main/fanUi/src/components/home.vue

后台定时任务

后台定时任务:1. 定时读取任务,根据设定的温度决定是否开/关风扇 2. 定时记录信息,将信息存在数据里面

这些服务本来想用node写,奈何node操作gpio的库一直不能下载,只能用python来搞了
注意这个代码我是直接复制的,依赖一些我写的其他的python脚本,如果想跑起来的话还直接拉全部代码去看吧
这里就是用python启动一个服务,接收网页发送的请求,例如设定温度,还有启停的制冷

定时任务python代码

这里就是每隔5分钟读取一次温度,超过了就启动风扇,没超过就停止


# 使用内建的signal库捕获Ctrl+C
import signal
# 风扇模块
import controlFan
# 退出程序
import sys
# 引用db模块
import db
import time


# 开始时间
beginTimeHour = 7
# 结束时间
endTimeHour = 20

# 每隔5分钟判断一次温度
timeOut = 60*5



# 程序停止
def stop():
    # 停止gpio操作
    controlFan.quit()
    # 退出程序
    sys.exit()

controlFan.init_gpio()

# 监听Ctr+C
signal.signal(signal.SIGINT, stop)
while True:
    # 0/1 当前风扇状态
    fanStatus = 0
    # 设定状态,默认40度
    setTemp = 0
    # 获取状态
    lastData = db.getLastData()
    fanStatus =  lastData.get('fanStatus')
    setTemp = lastData.get('setTemp')

    # 获取当前温度
    currentTemp = controlFan.read_cpu_temperature()
    # 时间
    currentTime = time.localtime()
    dt = time.strftime('%Y:%m:%d %H:%M:%S', currentTime)
    print(dt)
    # 当前温度大于设定温度
    ctrlVal = currentTemp > setTemp
    # 判断逻辑
    if ctrlVal:
        fanStatus = 1
    else:
        fanStatus = 0
    # 初始化后追加状态
    db.addInfo(fanStatus, currentTemp, setTemp)
    if ctrlVal:
        # 夜间模式
        if currentTime.tm_hour < beginTimeHour and currentTime.tm_hour > endTimeHour:
            controlFan.set_fan(False)
        else:
            controlFan.set_fan(True)
    else:
        controlFan.set_fan(False)
    time.sleep(timeOut)
服务端python的代码

这里就是用python启动一个服务,接收网页发送的请求,例如设定温度,还有启停的风扇指令,写这个代码还了解了一下python的数据类型,赚到了
代码如下

# 导入http.server模块
import http.server
import socketserver

# json对象
import json

# 参数解析
from urllib.parse import urlparse, parse_qs, parse_qsl

import db
import controlFan

# 定义端口号
HTTP_PORT = 3001

# 获取query信息并转为obj


def getQureyData(url):
    retObj = {}
    currentQuery = parse_qs(urlparse(url).query)
    for key in currentQuery:
        if len(currentQuery[key]) == 1:
            retObj[key] = currentQuery[key][0]
        else:
            retObj[key] = currentQuery[key]
    return retObj


# 处理相应
class httpResponse(http.server.SimpleHTTPRequestHandler):
    # 处理get请求
    def do_GET(self):
        # 当前访问的链接决定
        currentUrl = urlparse(self.path).path
        print(currentUrl)
        if currentUrl == '/getFan':
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            # 读取信息
            query = getQureyData(self.path)
            jsonInfo = db.getInfo(
                query.get('startTimestamp'), query.get('endTimestamp'), query.get('pageIndex'), query.get('pageSize'), query.get('all'))

            retStr = json.dumps(jsonInfo)
            self.wfile.write(bytes(retStr, "utf8"))

        if currentUrl == '/getLast':
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            jsonInfo = db.getLastData()
            retStr = json.dumps(jsonInfo)
            self.wfile.write(bytes(retStr, "utf8"))
        return

    # 处理post请求
    def do_POST(self):
        # 获取POST请求的数据
        currentUrl = urlparse(self.path).path
        if currentUrl == '/setFan':
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            # 当前信息
            query = getQureyData(self.path)
            # 获取最后的信息
            lastData = db.getLastData()
            fanStatus = int(query.get('fanStatus')
                            or lastData.get('fanStatus'))
            setTemp = int(query.get('setTemp') or lastData.get('setTemp'))
            print(fanStatus, fanStatus == 1)
            # 写入状态
            db.addInfo(fanStatus, controlFan.read_cpu_temperature(), setTemp)

            if fanStatus == 1:
                controlFan.set_fan(True)
            else:
                controlFan.set_fan(False)

            self.wfile.write(bytes("{status:200}", "utf8"))
        return


# 启动http服务
def beginServer():
    with socketserver.TCPServer(("", HTTP_PORT), httpResponse) as httpd:
        print("serving at port", HTTP_PORT)
        httpd.serve_forever()

controlFan.init_gpio()
# 开启服务
beginServer()

主要逻辑就这么多,全部的代码看git的地址吧,readme里面也有对应的操作,想网访问的话可以看我上一篇文章,有对应的链接,就不再这里哔哔了

标签:树莓,闲来无事,get,self,controlFan,风扇,启停,query,fanStatus
From: https://www.cnblogs.com/niexianda/p/17506382.html

相关文章

  • 闲来无事-控制树莓派风扇启停
    扯淡时间端午放假,本想注册个美团众包骑自行车送外卖体验一下生活,奈何这几天北京热的要死,只能作罢,还是苟在屋里空调续命吧。无事干的时候,想着给我花盆监控升个级,换个电容的土壤检测(之前的腐蚀了gg了)但是电容的是3v的,esp8266只能检测1v的,所以买了一个新的esp32-cam,正好带个摄像......
  • Hadoop中HDFS集群启停命令
    一键启停脚本#一键启动hdfs集群start-dfs.sh#一键关闭hdfs集群stop-dfs.sh单进程启停$HADOOP_HOME/sbin/hadoop-daemon.sh,此脚本可以单独控制所在机器的进程的启停用法:hadoop-daemon.sh(start|status|stop)(namenode|secondarynamenode|datanode) $HADOOP_HOME/bin......
  • 树莓派4B改造成云桌面客户端,连接DoraCloud免费版
     RaspberryPi(树莓派)是为学习计算机编程教育而设计的只有信用卡大小的微型电脑,自问世以来受众多计算机发烧友和创客的追捧,曾经一“派”难求。DoraCloud是一款多平台的桌面虚拟化管理软件,支持Hyper-V、VMware、Proxmox、XenServer等多种虚拟化平台。DoraCloud提供免费版,可以支......
  • ceph存储osd启动异常处理和正常启停操作
    机器角色:cloudstack虚拟机的宿主机;ceph存储机器。事件:ceph存储的物理机器由于内存异常,需要停机更换,仅仅是把该物理机上面的虚拟机迁移走,同时启动了停机维护,然后就直接关机。结果造成重启之后ceph异常 原因:由于异常关闭,ceph进程的相关信息没有正常关闭,信息没有同步到文件系统,如pid......
  • 树莓派、PS4、Switch、STM32、安卓、iOS
    系统架构树莓派:基于ARMCortex-A系列处理器(如Cortex-A53)的Linux操作系统。PS4:基于x86-64架构的FreeBSD操作系统。Switch:基于ARMv8-A架构的NvidiaCustom操作系统,也被称为“HorizonOS”。STM32:无操作系统或基于实时操作系统(RTOS)的固件(裸机)编程。安卓:基于Linux内核的软件堆栈......
  • 树莓派4B装Windows 11
    树莓派4B装Windows11下载系统与相关安装软件windowsforraspberryhttps://worproject.ml/https://pan.baidu.com/s/1ZrVS69Q4b8phlbAiiU6igw?pwd=eyhn下载windows映像http://uupdump.net/注意Windows1122H2及以上版本需要Windows102004及以上系统才能正常生成映像,否......
  • shell启停脚本
    #!/usr/bin/envbash#获取服务目录xxx_dir=$(cd$(dirname"${BASH_SOURCE[0]}")&&pwd)#端口检测间隔w_interval=3#启动后端口检测次数max_retried_times=50REDIS_INSTALL_DIR=/bin/REDIS_CONFIG_FILE=/etc/redis/redis.confMONGO_INSTALL_DIR=/usr/MONGO_CON......
  • 树莓派sd卡容量显示不全的解决办法
    32G的sd卡,插上之后df-h1显示只有7G需要对文件系统进行扩容操作:sudoraspi-config->AdvancedOptions->ExpandFilesystem123然后跟着操作就行,之后reboot即可......
  • RK3568 vs 树莓派4: 嵌入式计算的巅峰之争
    ▎引言  嵌入式计算领域一直以来都有着激烈的竞争,RK3568和树莓派4作为两个备受瞩目的平台,引起了广泛的关注。本文将以处理器性能、扩展性、功耗和软件支持等方面对RK3568和树莓派4进行综合比较,以帮助读者更好的了解这两个平台的优势和适用场景。  ▎RK3568   经......
  • 树莓派连接wifi报错
    之前树莓派正常使用,换手机后无法连接wifi,是因为换手机后ip地址改变。手机开热点,电脑连接。在电脑上windows+R,打开运行命令对话框,输入cmd调出命令行,输入ipconfig/all,找到无线局域网适配器WLAN,即可查看ip地址。对应于树莓派,终端输入sudonano/etc/dhcpcd.conf即可用nano编辑配置......