![Logo](../../admin/automatic-feeder.png) # ioBroker.automatic-feeder

## 用于 ioBroker 的 automatic-feeder 适配器 本适配器可将任意一个 ioBroker 中已有的开关(一个插座、一个继电器、一个 GPIO 输出……) 变成一个**定时控制的喂食器**。它会在你设定的时间将输出端打开持续指定的秒数, 并且在此过程中可以考虑温度以及昼夜变化,从而确保绝不会在错误的时间喂食。 本文档是一份完整的使用说明。如果你从未使用过本适配器,请从上到下通读—— **快速上手**会在几分钟内带你完成第一次喂食,其余部分会详细解释每一项设置。 --- ## 目录 1. [适配器的功能](#1-适配器的功能) 2. [前提条件](#2-前提条件) 3. [安装](#3-安装) 4. [快速上手——第一次喂食](#4-快速上手第一次喂食) 5. [设置页面详解](#5-设置页面详解) 6. [对象 / 数据点](#6-对象--数据点) 7. [示例 / 配方](#7-示例--配方) 8. [Telegram 通知](#8-telegram-通知) 9. [故障排除与常见问题](#9-故障排除与常见问题) 10. [日志记录与排错](#10-日志记录与排错) --- ## 1. 适配器的功能 一次“喂食”从本质上讲非常简单:**输出端打开 → 等待可设置的秒数 → 再次关闭**。 对于改装过的喂食器来说,电机会在这段时间内运转并投放饲料。 本适配器最多可管理 **5 个开关**,每个开关都完全独立,并拥有以各自开关命名的专属 配置选项卡。每个开关你都可以设定: * **何时**喂食——既可以在**固定时间**(例如 08:00 和 18:00),也可以在某个时间段内 按**间隔**喂食(例如在 08:00 到 18:00 之间每隔 60 分钟一次); * 输出端保持打开**多长时间**(喂食时长,以秒为单位); * 当水温或气温过低/过高时**是否阻止**喂食; * **是否在夜间**不喂食(基于你所在位置的真实日出/日落时间); * **是否对开关动作进行监控**(检查是否真的完成了开和关),并可选地通过 **Telegram** 发送结果通知; * **是否在**每年重复的**冬季**季节期间减量或暂停喂食——可选地在开始前和结束前通过 Telegram 发送提醒; * **是否**根据水温/气温自动调整间隔和投喂量(**动态投喂**,Q10 模型); * 当溶解**氧**(O₂)过低时**是否阻止**喂食。 你随时都可以**手动**触发一次喂食——既可以直接在设置页面上(带有可自由选择时长的按钮), 也可以通过一个数据点(例如 VIS 视图中的一个按钮)。 > 重要:适配器本身不会创建开关。它**控制的是你 ioBroker 中已有的对象**。 > 你需要在配置中选择这个对象。 --- ## 2. 前提条件 | 你需要 | 详情 | |-------------|---------| | 安装了较新版 **admin**(≥ 7)的 **ioBroker** | 配置页面是使用 React 实现的。 | | **一个开关对象** | 一个可写的 ioBroker 数据点,用于开关喂食器——例如一个插座(`shelly.0.…`、`sonoff.0.…`、`zigbee.0.…`)、一个继电器或一个脚本变量。 | | **地理坐标** | 用于计算日出/日落。既可以来自 ioBroker 系统设置,也可以通过地址/地图设置。**必填。** | | *(可选)* 温度对象 | 已有的、包含气温和/或水温的数据点,用于温度阻止或动态投喂。**针对每个开关**在开关选项卡中分配。 | | *(可选)* **溶氧(O₂)**对象 | 已有的、包含溶解氧的数据点,用于在溶解氧过低时阻止喂食。**针对每个开关**分配。 | | *(可选)* 一个 **Telegram** 实例 | 官方的 `telegram` 适配器,已设置并启动,前提是你想要推送通知。 | | ioBroker 主机上的互联网连接 | 仅用于配置中的地址搜索/地图。正常运行时离线即可。 | --- ## 3. 安装 1. 在 ioBroker **admin** 中打开**适配器(Adapter)**选项卡。 2. 在适配器列表中找到 **automatic-feeder**,并点击**安装(Install)**。 3. 创建该适配器的一个**实例**。 4. 打开实例设置(齿轮图标)——应当会出现带有**基本设置(Grundeinstellungen)** 选项卡的配置页面。如果页面保持空白,请参见[故障排除](#9-故障排除与常见问题)。 --- ## 4. 快速上手——第一次喂食 目标:让一个开关——立即进行测试——喂食 5 秒。 1. **打开** automatic-feeder 实例的**设置**。 2. 在**基本设置(Grundeinstellungen)**选项卡中: * 在**位置(Standort)**下,如果你的 ioBroker 已有坐标,请选择*采用系统设置*。 否则选择*指定具体位置*,输入地址,点击**搜索**,并在地图上确认标记。 * 向下滚动到**开关(Schalter)**,并点击**添加开关**。 * 起一个**名称**(例如 `Koi-Teich`)。这个名称将成为一个独立选项卡的标题。 * 在**开关对象(Schalter-Objekt)**旁点击列表图标,选择控制你喂食器的数据点 (例如你的插座)。开关必须处于**激活**状态(左侧勾选框)。 3. **保存**(底部的软盘/对勾)。会出现一个以你的开关名称命名的新选项卡。 4. 打开这个**开关选项卡**。在最上方的**手动喂食(Manuelle Fütterung)**下设置一个时长 (例如 `5` 秒),并点击**立即喂食**。输出端应当打开 5 秒,然后再次关闭。 5. 在同一选项卡中,在**喂食计划(Fütterungsplan)**下设置真正的时间计划 (例如固定时间 08:00 和 18:00),并在**喂食过程(Fütterungsvorgang)**下设置 **喂食时长**,然后**保存**。 完成——从现在起适配器会自动喂食。其余内容会详细解释各项选项。 --- ## 5. 设置页面详解 配置包含一个**基本设置(Grundeinstellungen)**选项卡,以及**每个开关一个选项卡** (一旦某个开关有了名称就会自动创建)。如果某个页面无法滚动,请放大窗口或使用右侧的 滚动条——所有部分都是可以访问到的。 ### 5.1 选项卡“基本设置(Grundeinstellungen)” #### 位置(Standort,必填) 适配器需要你的地理位置,以便计算日出和日落(用于夜间阻止)。有两种方式: * **采用系统设置(Systemeinstellungen übernehmen)**——从 ioBroker 系统配置中取得纬度/经度 (如果那里已经设置好,则推荐此项)。会显示当前的值。 * **指定具体位置(Standort spezifisch festlegen)**——自行确定位置: * 输入一个**地址**并按**搜索**。适配器会解析它(通过 OpenStreetMap / Nominatim) 并设置一个标记。 * 或者**点击地图** / **拖动标记**,以选择精确位置。 * 也可以直接填写纬度/经度;地图会随之跟进。 > 地址搜索在适配器后端运行,因此**实例必须正在运行**。地图和搜索需要互联网连接。 #### 日照时段(夜间不喂食) 设定允许喂食的时间段: * **日出后的分钟数**——日出*之后*经过这么多分钟才开始喂食。 * **日落前的分钟数**——在日落*之前*这么多分钟停止喂食。 示例:当日出为 06:30、日落为 21:00,偏移量为 30 / 30 时,喂食仅允许在 **07:00 到 20:30** 之间进行。每个开关都可以单独遵守或忽略这个时段(见开关选项卡中的*限制*)。 计算出的时间还会存放在数据点 `sunrise` / `sunset` 中,并每晚自动重新计算。 #### 开关 喂食器列表(最多 5 个)。每一项包含: * **激活(Aktiv)**(勾选框)——只有激活的开关才会被排入计划。 * **名称(Name)**——自由文本;会成为该开关的选项卡标题以及对象树中的通道名称。 * **开关对象(Schalter-Objekt)**——要控制的、已有的 ioBroker 数据点。通过列表图标选择, 通过叉号清空。 通过**添加开关(Schalter hinzufügen)**再添加一个(最多 5 个),通过垃圾桶图标删除一个。 删除时也会同时删除其数据点。 ### 5.2 开关选项卡 每个已配置的开关都会获得一个以其名称命名的专属选项卡。它包含以下部分。 #### 手动喂食(Manuelle Fütterung) * **手动喂食时长(秒)**——按钮所使用的时长。 * **立即喂食(Jetzt füttern)**——立即触发一次该时长的喂食。便于测试或额外加餐。 (是否忽略阻止,取决于*限制*下的*手动触发器忽略所有阻止*。) * 要使用该按钮,实例必须正在运行且配置已**保存**。 #### 喂食计划(Fütterungsplan) 选择**一种**模式: * **固定时间**——一个时间列表(`HH:mm`)。可任意添加;喂食器每天会在其中每个时间运行。 示例:`08:00` 和 `18:00`。 * **某时间段内的间隔**——在一个时间窗口内重复喂食: * **时间段开始** / **时间段结束**——例如 08:00 到 18:00。 * **间隔(分钟)**——例如 60 → 每天在 08:00、09:00……一直到窗口结束时喂食。 下一次计划的时间随时可在数据点 `status.nextFeeding` 中查看。 #### 喂食过程(Fütterungsvorgang) * **喂食时长(秒)**——在一次计划喂食时输出端保持打开的时长。 * **开值(Ein-Wert)** / **关值(Aus-Wert)**——写入开关对象的值。默认是 `true` 和 `false`, 适用于大多数插座/继电器。如果你的设备期望数字或文本,请在此填写例如 `1` / `0` 或 `ON` / `OFF`。 #### 温度与溶氧来源 每个开关(喂食站点)都拥有**各自独立的**传感器——不同的池塘/水箱可以使用不同的对象: * **气温**——勾选并选择包含该站点气温的数据点。 * **水温**——勾选并选择包含该站点水温的数据点。 * **溶氧(O₂)**——勾选并选择包含溶解氧的数据点。 只有数字类型的数据点才有意义。当前值会被镜像到该开关的 `status.airTemperature`、`status.waterTemperature` 和 `status.oxygen` 数据点。阈值在下方设置(*温度阻止*),温度同时也驱动*动态投喂*。 #### 温度阻止 仅对在上方(*温度与溶氧来源*)激活的温度来源显示。每个开关: * **按水温阻止**——*低于时阻止*和/或*高于时阻止*(°C)。 * **按气温阻止**——气温方面同上。 如果当前温度处于允许范围之外,喂食将被跳过,原因会写入 `status.blockReason`。 (如果某个温度值未知,则该来源不会阻止。) #### 限制 * **夜间不喂食**——遵守日照时段(含偏移量)。如果该开关允许全天候喂食,则关闭此项。 * **手动触发器忽略所有阻止**——如果激活,则即使温度/夜间阻止处于生效状态,按钮和数据点 `feedNow` 也会喂食。 #### 动态投喂 可选:使用 Q10 模型让**投喂间隔和时长随温度自适应**(温度每升高 10 °C,代谢率约翻倍)。需要启用温度源;此时固定时间将由窗口内的间隔取代。 * **启用 / 来源** —— 打开并选择水温或气温。 * **参考 / Q10** —— 基准间隔和时长在参考温度(如 20 °C)时生效;Q10 通常为 2–2.5。 * **间隔 / 时长(基准、最小、最大)** —— 计算所得间隔(分钟)和时长(秒)的上下限。**基准间隔和最大间隔必须大于 0**,否则无法规划任何喂食。 * **平均窗口 / 迟滞** —— 移动平均(如 24 小时)平滑波动;迟滞避免因微小变化而重新排程。 当前值可在 `status.dynamicAvgTemperature`、`status.dynamicRate`、`status.dynamicIntervalMin` 和 `status.dynamicDurationSec` 中查看。可选的**溶氧 (O₂)** 源可在溶解氧低于阈值时阻止投喂。冬季暂停优先于动态投喂。 > 如果已启用动态投喂但无法计算出有效的间隔(基准或最大间隔为 0,或时间窗口无效),则不会排入任何计划:`status.nextFeeding` 保持为空,`status.blockReason` 会显示提示。请将基准间隔和最大间隔设为大于 0。 #### 冬季暂停 每个开关都可以设置一个重复的**冬季暂停**(按季节,以每年重复的 `MM-DD` 日期表示,可跨越新年)。 * **启用冬季暂停** —— 打开暂停。 * **冬季开始 / 冬季结束** —— 从日历中选择日和月(显示为 dd.mm),例如 01.11 到 15.03。 * **模式** —— 暂停期间可以**暂停投喂**、以**减量**的自定义间隔投喂,或每日**一次**在固定时间投喂;并使用单独的**冬季投喂时长**。 * **提醒 (Telegram)** —— 在开始前和结束前的若干天,每天(最后一次为当天)在设定的小时发送提醒。需要 Telegram 实例(见下方)。 当前状态显示在数据点 `status.winterActive` 中。暂停结束后会自动恢复投喂。 #### 开关监控(Schaltüberwachung) 在切换之后,适配器可以检查开关是否**确实**达到了开启和关闭状态,并为每次喂食报告 三种结果之一: | 结果 | 含义 | 通知 | |----------|-----------|---------| | ✅ 成功 | 开关按预期完成了开和关 | „已触发投喂 x 秒。" | | ❌ 开启失败 | 开关从未确认 EIN(开启)状态 | „无法执行投喂。请检查开关!" | | ❌ 关闭失败 | 它打开了,但未能再次关闭 | „故障:喂食器未关闭!" | > 通知将以配置的 ioBroker 系统语言发送(默认英语)。 * **检查开关是否确实开启和关闭**——启用监控。 * **监控超时(秒)**——等待确认的时长。 * **验证次数**——在报告故障前执行多少次错时复查(默认 3)。每次尝试还会主动回读当前状态,因此延迟的状态反馈(例如 Homematic 无线电)不再触发误报。 > **重要:** 监控只有在开关**回报其实际状态**时才有效,也就是说目标对象会以 `ack=true` > 更新(对于带状态回报的插座/继电器是典型情况)。一个没有任何人确认的简单辅助布尔值 > 总会报告故障——这时应为该开关关闭监控。 结果还会写入数据点 `status.lastResult`(文本)和 `status.error`(boolean),以便你据此做出响应 (例如触发你自己的通知)。 #### Telegram 通知 将开关监控的通知发送到 Telegram——**针对每个开关**配置: * **Telegram 实例**——选择已安装的 `telegram.*` 实例之一(或选*无*,以为该开关禁用 Telegram)。如果未安装任何实例,该字段会有相应提示。 * **Telegram 接收人(可选)**——一个特定的用户/聊天名称,与 telegram 适配器中配置的一致; 留空则发送给所有已配置的接收人。 * **复选框**——选择要发送哪些通知:成功喂食、无法执行和/或关闭故障。 **冬季暂停提醒**(如已启用,见*冬季暂停*)会发送到同一个 Telegram 实例, 与这些监控复选框无关。 完整的设置说明见 [Telegram 通知](#8-telegram-通知)。 --- ## 6. 对象 / 数据点 适配器会在其命名空间下创建以下数据点(`automatic-feeder..`)。 **全局** | 数据点 | 类型 | 含义 | |------------|-----|-----------| | `info.connection` | boolean (ro) | 适配器正在运行且配置有效。 | | `sunrise` / `sunset` | string (ro) | 计算出的今日日出/日落。 | **每个开关下,位于 `switches..`**(`` 是诸如 `sw-0` 的内部 ID) 开关下方直接放置了手动触发器和两个子通道: * **`status`**(`switches..status.*`)——下方列出的只读状态数据点。 * **`settings`**(`switches..settings.*`)——该开关配置的**可编辑**镜像。在此写入新值(从 VIS 或脚本)会更改配置并重启实例以使更改生效。少数派生字段为只读(例如 `winterWindow`)。 | 数据点 | 类型 | 含义 | |------------|-----|-----------| | `feedNow` | boolean (rw) | 写入 `true` 以手动喂食。 | | `status.feedingActive` | boolean (ro) | 当前正在进行一次喂食。 | | `status.lastFeeding` | string (ro) | 上次喂食的时间点。 | | `status.nextFeeding` | string (ro) | 下一次计划喂食的时间点。 | | `status.blocked` | boolean (ro) | 上次尝试被阻止。 | | `status.blockReason` | string (ro) | 阻止的原因(夜间/温度/氧)。 | | `status.lastResult` | string (ro) | 上次喂食尝试的结果文本。 | | `status.error` | boolean (ro) | 上次尝试出现了开关故障。 | | `status.winterActive` | boolean (ro) | 冬季暂停当前处于生效状态。 | | `status.winterLastStartReminder` | string (ro) | 上次发送“冬季开始”提醒的日期。 | | `status.winterLastEndReminder` | string (ro) | 上次发送“冬季结束”提醒的日期。 | | `status.dynamicAvgTemperature` | number (ro) | 动态投喂所用的平均温度。 | | `status.dynamicRate` | number (ro) | 动态投喂当前应用的 Q10 速率因子。 | | `status.dynamicIntervalMin` | number (ro) | 当前计算得出的动态间隔(分钟)。 | | `status.dynamicDurationSec` | number (ro) | 当前计算得出的动态时长(秒)。 | | `status.airTemperature` | number (ro) | 该开关自身气温来源的值。 | | `status.waterTemperature` | number (ro) | 该开关自身水温来源的值。 | | `status.oxygen` | number (ro) | 该开关自身溶解氧来源的值。 | 这些数据点可在 VIS、脚本或其他适配器中使用——例如在仪表盘上显示 `status.nextFeeding`, 或在 `status.error = true` 时触发你自己的报警。 --- ## 7. 示例 / 配方 **锦鲤池,每天两次,仅在足够温暖时** * 模式*固定时间* → `08:00`、`18:00`;时长 `6` 秒。 * 在开关选项卡的*温度与溶氧来源*下激活*水温*并选择传感器;然后选*按水温阻止* → *低于时阻止* `8` °C (水太冷时不喂食)。 * 开启*夜间不喂食*。 **鸟舍,白天频繁少量投喂** * 模式*某时间段内的间隔* → 07:00–19:00,间隔 `90` 分钟;时长 `3` 秒。 **锦鲤池,随温度自适应(动态投喂)** * 在开关选项卡的*温度与溶氧来源*下激活*水温*并选择传感器。 * 然后打开*动态投喂*,启用它,来源选*水温*。 * 参考 `20` °C,Q10 `2.2`,基准间隔 `60` 分钟(最小 `30`,最大 `480`),基准时长 `5` 秒 (最小 `2`,最大 `15`)。这样它会在温暖时更频繁地喂食并略微增量,在寒冷时减少。 **为池塘设置冬季休息** * 在开关选项卡中打开*冬季暂停*,启用它,设置*冬季开始* `01.11` 和*冬季结束* `15.03`, 模式*暂停投喂*。 * 可选地勾选提醒,以便在开始/结束前几天收到一条 Telegram 提示。 **通过 VIS 按钮手动加餐** * 在 VIS 中创建一个按钮,将 `true` 写入 `automatic-feeder.0.switches.sw-0.feedNow`。 * 可选地激活*手动触发器忽略所有阻止*,以便始终喂食。 --- ## 8. Telegram 通知 1. 安装并设置 **telegram** 适配器(用 @BotFather 创建机器人,填入 Token,与机器人开始聊天)。 Telegram 实例必须**正在运行**。 2. 在某个 automatic-feeder **开关选项卡**中打开 **Telegram 通知**部分: * 在下拉菜单中选择 **Telegram 实例**(例如 `telegram.0`)。 * 可选地填写一个**接收人**(telegram 适配器中显示的用户/聊天名称);留空则通知所有人。 * 勾选想要的通知:*成功喂食*、*无法执行*、*关闭故障*。 3. 保存。从现在起,所选的监控结果会被发送到 Telegram(前面带有开关名称)。前提是该开关的 *开关监控*已激活。 4. **冬季暂停提醒**使用同一个 Telegram 实例和接收人。它们在*冬季暂停*部分中控制 (开始/结束前的天数以及提醒的小时),且**无需**启用监控。 --- ## 9. 故障排除与常见问题 **设置页面是空白的 / 白屏。** 请用 **Strg+Shift+R** 重新加载浏览器。如果仍然如此,请重启该实例并重新打开设置。 **新图标 / 某项改动没有出现。** 浏览器缓存。请用 **Strg+Shift+R** 强制重新加载。 **完全没有喂食。** 依次检查:开关已**激活**;已选择一个**开关对象**;**时间计划**有效(`status.nextFeeding` 显示一个时间); 未被**阻止**(查看 `status.blocked` / `status.blockReason`);**日照时段**没有排除该时间;将实例的 **日志级别**设为 `debug` 并观察日志。 **尽管我想要,但从来不在夜间喂食。** 要么为该开关停用*夜间不喂食*,要么调整日照偏移量。没有有效坐标时夜间阻止会被停用 (并会记录一条警告)。 **监控总是报告故障。** 你的开关对象很可能没有回报其实际状态(`ack=true`)。要么使用带状态回报的开关, 要么为该开关停用*开关监控*。 **动态投喂没有任何变化。** 请确保所选的温度来源(水温或气温)已在开关选项卡(*温度与溶氧来源*)中激活并提供数值。刚重启后移动平均仍在 填充,因此会从基准值开始。请观察 `status.dynamicAvgTemperature` 和 `status.dynamicIntervalMin`。 **已启用动态投喂但从未喂食(`status.nextFeeding` 为空)。** **基准间隔或最大间隔为 0**(或时间窗口无效),因此无法计算出间隔——此时 `status.blockReason` 会显示提示。请将基准间隔和最大间隔设为大于 0(并设置有效的窗口)。注意:将最小和最大间隔*都*保持为 0 也会使结果被强制为 0。 **尽管不是冬季却没有喂食(或应当暂停却仍在喂食)。** 请检查*冬季暂停*的日期(`冬季开始` / `冬季结束`,格式 dd.mm)和模式。数据点 `status.winterActive` 会显示暂停当前是否处于生效状态。 **地址搜索提示实例必须正在运行。** 启动 automatic-feeder 实例——地理编码在后端运行。 **Telegram 消息没有送达。** 开关选项卡中是否选择了 Telegram 实例?telegram 适配器是否已设置并启动? 是否至少勾选了一种通知类型且*开关监控*已激活? --- ## 10. 日志记录与排错 适配器在常见的 ioBroker 级别上记录日志。要获得详细的消息,请将实例的日志级别 (实例 → automatic-feeder.x → 日志级别)提升到 **debug** 或 **silly**: * **error**——需要关注的错误(例如写入开关失败)。 * **warn**——配置错误(无坐标、时间计划无效……)。 * **info**——里程碑(启动、执行或阻止了一次喂食、手动触发)。 * **debug**——详细的流程(计划决策、温度更新、地理编码、开/关值、验证确认/超时)。 * **silly**——非常详尽的追踪(每个定时器、每次阻止检查、每次状态变化)。 --- 📖 [主文档(英文)](../../README.md)