Skip to content

Repository files navigation

斐讯悟空 M1 服务器

Lite 版upcyan/aircat-server-lite — 轻量级数据采集

Web 版upcyan/aircat-server-web — 数据存储 + Web 可视化界面,支持 SQLite/DuckDB 双引擎切换

支持架构:linux/amd64 · linux/arm64

本项目基于 fenggenet/PhicommM1_Server 修改而来,在原项目基础上增加了 Docker 容器化部署、SQLite 存储、Web 可视化界面、设备亮度控制等功能。

基于 Docker 和 Python 的斐讯悟空(Phicomm AirCat)M1 设备数据采集服务器,提供两个版本:

版本 说明 适用场景
Lite 仅采集数据并输出日志 轻量部署、二次开发
SQLite 采集数据存入 SQLite + Web 界面展示 开箱即用、数据可视化

功能特性

通用功能

  • 监听 TCP Socket 端口,接收 M1 设备上报的环境数据
  • 解析设备数据:湿度、温度、PM2.5、甲醛(HCHO)
  • Docker 容器化部署,一键启动
  • 支持多客户端并发连接
  • 自动断线重连机制
  • 多架构镜像支持(x86 / ARM64)
  • 日志级别和日志文件可通过环境变量控制
  • M1 设备屏幕亮度控制(固定亮度 / 定时开关屏)

SQLite 版独有功能

  • 数据自动存入 SQLite 数据库,支持持久化
  • 内置 Web 管理界面,实时查看各项数据
  • 历史数据折线图(ECharts),支持点击图例隐藏/显示各项数据
  • 时间范围切换:1小时 / 6小时 / 24小时 / 7天
  • 实时数据自动刷新(5秒更新卡片,60秒更新图表)
  • 数据量限制与自动清理(可配置最大记录数和保存天数)
  • Web 设置面板(认证、数据管理、调试设置)
  • 可选用户名密码认证(默认不启用)
  • 支持 Docker 命令行重置用户名密码

技术栈

  • 语言: Python 3.14
  • 框架: 原生 Socket + http.server(SQLite 版)
  • 数据库: SQLite(SQLite 版)
  • 前端: ECharts 5(SQLite 版)
  • 容器: Docker / Docker Compose
  • CI/CD: GitHub Actions 自动构建双镜像

项目结构

aircat-svr-py/
├── aircat-server-lite.py          # Lite 版主程序
├── aircat-server-web.py           # Web 版主程序(Socket + Web + SQLite/DuckDB)
├── aircat-server-py/
│   └── templates/
│       └── web.html               # Web 版界面(自包含,内联 CSS/JS)
├── docker-yaml/
│   ├── docker-lite/
│   │   └── docker-compose.yml     # Lite 版 Docker Compose
│   └── docker-web/
│   │   └── docker-compose.yml     # Web 版 Docker Compose
├── .github/
│   └── workflows/
│       └── docker-build.yml       # GitHub Actions 自动构建双镜像
├── lite.Dockerfile                # Lite 版 Docker 镜像
├── web.Dockerfile                 # Web 版 Docker 镜像
├── storage_backends.py            # 存储引擎抽象层(SQLite/DuckDB)
├── VERSION                        # 版本号
└── README.md                      # 项目说明文档

快速开始

Lite 版(轻量级)

Docker 部署

# 拉取镜像
docker pull upcyan/aircat-server-lite:latest

# 运行容器
docker run -d \
  --name aircat-server-lite \
  -p 9000:9000 \
  -e TZ=Asia/Shanghai \
  -e LOG_LEVEL=DEBUG \
  -e LOG_FILE=false \
  --restart always \
  upcyan/aircat-server-lite:latest

# 查看日志
docker logs -f aircat-server-lite

Docker Compose 部署

services:
  aircat-server-lite:
    image: upcyan/aircat-server-lite:latest
    pull_policy: always
    container_name: aircat-server-lite
    ports:
      - "9000:9000"
    environment:
      - TZ=Asia/Shanghai
      - LOG_LEVEL=DEBUG
      - LOG_FILE=false
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

SQLite 版(数据存储 + Web 界面)

Docker 部署

# 拉取镜像
docker pull upcyan/aircat-server-web:latest

# 运行容器(建议设置管理认证)
docker run -d \
  --name aircat-server-web \
  -p 9000:9000 \
  -p 8080:8080 \
  -e TZ=Asia/Shanghai \
  -e LOG_LEVEL=DEBUG \
  -e LOG_FILE=false \
  -e DB_PATH=/data/aircat.db \
  -e WEB_PORT=8080 \
  -e AUTH_USER=admin \
  -e AUTH_PASS=请替换为强密码 \
  -v ./data:/data \
  --restart always \
  upcyan/aircat-server-web:latest

