显示菜单
该组件提供了一个菜单,主要旨在通过带按钮的旋转编码器或五键摇杆控制器进行控制。它允许导航项目和子菜单的层次结构,能够更改值和执行命令。菜单可以按需激活和停用,允许在将屏幕用于菜单和其他信息之间切换。
本文档描述了实现此组件的组件通用的配置和自动化。目前支持使用 lcd_menu 组件的字符型 LCD 显示屏,配置示例中使用了它的实例。
# 示例配置display: - platform: lcd_pcf8574 id: my_lcd ... lambda: |- id(my_lcd_menu).draw(); if (!id(my_lcd_menu).is_active()) it.print("菜单未激活");
# 声明 LCD 菜单lcd_menu: id: my_lcd_menu display_id: my_lcd active: true mode: rotary on_enter: then: lambda: 'ESP_LOGI("display_menu", "root enter");' on_leave: then: lambda: 'ESP_LOGI("display_menu", "root leave");' items: - type: back text: '返回' - type: label text: '标签 1' - type: label text: !lambda |- return "模板标签";
# 编码器提供导航sensor: - platform: rotary_encoder ... on_anticlockwise: - display_menu.up: on_clockwise: - display_menu.down:
# 使用去抖动的 GPIO 进行"点击"binary_sensor: - platform: gpio ... filters: - delayed_on: 10ms - delayed_off: 10ms on_press: - display_menu.enter:配置变量:
-
root_item_id (可选, ID):手动指定根菜单项的 ID。
-
active (可选, 布尔值):菜单是否应以活动状态启动,即接受用户交互并显示输出。默认为
true。 -
mode (可选, 枚举):定义导航逻辑。默认为
rotary。-
rotary:旋转模式期望顺时针移动连接到 display_menu.down,逆时针移动连接到 display_menu.up,开关连接到 display_menu.enter 动作。 -
joystick:摇杆模式期望上、下、左、右按钮连接到 display_menu.up、display_menu.down、display_menu.left 和 display_menu.right 动作,中间按钮连接到 display_menu.enter 动作。
-
-
items (必需):菜单的第一层。
自动化:
组件管理菜单项的层次结构。通用配置变量为:
- id (可选, ID):手动指定用于代码生成的 ID。
- type (*必需, 字符串):菜单项的类型(见下文)。
- text (可选, 字符串, 可模板化):菜单项显示的文本。如果指定了 lambda,它会获得一个指向正在绘制的
MenuItem的it参数。
某些菜单项提供了一种编辑值的方式,可以通过从选项列表中选择或更改数值来实现。此类项可以以两种方式配置。
如果 immediate_edit 配置为 false,则必须先通过激活旋转编码器的开关或摇杆的中心按钮来激活编辑模式。激活时调用 on_enter 自动化,项目被标记为可编辑(默认情况下 > 选择标记变为 *)。然后可以通过旋转轮盘(在 rotary 模式下)或摇杆左右按钮(在 joystick 模式下)来遍历值。再次点击开关可停用编辑模式,调用 on_leave 自动化,选择标记恢复原状。
如果 immediate_edit 配置为 true,则在选中菜单项时立即可编辑。不调用 on_enter 和 on_leave。在 joystick 模式下,左右按钮遍历值;可编辑的项目显示可编辑标记以指示可以使用按钮。在 rotary 模式下,激活开关遍历到下一个值。选择标记不变(此处用于指示旋转旋钮是导航菜单还是更改值)。number 类型的菜单项在 joystick 模式下只能立即可编辑。
items: - id: my_label type: label text: '我的标签'label 类型的菜单项仅显示文本。没有配置选项,无法进行交互。
items: - type: menu text: '我的子菜单' on_enter: then: lambda: 'ESP_LOGI("display_menu", "enter: %s", it->get_text().c_str());' on_leave: then: lambda: 'ESP_LOGI("display_menu", "leave: %s", it->get_text().c_str());' items: - type: label text: '标签' - type: back text: '返回'menu 类型的菜单项定义了子菜单项列表。当点击该菜单项时,显示屏显示新的菜单层级。
配置变量:
- items (必需):定义子菜单项。
自动化:
items: - type: back text: '返回'back 类型的菜单项关闭当前菜单层级并向上进入菜单层级层次结构。调用当前层级的 on_leave 自动化和上级层级的 on_enter 自动化。没有配置选项。
lcd_menu: items: - type: select immediate_edit: false text: '我的颜色' select: my_color on_enter: then: lambda: 'ESP_LOGI("display_menu", "select enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' on_leave: then: lambda: 'ESP_LOGI("display_menu", "select leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' on_value: then: lambda: 'ESP_LOGI("display_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());'
select: - platform: template id: my_color optimistic: true options: - '红色' - '绿色' - '蓝色'select 类型的菜单项允许遍历由关联的 select 组件定义的一组值。
配置变量:
-
immediate_edit (可选, 布尔值):选中时是否可以立即编辑该项目。请参阅 编辑值。默认为
false。 -
select (*必需, ID):管理编辑值的
select组件。 -
value_lambda (可选, lambda): 返回要显示为值的字符串的 lambda。lambda 获得一个指向
MenuItem的it参数。如果未指定,则使用select组件的选中选项名称作为值。
自动化:
lcd_menu: items: - type: number text: '我的数值' format: '%.2f' number: my_number on_enter: then: lambda: 'ESP_LOGI("display_menu", "number enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' on_leave: then: lambda: 'ESP_LOGI("display_menu", "number leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' on_value: then: lambda: 'ESP_LOGI("display_menu", "number value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());'
number: - platform: template id: my_number optimistic: true min_value: 10.0 max_value: 20.0 step: 0.5 on_value: then: lambda: 'ESP_LOGI("number", "value: %f", x);'number 类型的菜单项允许编辑浮点数。
点击时调用 on_enter 自动化,项目被标记为可编辑(默认情况下 > 选择标记变为 *)。然后上下事件按照 number 中定义的步长增加和减少值,遵守 min_value 和 max_value。再次点击可退出编辑模式。
请注意,小数浮点值不一定能很好地相加,十次 0.100000 不一定是 1.000000。使用 2 的幂次方的步长(如 0.125)或显式处理舍入。
配置变量:
-
immediate_edit (可选, 布尔值):选中时是否可以立即编辑该项目。请参阅 编辑值。在
rotary模式下忽略。默认为false。 -
number (*必需, ID):管理编辑值的
number组件。如果进入时值小于min_value或大于max_value,值将被限制在范围内。 -
format (可选, 字符串):类似
printf的格式字符串,指定用于显示当前值的一个f或g类型转换。默认为%.1f。 -
value_lambda (可选, lambda): 返回要显示为值的字符串的 lambda。lambda 获得一个指向
MenuItem的it参数。如果未指定,则使用根据format格式化的number组件值作为值。
自动化:
lcd_menu: items: - type: switch immediate_edit: false text: '我的开关' on_text: '亮' off_text: '暗' switch: my_switch on_enter: then: lambda: 'ESP_LOGI("display_menu", "switch enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' on_leave: then: lambda: 'ESP_LOGI("display_menu", "switch leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' on_value: then: lambda: 'ESP_LOGI("display_menu", "switch value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());'
switch: - platform: template id: my_switch optimistic: trueswitch 类型的菜单项允许切换关联的 switch 组件。
配置变量:
-
immediate_edit (可选, 布尔值):选中时是否可以立即编辑该项目。请参阅 编辑值。默认为
false。 -
on_text (可选, 字符串):
ON状态的文本。默认为On。 -
off_text (可选, 字符串):
OFF状态的文本。默认为Off。 -
switch (*必需, ID):管理编辑值的
switch组件。 -
value_lambda (可选, lambda): 返回要显示为值的字符串的 lambda。lambda 获得一个指向
MenuItem的it参数。如果未指定,则使用on_text/off_text。
自动化:
items: - type: command text: '隐藏' on_value: then: - display_menu.hide:command 类型的菜单项允许触发命令。没有额外的配置。
自动化:
lcd_menu: items: - type: custom immediate_edit: false text: '我的自定义' value_lambda: 'return to_string(some_state);' on_next: then: lambda: 'some_state++;' on_prev: then: lambda: 'some_state--;'custom 类型的菜单项将遍历值的操作委托给自动化,将显示值的操作委托给 value_lambda。
配置变量:
-
immediate_edit (可选, 布尔值):选中时是否可以立即编辑该项目。请参阅 编辑值。默认为
false。 -
value_lambda (可选, lambda): 返回要显示为值的字符串的 lambda。lambda 获得一个指向
MenuItem的it参数。
自动化:
on_enter
Section titled “on_enter”当进入菜单层级时,即组件在显示屏上绘制其项目时,将触发此自动化。it 参数指向包含描述显示的子项目的菜单项信息的 MenuItem 类。如果出现在顶层,它是内部生成的根菜单项,否则是用户定义的菜单项。
lcd_menu: ... items: - type: menu text: '子菜单 1' on_enter: then: lambda: 'ESP_LOGI("display_menu", "enter: %s", it->get_text().c_str());'on_leave
Section titled “on_leave”当退出菜单层级时,即组件不再在显示屏上绘制其项目时,将触发此自动化。it 参数指向包含菜单项信息的 MenuItem 类。如果出现在顶层,它是内部生成的根菜单项,否则是用户定义的菜单项。无论是由于进入子菜单还是返回父菜单而离开层级,都没有影响。
lcd_menu: ... items: - type: menu text: '子菜单 1' on_leave: then: lambda: 'ESP_LOGI("display_menu", "leave: %s", it->get_text().c_str());'on_value
Section titled “on_value”当通过菜单编辑的值发生更改或触发命令时,将触发此自动化。
lcd_menu: ... items: - type: select text: '选择项目' select: my_select_1 on_value: then: lambda: 'ESP_LOGI("display_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());'on_next
Section titled “on_next”当用户请求将值设置为下一个时,将触发此自动化。
lcd_menu: ... items: - type: custom text: '自定义项目' value_lambda: 'return to_string(some_state);' on_next: then: lambda: 'some_state++;'on_prev
Section titled “on_prev”当用户请求将值设置为上一个时,将触发此自动化。
lcd_menu: ... items: - type: custom text: '自定义项目' value_lambda: 'return to_string(some_state);' on_prev: then: lambda: 'some_state--;'display_menu.up 动作
Section titled “display_menu.up 动作”这是一个用于在菜单中向上导航的 动作。该动作通常连接到旋转编码器的逆时针转动或摇杆的上按钮。
sensor: - platform: rotary_encoder ... on_anticlockwise: - display_menu.up:配置变量:
- id (可选, ID):要导航的菜单 ID。
display_menu.down 动作
Section titled “display_menu.down 动作”这是一个用于在菜单中向下导航的 动作。该动作通常连接到旋转编码器的顺时针转动或摇杆的下按钮。
sensor: - platform: rotary_encoder ... on_clockwise: - display_menu.down:配置变量:
- id (可选, ID):要导航的菜单 ID。
display_menu.left 动作
Section titled “display_menu.left 动作”这是一个通常连接到摇杆左按钮的 动作。在 joystick 模式下,它用于设置上一个值或递减数值;根据 immediate_edit 标志,可能需要进入编辑模式。如果在 rotary 模式下使用,它退出编辑。在两种模式下,与 back 菜单项一起使用时,也可以用于返回上一级。
binary_sensor: - platform: gpio ... on_press: - display_menu.left:配置变量:
- id (可选, ID):要导航的菜单 ID。
display_menu.right 动作
Section titled “display_menu.right 动作”这是一个通常连接到摇杆右按钮的 动作。在 joystick 模式下,它用于设置下一个值或递增数值;根据 immediate_edit 标志,可能需要进入编辑模式。在两种模式下,与 menu 菜单项一起使用时,也可以用于进入子菜单。
binary_sensor: - platform: gpio ... on_press: - display_menu.right:配置变量:
- id (可选, ID):要导航的菜单 ID。
display_menu.enter 动作
Section titled “display_menu.enter 动作”这是一个用于触发选中菜单项的 动作,产生的动作取决于项目的类型 - 进入子菜单、开始/停止编辑或触发命令。该动作通常连接到旋转编码器的按下按钮或摇杆的中心按钮。
binary_sensor: - platform: gpio ... filters: - delayed_on: 10ms - delayed_off: 10ms on_press: - display_menu.enter:配置变量:
- id (可选, ID):要导航的菜单 ID。
display_menu.show 动作
Section titled “display_menu.show 动作”这是一个用于显示非活动菜单的 动作。菜单的状态保持不变,即隐藏时显示的菜单层级被恢复,选中的项目也被恢复。以下片段在菜单非活动时显示菜单,否则触发选中的项目。
on_press: - if: condition: display_menu.is_active: then: - display_menu.enter: else: - display_menu.show:配置变量:
- id (可选, ID):要显示的菜单 ID。
display_menu.hide 动作
Section titled “display_menu.hide 动作”这是一个用于隐藏菜单的 动作。隐藏的菜单不响应 draw() 且不处理导航动作。
lcd_menu: ... items: - type: command text: '隐藏' on_value: then: - display_menu.hide:配置变量:
- id (可选, ID):要隐藏的菜单 ID。
display_menu.show_main 动作
Section titled “display_menu.show_main 动作”这是一个用于显示菜单根层级的 动作。
lcd_menu: ... items: - type: command text: '显示主菜单' on_value: then: - display_menu.show_main:配置变量:
- id (可选, ID):要隐藏的菜单 ID。
display_menu.is_active 条件
Section titled “display_menu.is_active 条件”此 条件 检查给定菜单是否处于活动状态,即显示在显示屏上并处理导航事件。
on_press: - if: condition: display_menu.is_active: ...