[APP][Pro] Dashboard Studio - A completely free-form dashboard designer

I received more of these requests. I think I am going add a few option to implement this native in the graph widget: An option to make the percentage bar color uniform. So not a gradient fill like it is now, but a flat color but based on the gradient and the current value. (so cold the whole bar is blue, hot the whole bar is red).
And an option to link this color to the icon.

Small tip: You should set “Gap” or translated “Lücke” to -25 with round gauges. In the new (test) version this is the default setting. I notice a lot of users miss this setting, It set’s the distance between the gauge and the text. (now there is a big “Lücke”)

Thought about it and it is also a technical limitation. Dashboard Studio is based on MQTT and I really want to keep it completely compatible. With MQTT you generally just send one pure value per topic. It can’t send both a button value and a page in the exact same message. You would have to format it like JSON or something similar which honestly brings way more trouble than it is worth. Because of this Homey only knows which dashboard is sending the value but it has absolutely no idea what page it is on. So your best bet is to create a specific button for each page with its very own topic. Or you could put a topic in “Current Page Output Topic”, create a quick little flow and use that topic to keep track of the current page number right inside a Homey variable. That way you can just use the Homey variable to know exactly what page you are on the second a button is pressed.

I think I understand. You can’t send an event with 2 values.

New Test version 1.7.3

The button / switch / menu item “state” now can be controlled dynamically and they behave now as expected when configured as a radio group when they have the same “Selection Group ID”. Also I have implemented a timestamp to the cache system. It now replays the cache in the original order. So when multiple buttons or menu items are also dynamically controlled, the final state should be correct.

Basically this could simplify above graph massively if it did not need the translation.

Thank you.

Some weird things happening with 2 drop down menus below:
auto copying menu names and settings from one submenu to the other. Please try this snippet in version 1.7.3 and change menu item names and Selection group ids of the 2 right dropdown menus.
Maybe it’s related to “Also I have implemented a timestamp to the cache system”.

