跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI

智能家居笔记:Home Assistant 与小智 AI 搭建指南

记录了基于 Home Assistant 的智能家居系统搭建过程。架构包括小智 ESP32 作为语音前端,树莓派运行 HAOS 作为中控,后端连接阿里云服务器通过 FRP 内网穿透。集成了 Frigate 进行摄像头管理,Music Assistant 播放本地音乐和播客,并接入甲醛检测仪、小米摄像头及拓竹 3D 打印机等设备。涉及 ESPHome 自定义组件开发、Python 脚本抓取播客及视频硬解配置等技术细节。

嘘发布于 2026/4/6更新于 2026/7/2561 浏览
智能家居笔记:Home Assistant 与小智 AI 搭建指南

设备框架图

概述: 总体而言借用各种开源项目,致力做到好用可控。输入设备小智 AI 作为用户前端,后端用小智 AI 华南理工开源服务器。智能家庭中控采用树莓派 5 搭载 HAOS,用 homeassistant,包括手机 APP。各种终端设备,支持 zigbee 通信协议,wifi 通信协议,小米设备支持 miloco 的设备可以连接,其他类似美的海尔的设备也看 home assistant 的插件支持程度,没有本身开源的使用舒适。

image.png

主机:thinkpad-S5-yoga 地址 xxxxxxxxxxxx 用户:xxxxxxxxxxx

服务备注服务端口
frigate5000
sambamnt/media/usbshare
http/mnt/usb_share/podcast10086
mediamtx.servicexxxxxxxxxxx8554
napcat
koi
miloco
micamxxxxxxxxxxxxxx
astra-color.service
zaokafei-fetch.timer/mnt/usb_share/podcast/zaokafei
bambucam.serviceDesktop/bambustudio/bambucam5004
glances.service61208

主机:MacBookAir 地址:xxxxxxxxxxxxx 用户:xxxxxxxxxxxxx

服务备注服务端口
intel-color
ir
switchDesktop/swtich_rtsp/swtich_rtsp.py
mediamtxxxxxxxxxxxxxx8554

主机:PC 地址:xxxxxxxxxxxxxxx 用户:xxxxxxxxxxx

image.png

小智 ESP32 嵌入式前端

开源地址:78/xiaozhi-esp32: An MCP-based chatbot | 一个基于 MCP 的聊天机器人

前端若需要连 M3.5 的扬声器接口,可换 PCM5102A 模块

参考链接:用 ESP32 + PCM5102 打造一个无线的 HIFI 音乐播放器

重新配置 OTA 地址,开机时按 boot 键

小智 ESP32 后端服务器

开源地址:xinnan-tech/xiaozhi-esp32-server: Backend service for xiaozhi-esp32, helps you quickly build an ESP32 device control server.

连接 home assistant 采用了很多尝试 最先 MCP 连接方式:ha-mcp-for-xiaozhi/README.md at v0.1.1 · c1pher-cn/ha-mcp-for-xiaozhi 该方式能将多个 SSE 都连入 Home assistant 封装为 function call 让 xiaozhi-server 调用,在 home assistant 端采用的是 assist 提供的接口

也尝试用 xiaozhi-server 贡献的 home assistant 代码,其实用了 home assisttant 的 API,好处是可以精简 MCP,对音乐播放进行了一些修改。

Home Assistant

树莓派地址:xxxxxxxxxxxxxx

公网访问

image.png

使用 frp 加载项 内网穿透至阿里云服务器,再 nginx 反向代理出来。 参考:Frp 内网穿透使用记录

感觉有一个 bug,重启 HAOS 之后,自启动 FRP Client,但是 FRP Server 会还在重新尝试原先的客户端,就会崩溃。因此必须开崩溃自动恢复。

网络存储

此处用部署在局域网的 samba 服务,用户名:admin

image.png

Music Assistant

使用 provider 模式,youtube music 等使用延迟较大,因此还是本地使用方案。

歌曲下载地址

SQUID.WTF - Home lucida | music at internet speed

使用 Filesystem provider

image.png

podcast 收听地址

发现 RSS 真的还挺方便

使用 podcast provider

image.png

链接:weekend-project-space/top-rss-list: 订阅人数最多的 rss 源,中文优质 rss 源

也可以自己抓取节目,小宇宙的音频都可以抓比较方便

