Reproducing Echo Show screens with Custom Button Card

I’d like to replace my Echo Show devices with Android tablets and phones using Lovelace dashboard designed to fit those screens. The amount of unwanted stuff being displayed as well as the constant maintenance to turn off ‘new features’ is really getting annoying. I am hoping that you guys can give me advice on if what I’m wanting to do is possible with existing Lovelace cards and service calls. I have been using HA for a long time (0.34 release) and have a good understanding of how things work. I’ve already written some automations that will advance through the different views via calls to the ‘Browser Mod’ integration and think I can do some cool stuff like switch to the doorbell camera view when someone rings the bell, show alerts when the dryer finishes, etc. This part I have confidence in my ability to create.

For the display, the idea would be to have an Android device running HA Companion and the Fully Kiosk integration allowing for only the main view to show. I am wanting to attempt to replicate some of the display screens used on the Echo Show device. I think this can be done using the Custom Button Card and some css. Here’s an example of the first screen I am attempting to replicate :

Image

I am pretty confident that I can modify the code for pulling information for my system clock and weather data from HA and use the code examples for custom fields in the Custom Button Card readme. I have already been successfully in pulling that data in. What I don’t understand is the css grid set up, how to best size and format, and most importantly how to assign these to the proper grid template areas. My attempts to do this have not met with success and I’m pretty sure it’s because I lack the experience in dealing with both css and lovelace.

Image