{
  "snippetHeader": "Dashboard Studio Snippet",
  "snippetType": "widget-snippet",
  "snippetFormatVersion": 1,
  "version": "1.7.3",
  "source": {
    "dashboardName": "HomeDashV2",
    "page": 31,
    "createdAt": "2026-04-16T18:06:38.277Z"
  },
  "master": {
    "currentPage": 31
  },
  "widgets": {
    "menu_8142": {
      "type": "menu",
      "overrides": {
        "x": 1580,
        "y": 680,
        "width": 290,
        "height": 60,
        "zIndex": 31,
        "page": 31,
        "menuItems": [
          {
            "label": "Automatisch",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "aircoHuiskamerModus",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "phosphor",
                "builtin": "ph-head-circuit",
                "filled": false,
                "customUrl": "",
                "tintImage": false
              },
              "off": {
                "source": "phosphor",
                "builtin": "ph-head-circuit",
                "filled": false,
                "customUrl": "",
                "tintImage": false
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "huiskamer-airco/thermostat_mode",
            "onPayload": "auto",
            "offPayload": "",
            "pageTo": 1,
            "urlTo": "https://"
          },
          {
            "label": "Koelen",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "aircoHuiskamerModus",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "phosphor",
                "builtin": "ph-snowflake",
                "filled": false,
                "customUrl": "",
                "tintImage": false
              },
              "off": {
                "source": "phosphor",
                "builtin": "ph-snowflake",
                "filled": false,
                "customUrl": "",
                "tintImage": false
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "huiskamer-airco/thermostat_mode",
            "onPayload": "cooling",
            "offPayload": "",
            "pageTo": 1,
            "urlTo": "https://"
          },
          {
            "label": "Verwarmen",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "aircoHuiskamerModus",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "custom",
                "builtin": "ph-flame",
                "filled": false,
                "customUrl": "https://cdn.jsdelivr.net/npm/@mdi/svg@7.2.96/svg/heat-wave.svg",
                "tintImage": true
              },
              "off": {
                "source": "custom",
                "builtin": "ph-flame",
                "filled": false,
                "customUrl": "https://cdn.jsdelivr.net/npm/@mdi/svg@7.2.96/svg/heat-wave.svg",
                "tintImage": true
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "huiskamer-airco/thermostat_mode",
            "onPayload": "heating",
            "offPayload": "",
            "pageTo": 1,
            "urlTo": "https://"
          },
          {
            "label": "Drogen",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "aircoHuiskamerModus",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "custom",
                "builtin": "ph-drop",
                "filled": false,
                "customUrl": "https://cdn.jsdelivr.net/npm/@mdi/svg@7.2.96/svg/water-remove-outline.svg",
                "tintImage": true
              },
              "off": {
                "source": "custom",
                "builtin": "ph-drop",
                "filled": false,
                "customUrl": "https://cdn.jsdelivr.net/npm/@mdi/svg@7.2.96/svg/water-remove-outline.svg",
                "tintImage": true
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "huiskamer-airco/thermostat_mode",
            "onPayload": "dry",
            "offPayload": "",
            "pageTo": 1,
            "urlTo": "https://"
          },
          {
            "label": "Ventileren",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "aircoHuiskamerModus",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "phosphor",
                "builtin": "ph-fan",
                "filled": false,
                "customUrl": "",
                "tintImage": false
              },
              "off": {
                "source": "phosphor",
                "builtin": "ph-fan",
                "filled": false,
                "customUrl": "",
                "tintImage": false
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "huiskamer-airco/thermostat_mode",
            "onPayload": "fanOnly",
            "offPayload": "",
            "pageTo": 1,
            "urlTo": "https://"
          }
        ],
        "menuStyle": "dropdown",
        "menuTriggerTopic": "toonModus",
        "metaName": "Modus menu",
        "typography": {
          "menuItem": {
            "fontSize": 30,
            "color": "@background",
            "colorOff": "@surfaceHover"
          }
        },
        "iconSize": 40,
        "itemBgOn": "@background",
        "item_0_state": false,
        "itemBgOnOpacity": 10,
        "itemCornerRadius": 0,
        "itemSpacing": 4,
        "iconColOn": "@background",
        "iconColOff": "@surface",
        "padding": 0,
        "cornerRadius": 20,
        "bgVisible": true,
        "glowEnabled": true,
        "bgColStart": "@background",
        "bgColEnd": "rgb(51, 65, 85)",
        "bgOpacityStart": 0,
        "bgOpacityEnd": 0,
        "glowColor": "@surface",
        "glowOpacity": 60,
        "borderColor": "@surface",
        "borderWidth": 2,
        "item_1_state": false,
        "item_2_state": false,
        "item_3_state": false,
        "item_4_state": false,
        "bgAngle": 90,
        "glowRadius": 40
      },
      "bindings": {
        "menuItems": [
          {
            "state": "aircoHuiskamerAuto"
          },
          {
            "state": "aircoHuiskamerCooling"
          },
          {
            "state": "aircoHuiskamerHeating"
          },
          {
            "state": "aircoHuiskamerDry"
          },
          {
            "state": "aircoHuiskamerFanOnly"
          }
        ],
        "__trigger": "toonModus"
      }
    },
    "menu_4323589": {
      "type": "menu",
      "overrides": {
        "x": 1590,
        "y": 1030,
        "width": 290,
        "height": 60,
        "zIndex": 31,
        "page": 31,
        "menuItems": [
          {
            "label": "Automatisch",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "phosphor",
                "builtin": "ph-head-circuit",
                "filled": false,
                "customUrl": "",
                "tintImage": false
              },
              "off": {
                "source": "phosphor",
                "builtin": "ph-head-circuit",
                "filled": false,
                "customUrl": "",
                "tintImage": false
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "huiskamer-airco/fan_mode.mode",
            "onPayload": "auto",
            "offPayload": "",
            "pageTo": 1,
            "urlTo": "https://"
          },
          {
            "label": "Stil",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "phosphor",
                "builtin": "ph-snowflake",
                "filled": false,
                "customUrl": "",
                "tintImage": false
              },
              "off": {
                "source": "phosphor",
                "builtin": "ph-snowflake",
                "filled": false,
                "customUrl": "",
                "tintImage": false
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "huiskamer-airco/fan_mode.mode",
            "onPayload": "quiet",
            "offPayload": "",
            "pageTo": 1,
            "urlTo": "https://"
          },
          {
            "label": "Handmatig",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "custom",
                "builtin": "ph-flame",
                "filled": false,
                "customUrl": "https://cdn.jsdelivr.net/npm/@mdi/svg@7.2.96/svg/heat-wave.svg",
                "tintImage": true
              },
              "off": {
                "source": "custom",
                "builtin": "ph-flame",
                "filled": false,
                "customUrl": "https://cdn.jsdelivr.net/npm/@mdi/svg@7.2.96/svg/heat-wave.svg",
                "tintImage": true
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "huiskamer-airco/fan_mode.mode",
            "onPayload": "fixed",
            "offPayload": "",
            "pageTo": 1,
            "urlTo": "https://"
          }
        ],
        "menuStyle": "dropdown",
        "menuTriggerTopic": "toonVentilatorModus",
        "metaName": "Modus menu (Copy)",
        "typography": {
          "menuItem": {
            "fontSize": 30,
            "color": "@background",
            "colorOff": "@surfaceHover"
          }
        },
        "iconSize": 40,
        "itemBgOn": "@background",
        "item_0_state": false,
        "itemBgOnOpacity": 10,
        "itemCornerRadius": 0,
        "itemSpacing": 4,
        "iconColOn": "@background",
        "iconColOff": "@surface",
        "padding": 0,
        "cornerRadius": 20,
        "bgVisible": true,
        "glowEnabled": true,
        "bgColStart": "@background",
        "bgColEnd": "rgb(51, 65, 85)",
        "bgOpacityStart": 0,
        "bgOpacityEnd": 0,
        "glowColor": "@surface",
        "glowOpacity": 60,
        "borderColor": "@surface",
        "borderWidth": 2,
        "item_1_state": false,
        "item_2_state": false,
        "item_3_state": false,
        "item_4_state": false,
        "bgAngle": 90,
        "glowRadius": 40
      },
      "bindings": {
        "menuItems": [
          {
            "state": "aircoHuiskamerFanAuto"
          },
          {
            "state": "aircoHuiskamerFanQuiet"
          },
          {
            "state": "aircoHuiskamerFanFixed"
          }
        ],
        "__trigger": "toonVentilatorModus"
      }
    }
  },
  "groups": {
    "group_mo02cn4k_4bh": {
      "id": "group_mo02cn4k_4bh",
      "name": "Group Airco huiskamer settings 1",
      "locked": false,
      "visible": true,
      "bindings": {
        "overridePage": "local/toonGroepAircoHuiskamer"
      },
      "overridePage": "local/",
      "dimBackgroundWhenVisible": false,
      "widgets": {
        "image_211400044": {
          "type": "image",
          "overrides": {
            "x": 1040,
            "y": 560,
            "width": 330,
            "height": 15,
            "zIndex": 31,
            "page": "31",
            "sourceType": "svg",
            "svgRaw": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 330 15\" width=\"330\" height=\"15\">\n    <defs>\n        <linearGradient id=\"gradientTemperatuurAircoHuiskamer\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\">\n            <stop offset=\"0\" stop-color=\"#00f\" />\n            <stop offset=\"1\" stop-color=\"#f00\" />\n        </linearGradient>\n    </defs>\n    <rect width=\"330\" height=\"15\" fill=\"url(#gradientTemperatuurAircoHuiskamer)\"/>\n</svg>",
            "metaName": "Airco huiskamer temperatuur",
            "cornerRadius": 10,
            "visible": true
          },
          "bindings": {}
        },
        "slider_211417588": {
          "type": "slider",
          "overrides": {
            "x": 1040,
            "y": 540,
            "width": 370,
            "height": 60,
            "zIndex": 32,
            "page": "31",
            "value": 21,
            "min": 14,
            "max": 26,
            "allowDecimals": true,
            "stepSize": 0.5,
            "vertical": false,
            "valOffX": 230,
            "valAlign": "right",
            "outputTopic": "huiskamer-airco/target_temperature",
            "trackOutlineWidth": 0,
            "colThumb": "#ffffff",
            "thumbShadow": true,
            "metaName": "Airco huiskamer temperatuur",
            "visible": true,
            "cornerRadius": 0,
            "borderWidth": 0,
            "valFs": 25,
            "valFam": "'Exo 2', sans-serif",
            "trackThickness": 0,
            "fillThickness": 0,
            "thumbSize": 30,
            "labelCol": "#ffffff",
            "labelFs": 30,
            "labelFont": "'Exo 2', sans-serif",
            "colTrack": "#424242",
            "glowEnabled": false,
            "bgVisible": false,
            "glowOpacity": 60,
            "padding": 0
          },
          "bindings": {
            "value": "huiskamer-airco/target_temperature"
          }
        },
        "menu_211424079": {
          "type": "menu",
          "overrides": {
            "x": 1040,
            "y": 630,
            "width": 400,
            "height": 440,
            "zIndex": 31,
            "page": 31,
            "menuItems": [
              {
                "label": "Modus",
                "mode": "toggle",
                "actionType": "topic",
                "state": false,
                "selectionGroup": "aircoHuiskamerInstellingen",
                "sendOffOnGroupDeselect": true,
                "icons": {
                  "on": {
                    "source": "phosphor",
                    "builtin": "ph-caret-right",
                    "filled": true,
                    "customUrl": "",
                    "tintImage": false
                  },
                  "off": {
                    "source": "phosphor",
                    "builtin": "ph-caret-left",
                    "filled": true,
                    "customUrl": "",
                    "tintImage": false
                  }
                },
                "iconColorOverrides": {
                  "on": {
                    "enabled": false,
                    "color": "@surfaceAlt"
                  },
                  "off": {
                    "enabled": false,
                    "color": "@text"
                  }
                },
                "outputTopic": "toonModus",
                "onPayload": "true",
                "offPayload": "false",
                "pageTo": 1,
                "urlTo": "https://"
              },
              {
                "label": "Ventilator modus",
                "mode": "toggle",
                "actionType": "topic",
                "state": false,
                "selectionGroup": "aircoHuiskamerInstellingen",
                "sendOffOnGroupDeselect": true,
                "icons": {
                  "on": {
                    "source": "phosphor",
                    "builtin": "ph-caret-right",
                    "filled": true,
                    "customUrl": "",
                    "tintImage": false
                  },
                  "off": {
                    "source": "phosphor",
                    "builtin": "ph-caret-left",
                    "filled": true,
                    "customUrl": "",
                    "tintImage": false
                  }
                },
                "iconColorOverrides": {
                  "on": {
                    "enabled": false,
                    "color": "@surfaceAlt"
                  },
                  "off": {
                    "enabled": false,
                    "color": "@text"
                  }
                },
                "outputTopic": "toonVentilatorModus",
                "onPayload": "true",
                "offPayload": "false",
                "pageTo": 1,
                "urlTo": "https://"
              }
            ],
            "menuIconLoc": "right",
            "metaName": "New Menu",
            "typography": {
              "menuItem": {
                "color": "@background",
                "colorOff": "@text",
                "fontSize": 30,
                "fontFamily": "'Exo 2', sans-serif",
                "bold": false,
                "textAlign": "left"
              }
            },
            "cornerRadius": 10,
            "borderWidth": 0,
            "itemSpacing": 27,
            "itemBgOn": "@warning",
            "itemBgOnOpacity": 10,
            "item_0_state": true,
            "iconColOn": "@warning",
            "iconSize": 40,
            "item_1_state": false,
            "item_2_state": false,
            "item_3_state": false,
            "item_4_state": false,
            "item_5_state": false,
            "itemCornerRadius": 8,
            "iconColOff": "@surfaceAlt"
          },
          "bindings": {
            "menuItems": [
              {
                "label": "aircoHuiskamerModus"
              },
              {
                "label": "aircoHuiskamerFanModus"
              }
            ]
          }
        },
        "slider_211440180": {
          "type": "slider",
          "overrides": {
            "x": 1040,
            "y": 815,
            "width": 380,
            "height": 50,
            "zIndex": 31,
            "page": "31",
            "value": 1,
            "min": 1,
            "max": 5,
            "stepSize": 1,
            "valOffX": 190,
            "outputTopic": "huiskamer-airco/fan_mode.speed",
            "colThumb": "#ffffff",
            "metaName": "Airco huiskamer ventilator snelheid",
            "labelFs": 30,
            "labelFont": "'Exo 2', sans-serif",
            "borderWidth": 0,
            "labelCol": "#ffffff",
            "colTrack": "@iconMuted",
            "valFs": 25,
            "cornerRadius": 10,
            "trackThickness": 15,
            "thumbSize": 30,
            "fillThickness": 20,
            "visible": true,
            "colFill": "#0066ff"
          },
          "bindings": {
            "value": "huiskamer-airco/fan_mode.speed"
          }
        },
        "switch_211452612": {
          "type": "switch",
          "overrides": {
            "x": 1040,
            "y": 910,
            "width": 70,
            "height": 30,
            "zIndex": 31,
            "page": "31",
            "state": true,
            "buttonLabel": "",
            "outputTopic": "huiskamer-airco/fan_mode.powerful",
            "onPayload": "on",
            "offPayload": "off",
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "#ffffff"
              },
              "off": {
                "enabled": false,
                "color": "#94a3b8"
              }
            },
            "metaName": "Arico huiskamer krachtig blazen",
            "visible": true,
            "labelPos": "top",
            "typography": {
              "buttonLabelOutside": {
                "fontFamily": "'Exo 2', sans-serif",
                "textTransform": "none",
                "offsetX": 0,
                "fontSize": 30,
                "color": "#ffffff",
                "colorOff": "#ffffff",
                "offsetY": 0
              },
              "groupLabel": {
                "offsetX": 0,
                "offsetY": 0,
                "textAlign": "right",
                "fontSize": 30,
                "color": "#ffffff"
              }
            },
            "style": "switch",
            "contentAlign": "center",
            "btnRadius": 5,
            "buttonContentInset": 5,
            "scale": 1.2,
            "colOff": "#878787",
            "colThumb": "#ffffff",
            "colOn": "#0066ff",
            "cornerRadius": 10,
            "borderWidth": 0,
            "iconSize": 24,
            "bevel": true
          },
          "bindings": {
            "state": "huiskamer-airco/fan_mode.powerful"
          }
        },
        "switch_211465411": {
          "type": "switch",
          "overrides": {
            "x": 1040,
            "y": 1010,
            "width": 70,
            "height": 30,
            "zIndex": 31,
            "page": "31",
            "buttonLabel": "",
            "outputTopic": "huiskamer-airco/swing_mode.horizontal",
            "onPayload": "swing",
            "offPayload": "stop",
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "#ffffff"
              },
              "off": {
                "enabled": false,
                "color": "#94a3b8"
              }
            },
            "metaName": "Arico huiskamer horizontale swing",
            "visible": true,
            "labelPos": "top",
            "typography": {
              "buttonLabelOutside": {
                "fontFamily": "'Exo 2', sans-serif",
                "textTransform": "none",
                "offsetX": 0,
                "fontSize": 30,
                "color": "#ffffff",
                "colorOff": "#ffffff",
                "offsetY": 0
              },
              "groupLabel": {
                "offsetX": 0,
                "offsetY": 0,
                "textAlign": "right",
                "fontSize": 30,
                "color": "#ffffff",
                "fontFamily": "'Exo 2', sans-serif"
              }
            },
            "style": "switch",
            "contentAlign": "center",
            "btnRadius": 5,
            "buttonContentInset": 5,
            "scale": 1.2,
            "colOff": "#878787",
            "colThumb": "#ffffff",
            "colOn": "#0066ff"
          },
          "bindings": {
            "state": "huiskamer-airco/swing_mode.horizontal"
          }
        },
        "switch_211482243": {
          "type": "switch",
          "overrides": {
            "x": 1040,
            "y": 1095,
            "width": 70,
            "height": 30,
            "zIndex": 31,
            "page": "31",
            "buttonLabel": "",
            "outputTopic": "huiskamer-airco/swing_mode.vertical",
            "onPayload": "swing",
            "offPayload": "stop",
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "#ffffff"
              },
              "off": {
                "enabled": false,
                "color": "#94a3b8"
              }
            },
            "metaName": "Arico huiskamer verticale swing",
            "visible": true,
            "labelPos": "top",
            "typography": {
              "buttonLabelOutside": {
                "fontFamily": "'Exo 2', sans-serif",
                "textTransform": "none",
                "offsetX": 0,
                "fontSize": 30,
                "color": "#ffffff",
                "colorOff": "#ffffff",
                "offsetY": 0
              },
              "groupLabel": {
                "offsetX": 0,
                "offsetY": 0,
                "textAlign": "right",
                "fontSize": 30,
                "color": "#ffffff",
                "fontFamily": "'Exo 2', sans-serif"
              }
            },
            "style": "switch",
            "contentAlign": "center",
            "btnRadius": 5,
            "buttonContentInset": 5,
            "scale": 1.2,
            "colOff": "#878787",
            "colThumb": "#ffffff",
            "colOn": "#0066ff"
          },
          "bindings": {
            "state": "huiskamer-airco/swing_mode.vertical"
          }
        },
        "icon_211496921": {
          "type": "icon",
          "overrides": {
            "x": 940,
            "y": 1080,
            "width": 60,
            "height": 60,
            "zIndex": 31,
            "page": 31,
            "icon": "ph-arrows-vertical",
            "metaName": "New Icon",
            "colInactive": "@surface",
            "colActive": "@surface",
            "cornerRadius": 0,
            "iconFilled": false,
            "size": 60
          },
          "bindings": {}
        },
        "icon_211509355": {
          "type": "icon",
          "overrides": {
            "x": 940,
            "y": 990,
            "width": 60,
            "height": 60,
            "zIndex": 31,
            "page": 31,
            "icon": "ph-arrows-horizontal",
            "metaName": "New Icon",
            "colInactive": "@surface",
            "colActive": "@surface",
            "cornerRadius": 0,
            "iconFilled": false,
            "size": 60
          },
          "bindings": {}
        },
        "icon_211514822": {
          "type": "icon",
          "overrides": {
            "x": 940,
            "y": 900,
            "width": 60,
            "height": 60,
            "zIndex": 31,
            "page": 31,
            "icon": "ph-wind",
            "metaName": "New Icon",
            "colInactive": "@surface",
            "colActive": "@surface",
            "cornerRadius": 0,
            "iconFilled": false,
            "size": 60
          },
          "bindings": {}
        },
        "icon_211523842": {
          "type": "icon",
          "overrides": {
            "x": 940,
            "y": 810,
            "width": 60,
            "height": 60,
            "zIndex": 31,
            "page": 31,
            "icon": "ph-fan",
            "metaName": "New Icon",
            "colInactive": "@surface",
            "colActive": "@surface",
            "cornerRadius": 0,
            "iconFilled": false,
            "size": 60
          },
          "bindings": {}
        },
        "icon_211524136": {
          "type": "icon",
          "overrides": {
            "x": 940,
            "y": 720,
            "width": 60,
            "height": 60,
            "zIndex": 31,
            "page": 31,
            "icon": "ph-gear",
            "metaName": "New Icon",
            "colInactive": "@surface",
            "colActive": "@surface",
            "cornerRadius": 0,
            "iconFilled": false,
            "size": 60
          },
          "bindings": {}
        },
        "icon_211538750": {
          "type": "icon",
          "overrides": {
            "x": 940,
            "y": 630,
            "width": 60,
            "height": 60,
            "zIndex": 31,
            "page": 31,
            "icon": "ph-faders",
            "metaName": "New Icon",
            "colInactive": "@surface",
            "colActive": "@surface",
            "cornerRadius": 0,
            "iconFilled": false,
            "size": 60
          },
          "bindings": {}
        },
        "icon_211547581": {
          "type": "icon",
          "overrides": {
            "x": 940,
            "y": 543,
            "width": 60,
            "height": 60,
            "zIndex": 31,
            "page": 31,
            "icon": "ph-thermometer-simple",
            "metaName": "New Icon",
            "colInactive": "@surface",
            "colActive": "@surface",
            "cornerRadius": 0,
            "size": 60,
            "iconFilled": false,
            "bgColStart": "rgb(148, 163, 184)"
          },
          "bindings": {}
        },
        "empty_211552015": {
          "type": "empty",
          "overrides": {
            "x": 920,
            "y": 490,
            "width": 530,
            "height": 690,
            "zIndex": 30,
            "page": 31,
            "label": "Airco huiskamer instellingen",
            "labelAlign": "center",
            "metaName": "New Container",
            "bgVisible": true,
            "bgColStart": "rgb(82, 151, 255)",
            "bgColEnd": "#0A3575",
            "bgAngle": 135,
            "glowEnabled": true,
            "glowOpacity": 60,
            "labelCol": "@surfaceAlt",
            "labelFs": 20,
            "labelFont": "'Exo 2', sans-serif",
            "bgOpacityStart": 0,
            "bgOpacityEnd": 0,
            "borderColor": "@surface",
            "glowColor": "@surface",
            "cornerRadius": 20,
            "labelCase": "uppercase",
            "borderWidth": 2,
            "glowRadius": 40
          },
          "bindings": {}
        }
      }
    }
  },
  "selectionGroups": {
    "aircoHuiskamerModus": {
      "allowEmptySelection": false
    },
    "aircoHuiskamerInstellingen": {
      "allowEmptySelection": true
    }
  }
}