抓取代码 Desktop/zaokafei

#!/usr/bin/env python3 # -*- coding: utf-8 -*- import json import os import re from datetime import datetime, timezone from email.utils import format_datetime from urllib.parse import quote import requests import xml.etree.ElementTree as ET PODCAST_URL = "https://www.xiaoyuzhoufm.com/podcast/60de7c003dd577b40d5a40f3" # 音频/封面/XML 都放这里(U 盘) OUT_DIR = "/mnt/usb_share/podcast/zaokafei" XML_PATH = os.path.join(OUT_DIR, "zaokafei.xml") # 你这台 ThinkPad 的 HTTP 服务地址(用你确认的 IP) BASE_HTTP = "http://192.168.1.100:10086" HEADERS = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", } def get_next_data(url: str) -> dict: """从小宇宙网页里解析 __NEXT_DATA__ JSON""" html = requests.get(url, headers=HEADERS, timeout=30).text m = re.search( r'<script type="application/json">(.*?)</script>', html, re.S, ) if not m: raise RuntimeError("没找到 __NEXT_DATA__,小宇宙页面结构可能变了") return json.loads(m.group(1)) def sanitize_filename(name: str) -> str: """文件名安全化(保留中文,但去掉不允许字符,避免太长)""" name = re.sub(r'[\\/:*?"<>|]', "_", name).strip() name = re.sub(r"\s+", " ", name) return name[:160] if len(name) > 160 else name def parse_pubdate_to_utc(pub: str) -> datetime: """ 解析小宇宙 pubDate(通常 ISO801,可能带 Z) 返回 timezone-aware UTC datetime """ try: if pub.endswith("Z"): dt = datetime.fromisoformat(pub.replace("Z", "+00:00")) else: dt = datetime.fromisoformat(pub) if dt.tzinfo is None: dt = dt.replace(tzinfo=timezone.utc) return dt.astimezone(timezone.utc) except Exception: # 解析失败就用当前时间兜底(不影响下载,只影响 pubDate) return datetime.now(timezone.utc) def download_file(url: str, path: str): """流式下载,先写 .part 再原子替换""" r = requests.get(url, headers=HEADERS, stream=True, timeout=180) r.raise_status() tmp = path + ".part" with open(tmp, "wb") as f: for chunk in r.iter_content(chunk_size=1024 * 256): if chunk: f.write(chunk) os.replace(tmp, path) def ensure_xml_exists(): if os.path.exists(XML_PATH): return raise RuntimeError( f"找不到 {XML_PATH}\n" f"请先把 zaokafei.xml 放到 {OUT_DIR} 下(至少包含 <rss><channel>...</channel></rss>)" ) def xml_has_guid(root: ET.Element, guid: str) -> bool: for item in root.findall("./channel/item"): g = item.findtext("guid") if g and g.strip() == guid: return True return False def add_item_to_xml( title: str, guid: str, pub_dt_utc: datetime, enclosure_url: str, length_bytes: int, ): """ 把新一期插入到 XML 的最前面(靠前显示) 仅写入最必要字段:title/pubDate/guid/enclosure """ ET.register_namespace("itunes", "http://www.itunes.com/dtds/podcast-1.0.dtd") tree = ET.parse(XML_PATH) root = tree.getroot() channel = root.find("channel") if channel is None: raise RuntimeError("XML 里没找到 <channel>") if xml_has_guid(root, guid): print("XML 已存在该期 guid,跳过写入:", guid) return item = ET.Element("item") t = ET.SubElement(item, "title") t.text = title pub = ET.SubElement(item, "pubDate") pub.text = format_datetime(pub_dt_utc) # RFC 2822 g = ET.SubElement(item, "guid", attrib={"isPermaLink": "false"}) g.text = guid ET.SubElement( item, "enclosure", attrib={ "url": enclosure_url, "length": str(length_bytes), "type": "audio/mp4", }, ) # 插到最前面:放在第一个 item 前 first_item = channel.find("item") if first_item is None: channel.append(item) else: children = list(channel) idx = children.index(first_item) channel.insert(idx, item) tree.write(XML_PATH, encoding="UTF-8", xml_declaration=True) print("已更新 XML:", XML_PATH) def main(): os.makedirs(OUT_DIR, exist_ok=True) ensure_xml_exists() data = get_next_data(PODCAST_URL) podcast = data["props"]["pageProps"]["podcast"] latest = podcast["episodes"][0] eid = latest["eid"] title = latest["title"] pub_raw = latest.get("pubDate", "") # 音频 URL 兼容两种字段 audio_url = ( latest.get("media", {}).get("source", {}).get("url") or latest.get("enclosure", {}).get("url") ) if not audio_url: raise RuntimeError("没找到 media.source.url / enclosure.url") pub_dt_utc = parse_pubdate_to_utc(pub_raw) date_str = pub_dt_utc.strftime("%Y-%m-%d") safe_title = sanitize_filename(title) filename = f"{date_str} - {safe_title}.m4a" out_path = os.path.join(OUT_DIR, filename) # 先判断 XML 是否已经有 guid:有的话可以直接结束(更省事) # 但为了保险(避免 XML 手动改动),我们仍然会检查文件是否存在。 print("最新一期:", title) print("EID:", eid) print("发布时间 (UTC):", pub_dt_utc.isoformat()) print("音频:", audio_url) if os.path.exists(out_path): print("文件已存在,跳过下载:", out_path) else: download_file(audio_url, out_path) print("下载完成:", out_path) # URL 编码文件名(中文/空格更稳) enclosure_url = f"{BASE_HTTP}{quote('/' + filename)}" length_bytes = os.path.getsize(out_path) add_item_to_xml( title=title, guid=eid, pub_dt_utc=pub_dt_utc, enclosure_url=enclosure_url, length_bytes=length_bytes, ) if __name__ == "__main__": main()