I found a website ( https://grid.layoutit.com/ ) that allows me to visually set things up and I think I’m on the right path.

Can the CSS that is generated in the right be used directly with the custom button card? Do I need to change the ‘.’ values to ‘blank’? Do those blank cells need to have some sort of filler for them to exist? something like the ’ ’ html ? Any examples outside of the ones from the custom button card readme would be appreciated. I’ve tried a few things over the past week but haven’t really gotten anywhere in terms of placement so could use a push in the right direction. I have not tried using the CSS from the image above yet.

Bonus points for help on ensuring the card takes up the entire view and has a background image that takes up the entire space as well.

I certainly appreciate any time you can provide guiding me with this. I think that once I get one of these working that I can use it as the foundation for all of the others. I understand the concepts but I am having trouble putting all the pieces together.

For similar purpose, but based on DisplayLink USB monitor with MacOSX companion app in full screen mode I use:

  • kiosk mode add on that alows to hide unwanted elements of UI
  • I’m running single dashboard in panell mode, with multiple conditional cards occupying the same grid cell. I’m using input_number helper as condition to display only one selected card at the time and zigbee remote to change the value of this helper.
  • conditional cards contain different dashboard views I want to display: picture gallery, weather card, media info, map, energy.
  • if needed I use custom layout card to position elements to be displayed on the screen. Same concept as using button card, but more flexible and I think easier to configure.
  • for full screen picture (as background) with addional components being displayed over I’d suggest to use picture elements card and card-mod to posion/scale/format elements.

Hope this helps/inspire to find your way!

1 Like

Thanks for taking the time to provide this. It certainly is helpful. I have managed to make progress using custom button card but will definitely look at the custom layout card as well. I have next to know css or js experience so it’s a bit of a struggle but I think I’ll be able to find my way given a little time and effort. This is a quick clip of my work in progress:

The conditional card method you are using is brilliant. I think it will be much easier for me to implement that versus the one card per view that I have now. I may ping you if I get stuck!

@mirekmal Would you mind sharing your cards? I am trying to wrap my head around creating multiple css grids and use them conditionally the way you are and maybe that will give me some insight. The custom layout card appears to be using a grid set up in the view but I’m not certain how I would go about creating individual cards with different grid layouts.

Sure, here it goes. For overal layout and some cards I put some comments to better explain what the code is doing:

type: custom:layout-card # This is the top level grid card, it contains only one cell - 'main'. All other cards are placed within this cell.
layout_type: grid
layout_options:
  grid-template-columns: 100%
  grid-template-rows: auto
  grid-template-areas: |
    "main"
cards: # here all the carss go
  - type: conditional
    grid-area: main
    conditions:
      - entity: input_number.dashboard # input number in fact is concatenation of 2 other input numbers, representing virtual grid
        state: '12.0' # in this case 12 represents 1st row and 2nd column. Condition relates for floating number as I use 10, 20, 30... for rows and 1, 2, 3... for rows. and just add numbers.
    card:
      type: custom:vertical-stack-in-card # this is card representing actual 1st dashbord, here I use combination of vertical and horizontal stacks to build it.
      title: ''
      cards:
        - cards:
            - type: custom:clock-weather-card
              entity: weather.weatherbit
              sun_entity: sun.sun
              weather_icon_type: line
              animated_icon: true
              forecast_rows: 5
              locale: en
              time_format: 24
              hide_today_section: false
              hide_forecast_section: false
            - type: iframe
              aspect_ratio: 1.4:1
              url: >-
                https://embed.windy.com/embed2.html?lat=52.311&lon=21.161&zoom=9&overlay=rain&location=coordinates
          type: custom:vertical-stack-in-card
          horizontal: true
        - cards:
            - align_icon: left
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_ogrod_temperature
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--greenish)
              line_width: 3
              name: Temp Out
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
            - align_icon: left
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_ogrod_humidity
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--cyanish)
              line_width: 3
              name: Hum Out
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
            - align_icon: left
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_parter_pressure
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--light-magenta)
              line_width: 3
              name: Presure
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
            - align_icon: left
              view_layout:
                grid-area: t-i
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_parter_temperature
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--greenish)
              line_width: 3
              name: Temp In
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
            - align_icon: left
              view_layout:
                grid-area: h-i
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_parter_humidity
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--cyanish)
              line_width: 3
              name: Hum In
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
          type: horizontal-stack


  - type: conditional
    conditions:
      - entity: input_number.dashboard
        state: '13.0'
    card: # this dasboard might be more interesting as I use here custom layout card to build the grid, within which I display different components of 'media player dashboard'
      type: custom:config-template-card
      variables:
        - states['input_select.media_players'].state
        - states[vars[0]].attributes.friendly_name
        - >-
          states[vars[0].replace('media_player', 'sensor') +
          '_album_description'].attributes.song_title
        - >-
          states[vars[0].replace('media_player', 'sensor') +
          '_album_description'].attributes.artist_name
        - >-
          states[vars[0].replace('media_player', 'sensor') +
          '_album_description'].attributes.album_title
        - >-
          states[vars[0].replace('media_player', 'sensor') +
          '_album_description'].attributes.album_description
        - >-
          states[vars[0].replace('media_player', 'sensor') +
          '_album_description'].attributes.album_title
        - >-
          states[vars[0].replace('media_player', 'sensor') +
          '_album_description'].attributes.album_art
      entities:
        - ${vars[0]}
      card:
        type: picture-elements # here picture-elements card is used for background of dashboard. It displayes media picture with some overlays (half transparrent gray picture) to give it tinted look.
        image: ${vars[7]}
        elements:
          - type: image
            image: ${vars[7]}
            style:
              top: 49%
              left: 49%
              width: 102%
          - type: image
            image: /local/overlay.png
            style:
              top: 49%
              left: 49%
              width: 120%
          - type: image
            image: /local/overlay2.png
            style:
              top: 49%
              left: 49%
              width: 120%
          - type: custom:layout-card # and here is actual media info card composed of some pictures and markups placed within the grid
            style:
              top: 0%
              left: 0%
              transform-origin: left top
              transform: translate(-0%,-0%)
            layout_type: grid # here goeas definition of the grid
            layout_options:
              grid-template-columns: 3% 45% 1% auto 4%
              grid-template-rows: 7% auto auto
              grid-template-areas: | # a represents empty space at top, art is for cover, info for song title, artist and album, desc for album info I pull from ChatGPT
                "a a a a a" 
                "b art c desc d"
                "e info c desc d"
              mediaquery:
                '(max-width: 700px)':
                  grid-template-columns: 100%
                  grid-template-rows: auto auto auto
                  grid-template-areas: |
                    "art"
                    "desc"
                    "info"
            cards:
              - entity: ${vars[0]}
                type: custom:mini-media-player
                artwork: full-cover-fit
                scale: '1.5'
                hide:
                  mute: true
                  icon: true
                  power: true
                  volume: true
                  controls: true
                  source: true
                  name: true
                  info: true
                  progress: true
                view_layout:
                  grid-area: art
              - type: markdown
                view_layout:
                  grid-area: info
                card_mod:
                  style: |
                    ha-card {
                      background: transparent;
                      line-height: 1.2
                      }
                content: >-
                  ${"<font color=white><font size=6.0em>" + vars[2] + "<font
                  color=grey></br>" + "<font size=5.5em>" + vars[3] +
                  "<font></br>" + "<font size=5.0em>" + vars[4] }
              - type: markdown
                view_layout:
                  grid-area: desc
                card_mod:
                  style: |
                    ha-card {
                      background: transparent;
                      line-height: 1.1
                      }
                content: ${"<font size=4.0em>" + vars[5] + "<font>"}

  - type: conditional
    card:
      dark_mode: false
      default_zoom: 15
      entities:
        - entity: device_tracker.audi_q5_position
        - entity: zone.children_place
        - entity: zone.dorota_parents
        - entity: zone.mirek_mom
        - entity: zone.mirek_work
        - entity: zone.home
        - entity: zone.auchan_zielonka
        - entity: zone.selgros
        - entity: zone.lidl
        - entity: person.mirek_malinowski
        - entity: person.dorota_malinowska
        - entity: zone.api
      type: map
      hours_to_show: 48
      aspect_ratio: '1880:1270'
    conditions:
      - entity: input_number.dashboard
        state: '14.0'
  - type: conditional
    card:
      type: custom:sankey-chart
      show_names: true
      round: 1
      wide: true
      height: 500
      show_icons: false
      show_states: true
      min_box_height: 5
      min_box_distance: 10
      sections:
        - entities:
            - entity_id: sensor.phase_a_power
              color: var(--red5)
              name: Phase-A
              children:
                - sensor.power_total
            - entity_id: sensor.phase_b_power
              color: var(--red4)
              name: Phase-B
              children:
                - sensor.power_total
            - entity_id: sensor.phase_c_power
              color: var(--red3)
              name: Phase-C
              children:
                - sensor.power_total
            - entity_id: sensor.external_power_total
              color: var(--red2)
              name: External
              children:
                - sensor.power_total
        - entities:
            - entity_id: sensor.power_total
              color: var(--magenta3)
              name: Total Power
              children:
                - sensor.attic_power_total
                - sensor.first_floor_power_total
                - sensor.ground_floor_power_total
                - sensor.basement_power_total
                - sensor.garden_power_total
              remaining:
                name: Other Devices
                color: var(--orange3)
        - entities:
            - entity_id: sensor.attic_power_total
              color: var(--lightblue1)
              name: Attic
              children:
                - sensor.tv_room_power_total
                - sensor.wardrobe_power_total
            - entity_id: sensor.first_floor_power_total
              color: var(--lightblue2)
              name: First Floor
              children:
                - sensor.dorota_office_power_total
                - sensor.mirek_office_power_total
                - sensor.library_power_total
            - entity_id: sensor.ground_floor_power_total
              color: var(--lightblue3)
              name: Ground Floor
              children:
                - sensor.living_room_power_total
                - sensor.toilet_power_total
                - sensor.kitchen_power_total
                - sensor.hall_power_total
            - entity_id: sensor.basement_power_total
              color: var(--lightblue4)
              name: Basement
              children:
                - sensor.basement_main_power
                - sensor.my_it_rack
                - sensor.basement_equipment_power
            - entity_id: sensor.garden_power_total
              color: var(--green2)
              name: Garden
              children:
                - sensor.driveway_lights_power
                - sensor.external_stairway_lights_power
                - sensor.automover_power
                - sensor.garage_equipment_power
                - sensor.front_christmas_lights_power
                - sensor.balcony_christmas_lights_power
        - entities:
            - entity_id: sensor.tv_room_power_total
              color: var(--green3)
              name: TV Room
              children:
                - sensor.tv_room_main_light_total
                - sensor.desk_lamp_power
                - sensor.tv_shelf_illumination_power
                - sensor.tv_illumination_power
                - sensor.sony_bravia_tv_power
                - sensor.denon_avr_s750h_power
                - sensor.apple_tv_power
                - sensor.tv_room_equipment_power
                - sensor.stairway_lights_channel_4_power
            - entity_id: sensor.wardrobe_power_total
              color: var(--green2)
              name: Wardrobe
              children:
                - sensor.iron_power
            - entity_id: sensor.dorota_office_power_total
              color: var(--green1)
              name: Dorota Office
              children:
                - sensor.dorota_main_light_power_total
                - sensor.dorota_floor_lamp_power
                - sensor.dorota_office_equipment_power
                - sensor.dorota_imac_power
            - entity_id: sensor.mirek_office_power_total
              color: var(--lemon1)
              name: Mirek Office
              children:
                - sensor.mirek_ceiling_power
                - sensor.mirek_desk_lamp_power
                - sensor.mirek_mac_pro_power
                - sensor.mirek_work_laptop_power
                - sensor.mirek_office_equipment_power
            - entity_id: sensor.library_power_total
              color: var(--lemon2)
              name: Library
              children:
                - sensor.library_light_total
            - entity_id: sensor.living_room_power_total
              color: var(--lemon3)
              name: Living Room
              children:
                - sensor.living_room_ceiling_total
                - sensor.living_room_dinning_table_total
                - sensor.coffe_table_light_electric_consumption_w
                - sensor.living_room_table_lamp_power
                - sensor.marantz_model_30_power
                - sensor.living_room_equipment_power
            - entity_id: sensor.toilet_power_total
              color: var(--yellow2)
              name: Toilet
              children:
                - sensor.toilet_light_power
                - sensor.toilet_equipment_power
            - entity_id: sensor.kitchen_power_total
              color: var(--yellow3)
              name: Kitchen
              children:
                - sensor.kitchen_main_lights_power
                - sensor.kitchen_table_power
                - sensor.induction_owen_power_total
                - sensor.shelly_coffee_machine_power
                - sensor.shelly_dishwasher_power
                - sensor.microwave_owen_power_total
                - sensor.shelly_washing_machine_power
                - sensor.pantry_power
                - sensor.ground_floor_equipment_power
            - entity_id: sensor.hall_power_total
              color: var(--yellow4)
              name: Hall
              children:
                - sensor.stairways_power_total
                - sensor.hall_lights_power
        - entities:
            - entity_id: sensor.tv_room_main_light_total
              color: var(--orange1)
              name: TV Room Main Light
            - entity_id: sensor.desk_lamp_power
              color: var(--orange1)
              name: TV Room Lamp
            - entity_id: sensor.tv_shelf_illumination_power
              color: var(--orange1)
              name: Shelf Illumination
            - entity_id: sensor.tv_illumination_power
              color: var(--orange1)
              name: TV Illumination
            - entity_id: sensor.sony_bravia_tv_power
              color: var(--cyan1)
              name: Sony Bravia AG9
            - entity_id: sensor.denon_avr_s750h_power
              color: var(--cyan1)
              name: Denon AVR-S750H
            - entity_id: sensor.apple_tv_power
              color: var(--cyan1)
              name: Apple TV
            - entity_id: sensor.tv_room_equipment_power
              color: var(--magenta1)
              name: TV Room Devices
            - entity_id: sensor.stairway_lights_channel_4_power
              color: var(--orange1)
              name: Attic Stairways Illumination
            - entity_id: sensor.iron_power
              color: var(--green1)
              name: Iron
            - entity_id: sensor.dorota_main_light_power_total
              color: var(--orange1)
              name: Dorota Main Lights
            - entity_id: sensor.dorota_floor_lamp_power
              color: var(--orange1)
              name: Dorota Floor Lamp
            - entity_id: sensor.dorota_office_equipment_power
              color: var(--magenta1)
              name: Dorota Office Devices
            - entity_id: sensor.dorota_imac_power
              color: var(--cyan1)
              name: Dorota iMac
            - entity_id: sensor.mirek_ceiling_power
              color: var(--orange1)
              name: Mirek Main Lights
            - entity_id: sensor.mirek_desk_lamp_power
              color: var(--orange1)
              name: Mirek Desk Lamp
            - entity_id: sensor.mirek_mac_pro_power
              color: var(--cyan1)
              name: Mirek Mac Pro
            - entity_id: sensor.mirek_work_laptop_power
              color: var(--cyan1)
              name: Mirek Laptop
            - entity_id: sensor.mirek_office_equipment_power
              color: var(--magenta1)
              name: Mirek Office Devices
            - entity_id: sensor.library_light_total
              color: var(--orange1)
              name: Library Main Lights
            - entity_id: sensor.living_room_ceiling_total
              color: var(--orange1)
              name: Living Room Ceiling Lights
            - entity_id: sensor.living_room_dinning_table_total
              color: var(--orange1)
              name: Living Room Dinning Table
            - entity_id: sensor.coffe_table_light_electric_consumption_w
              color: var(--orange1)
              name: Living Room Coffee Table
            - entity_id: sensor.living_room_table_lamp_power
              color: var(--orange1)
              name: Living Room Lamp
            - entity_id: sensor.marantz_model_30_power
              color: var(--cyan1)
              name: Marantz SACD30n
            - entity_id: sensor.living_room_equipment_power
              color: var(--cyan1)
              name: Other Equipment
            - entity_id: sensor.toilet_light_power
              color: var(--orange1)
              name: Toilet Light
            - entity_id: sensor.toilet_equipment_power
              color: var(--orange1)
              name: Toilet Equipment
            - entity_id: sensor.kitchen_main_lights_power
              color: var(--orange1)
              name: Kitchen Main Lights
            - entity_id: sensor.kitchen_table_power
              color: var(--orange1)
              name: Kitchen Table Lights
            - entity_id: sensor.induction_owen_power_total
              color: var(--cyan1)
              name: Owen
            - entity_id: sensor.shelly_coffee_machine_power
              color: var(--cyan1)
              name: Coffee Machine
            - entity_id: sensor.shelly_dishwasher_power
              color: var(--cyan1)
              name: Dishwasher
            - entity_id: sensor.microwave_owen_power_total
              color: var(--cyan1)
              name: Microwave
            - entity_id: sensor.shelly_washing_machine_power
              color: var(--cyan1)
              name: Washing Machine
            - entity_id: sensor.pantry_power
              color: var(--orange1)
              name: Pantry Lights
            - entity_id: sensor.ground_floor_equipment_power
              color: var(--magenta1)
              name: Ground Floor Devices
            - entity_id: sensor.stairways_power_total
              color: var(--orange1)
              name: Stairways Lights
            - entity_id: sensor.hall_lights_power
              color: var(--orange1)
              name: Hall Lights
            - entity_id: sensor.basement_main_power
              color: var(--orange1)
              name: Basement Light
            - entity_id: sensor.my_it_rack
              color: var(--cyan1)
              name: IT Rack
            - entity_id: sensor.basement_equipment_power
              color: var(--magenta1)
              name: Basement Devices
            - entity_id: sensor.driveway_lights_power
              color: var(--orange1)
              name: Driveway Lights
            - entity_id: sensor.external_stairway_lights_power
              color: var(--orange1)
              name: Stairway Lights
            - entity_id: sensor.automover_power
              color: var(--green1)
              name: Automover
            - entity_id: sensor.garage_equipment_power
              color: var(--magenta1)
              name: Garage Devices
            - entity_id: sensor.front_christmas_lights_power
              color: var(--orange1)
              name: Front Christmas Lights
            - entity_id: sensor.balcony_christmas_lights_power
              color: var(--orange1)
              name: Balcony Christmas Lights
    conditions:
      - entity: input_number.dashboard
        state: '15.0'
  - type: conditional
    grid-area: main
    card:
      cards:
        - cards:
            - type: custom:clock-weather-card
              entity: weather.weatherbit
              sun_entity: sun.sun
              weather_icon_type: line
              animated_icon: true
              forecast_rows: 5
              locale: en
              time_format: 24
              hide_today_section: false
              hide_forecast_section: false
            - type: iframe
              aspect_ratio: 1.4:1
              url: >-
                https://embed.windy.com/embed2.html?lat=52.311&lon=21.161&zoom=9&overlay=wind&location=coordinates
          type: custom:vertical-stack-in-card
          horizontal: true
        - cards:
            - align_icon: left
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_ogrod_temperature
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--greenish)
              line_width: 3
              name: Temp Out
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
            - align_icon: left
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_ogrod_humidity
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--cyanish)
              line_width: 3
              name: Hum Out
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
            - align_icon: left
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_parter_pressure
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--light-magenta)
              line_width: 3
              name: Presure
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
            - align_icon: left
              view_layout:
                grid-area: t-i
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_parter_temperature
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--greenish)
              line_width: 3
              name: Temp In
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
            - align_icon: left
              view_layout:
                grid-area: h-i
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_parter_humidity
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--cyanish)
              line_width: 3
              name: Hum In
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
          type: horizontal-stack
      title: ''
      type: custom:vertical-stack-in-card
    conditions:
      - entity: input_number.dashboard
        state: '22.0'
  - type: conditional
    grid-area: main
    card:
      cards:
        - cards:
            - type: custom:clock-weather-card
              entity: weather.weatherbit
              sun_entity: sun.sun
              weather_icon_type: line
              animated_icon: true
              forecast_rows: 5
              locale: en
              time_format: 24
              hide_today_section: false
              hide_forecast_section: false
            - type: iframe
              aspect_ratio: 1.4:1
              url: >-
                https://embed.windy.com/embed2.html?lat=52.311&lon=21.161&zoom=9&overlay=temp&location=coordinates
          type: custom:vertical-stack-in-card
          horizontal: true
        - cards:
            - align_icon: left
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_ogrod_temperature
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--greenish)
              line_width: 3
              name: Temp Out
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
            - align_icon: left
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_ogrod_humidity
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--cyanish)
              line_width: 3
              name: Hum Out
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
            - align_icon: left
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_parter_pressure
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--light-magenta)
              line_width: 3
              name: Presure
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
            - align_icon: left
              view_layout:
                grid-area: t-i
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_parter_temperature
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--greenish)
              line_width: 3
              name: Temp In
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
            - align_icon: left
              view_layout:
                grid-area: h-i
              animate: false
              entities:
                - entity: sensor.netatmo_pogodynka_parter_humidity
                  index: 0
              font_size: 75
              hour24: true
              hours_to_show: 24
              line_color: var(--cyanish)
              line_width: 3
              name: Hum In
              show:
                extrema: true
                fill: fade
                icon: false
                name: true
              type: custom:mini-graph-card
          type: horizontal-stack
      title: ''
      type: custom:vertical-stack-in-card
    conditions:
      - entity: input_number.dashboard
        state: '32.0'
  - type: conditional
    grid-area: main
    card:
      type: iframe
      url: http://192.168.52.72:9330/display
      aspect_ratio: 67%
    conditions:
      - entity: input_number.dashboard
        state: '23.0'
  - type: conditional
    grid-area: main
    card:
      type: custom:config-template-card
      entities:
        - sensor.random_gallery_file
      card:
        type: custom:hui-image-element
        image: ${states['sensor.random_gallery_file'].state}
    conditions:
      - entity: input_number.dashboard
        state: '11.0'