Hello Satoer and all others too

I need your help again.

  1. How do I create a simple switch that I can use to turn a Philips Hue light on and off? Is this only possible via a flow, or can I link the light directly?

  2. The heating valve already displays the values ​​correctly. Now I want the function to open a slider when I click on the icon/widget in the dashboard, so I can set a desired temperature. After setting the temperature, the slider should disappear, and only the valve widget should be displayed again.

You can do this directly

Place a switch widget on the dashboard in dashboard studio. Keep te dashboard open and go to the the Dashboard Studio settings in Homey (in another browser tab). Find your light and capability you want to control. In this case “Turned on”

Enable this capability. Homey sends this capability state directivity to the dashboard. If you have the dashboard open (like you have in another tab) it stores it.

Now go back to the Dashboard Studio tab, and open up the “Data Stream Explorer”. Here You can monitor all incoming data. Type a part of the name of the device you want to control in the filter box:

And press the “copy Topic Name”

Now select the switch widget, and open up the “Action and Behaviour” section":

And paste this topic name in the output topic. Note: You can also go the the output topic and find the correct topic in there. I just want to inform you about the data explorer also so you can see and debug the actual data coming in.

Make sure the button is configured as “Toggle Switch”. Now go out of the edit mode and you can turn on and off your light.

There is also a “Light Grid” widget. Where you can easy add lights to on/off control directly, (even multiple lights at once) and when you select the light you can control the brightness / color and white mode.