然后放一个 xml 文件

<?xml version='1.0' encoding='UTF-8'?> <rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0"> <channel> <title>声动早咖啡</title> <link>http://192.168.1.100:10086/</link> <description> 一个十五分钟的晨间仪式,轻松同步日常生活与商业世界。 工作日早晨更新,来自声动活泼的清晨播客。 </description> <itunes:image href="http://192.168.1.100:10086/cover.png" /> <image> <url>http://192.168.1.100:10086/cover.png</url> <title>声动早咖啡</title> <link>http://192.168.1.100:10086/</link> </image> <item><title>咖啡豆|18 世纪就被誉为「全球最好」的美利奴羊毛,为何最近在国内热度大增?</title><pubDate>Thu, 08 Jan 2026 23:00:00 +0000</pubDate><guid isPermaLink="false">695fce90d4b8fa56f5f949fe</guid><enclosure url="http://192.168.1.100:10086/2026-01-08%20-%20%E5%92%96%E5%95%A1%E8%B1%86%EF%BD%9C18%20%E4%B8%96%E7%BA%AA%E5%B0%B1%E8%A2%AB%E8%AA%89%E4%B8%BA%E3%80%8C%E5%85%A8%E7%90%83%E6%9C%80%E5%A5%BD%E3%80%8D%E7%9A%84%E7%BE%8E%E5%88%A9%E5%A5%B4%E7%BE%8A%E6%AF%9B%EF%BC%8C%E4%B8%BA%E4%BD%95%E6%9C%80%E8%BF%91%E5%9C%A8%E5%9B%BD%E5%86%85%E7%83%AD%E5%BA%A6%E5%A4%A7%E5%A2%9E%EF%BC%9F.m4a" length="14036410" type="audio/mp4" /></item><item><title>图拉斯|必胜客推出独立汉堡门店,外卖大战补贴降温</title><pubDate>Wed, 07 Jan 2026 23:00:00 +0000</pubDate><guid isPermaLink="false">695e474fc1e012a7abdcfb1e</guid><enclosure url="http://192.168.1.100:10086/2026-01-07%20-%20%E5%9B%BE%E6%8B%89%E6%96%AF%EF%BD%9C%E5%BF%85%E8%83%9C%E5%AE%A2%E6%8E%A8%E5%87%BA%E7%8B%AC%E7%AB%8B%E6%B1%89%E5%A0%A1%E9%97%A8%E5%BA%97%EF%BC%8C%E5%A4%96%E5%8D%96%E5%A4%A7%E6%88%98%E8%A1%A5%E8%B4%B4%E9%99%8D%E6%B8%A9.m4a" length="16226181" type="audio/mp4" /></item><item><title>没有鱼子酱饮食传统的中国,为何成为全球鱼子酱的主要产地?</title><pubDate>Tue, 06 Jan 2026 23:00:00 +0000</pubDate><guid isPermaLink="false">695d07efc1e012a7abad496a</guid><enclosure url="http://192.168.1.100:10086/2026-01-06%20-%20%E6%B2%A1%E6%9C%89%E9%B1%BC%E5%AD%90%E9%85%B1%E9%A5%AE%E9%A3%9F%E4%BC%A0%E7%BB%9F%E7%9A%84%E4%B8%AD%E5%9B%BD%EF%BC%8C%E4%B8%BA%E4%BD%95%E6%88%90%E4%B8%BA%E5%85%A8%E7%90%83%E9%B1%BC%E5%AD%90%E9%85%B1%E7%9A%84%E4%B8%BB%E8%A6%81%E4%BA%A7%E5%9C%B0%EF%BC%9F.m4a" length="14320957" type="audio/mp4" /></item><item><title>山姆中国付费会员首次破千万,泡泡玛特将加速海外扩张</title><pubDate>Mon, 05 Jan 2026 23:00:00 +0000</pubDate><guid isPermaLink="false">695bafd9bdbeb6a09ee00719</guid><enclosure url="http://192.168.1.100:10086/2026-01-05%20-%20%E5%B1%B1%E5%A7%86%E4%B8%AD%E5%9B%BD%E4%BB%98%E8%B4%B9%E4%BC%9A%E5%91%98%E9%A6%96%E6%AC%A1%E7%A0%B4%E5%8D%83%E4%B8%87%EF%BC%8C%E6%B3%A1%E6%B3%A1%E7%8E%9B%E7%89%B9%E5%B0%86%E5%8A%A0%E9%80%9F%E6%B5%B7%E5%A4%96%E6%89%A9%E5%BC%A0.m4a" length="11324711" type="audio/mp4" /></item><item><title>频繁发射火箭的 SpaceX 今年上市,为什么星链服务是其价值关键?</title><pubDate>Sun, 04 Jan 2026 23:00:00 +0000</pubDate><guid isPermaLink="false">695a8775b9fb62614108f66e</guid><enclosure url="http://192.168.1.100:10086/2026-01-04%20-%20%E9%A2%91%E7%B9%81%E5%8F%91%E5%B0%84%E7%81%AB%E7%AE%AD%E7%9A%84%20SpaceX%20%E4%BB%8A%E5%B9%B4%E4%B8%8A%E5%B8%82%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%E6%98%9F%E9%93%BE%E6%9C%8D%E5%8A%A1%E6%98%AF%E5%85%B6%E4%BB%B7%E5%80%BC%E5%85%B3%E9%94%AE%EF%BC%9F.m4a" length="15438817" type="audio/mp4" /></item></channel>