# 查看日志
docker logs -f aircat-server-web

通过环境变量配置或恢复管理认证:

docker run -d \
  --name aircat-server-web \
  -p 9000:9000 \
  -p 8080:8080 \
  -e TZ=Asia/Shanghai \
  -e AUTH_USER=admin \
  -e AUTH_PASS=yourpassword \
  -v ./data:/data \
  --restart always \
  upcyan/aircat-server-web:latest

重置用户名和密码

# 重置用户名
docker exec -it aircat-server-web resetname

# 重置密码
docker exec -it aircat-server-web resetpasswd

Docker Compose 部署

services:
  aircat-server-web:
    image: upcyan/aircat-server-web:latest
    pull_policy: always
    container_name: aircat-server-web
    ports:
      - "9000:9000"
      - "8080:8080"
    environment:
      - TZ=Asia/Shanghai
      - LOG_LEVEL=DEBUG
      - LOG_FILE=false
      - DB_PATH=/data/aircat.db
      - WEB_PORT=8080
      - AUTH_USER=admin
      - AUTH_PASS=请替换为强密码
    volumes:
      - ./data:/data
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

启动后访问 http://服务器IP:8080 即可查看 Web 界面。

Web 设置面板

点击页面右上角齿轮图标打开设置面板,支持:

  • 认证设置:启用/关闭登录认证,设置用户名和密码
  • 数据管理:设置最大记录数(超出自动覆盖)、保存天数(超期自动清理)、手动清理全部数据
  • 调试设置:切换日志级别(DEBUG/INFO/WARNING/ERROR)、开启/关闭日志文件
  • 设备控制:设置 M1 屏幕亮度(不控制/息屏/微亮/较暗/较亮/正常)、定时开关屏(白天/夜晚亮度和时间)

本地构建

# Lite 版
docker build -t aircat-server-lite -f lite.Dockerfile .

# SQLite 版
docker build -t aircat-server-web -f web.Dockerfile .

直接运行 Python

# Lite 版
python aircat-server-lite.py

# SQLite 版
python aircat-server-web.py

配置说明

服务器运行参数

配置项 默认值 说明
监听端口 9000 TCP Socket 端口
采集间隔 5 秒 设备数据采集频率
接收缓冲区 4096 字节 Socket 接收缓冲区大小
接收超时 10 秒 数据接收超时时间
最大重试次数 3 次 超时后最大重试次数

通用环境变量

环境变量 默认值 可选值 说明
LOG_LEVEL DEBUG DEBUG / INFO / WARNING / ERROR 控制台日志级别
LOG_FILE false true / false 是否写入日志文件
MAX_FRAME_BYTES 65536 正整数 单个 M1 响应帧最大字节数
MAX_FRAME_SECONDS 10 正整数 单个 M1 响应帧总接收时限
MAX_DEVICE_CLIENTS 32 正整数 最大并发设备连接数

M1 设备亮度控制环境变量

环境变量 默认值 可选值 说明
M1_BRIGHTNESS -1 -1 / 0 / 25 / 50 / 75 / 100 屏幕亮度,-1=不控制,0=息屏,100=最亮
M1_TIMER_ENABLED false true / false 启用定时开关屏
M1_TIMER_DAY_BRIGHTNESS 100 0 / 25 / 50 / 75 / 100 白天屏幕亮度
M1_TIMER_NIGHT_BRIGHTNESS 0 0 / 25 / 50 / 75 / 100 夜晚屏幕亮度
M1_TIMER_DAY_START 07:00 HH:MM 白天开始时间
M1_TIMER_NIGHT_START 23:00 HH:MM 夜晚开始时间

M1_BRIGHTNESS 优先级高于定时设置。当 M1_BRIGHTNESS >= 0 时使用固定亮度,忽略定时设置。

Lite 版通过环境变量配置,SQLite 版通过 Web 设置面板配置(也可通过环境变量初始化)。

Web 版独有环境变量

环境变量 默认值 说明
DB_PATH /data/aircat.db 数据库文件路径(sqlite 用 .db,duckdb 用 .duckdb)
DB_ENGINE sqlite 存储引擎:sqlite / duckdb,首次启动后可在 Web 设置里切换
WEB_PORT 8080 Web 界面端口
AUTH_USER admin(仅设置密码时) 设置管理用户名
AUTH_PASS (空) 设置后启用认证;也可修复已有数据库的无认证状态
MAX_HTTP_BODY_BYTES 16384 JSON 请求体最大字节数
MAX_HTTP_WORKERS 16 Web 请求最大并发处理数