This needs the custom virtual “Unified Light State (JSON)” Capability, because it needs to set multiple settings at once.

Icon widgets do not have interactive controls. You need the button for that, but you can configure the button to show only the icon. Let’s keep it simple for now: Show the slider when the button (icon) is pressed, and hide it when the button is disabled:

This tutorial looks like a lot of steps, but it is quite easy and straightforward once you understand how to do things:

Add a switch widget to the dashboard and configure it like this:
Container style => Background = Disabled (this hides the container behind it)
Appearance => Visual Style = Image Only (I should rename this to Image and Icon only)
Icon => Select the on and off icons.

Now in the Action & Behavior go to the Output Topic. In this example we are going to use a local topic. This is a topic that does not broadcast over the network. If you want to do a more advanced setup, I explain later, we need some Homey logic and then you do not need to create a local topic. But it is good practice to use local topics when you want to interact directly with Dashboard studio widgets on the same dashboard:
Add “local/sliderVisible” (the “local/” indicates it is a local topic. And the “sliderVisible” is a custom name you can invent (case sensitive!)).

Now add the slider widget. Go to the “Widget Info” section an click the little chain icon above the visibility. With this action you make the visibility seting dynamic, and you can fill in a topic (you can make almost any setting dynamic). Fill in “local/sliderVisible”:

The button is now sending “true / false” to this setting. Go out of edit mode, and press the icon to show and hide the slider.

Now for your more advanced solution:

There are no timers or something that automaticaly hides controls after usage. You need to make your own Homey Logic for that. In this case, you do need to broadcast the topic to Homey. So homey can control the visibility and the switch when you use it.

Replace the “local/sliderVisible” to “sliderVisible” (remove the “local/”) Now this value is also send to Homey. Also add a topic in the “output topic” of the slider:

I chose “sliderValue”. This value gets send to Homey. Note: Lots of homey controls use 0 to 1 values (not 0 to 100). So you might need to change the min and max values and enable fractions.

Go to your homey flows and create the following flow:

When the slider is moved it triggers “sliderValue”, waits 5 seconds and then sends sliderVisible, with “false” to the dashboard. So after the sider is moved it hides the slider automatically. This should work now. But the button does not know that. En in this case the button stay’s enabled, while the silder is automatically hidden. Simple way is to change the button to momentary. So it only shows the slider and the silder automatically hides when you slide it. More advanced way is to also make the button dynamic:
In the “Action & Behavior” setting of the Button / switch, there is a “State” setting. Make this dynamic, and fill in the same “sliderVisible” topic. Now when the slider gets a false to set the slider invisible, the button also gets the same false to set the state of the button to off.

