火灾检测系统:如何根据文本文件0/1值切换HTML页面
火灾检测Web监控系统问题解决
问题背景
我是嵌入式软件工程师,不熟悉Web开发。正在开发火灾检测项目:火焰传感器连接STM32F103C8T6单片机,检测到火灾时ESP8266通过PUT方法将值1写入服务器的file.txt;网页需持续监控该文件,值为0显示“无火灾”,值为1显示“火灾警报”。
已完成index.html首页,但PHP代码及Web监控逻辑多次尝试均无效,现有文件如下:
现有文件
index.html
<html> <meta charset="UTF-8"> <head> <title> Fire Detection System </title> </head> <body> <h1> <br> <font face = "Verdana" size = "5">Welcome to my Fire Detection System</font><br /> </h1> <font face = "Arial"> <br> <h4 style="line-height:19px;"> This is an IOT project consisting of two sides: <br> <br>1) On the embedded side, I have a fire detector system based on STM32F103C8T6 microcontroller <br>2) On the web side, I have a website that you are viewing right now 😁 </font> </h4> <br> <br> You can find the project details and the source code on this GitHub <a href="https://github.com/AhmedHeshamMostafa/Fire-Detector.git"> Repository </a> <br> <br> <p style="font-family:'Courier New'">Designed and developed by <br> Ahmed Hesham Mostafa <br> Embedded Software Engineer</p> <p style="font-family:'Times New Roman'">ahmed.hesham.mostafa7@gmail.com</p> <br> <p> <a href="https://github.com/AhmedHeshamMostafa/"><img src="GitHub Logo.png" width="60" height="60"></a> <a href="https://www.linkedin.com/in/ahmedhesham285/"><img src="LinkedIn Logo.png" width="60" height="60"></a> </p> </body> </html>
monitor.html
<html> <meta charset="UTF-8"> <head> <title> No Fire </title> </head> <body> <h1> <br> <font face = "Arial" size = "5">Now you are monitoring the fire detection system</font><br /> </h1> </html>
Backbone.php(存在问题的代码)
<?php while(1) { lines = file('file.txt'); $line_number = 0; if(($lines[0] == 1)) { header("FirePage.html"); } else { header("NoFirePage.html"); } }
问题分析与解决方案
原PHP代码的核心问题
- 变量语法错误:PHP变量必须以
$开头,lines = file('file.txt');应改为$lines = file('file.txt'); - 死循环导致服务器崩溃:
while(1)是无限循环,HTTP是单次请求-响应模型,这种写法会让PHP进程一直运行直到超时,无法实现前端持续监控 - 跳转语法错误:
header()跳转需要使用Location:前缀,且跳转后必须用exit()终止脚本,正确写法是header("Location: FirePage.html"); exit(); - 未处理文件空白字符:
file.txt中的值可能带有换行符,直接用$lines[0] == 1会判断失败,需要用trim()去除空白
正确实现方案
由于PHP是服务器端脚本,无法主动推送更新到前端,因此采用前端轮询+后端状态接口的方案:
1. 后端状态接口(get_status.php)
创建一个简单的PHP接口,返回file.txt中的状态值:
<?php // 读取状态文件并去除空白字符(换行、空格等) $status = trim(file_get_contents('file.txt')); // 返回纯文本状态 echo $status; ?>
2. 改造监控页面(monitor.html)
用JavaScript实现定时轮询后端接口,根据返回值动态更新页面内容:
<html> <meta charset="UTF-8"> <head> <title>火灾监控系统</title> <script> // 轮询间隔(毫秒),可根据需求调整 const POLL_INTERVAL = 2000; function checkFireStatus() { fetch('get_status.php') .then(response => response.text()) .then(status => { const statusDisplay = document.getElementById('status-display'); const pageBody = document.body; if (status.trim() === '1') { // 触发火灾警报 document.title = '⚠️ 火灾警报!'; statusDisplay.innerHTML = '<h1 style="color: #d32f2f; text-align: center;">⚠️ 火灾警报!请立即处理!⚠️</h1>'; pageBody.style.backgroundColor = '#ffebee'; } else { // 无火灾状态 document.title = '✅ 无火灾'; statusDisplay.innerHTML = '<h1 style="color: #2e7d32; text-align: center;">✅ 当前无火灾,系统正常运行</h1>'; pageBody.style.backgroundColor = '#e8f5e9'; } }) .catch(error => { console.error('获取状态失败:', error); }); } // 页面加载后立即检查状态,之后开始定时轮询 window.onload = function() { checkFireStatus(); setInterval(checkFireStatus, POLL_INTERVAL); }; </script> </head> <body> <div id="status-display"> <h1 style="text-align: center;">正在初始化监控...</h1> </div> </body> </html>
3. 额外注意事项
- 确保服务器上的
file.txt有写入权限(可设置权限为664或775,根据服务器配置调整) - ESP8266的PUT请求需正确写入
file.txt,确保内容仅为0或1,无多余字符 - 如果需要更高效的实时更新,可考虑使用WebSocket,但轮询方案对初学者更简单易实现
内容的提问来源于stack exchange,提问作者Ahmed Hesham
相关产品推荐
相关产品推荐