And here are screenshots of the actual dashboard. The first 2 represents dashboards I commented in code, for easier reference to what the code renders:





I’m skipping gallery card, as it just display random picture from galery forlder…

1 Like

Absolutely perfect and these look REALLY nice as well. Will digest this more once I get a reprieve from work!

Back again. I’m still working on this and also looking at the examples @mirekmal was kind enough to share.

I’m trying to learn this stuff and use tools to try and visualize but running into stumbling blocks. To get a better understanding of how CSS grids work, I found a site called CSS Grid Playground that allows the user to experiment with settings and get things laid out and then grab that code. It looks very similar to HA card options for the layout-card so I was hoping it would translate directly. Here’s and example of what I came up with there:

image

I then tried to incorporate that into my card. This is the code I am trying to use:

type: conditional
grid-area: main
conditions:
  - condition: state
    entity: input_select.lr_display
    state: listening
card:
  type: picture-elements
  image: >-
    /local/alexaclone/tropical-green-foliage-leaf-dark-background-natural-rain-forest_512343-121.jpg
  elements:
    - type: custom:layout-card
      style:
        top: 0%
        left: 0%
        transform-origin: left top
        transform: translate(-0%,-0%)
      layout_type: grid
      layout_options:
        grid-template-columns: 2fr 5fr 2fr;
        grid-template-rows: 1fr 5fr 1fr;
        grid-template-areas: |
          "weather . alarm"
          "time time time"
          "foot1 . foot2";
      cards:
        - type: markdown
          view_layout:
            grid-area: weather
          content: >-
            ![image](https://cdn.jsdelivr.net/gh/bramkragten/weather-card@master/dist/icons/rainy-6.svg){{
            state_attr('weather.home', 'temperature') }}°
        - type: markdown
          view_layout:
            - grid-area: alarm
          content: 9:30am
        - type: markdown
          view_layout:
            grid-area: time
            height: 50vh
          content: '{{ now().strftime(''%-I:%M'')}}<br>{{ now().strftime(''%a, %b %-d'')}}'

I have not attempted to style the text for size, font type, or background transparency but figure that will come later once I can figure out how to position the elements. This is how it looks:

image

I’m having a hard time understanding why the weather content is not showing up at all and why the alarm content is showing up where the weather content should be. Also the size of the rows do not look like they are being honored as the time area is narrow compared to what it looks like at the CSS playground site.

I know it’s part of the learning process. My thinking is if I can get one of these to look good then I can do others in a similar way. Any advice anyone can give is most appreciated. Thanks for your patience.

Additionally I’ve tried doing this in straight html. Here’s the code:

<html>
  <style>
    .grid-container {
      display: grid;
      grid-gap: 1rem;
      grid-template-columns: 1fr 5fr 2.5fr;
      grid-template-rows: 1fr 5fr 1fr;
      grid-template-areas:
        "weather . alarm"
        "time time time"
        "foot1 . foot2";
    }

    .weather {
      grid-area: weather;
      text-align: center;
    }

    .alarm {
      grid-area: alarm;
      text-align: center;
    }

    .time {
      grid-area: time;
      text-align: center;
    }

    .foot1 {
      grid-area: foot1;
    }

    .foot2 {
      grid-area: foot2;
    }
  </style>

  <div class="grid-container">
    <div class="weather">65F</div>
    <div class="alarm">3:00am</div>
    <div class="time">12:00</div>
    <div class="foot1">Footer 1</div>
    <div class="foot2">Footer 2</div>
  </div>

  </html>