认证开关同时控制读取与管理写操作:关闭时无需登录即可保存设置、清理数据或切换存储,所有能访问服务的人都可以操作;开启时必须登录。仅在受信任的网络关闭认证。设置 AUTH_PASS 并重启可为首次或已有数据库启用认证。

存储引擎切换

Web 版支持 SQLiteDuckDB 两种存储引擎,默认 SQLite:

  • SQLite:轻量级嵌入式数据库,适合中小数据量(<50万条),零配置
  • DuckDB:列存分析型数据库,聚合查询更快,适合大数据量和长时间跨度分析

在 Web 设置面板 → 存储引擎区域可一键切换,切换时会自动迁移全部本地数据(含设置、原始数据、聚合数据),旧库文件保留作为备份。切换后需重启容器使采集端使用新引擎。

配置示例

  • 调试排查LOG_LEVEL=DEBUG + LOG_FILE=false(默认),通过 docker logs -f 查看所有日志
  • 生产环境LOG_LEVEL=INFO + LOG_FILE=false,仅输出重要信息
  • 持久化日志LOG_LEVEL=DEBUG + LOG_FILE=true,挂载 ./logs:/logs 目录保存日志文件
  • 数据持久化(SQLite 版):挂载 ./data:/data 目录,数据库文件持久保存到宿主机

数据格式

服务器接收 M1 设备上报的 JSON 数据,包含以下字段:

字段 类型 说明
humidity float 湿度(%)
temperature float 温度(°C)
value int PM2.5 值(μg/m³)
hcho float 甲醛浓度(mg/m³)

SQLite 数据表结构

CREATE TABLE sensor_data (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
    humidity REAL,        -- 湿度(%)
    temperature REAL,     -- 温度(°C)
    pm25 INTEGER,         -- PM2.5(μg/m³)
    hcho REAL,            -- 甲醛(mg/m³)
    client_ip TEXT        -- 设备 IP 地址
);

Web API(SQLite 版)

接口 方法 认证 说明
/ GET 可选 Web 界面页面
/api/latest GET 可选 获取最新一条数据记录
/api/history?hours=24 GET 可选 获取指定小时数内的历史数据
/api/settings GET 需要 获取当前设置
/api/settings POST 启用认证时需要 更新设置(最大记录数、保存天数、认证、日志等)
/api/cleanup POST 启用认证时需要 清理全部传感器数据
/api/login POST 不需要 登录认证,返回 token

数据管理配置(SQLite 版)

通过 Web 设置面板或 API 配置,所有设置持久化在 SQLite 数据库中:

设置项 默认值 说明
max_records 10000 最大记录数,超出后自动删除最早记录
retention_days 30 保存天数,超期记录自动清理
auth_enabled 0 是否启用登录认证(0=关闭,1=开启)
auth_user (空) 登录用户名
log_level DEBUG 日志级别(可通过 Web 面板动态修改)
log_file 0 是否写入日志文件(0=关闭,1=开启)

数据清理由后台线程每 5 分钟自动执行一次,同时每次插入数据后也会检查。

Docker Hub 仓库

仓库 说明
upcyan/aircat-server-lite 斐讯悟空 M1 轻量级数据采集服务器
upcyan/aircat-server-web 斐讯悟空 M1 数据采集服务器(SQLite/DuckDB + Web 界面)
  • 支持架构:amd64 / arm64
  • 自动构建:每次推送到 main 分支自动构建两个镜像并递增版本号
  • 绿联 NAS 更新:请启用 UGOS Docker 的“更新检测”,并使用 :latest 标签跟随更新。Compose 的 pull_policy: always 仅影响部署时拉取镜像,不会开启 NAS 的后台更新检测。版本标签和 sha-... 标签用于固定版本,不会跟随 latest 更新。
  • 镜像格式兼容:发布时显式使用 Docker Schema 2 清单 / manifest list 和 gzip 层,关闭 provenance、SBOM,并在发布后校验两个架构的实际清单。仅关闭 provenance 仍可能输出 OCI index,不能保证旧版 NAS 检测器兼容;多架构支持保持不变。

绿联 NAS 仍未提示更新时

已知机制与兼容标签

