UI-Lovelace-Minimalist / UI

UI-Lovelace-Minimalist is a "theme" for HomeAssistant
https://ui-lovelace-minimalist.github.io/UI/
Other
1.62k stars 431 forks source link

cover card enhancement #1215

Open shift-del1 opened 1 year ago

shift-del1 commented 1 year ago

I made some changes on the original cover card, can someone help and put it in a PR (to be honest, I never did one, so I have no experience with the procedure). Here is the code I added:

custom_card_cover:
  template: "card_cover"
  variables:
    ulm_custom_card_cover_favorite_percentage: null
    ulm_custom_card_cover_enable_swap: false
  styles:
    grid:
      - grid-template-areas: >
          [[[
            var areas = [];
            if (variables.ulm_card_cover_enable_horizontal &&
                variables.ulm_card_cover_enable_slider &&
                !variables.ulm_card_cover_enable_controls) {
                return "\"item1 item3\"";
            } else if (variables.ulm_card_cover_enable_horizontal &&
                !variables.ulm_card_cover_enable_slider &&
                variables.ulm_card_cover_enable_controls) {
                return "\"item1 item2\"";
            } else if (variables.ulm_card_cover_enable_horizontal &&
                variables.ulm_card_cover_enable_slider &&
                variables.ulm_card_cover_enable_controls&&
                !variables.ulm_custom_card_cover_enable_swap) {
                return "\"item1 item2\" \"item3 item3\"";
            } else if (variables.ulm_card_cover_enable_horizontal &&
                variables.ulm_card_cover_enable_slider &&
                variables.ulm_card_cover_enable_controls &&
                variables.ulm_custom_card_cover_enable_swap
                ) {
                return "\"item1 item3\" \"item2 item2\"";
            } else {
                areas.push("item1 item1");
                if (variables.ulm_card_cover_enable_controls) {
                    areas.push("item2 item2");
                }
                if (variables.ulm_card_cover_enable_slider) {
                    areas.push("item3 item3");
                }
                if (variables.ulm_card_cover_enable_tilt) {
                    areas.push("item4 item4");
                }
            }
            return "\"" + areas.join("\" \"") + "\"";
          ]]]
  custom_fields:
    item2:
      card:
        type: "custom:button-card"
        template: "[[[ return (variables.ulm_custom_card_cover_favorite_percentage) ? 'list_4_items' : 'list_3_items' ]]]"
        custom_fields:
          item1:
            card:
              type: "custom:button-card"
              template: "widget_icon"
              state:
                - operator: "template"
                  value: >
                    [[[
                      return entity.attributes.current_position == "0";
                    ]]]
                  styles:
                    icon:
                      - color: "rgba(var(--color-theme),0.4)"
                - operator: "template"
                  value: >
                    [[[
                      return entity.state == "closing";
                    ]]]
                  styles:
                    icon:
                      - color: "rgba(var(--color-theme),0.4)"
                - operator: "template"
                  value: >
                    [[[
                      return entity.state == "opening";
                    ]]]
                  styles:
                    icon:
                      - color: "rgba(var(--color-theme),0.4)"
              tap_action:
                action: "call-service"
                service: "cover.close_cover"
                service_data:
                  entity_id: "[[[ return entity.entity_id ]]]"
              icon: >-
                [[[
                  if (variables.ulm_card_cover_display_left_right){
                      return "mdi:arrow-left";
                  }
                  var device_class = entity.attributes?.device_class;
                  if (device_class == 'curtain' || device_class == 'gate'){
                      return "mdi:arrow-collapse-horizontal";
                  }
                  return "mdi:arrow-down";
                ]]]
          item2:
            card:
              type: "custom:button-card"
              template: "widget_icon"
              tap_action:
                action: "call-service"
                service: "cover.stop_cover"
                service_data:
                  entity_id: "[[[ return entity.entity_id ]]]"
              icon: "mdi:stop"
          item3:
            card:
              type: "custom:button-card"
              template: "widget_icon"
              state:
                - operator: "template"
                  value: >
                    [[[
                      return entity.attributes.current_position == variables.ulm_custom_card_cover_favorite_percentage;
                    ]]]
                  styles:
                    icon:
                      - color: "rgba(var(--color-theme),0.4)"
                - operator: "template"
                  value: >
                    [[[
                      return entity.state == "closing";
                    ]]]
                  styles:
                    icon:
                      - color: "rgba(var(--color-theme),0.4)"
                - operator: "template"
                  value: >
                    [[[
                      return entity.state == "opening";
                    ]]]
                  styles:
                    icon:
                      - color: "rgba(var(--color-theme),0.4)"
              tap_action:
                action: "call-service"
                service: "cover.set_cover_position"
                service_data:
                  entity_id: "[[[ return entity.entity_id ]]]"
                  position: "[[[ return variables.ulm_custom_card_cover_favorite_percentage ]]]"
              icon: "mdi:star"
          item4:
            card:
              type: "custom:button-card"
              template: "widget_icon"
              state:
                - operator: "template"
                  value: >
                    [[[
                      return entity.attributes.current_position == "100";
                    ]]]
                  styles:
                    icon:
                      - color: "rgba(var(--color-theme),0.4)"
                - operator: "template"
                  value: >
                    [[[
                      return entity.state == "closing";
                    ]]]
                  styles:
                    icon:
                      - color: "rgba(var(--color-theme),0.4)"
                - operator: "template"
                  value: >
                    [[[
                      return entity.state == "opening";
                    ]]]
                  styles:
                    icon:
                      - color: "rgba(var(--color-theme),0.4)"
              tap_action:
                action: "call-service"
                service: "cover.open_cover"
                service_data:
                  entity_id: "[[[ return entity.entity_id ]]]"
              icon: >-
                [[[
                  if (variables.ulm_card_cover_display_left_right){
                      return "mdi:arrow-right";
                  }
                  var device_class = entity.attributes?.device_class;
                  if (device_class == 'curtain' || device_class == 'gate'){
                      return "mdi:arrow-expand-horizontal";
                  }
                  return "mdi:arrow-up";
                ]]]