把自己的文件夹地址代理出来就可以

Frigate

摄像头管理 NVR,目前我是跑在 I5-5500U,M840 上,其实无法硬解 H265 视频,并且做 detect 其实也比较吃力。 官方地址:Frigate 中文文档 - Frigate 中文文档

视频硬解适配

image.png

intel cpu:

image.png

nvidia:Video Encode and Decode Support Matrix | NVIDIA Developer

在我的配置中,用 vappi 对 H264 硬解,对 H265 软解

hwaccel_args: preset-vaapi

有时候会报错,需要指定设备及视频格式

 hwaccel_args: --hwaccel vaapi --hwaccel_device /dev/dri/renderD128 --hwaccel_output_format yuv420p

视频推流

rtsp 推流,但是用 qsv 进行硬编码。

各种嵌入式设备

Marshall 音箱

因为该音箱是一个有源音箱,连接方式有蓝牙和 3.5mm 连接两种

music assistant 安装 snapcast provider

image.png

在终端设备安装 snapcast 客户端

甲醛检测仪

使用 ZH08 CH2O 传感器,是电化学传感器

image.png

image.png

具体代码

ze08-ch2o.yaml

esphome:
  name: ze08-ch2o
  friendly_name: ZE08 CH2O
  esp32:
    board: esp32dev
  framework:
    type: arduino
  wifi:
    ssid: "xxxxxxxxxxxxx"
    password: "xxxxxxxxxxx"
  logger:
    baud_rate: 0
  api:
    ota:
      - platform: esphome
  external_components:
    - source:
        type: local
        path: components
      components: [ ze08_ch2o ]
  uart:
    id: uart_ze08
    rx_pin: GPIO3 # 板子上 RX
    tx_pin: GPIO1 # 板子上 TX
    baud_rate: 9600
    data_bits: 8
    parity: NONE
    stop_bits: 1
  ze08_ch2o:
    id: ze08_sensor
    uart_id: uart_ze08
    ch2o_ppb:
      name: "CH2O (ppb)"
    ch2o_mg_m3:
      name: "CH2O (mg/m³)"
  sensor:
    - platform: template
      name: dummy_sensor
      id: dummy_sensor
      lambda: |- return 0.0;
      update_interval: 1h
  internal: true