绿联官方说明确认:在“管理”启用检测后,项目列表提示镜像更新;执行更新时拉取镜像并重建容器。该文档没有公开检查周期、使用的仓库 API、缓存策略或摘要比较算法。不能断言 UGOS 根据 APP_VERSION、版本标签大小或某个 OCI label 判断更新,也不能把“其他容器能检测”当作本镜像构建失败的证据。

Docker 的多架构标签指向 manifest list,各架构还有独立的 manifest 和 config 摘要;这些摘要不能跨层直接比较。参见 Docker 摘要说明。本项目既往已验证 latest 实际变化且 NAS 能手动拉取新版本;将 OCI index 改为 Docker manifest list 后仍未获得用户端更新提示,因此格式转换并未证明解决问题。

发布流程新增以下可选兼容标签,用于排除多架构清单解析这一因素(需本次流程首次成功发布后才能使用):

标签 内容
latest 保持 amd64 / arm64 多架构自动选择
latest-arm64 直接指向 ARM64 的单镜像 Docker Schema 2 清单
latest-amd64 直接指向 AMD64 的单镜像 Docker Schema 2 清单
<版本>-arm64 / <版本>-amd64 对应发布版本的单架构清单

这些标签复用同一构建产物,不重新编译,不改变数据挂载。通过 imagetools create --prefer-index=false复制子清单,并在发布后校验标签内容与源清单一致,避免单架构又被包成索引。这是诊断性兼容方案,不是已经实机证实的 UGOS 修复;现有 latest 用户不会自动切换到兼容标签。

在 NAS SSH 终端用 docker image inspect "$(docker inspect aircat-server-web --format '{{.Image}}')" --format '{{.Architecture}}' 确认当前镜像架构,再在绿联原项目中只改 image 一行,例如 ARM64 使用 image: upcyan/aircat-server-web:latest-arm64。保留原服务名、项目名、端口、数据挂载和其余设置;不要另建同名容器。

已知旧部署的项目名为 aircat-svr-lite、服务名为 aircat-server-sqlite,配置路径为 /volume2/DockerFiles/yamlfiles/aircat-server-lite/docker-compose.yaml。文件夹名不等于 Compose 项目名。优先在绿联原项目界面修改和部署,避免仅由命令行创建的项目与管理界面记录不一致;是否存在这种不同步仍须在 NAS 上核实。

首次切换标签并重新部署后只是建立新的比较基线,需下一次该标签更新才能验证自动提示。测试期间不要提前手动拉取新镜像,否则会改变本地比较状态。如果单架构标签仍无提示,应采集 UGOS / Docker 应用版本、同一项目的检测开关及检查请求返回结果,不能继续宣称镜像格式就是根因。分享日志时隐藏登录令牌和密码。

手动更新与版本检查

此修复需推送到 main 并等待 GitHub Actions 成功发布新镜像后才生效,本地修改不会改变 Docker Hub 上的镜像。

  1. 确认容器使用 upcyan/aircat-server-web:latestupcyan/aircat-server-lite:latest,没有固定版本号或 @sha256:... 摘要。

  2. 在 UGOS 中手动拉取该镜像并重新创建容器(保留原来的端口、环境变量和数据目录挂载)。仅重启容器不会切换到新镜像。

  3. 若使用仓库提供的 Compose 文件,可在对应项目目录执行下面的命令;轻量版将服务名改为 aircat-server-lite。不要删除数据目录或卷。

    docker compose pull aircat-server-web
    docker compose up -d aircat-server-web
  4. 若拉取失败,先检查 NAS 到 Docker Hub 的连接、认证及限流;使用镜像代理时还需检查代理缓存是否同步。若可以拉取到新镜像却没有更新提示,请记录 UGOS / Docker 应用版本、完整镜像标签和检测日志,进一步确认检测器兼容性。

断网恢复

服务端监听 0.0.0.0:9000,WAN 断开不会停止本地监听;网络恢复后,终端重新建立 TCP 连接即可立即继续接受轮询。Web 版会关闭同一设备 IP 的旧半开连接,两个版本都启用了 keepalive、连接上限、完整帧上限和总接收时限。若终端仍显示 WiFi 叉号,请确认路由器的 DNS 劫持/静态解析在断网期间仍把原厂服务域名指向 NAS,并确保 NAS 使用固定局域网 IP;终端固件自身的重连周期无法由服务端强制改变。

端口说明

端口 版本 说明
9000 通用 TCP Socket 服务端口,接收 M1 设备连接
8080 SQLite 版 Web 界面端口,浏览器访问查看数据

许可证

MIT License

About

phicomm aircat server base on docker and python

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages