Time Picker

Please welcome my first UI widget which allows to set the time of DateTime items.

Resources

The widget code:

uid: timepicker
tags: []
props:
  parameters:
    - description: Time format (12h|24h)
      label: Format
      name: timeFormat
      required: true
      type: TEXT
    - context: item
      description: Item to control
      label: Item
      name: item
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Mar 12, 2021, 10:17:53 PM
component: f7-block
config:
  label: Time picker
slots:
  default:
    - component: f7-row
      config:
        class:
          - margin
      slots:
        default:
          - component: f7-col
            config:
              width: "=(props.timeFormat === '12h') ? '70': '100'"
            slots:
              default:
                - component: f7-row
                  config: {}
                  slots:
                    default:
                      - component: f7-col
                        config:
                          width: "45"
                          style:
                            text-align: center
                        slots:
                          default:
                            - component: oh-button
                              config:
                                action: command
                                actionItem: =(props.item)
                                actionCommand: =(dayjs(items[props.item].state).add(1, 'hour').format('YYYY-MM-DDTHH:mm:ss.ZZ'))
                                text: ▲
                                style:
                                  font-family: u2400
                                  font-size: 150%
                                  --f7-button-text-color: var(--f7-text-color)
                      - component: f7-col
                        config:
                          width: "10"
                      - component: f7-col
                        config:
                          width: "45"
                          style:
                            text-align: center
                        slots:
                          default:
                            - component: oh-button
                              config:
                                action: command
                                actionItem: =(props.item)
                                actionCommand: =(dayjs(items[props.item].state).add(1, 'minute').format('YYYY-MM-DDTHH:mm:ss.ZZ'))
                                text: ▲
                                style:
                                  font-family: u2400
                                  font-size: 150%
                                  --f7-button-text-color: var(--f7-text-color)
                - component: f7-row
                  config: {}
                  slots:
                    default:
                      - component: f7-col
                        config:
                          width: "45"
                        slots:
                          default:
                            - component: oh-label-card
                              config:
                                label: "=(((items[props.item].state === 'NULL') || !props.item) ? '?': props.timeFormat == '12h' ? dayjs(items[props.item].state).format('hh'): dayjs(items[props.item].state).format('HH'))"
                      - component: f7-col
                        config:
                          width: "10"
                          style:
                            margin: auto
                            text-align: center
                        slots:
                          default:
                            - component: Label
                              config:
                                style:
                                  font-size: 200%
                                text: ":"
                      - component: f7-col
                        config:
                          width: "45"
                        slots:
                          default:
                            - component: oh-label-card
                              config:
                                label: "=(((items[props.item].state === 'NULL') || !props.item) ? '?': dayjs(items[props.item].state).format('mm'))"
                - component: f7-row
                  config: {}
                  slots:
                    default:
                      - component: f7-col
                        config:
                          width: "45"
                          style:
                            text-align: center
                        slots:
                          default:
                            - component: oh-button
                              config:
                                action: command
                                actionItem: =(props.item)
                                actionCommand: =(dayjs(items[props.item].state).add(-1, 'hour').format('YYYY-MM-DDTHH:mm:ss.ZZ'))
                                text: ▼
                                style:
                                  font-family: u2400
                                  font-size: 150%
                                  --f7-button-text-color: var(--f7-text-color)
                      - component: f7-col
                        config:
                          width: "10"
                      - component: f7-col
                        config:
                          width: "45"
                          style:
                            text-align: center
                        slots:
                          default:
                            - component: oh-button
                              config:
                                action: command
                                actionItem: =(props.item)
                                actionCommand: =(dayjs(items[props.item].state).add(-1, 'minute').format('YYYY-MM-DDTHH:mm:ss.ZZ'))
                                text: ▼
                                style:
                                  font-family: u2400
                                  font-size: 150%
                                  --f7-button-text-color: var(--f7-text-color)
          - component: f7-col
            config:
              width: "30"
              visible: =(props.timeFormat === '12h')
              style:
                margin: auto
            slots:
              default:
                - component: f7-row
                  config:
                    class:
                      - padding-bottom
                  slots:
                    default:
                      - component: f7-col
                        config:
                          style:
                            margin: auto
                        slots:
                          default:
                            - component: oh-button
                              config:
                                visible: =((items[props.item].state != 'NULL') && props.item && dayjs(items[props.item].state).hour() < 12)
                                style:
                                  --f7-button-bg-color: var(--f7-button-fill-bg-color,var(--f7-theme-color))
                                text: AM
                                fill: true
                                large: true
                            - component: oh-button
                              config:
                                visible: =((items[props.item].state != 'NULL') && props.item && dayjs(items[props.item].state).hour() >= 12)
                                style:
                                  --f7-button-bg-color: var(--f7-card-bg-color)
                                text: AM
                                fill: true
                                large: true
                                action: command
                                actionItem: =(props.item)
                                actionCommand: =(dayjs(items[props.item].state).add(-12, 'hour').format('YYYY-MM-DDTHH:mm:ss.ZZ'))
                - component: f7-row
                  config:
                    class:
                      - padding-top
                  slots:
                    default:
                      - component: f7-col
                        config:
                          style:
                            margin: auto
                        slots:
                          default:
                            - component: oh-button
                              config:
                                visible: =((items[props.item].state != 'NULL') && props.item && dayjs(items[props.item].state).hour() >= 12)
                                style:
                                  --f7-button-bg-color: var(--f7-button-fill-bg-color,var(--f7-theme-color))
                                text: PM
                                fill: true
                                large: true
                            - component: oh-button
                              config:
                                visible: =((items[props.item].state != 'NULL') && props.item && dayjs(items[props.item].state).hour() < 12)
                                style:
                                  --f7-button-bg-color: var(--f7-card-bg-color)
                                text: PM
                                fill: true
                                large: true
                                action: command
                                actionItem: =(props.item)
                                actionCommand: =(dayjs(items[props.item].state).add(12, 'hour').format('YYYY-MM-DDTHH:mm:ss.ZZ'))