init.py

import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import uart, sensor
from esphome.const import CONF_ID

ze08_ns = cg.esphome_ns.namespace("ze08_ch2o")
ZE08CH2OUart = ze08_ns.class_("ZE08CH2OUart", cg.Component, uart.UARTDevice)

CONF_PPB = "ch2o_ppb"
CONF_MGM3 = "ch2o_mg_m3"

CONFIG_SCHEMA = cv.Schema(
    {
        cv.GenerateID(): cv.declare_id(ZE08CH2OUart),
        cv.Required(CONF_PPB): sensor.sensor_schema(
            unit_of_measurement="ppb",
            accuracy_decimals=0,
            icon="mdi:molecule",
        ),
        cv.Required(CONF_MGM3): sensor.sensor_schema(
            unit_of_measurement="mg/m³",
            accuracy_decimals=3,
            icon="mdi:molecule",
        ),
    }
).extend(uart.UART_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA)

async def to_code(config):
    var = cg.new_Pvariable(config[CONF_ID])
    await cg.register_component(var, config)
    await uart.register_uart_device(var, config)
    ppb = await sensor.new_sensor(config[CONF_PPB])
    mgm3 = await sensor.new_sensor(config[CONF_MGM3])
    cg.add(var.set_sensors(ppb, mgm3))

ze08_ch2o_uart.h

#pragma once
#include "esphome/core/component.h"
#include "esphome/components/uart/uart.h"
#include "esphome/components/sensor/sensor.h"

namespace esphome {
namespace ze08_ch2o {
class ZE08CH2OUart : public Component, public uart::UARTDevice {
public:
    ZE08CH2OUart() : uart::UARTDevice(nullptr) {}
    explicit ZE08CH2OUart(uart::UARTComponent *parent) : uart::UARTDevice(parent) {}
    void set_sensors(sensor::Sensor *ppb, sensor::Sensor *mgm3) {
        ch2o_ppb_ = ppb;
        ch2o_mg_m3_ = mgm3;
    }
    void loop() override {
        while (available()) {
            uint8_t b = read();
            if (idx_ == 0) {
                if (b != 0xFF) continue;
                buf_[idx_++] = b;
                continue;
            }
            buf_[idx_++] = b;
            if (idx_ >= 9) {
                parse_frame_();
                idx_ = 0;
            }
        }
    }
protected:
    sensor::Sensor *ch2o_ppb_{nullptr};
    sensor::Sensor *ch2o_mg_m3_{nullptr};
    uint8_t buf_[9]{0};
    uint8_t idx_{0};
    void parse_frame_() {
        // FF 17 04 dec hi lo fs_hi fs_lo checksum
        if (buf_[0] != 0xFF) return;
        if (buf_[1] != 0x17) return; // CH2O
        if (buf_[2] != 0x04) return; // ppb
        uint16_t sum = 0;
        for (int i = 1; i <= 7; i++) sum += buf_[i];
        uint8_t cs = (uint8_t)(~(sum & 0xFF) + 1);
        if (cs != buf_[8]) return;
        uint16_t ppb = ((uint16_t) buf_[4] << 8) | buf_[5];
        float mgm3 = (ppb / 1000.0f) * 1.25f;
        if (ch2o_ppb_) ch2o_ppb_->publish_state(ppb);
        if (ch2o_mg_m3_) ch2o_mg_m3_->publish_state(mgm3);
    }
};
} // namespace ze08_ch2o
} // namespace esphome
刷机页面

链接:Web - ESPHome