and this is what it looks like in the browser:

image

I think this is what I’m expecting. Can someone tell me how this translates to the markup card?

Looks like I found it. I had an extra ‘;’ where I’m pointing and it was causing all the issues. Here’s what it looks like now:

Now on to resizing and theming!

Getting really close with the mockup now. I still need to find some better icons and translate HASS state to those icons and size correctly (1), figure out how do a center vertically in the div (2), and better position the clock (3) as it appears to be too low. If anyone has any suggestions on how to do those items that info is most appreciated.

Last item to add is an animated bar at the bottom as a conditional card that will pop on when assist detects the wake word and is listening. Will probably try to mute the background image some as well.

Here’s the code if interested:

type: custom:mod-card
card_mod:
  style: |
    ha-card  {
      background: url("/local/alexaclone/tropical-green-foliage-leaf-dark-background-natural-rain-forest_512343-121.jpg");
      background-size: cover;
      border-radius: 0;
     }
card:
  type: custom:layout-card
  layout_type: grid
  layout_options:
    grid-template-columns: 2fr 5fr 2fr;
    grid-template-rows: 1fr 5fr 1fr;
    grid-template-areas: |
      "weather . alarm"
      "time time time"
      "foot1 . foot2"
  cards:
    - type: markdown
      view_layout:
        grid-area: weather
      content: >-
        #
        ![image](https://cdn.jsdelivr.net/gh/bramkragten/weather-card@master/dist/icons/rainy-6.svg){{
        state_attr('weather.home', 'temperature') }}°
      card_mod:
        style:
          .: |
            ha-card {
              background-color: transparent;
              border: 0;
            }        
          ha-markdown $: |
            h1 {
              text-align: center;
              #margin: auto;
              vertical-align: middle;
              font-family: "Roboto", sans-serif;
              font-size: 500%;
              color: white;
    - type: markdown
      view_layout:
        grid-area: alarm
      content: '# 9:30AM'
      card_mod:
        style:
          .: |
            ha-card {
              background-color: transparent;
              border: 0;
            }        
          ha-markdown $: |
            h1 {
              text-align: center;
              #margin: auto;
              vertical-align: middle;
              font-family: "Roboto", sans-serif;
              font-size: 400%;
              color: white;
    - type: markdown
      view_layout:
        grid-area: time
      content: |-
        # {{ now().strftime('%-I:%M')}}
        ## {{ now().strftime('%a, %b %-d')}}
      card_mod:
        class: class1
        style:
          .: |
            ha-card {
              background-color: transparent;
              border: 0;
            }
          ha-markdown $: |
            h1, h2 {
              text-align: center;
              font-family: "Roboto", sans-serif;
            }
            h1 {
              font-size: 2500%;
              padding-top: 8px;
              padding-bottom: 8px;
              margin-bottom: -8%;
              color: white;
            }      
            h2 {
              font-size: 350%!important;;          
            }  

Note that I did change from the custom button card as I found the examples shown by @mirekmal were much easier to deal with. Also thanks to @d_sellers1 for the help and encouragement on Discord. I’m not done with this one yet but I’ve learned a lot and hope that the next cards will come together faster and easier due to what I’ve accomplished here.

This is the icon pack that includes the one you have in your screenshot and used by bramkragten’s weather card (which is where you’re pulling that one from). Free animated SVG weather icons

I’ve used this to pull icons from his source:

return '<img src = "https://cdn.jsdelivr.net/gh/bramkragten/weather-card/dist/icons/' + weather_icon + '.svg" width="90%" height="90%" />'

The above was adapted for someone who wanted animated icons based off of an example I posted on Github. The only problem is that it is written in JavaScript and I don’t think I’ve gotten around to trying to make one work in Jinja. I basically mapped the weather entity’s state to a corresponding icon. custom:button-card with mapped icon and icon color based on weather condition
Also, this example doesn’t handle icons for night properly (but does in the one that was adapted; I just haven’t gotten around to fixing the example.)

1 Like

SO whats the plan with this?

Android tab using Wyoming to be a local voice assistant with some kinda custom UI?

What about Spotify and media playback and speakers for decent sound?

Also more generally, do you guys think 2024 will be the year we can get rid of Alexa with Wyoming Satellites being dot analogs and Android tabs being show analogs?

Im super keen for this future :slight_smile:

What’s the plan for me? I’m wanting to replace all my Alexa based devices (Echo Show x2 Echo Dot x4 Echo Flex x2) with some sort of device running Wyoming. My hope and feeling is that we will see Assist on on HA Companion Android app this year. I see other options with Tasker that some smart folks have tied into Assist that may be an option as well.

I am choosing to spend my time working on the interface portion for the Echo Show display portion via this and other planned custom cards. As you can see above, I have managed to piece something together that looks similar to the clock display. I have also written this as a condition card that is tied to an input select which I can use to control which Alexa display card to display. This works and I feel confident I can tie this in with Assist using some custom sentence detection though I have not tried this yet.

For now, I am testing using a M5Stack ATOM Echo Development Kit for Assist voice commands and an old Amazon Fire HD 7 as my display. This tablet is very old and I’m having trouble getting HA Companion to install on it so I will end up with another cheap tablet in the future so that I can use it as a media player. At that point, I am hoping to find a wireless charging stand with integrated speakers or standalone speaker that I can somehow incorporate/hide to have better sound output than the tablet speaker.

I’m attempting to create this card and future card so that the display can be extended to different sized tablets and phones without code specific for those devices. Currently I’m wanting to finish this first card up. I have started work on the little bar at the bottom that glows when Assist is detected on the M5Stack and have that working but am seeing resizing when the animated gif is shown.

The list of cards I’d like to create as of now are:

  • Time card (this one)
  • Weather card using data from my local station
  • Security camera cards (per camera and four camera view)
  • Device action cards using custom button card to handle when commands are given to turn on/off devices or view status of that device
  • Device feedback cards that show status of devices like washer/dryer run time or time between actions for unloading wash into dryer. Also to show status of Alarm arm/disarm and other things
  • Music display (see example shared above). To be honest, I don’t play a lot of music on my device now so this would just be for completeness. We do listen to online radio so that will probably be part of this card
  • Timer and alarm card for kitchen timer type things

Commands I’d like to be able to give and have the display and Assist voice respond to:

  • “Show [card] '” and it shows the request card. Show weather, show time, show front camera, etc Assist processes the request and automation changes the input boolean to the appropriate card and the conditional card is shown
  • “Is the [device] on/off/open/closed/running/etc ?” Shows the device feedback card with MDI icon and status. Assist processes and automation changes boolean and sets variable for device requested and the feedback card is wired to show that variable
  • “Announce [message]” and it displays message on all displays as well as plays a TTS or WAV announcement on all Alexa replacement devices’ media player service
  • “Add [item] to shopping list” and HA adds item to list and display shows HA shopping list (reverse sort limited items shown) with that item showing for confirmation.

I feel pretty confident I can do these two things without much issue once I look into Assist custom sentences.

Things that I do now that I’m not sure I’ll be able to figure out or will have to wait on:

  • General knowledge questions like “How many eggs in a dozen”, “What time is it in Sweden”, etc . This will have to come as Assist increases it’s ability to handle. I’ve attempted locally hosted LLM tied to Assist but it’s too slow on my hardware to get responses like this
  • Drop in function which allows an intercom of sorts between two devices. This is basically like a phone call between the two Alexa devices. I doubt that HA Companion will extend to do this but perhaps a separate app can be tied in.

Thanks for asking this question as I can use my response as a punch list of items to work on. This is probably much more than you were wanting to see.

Truth be known, I am much more of a hacker than a programmer or designer but I can do some things given enough time which is also in short supply. I’m pretty sure I’m not the only one interested in doing this and hope that my hacky proof-of-concept will encourage folks with more skill and time to work with me by offering guidance or code or even spur them to start their own project and share it with others.

1 Like

Wow, that is quite the response, thank you :slight_smile: Its great to see what other people are doing to migrate away from Alexa.

For me, I use the Alexa media player integration very extensively for things like follow me music. But with all of Amazon’s Alexa monetization issues and staff cut backs. So many things both in general and with the API just dont work or work well anymore.

The thing is I like the screen based Alexas. Once you get the rubbish off it, it’s a great photo frame/ music player. And I want to have that functionality most of all.

So a tablet, like the pixel tablet with that speaker base station would be perfect. I’m just waiting for something like that to popup on aliexpress or the like that I can root, put lineageOS or some other thing on and then use something like Kiosk browser with voice and music assistant for album art ect.

You can use chat GPT or a locally running LLM (if you have the compute) as a backend to answer general questions.

See this guide for the Wyoming Satellite, its pretty much the perfect dot replacement already.

I’m actually working on integrating one into a broken Echo Show (Just for speakers) ill post something when/ if lol I get it working.

Same here. The Echo Show devices we have really replaced the clock we had before. It’s unfortunate, however, that seemingly every time I look at it it’s showing something other than the clock. Something that I am not interested in like ‘Watch Viral Videos’ or something else that I thought I turned off in settings. It’s gotten to the point where it’s not serving it’s intended purpose and I am sure that it will only worsen as Amazon tries to figure out more ways to try and get money by using that display. I get it and I don’t blame them. The devices are a steal at the price you pay for them and the service but I would prefer to have a lot more control. I’m not a hyper privacy concerned person but more so concerned about function control.

Correct. That’s the type of set up I’m aiming for. I’m very budget conscious (aka cheap) so really looking to repurpose old hardware at a good price if I can find something suitable. I’m even considering replacing some of the dots with old phones with these charger speaker bases if those even exist. Again, the success of this is dependent on Android HA Companion incorporating Assist listen otherwise I’ll be trying to get these Atom devices strapped on for voice input.

Yep. I was super excited to watch this video and to find that channel. Really excellent work. Did I mention I am cheap? The YT Creator said that he’s spending some $10-$15/month on ChatGPT services. That’s too rich for me. I know that the problem is that HA integration is sending a TON of information on each call and the tokens are based on the volume of data sent in your prompt and volume received in the response. A question like ‘What time is it?’ still sends every device state and every service call you have exposed to assist. This equates to a bunch of extra tokens for each call. I understand why this is happening and hopefully someone will figure out how to tune this better.

I have integrated with Ollama for local LLM integration. This works and I can turn things on and off and otherwise interact in ways I cannot with Assist, BUT it is slow. My server is super powerful in regards to being able to run the 25+ Docker containers I have and still have about 50% CPU and RAM to spare, BUT it cannot handle the strain of the large prompts being fed. I had to increase the 90 second wait time to keep it from timing out. I’m getting response times in the 120 second range which is way too long to wait.

So in summary, my goal of replacing Alexa in my home for voice control are waiting on these things:

  • Better Assist controls from HA natively and/or better LLM integration for local AI control for less powerful hardware and/or cheaper calls to ChatGPT
  • Wake word detect on Android devices or a cheap Wyoming device for coupling with a display and speakers
  • Integration of a bunch of HA dashboard cards to replicate the display function of the assistant displays

About the only one I can possibly work on are these cards. I have no doubt that others are interested in this and was the other two items happen more and more folks will start working on these items and maybe I can find a better solution than what I’ve put together.

So they are tricky with this, they add more/ change it like once a month it feels like,

If anything pops up, just use the guide and remove it from the settings :slight_smile:

I think he’s overstated the price, I brought $10 and ive used $0.08 in the last month.

To be fair, I don’t use it that much yet, so will see. I automate in a way where I don’t have to talk to alexa very often. Radar is your friend :slight_smile:

Keen to see if I can get this busted Echo Show reproposed as a Wyoming Satellite.

2.1 Amp from Aliexpress and a Pi Zero with Keyestudio 5V ReSpeaker 2-Mic Pi HAT