7 Likes

Hi Gabor

Where can this be used? Imagine just in Main UI and HabPanel…?
Thanks!

Hi, which type of item can I control with the widget? I tried “number:time”, but it doesn’t work. The widget shows only “?:?”

Hi,
If you need a time input new opportunities have come up since this widget:

- component: oh-input
  config:
      style:
        margin-top: 6px
        font-size: large
        width: 200px
      item: =props.timeItem
      type: time
      sendButton: true
      dateFormat: HH:mm
      inputmode: text
      validate: true

This will render this:

ThermostatProfile

which can set a time value into a String item.

BR

this is, how it looks in my configuration:

this is the configuration:

An this is the item:

can u help me? What am i doing wrong

For me the widget works as it should, if the datetime item to be controlled already has a value. If the item is undefined, I get the same as you. For my use case this is a little unfortunate.

Thats how its supposed to be , problem is that it wont show time if item is NULL ie if no time/date stamp has been asigned to DateTime item.
Either create a rule to populate item or create a “manual” input card and use datetime for type .
I did it once , deleted the input card , setup mapdb persistence to carry over in reboot event and added To Today and Alarm Clock Rule to make morning tea :slight_smile:

edit : or edit the widget to your liking :wink:

I dint like this because it has “send button” and than hides actual timestamp input when sent (at least i couldnt make it show time without header/footer ) , while this widget shows its stamp and can easily be used in one in all another widget with popup action (great for mobile screen limited space) when to switch something on/off

    - component: oh-list-card
      config: {}
      slots:
        default:
          - component: oh-toggle-item
            config:
              action: popover
              actionModal: widget: timepicker
              actionModalConfig:
                item: YourTimeDateItemPopulatedWithTimepicker
                timeFormat: "24"
              icon: 
              iconUseState: true
              item: YourTimeControlledItem
              title: 

where you get your previous timestamp by widget default settings .

Hi,
The item you’re setting has to be String item. If you use DateTime the value disappears as you said.
BR

@Goran just a stupid question.

I’ve understood how to add a custom widget in developer tools.

And how to use the widget in a page.

But how and where can I insert this Code for an oh-list-card on a page?

- component: oh-list-card
      config: {}
      slots:
        default:
          - component: oh-toggle-item
            config:
              action: popover
              actionModal: widget: timepicker
              actionModalConfig:
                item: YourTimeDateItemPopulatedWithTimepicker
                timeFormat: "24"
              icon: 
              iconUseState: true
              item: YourTimeControlledItem
              title:

in other words, what do I have to do here? Where can I paste the code above?

Create a widget out of your code and give it a name in dev tools , then using that big + on UI page, in popup menu that opens , scroll down and you will find your premade widget .

Other option is again using big + on UI page …“create list card” , + , "add list item " , and then edit YAML and paste your code.

okay, i did it.

But then I’m struggeling here

Welcome to the club . It’s indentation problem , that’s how the code works .
Some lines must start at same column. First Config must be inline with component above and slots below . Default is indented few columns (usually hitting tab ). Second config is already in line with above component you dont have to move it…etc . Use space and backspace to organize it

As you indent it properly red underline will be removed .

I’m still fighting with this last one

component: oh-toggle-item
config:
  action: toggle
  actionModal: widget: your_time_widget
  actionModalConfig:
    item: tea
    timeFormat: "24"
  icon: your_icon
  iconUseState: true
  item: your_item_for_state_display
  title: 
  actionItem: your_item_for_toggle_action
slots: null

My code was from wigdets dev tool. Appears UI needs a bit diff code . Try instead this code with UI blocks . And also “create list card” , + , "add list item " ← instead choose “toogle list item” to get a switch inside .
Im still new to this and still experimenting.

Thank you very much for the Widget. I got it working with a DateTime Item as mentioned above. The goal would be to run a rule every day on the time adjusted with the widget. Usually this is done with a cron job. However, only constants can be used to my knowledge. Has anybody got that working?

HI,
I use a cron job that runs every minute and compares the current time with the item value set by the widget. If they match I execute the logic. This approach survives even OH restart compared to the future jobs…
BR

For that you have To Today