There are 3 issues I'm aware of:

image

ben-burwood commented 1 year ago

@shift-del1 could you just explain what improvements you have implemented in your code - is it just the 'favourite position' button? I'm happy to add this for you in a PR but just want to get an idea of what you've added :)

shift-del1 commented 1 year ago

@benbur98: first of all, thank you for helping. Yes, the main "enhancement" is the addition of a forth button for the favorite position. The second is the option to swap the control and slider in horizontal mode (originally the control will used for horizontal mode, I tried to add the same option for the slider).

image

The case when tilt is enabled is not really handled in my case, maybe we need to drop the variable for swapping and define a new one for the prioritized element (slider, control, tilt). Whatever is defined should be used for horizontal displaying. As I'm not very experienced with coding, I was not able to fix the 3 issues I mentioned in my original post, so I would like to get some help here as well..

Currently I created a custom template where all the changes are made (including the new variables) and this template relies on the original cover card, so for the PR it requires a major rework. So not all the codes are new, but I had to take over larger parts of the original code for the template.

ben-burwood commented 1 year ago

Hi @shift-del1 - finally had some time to look at this more. I am working on the cover card now and have added the option for the Favorite Position (it is at the end as i think this makes more sense - however it should be possible to change it if people prefer). image

The icon is always the 'full-color' and not 'greyed out' so I think that fixes your issue.

The case of prioritising the horizontal option is a good one, and it links to your issue in #1251 - will continue thinking on how best to do this.

I will open a pull request once I do these tweaks/update docs/etc...

shift-del1 commented 1 year ago

Hello @benbur98, thank you for taking time on my request. My preference would be to have the up and down arrow on the 2 sides, but it would make the card a bit more complex. Regarding the "full color" vs. "grayed out" thing I wanted to disable the buttons which makes no sense to push in a given status (like the down arrow when the blind is fully closed, or the star when the blind is set to the favorite position). As the card is a WIP, can you please add this to the states? For the horizontal topic, I would create a prioritized/primary key, where the slider, control or tilt_control can be defined, define a default order for the elements when horizontal is disabled, like: header slider control tilt_control and whenever the horizontal is enabled, I would remove the prioritized element from the list (setting the slider for example as default prioritized element). So only horizontal enabled: header slider control tilt_control Horizontal and prioritized=tilt_control enabled: header tilt_control slider control and so on. This is just an idea how I would realize it with enough experience :-) Anyway, thank you for your PR, I applied it and it works fine.