Well that it. Like I said, looks like a massive amount of things you need to do, but it is really not that complicated. Just a couple of settings.

Note: You can control your device with the slider value in the same flow:

(I controlled a brightness of a light with it)

If setting the button state does not correctly behaves, please install the latest 1.7.3 test version. There is a bug fixed that involves the button state setting.

I am trying to figure out what these “weird things” are. I tried your snippet, but I do not have the Homey back-end logic to see exactly what is going wrong. You do not explain what these “weird things” are. Can you please explain what you are trying to do, what you expected it to do and what it actually does?

I tried to recreate the method you are using. But in my case everything works as expected. :thinking:

Two menus:

One of the menu items

The Homey backend:

And it does this only to store the latest state of the buttons. The text on the left menu (that activates the right menu) is directly dynamically changed.
Snippet:

{
  "snippetHeader": "Dashboard Studio Snippet",
  "snippetType": "widget-snippet",
  "snippetFormatVersion": 1,
  "version": "1.7.3",
  "source": {
    "dashboardName": "test-DynamicMenu",
    "page": 1,
    "createdAt": "2026-04-17T11:45:27.485Z"
  },
  "master": {
    "currentPage": 1
  },
  "widgets": {
    "menu_6962": {
      "type": "menu",
      "overrides": {
        "x": 360,
        "y": 140,
        "width": 260,
        "height": 300,
        "page": 1,
        "menuItems": [
          {
            "label": "Heating",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "AircoGroupID",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              },
              "off": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "AircoState",
            "onPayload": "Airco State: Heating!",
            "offPayload": "false",
            "pageTo": 1,
            "urlTo": "https://"
          },
          {
            "label": "Cooling",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "AircoGroupID",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              },
              "off": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "AircoState",
            "onPayload": "Airco State: Cooling!",
            "offPayload": "false",
            "pageTo": 1,
            "urlTo": "https://"
          },
          {
            "label": "Sleeping",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "AircoGroupID",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              },
              "off": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "AircoState",
            "onPayload": "Airco State: Sleeping!",
            "offPayload": "false",
            "pageTo": 1,
            "urlTo": "https://"
          }
        ],
        "menuStyle": "slide_right",
        "menuTriggerTopic": "local/ToggleAircoMenu",
        "menuStatusTopic": "local/AircoMenuState",
        "metaName": "New Menu",
        "item_0_state": false,
        "item_1_state": true,
        "item_2_state": false
      },
      "bindings": {
        "menuItems": [
          {
            "state": "StateHeatingButton"
          },
          {
            "state": "StateCoolingButton"
          },
          {
            "state": "StateSleepingButton"
          }
        ],
        "__trigger": "local/ToggleAircoMenu"
      }
    },
    "menu_9854": {
      "type": "menu",
      "overrides": {
        "x": 90,
        "y": 140,
        "width": 260,
        "height": 300,
        "page": 1,
        "menuItems": [
          {
            "label": "Airco State",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              },
              "off": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "local/ToggleAircoMenu",
            "onPayload": "true",
            "offPayload": "false",
            "pageTo": 1,
            "urlTo": "https://"
          }
        ],
        "metaName": "Airco State",
        "item_0_state": true
      },
      "bindings": {
        "menuItems": [
          {
            "state": "local/AircoMenuState",
            "label": "AircoState"
          }
        ]
      }
    }
  },
  "selectionGroups": {
    "AircoGroupID": {
      "allowEmptySelection": false
    }
  }
}

