Home Assistant 接入 MBE 指南

让 Home Assistant 设备获得 MBE 的 AI 能力,实现智能语音问答。

架构

┌─────────────────────────────────────────────────────────┐
│                    Home Assistant                        │
│                                                          │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐              │
│  │ ESPHome  │  │  Assist  │  │ 自动化   │              │
│  │ 语音设备 │  │ 语音助手 │  │ Scripts  │              │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘              │
│       │             │             │                      │
│       └─────────────┼─────────────┘                      │
│                     ↓                                    │
│            RESTful Command                               │
│                     │                                    │
└─────────────────────┼────────────────────────────────────┘
                      ↓
              ┌──────────────┐
              │     MBE      │
              │  REST API    │
              │ 专家知识系统 │
              └──────────────┘

API 端点

端点 方法 用途
/api/ha/ask POST 主查询接口(完整响应)
/api/ha/query POST 简化查询接口
/api/ha/ping GET 服务健康检查
/api/ha/experts GET 列出可用专家
/api/ha/expert/{id} POST 向指定专家提问

快速配置

1. 添加 RESTful Command

configuration.yaml 中添加:

rest_command:
  # MBE 智能问答
  mbe_ask:
    url: "http://YOUR_MBE_SERVER:9999/api/ha/ask"
    method: POST
    content_type: "application/json"
    payload: >
      {
        "text": "{{ text }}",
        "entity_id": "{{ entity_id | default('') }}",
        "area": "{{ area | default('') }}",
        "user_id": "{{ user_id | default('default') }}"
      }
    timeout: 10

2. 添加服务状态传感器

binary_sensor:
  - platform: rest
    name: "MBE 服务状态"
    resource: "http://YOUR_MBE_SERVER:9999/api/ha/ping"
    value_template: "{{ value_json.ok }}"
    scan_interval: 60

3. 创建脚本

script:
  ask_mbe:
    alias: "询问 MBE"
    sequence:
      - service: rest_command.mbe_ask
        data:
          text: "{{ question }}"
          area: "{{ area }}"
        response_variable: mbe_response
      - service: tts.speak
        target:
          entity_id: "{{ tts_entity }}"
        data:
          message: "{{ mbe_response.content.speech }}"

  # 示例:询问并播报
  living_room_ask:
    alias: "客厅语音助手"
    sequence:
      - service: script.ask_mbe
        data:
          question: "{{ question }}"
          area: "living_room"
          tts_entity: media_player.living_room_speaker

语音助手集成

方式一:自定义 Assist 管道

创建 custom_sentences/zh-CN/mbe.yaml

language: "zh-CN"
intents:
  AskMBE:
    data:
      - sentences:
          - "问问 {query}"
          - "请问 {query}"
          - "帮我查 {query}"
          - "{query}"

创建 custom_components/mbe_intent/ 自定义组件处理意图。

方式二:使用自动化

automation:
  - alias: "MBE 语音问答"
    trigger:
      - platform: conversation
        command:
          - "问问 {query}"
          - "请问 {query}"
    action:
      - service: rest_command.mbe_ask
        data:
          text: "{{ trigger.slots.query }}"
        response_variable: response
      - service: tts.speak
        target:
          entity_id: media_player.assistant
        data:
          message: "{{ response.content.speech }}"

ESPHome 设备集成

对于基于 ESPHome 的自制智能音箱:

# ESPHome 配置
esphome:
  name: smart-speaker
  
http_request:
  useragent: esphome/smart-speaker
  timeout: 10s

# 发送语音识别结果到 MBE
button:
  - platform: template
    name: "Ask MBE"
    on_press:
      - http_request.post:
          url: "http://YOUR_MBE_SERVER:9999/api/ha/query"
          headers:
            Content-Type: application/json
          json:
            q: !lambda 'return id(voice_text).state;'
            eid: "esphome.smart_speaker"
          on_response:
            then:
              - lambda: |-
                  if (response->status_code == 200) {
                    auto json = response->parse_json();
                    std::string speech = json["speech"].as<std::string>();
                    // 发送到 TTS
                    id(tts_text).publish_state(speech);
                  }

仪表盘卡片

聊天输入卡片

type: custom:mushroom-text-input-card
entity: input_text.mbe_question
name: 问问 MBE
icon: mdi:robot

type: custom:button-card
entity: script.ask_mbe
tap_action:
  action: call-service
  service: script.ask_mbe
  data:
    question: "{{ states('input_text.mbe_question') }}"

专家列表卡片

type: custom:auto-entities
card:
  type: entities
  title: MBE 专家
filter:
  template: |
    {% set response = state_attr('rest.mbe_experts', 'experts') %}
    {% for expert in response %}
      {{ {'entity': 'input_boolean.mbe_expert_' + expert.id, 'name': expert.name} }}
    {% endfor %}

完整示例:智能语音助手

configuration.yaml

# 输入文本
input_text:
  mbe_question:
    name: MBE 问题
    max: 200

# REST 命令
rest_command:
  mbe_ask:
    url: "http://192.168.1.100:9999/api/ha/ask"
    method: POST
    content_type: "application/json"
    payload: '{"text": "{{ text }}", "area": "{{ area }}"}'
    timeout: 10

# 服务状态
binary_sensor:
  - platform: rest
    name: "MBE Online"
    resource: "http://192.168.1.100:9999/api/ha/ping"
    value_template: "{{ value_json.ok }}"

# 脚本
script:
  mbe_voice_assistant:
    alias: "MBE 语音助手"
    mode: single
    sequence:
      # 调用 MBE
      - service: rest_command.mbe_ask
        data:
          text: "{{ question }}"
          area: "{{ area | default('home') }}"
        response_variable: mbe_result
      
      # 检查响应
      - choose:
          - conditions:
              - condition: template
                value_template: "{{ mbe_result.content.success }}"
            sequence:
              # 播报回答
              - service: tts.google_translate_say
                target:
                  entity_id: "{{ speaker | default('media_player.living_room') }}"
                data:
                  message: "{{ mbe_result.content.speech }}"
                  language: "zh-CN"
        default:
          - service: tts.google_translate_say
            target:
              entity_id: "{{ speaker | default('media_player.living_room') }}"
            data:
              message: "抱歉,我没有理解您的问题"
              language: "zh-CN"

# 自动化
automation:
  - alias: "语音问答触发"
    trigger:
      - platform: state
        entity_id: input_text.mbe_question
    condition:
      - condition: template
        value_template: "{{ trigger.to_state.state | length > 0 }}"
    action:
      - service: script.mbe_voice_assistant
        data:
          question: "{{ states('input_text.mbe_question') }}"
          speaker: media_player.living_room
      - delay: 1
      - service: input_text.set_value
        target:
          entity_id: input_text.mbe_question
        data:
          value: ""

请求/响应格式

请求

{
  "text": "糖尿病患者饮食要注意什么",
  "entity_id": "media_player.living_room",
  "area": "living_room",
  "user_id": "user123",
  "language": "zh-CN",
  "context": {
    "temperature": 26.5,
    "humidity": 65
  }
}

响应

{
  "success": true,
  "speech": "糖尿病患者饮食应注意控制碳水化合物摄入...",
  "display": "完整的详细回答...",
  "expert": "营养治疗师专家",
  "intent": "answer",
  "data": {
    "original_length": 856,
    "expert_id": "dynamic_f21c2aed7d7b"
  }
}

故障排除

连接问题

  1. 检查 MBE 服务是否运行:

    curl http://YOUR_MBE_SERVER:9999/api/ha/ping
    
  2. 检查网络连通性(HA 主机能否访问 MBE)

  3. 检查防火墙是否开放 9999 端口

响应超时

  • 增加 timeout 配置
  • 检查 MBE 服务负载
  • 考虑启用 fast_mode

TTS 不播报

  1. 检查 TTS 服务配置
  2. 确认 media_player 实体正确
  3. 查看 HA 日志