IntelRealsense 摄像头/astra_color 摄像头

采用 qsv 硬编码

image.png

夜视模式根据灰度直方图判断自动切换切换夜里用 IR 流和 RGB 流,同一个流输出

image.png

小米 4C 摄像头

由于小米摄像头本身无提供 RTSP 视频流,使用小米官方开源的 miloco 项目接受 websocket 流,之后三方的 micam 将此流转换为 rtsp 视频流,官方用 go2rtc 推流,我这边改用了 mediamtx,另外小米 4C 为 H265 编码,docker 运行

miloco

开源地址:XiaoMi/xiaomi-miloco: Xiaomi Miloco

micam

开源地址:miiot/micam: 🎦 Micam 是一个专为小米摄像头设计的 RTSP 桥接服务 (非官方),能够将小米摄像头的视频流本地转推到 RTSP 服务器,支持接入 HomeAssistant、Go2rtc、Frigate、Scrypted、Homekit 等多种 NVR 和智能家居系统。该项目采用 Docker Compose 快速部署方案,基于小米官方的 Miloco,并集成 Go2rtc 实现 RTSP 流服务,无需 GPU 即可运行,使小米摄像头能与各类主流智能家居平台无缝集成。

拓竹 A1 mini

使用插件:Integration Overview

根据官方配置,能进行的操作似乎蛮多

开启局域网模式以后获取视频流方法

链接:jtessler/bambucam: Linux command line tool to access camera feed from a Bambu 3D printer

但我是 A1 mini 似乎智能获取 HTTP 视频流,效果如下

image.png

ESPHOME 排插/MQTT 插座/zigbee 插座

淘宝购入 zigbee 信号接收器插在跑 HA 的树莓派上

0db72f02e4774f444f6d128e07b1.jpg

在 homeassistant/configuration.yaml 配置

image.png

终端设备淘宝非常多,几种通信协议的设备都能够支持,参考店家说明配置没啥难度

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Tasmota 设置 Set'Option 为 OFF 时为 switch,设置为 ON 时为 light

目录

  1. 设备框架图
  2. 小智 ESP32 嵌入式前端
  3. 小智 ESP32 后端服务器
  4. Home Assistant
  5. 公网访问
  6. 网络存储
  7. Music Assistant
  8. 歌曲下载地址
  9. podcast 收听地址
  10. Frigate
  11. 视频硬解适配
  12. 视频推流
  13. 各种嵌入式设备
  14. Marshall 音箱
  15. 甲醛检测仪
  16. 具体代码
  17. 刷机页面
  18. IntelRealsense 摄像头/astra_color 摄像头
  19. 小米 4C 摄像头
  20. miloco
  21. micam
  22. 拓竹 A1 mini
  23. ESPHOME 排插/MQTT 插座/zigbee 插座
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 鸿蒙金融理财全栈项目:上线运维、用户反馈与持续迭代
  • Python 全栈开发学习路线:从基础语法到项目部署
  • 【论文阅读】DreamZero:World Action Models are Zero-shot Policies
  • GTC 2026 前瞻:Rubin 平台与 AI 工厂基础设施
  • Spring Boot 集成 Eclipse Mosquitto MQTT 实战
  • 使用 Copilot 制定 60 天 AI 学习计划并同步至 Outlook 日程
  • Hive 多租户管理:企业级部署方案
  • 3DMAX VR渲染器局部渲染设置教程
  • VR、具身智能与人形机器人:通往现实世界的智能接口
  • DGX Spark 部署 Stable Diffusion 3.5 与 ComfyUI 实战
  • Spring Security 6.3.x 使用指南
  • FANUC 机器人 PR 寄存器详解
  • Open Duck Mini v2 智能行走机器人构建指南
  • Qwen3 与 Qwen Agent 智能体开发实战:接入 MCP 工具
  • Python 列表与元组的区别及常用操作
  • Rust 与 WebAssembly 实战:在浏览器与 Node.js 中运行高性能代码
  • 平凡人的努力与坚持:致敬默默前行者
  • 2 小时用 AI 从零开发微信小程序实战
  • Python 爬虫接单指南:技能要求、法律边界与实战建议
  • 实战演练:基于 Next.js 和 Wagmi 构建支持 TokenP 钱包登录的 DApp 前端

相关免费在线工具

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online