Hi Satoer

You respond incredibly quickly. Thanks again! I can only speak for myself, but your reply and response time have kept me interested.

I followed your instructions. The light switch really is very simple to use.

The button and the slider work just as well. Now I just need to test and implement the last part.

Here’s a short video of the current progress. And that is just the Beginning of a long journey, Currently, I’m just experimenting to understand and comprehend everything. Thanks for Google-Translater… also

Ah, of course. You can create an invisible button as well. But it will be harder to find in the editor :sweat_smile:
Nice video. When Dashboard Studio is finalised I intend to create some video-tutorials as well. But first I need to overhaul lots of parts of the software first.
Quick tip about your dashboard. Set the Gap size to -25:


this will push the text closer to the gauge. It is a default setting in the new test version.

One submenu had 5 items and the other 3. At first, I thought I had done something wrong when the first 3 items from the menu with 5 rows were copied to the submenu with 3 items: item names and group names (perhaps other values ​​as well, but I can’t remember them). After I corrected the values, the same thing happened again.

Now I am trying to reproduce it after restarting the PC, but I am unable to do so. I will make a video as soon as I succeed (I hope not).

The flow is now easier than before:

Could you tell the main subjects you want to realise before the software gets the status Finalised?

I need to overhaul most of the widgets so they align better with the style like I used in the menu widget. I want to clean them up, use the same typography and icons sections, hide any unused settings, and create a more logical order for everything. I also plan to clean up the editor buttons and organize those more effectively. Beyond that, I want to split the editor from the viewer. Finally, I might add translations, though I wonder if that is actually necessary. I have seen that our German friends just use in browser translations, and I think that would probably be fine too.

Hi @Satoer I applaud your intent to “tidy-up” everything! Because of the multitude of options, things get cluttered and it harder to find. With so many options, I completely second your plan to “hide” some settings until you really need them.

Off-topic: as the product can lead to so many nice design ideas by it’s users, have you ever thought about a “library” or “marketplace” where user could exchange their own custom widgets? (a custom widget probably being a group of widgets)?

I have been thinking about sharing things like widget templates and themes. Or, like you mentioned, maybe we could create a group of widgets that acts as a single widget control. Sharing snippets like this is already possible. But right now, I do not think I will let users implement their own truly custom widgets. For now, I want to keep a tight grip on things to protect the overall look and feel. If developers can build their own widgets, we will end up with all sorts of specialized ones with completely different custom designs. Think of a garbage collection calendar or an F1 results summary. They might look great on their own, but when a dashboard is filled with all those different styles, it just turns into a mess. Plus, the native Homey dashboard already solves that problem. For Dashboard studio I really believe all widgets should share the same basic styling options and remain universal. Users should be able to build their own F1 standings dashboard themselves instead of relying on fixed pre made ones. I can definitely imagine sharing something preconfigured using the native widgets though. The only catch is that Dashboard Studio only handles simple logic. Advanced stuff like talking to APIs and retrieving data requires Homey Logic. And you cannot pack all of that into a single combined widget file. Anyway, that is all future talk. First, I need to iron out the current version and add all the reasonable features users have requested. Once every feature is solidly established, I will clean it all up. Improve the help file and maybe create some tutorial video’s.

New TEST release 1.7.4!

Every setting that has been made dynamic, has now an extra small “invert” button. When this button is clicked it shows an option to change the default value (this is the value when there is no data send to that topic when the dashboard was open):

It has also options to accept custom boolean values when boolean variables are made dynamic:

You can also invert incoming values by pressing the invert values button (this just populates False in the True edit box and True in the False edit box)

Fixed :+1:

Also @Amersfoort :
The new custom boolean setting eliminates the need for your flow chart. You can now set the text of a mainmenu item based on the selection of a submenu and even store this value without the need for any homey logic. It is even advisable to disable the “Selection Group ID” since this is now directly controlled with the button / menu item itself (although I did not notice problems during testing when this had an Selection Group ID):

Snippet:

{
  "snippetHeader": "Dashboard Studio Snippet",
  "snippetType": "widget-snippet",
  "snippetFormatVersion": 1,
  "version": "1.7.4",
  "source": {
    "dashboardName": "test-DynamicMenu",
    "page": 1,
    "createdAt": "2026-04-18T12:34:39.270Z"
  },
  "master": {
    "currentPage": 1
  },
  "widgets": {
    "menu_6962": {
      "type": "menu",
      "overrides": {
        "x": 300,
        "y": 360,
        "width": 260,
        "height": 300,
        "page": 1,
        "menuItems": [
          {
            "label": "Heating",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              },
              "off": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "AircoState",
            "onPayload": "Airco State: Heating!",
            "offPayload": "false",
            "pageTo": 1,
            "urlTo": "https://"
          },
          {
            "label": "Cooling",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              },
              "off": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "AircoState",
            "onPayload": "Airco State: Cooling!",
            "offPayload": "false",
            "pageTo": 1,
            "urlTo": "https://"
          },
          {
            "label": "Sleeping",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              },
              "off": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "AircoState",
            "onPayload": "Airco State: Sleeping!",
            "offPayload": "false",
            "pageTo": 1,
            "urlTo": "https://"
          }
        ],
        "menuStyle": "slide_right",
        "menuTriggerTopic": "local/ToggleAircoMenu",
        "menuStatusTopic": "local/AircoMenuState",
        "metaName": "New Menu",
        "item_0_state": true,
        "item_1_state": false,
        "item_2_state": false,
        "menuItemBind_0_state_bind_mapTrue": "Airco State: Heating!",
        "menuItemBind_1_state_bind_mapTrue": "Airco State: Cooling!",
        "menuItemBind_2_state_bind_mapTrue": "Airco State: Sleeping!"
      },
      "bindings": {
        "menuItems": [
          {
            "state": "AircoState"
          },
          {
            "state": "AircoState"
          },
          {
            "state": "AircoState"
          }
        ],
        "__trigger": "local/ToggleAircoMenu"
      }
    },
    "menu_9854": {
      "type": "menu",
      "overrides": {
        "x": 30,
        "y": 360,
        "width": 260,
        "height": 300,
        "page": 1,
        "menuItems": [
          {
            "label": "Airco State",
            "mode": "toggle",
            "actionType": "topic",
            "state": false,
            "selectionGroup": "",
            "sendOffOnGroupDeselect": false,
            "icons": {
              "on": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              },
              "off": {
                "source": "phosphor",
                "builtin": "",
                "filled": true,
                "customUrl": "",
                "tintImage": false
              }
            },
            "iconColorOverrides": {
              "on": {
                "enabled": false,
                "color": "@surfaceAlt"
              },
              "off": {
                "enabled": false,
                "color": "@text"
              }
            },
            "outputTopic": "local/ToggleAircoMenu",
            "onPayload": "true",
            "offPayload": "false",
            "pageTo": 1,
            "urlTo": "https://"
          }
        ],
        "metaName": "Airco State",
        "item_0_state": true
      },
      "bindings": {
        "menuItems": [
          {
            "state": "local/AircoMenuState",
            "label": "AircoState"
          }
        ]
      }
    }
  }
}

That looks promising!

However, the example doesn’t provide me with enough guidance.
The translated (in this case Dutch) selected user value must appear in the main menu. In the submenu, I have 2 options: Heating and Cooling.

I need 3 values for Heating:

  • the end-user name (e.g. Verwarmen)
  • the technical name (heating)
  • device and capability name (in my case, livingroom-airco/thermostat_mode)

I need 3 values for Cooling:

  • the end-user name (e.g. Koelen)
  • the technical name (cooling)
  • device and capability name (in my case, livingroom-airco/thermostat_mode, same as heating)

Could you clarify a bit more what I need to use where?

I just made a basic example. But the example works right? When the user clicks “Sleeping” the main menu item shows: “Airco State: Sleeping!” It is just the “on value” that it shows.

You can translate this to dutch if you want.

However, if you want to act on this, then Yes, you have to filter the “AircoState” Topic inside Homey, and set the airco based on it. Or do it the other way around like you did. translate the menu item text inside Homey based on the actual airco state. (and set the airco state directly). Like I said, if you need to translate every state, then yes. you need to filter every option.

Thanks @Satoer Fully agree that it should not become a patchwork of things :slight_smile: I was more referring to grouping existing widgets into a reusable “template”. This could be shared by save/load a file or a central market place, that would be neat. This way everything stays within the features/properties that are available, and one could even enforce colors and/or theme on the whole thing.
Love your work and no, it’s not thát important :wink: