Share your HADashboard setups

I tried this,

hallway_motion_motion_sensor:
    widget_type: sensor
    title: Hallway Motion
    icon_on: mdi-eye-outline
    icon_off: mdi-eye-off-outline
    entity: sensor.hallway_motion_motion_sensor
    sub_entity: sensor.hallway_motion_motion_sensor.last_changed

and as you said, I get the on/off, but still no updated time :frowning:

hallway%20motion

unfortunately, I this time, that is beyond my skill level, but I will have a look when I get a bit more time and see if I can figure it out.

i just tried it out myself.
bad news, last_changed is no attribute :frowning:

this works:

widget_name:
    widget_type: sensor
    entity: switch.anyswitch
    sub_entity: switch.anyswitch
    entity_to_sub_entity_attribute: friendly_name

so i am back to my earlier posting. you need to create a template sensor for that in HA.
something like:

    sensor:
      your_name:
        friendly_name: anything
        value_template: '{{states.input_boolean.something.last_changed}}'
        entity_id:
          - input_boolean.something

replace the input_boolean with any entity and you might want to modify the way the datetime will be displayed.
then you can use

widget_name:
    widget_type: sensor
    entity: input_boolean.something
    sub_entity: sensor.your_name
1 Like

Hereā€™s one of the pages from my HAdashboard. The row along the bottom are navigation tabs, and with help from @ReneTode and @tjntomas I managed to get them to indicate which page is currently active.

Still much more I want to do, but this is a sample

1 Like

i just had a little time to get into this because it is not that complicated.
to get the time from the last updated below a switch, input_boolean or binary sensor do the following:

  1. in the config dir from appdaemon (where appdaemon.yaml is) create a subdir called custom_widgets (if it doesnt exists already)
  2. in that dir create a subdir called baseswitch
  3. in that dir place the files that you can download or copy here: https://github.com/home-assistant/appdaemon/tree/dev/appdaemon/widgets/baseswitch
  4. edit the js file and replace it with this code:
function baseswitch(widget_id, url, skin, parameters)
{
    // Will be using "self" throughout for the various flavors of "this"
    // so for consistency ...
    
    self = this;
    
    // Initialization
    
    self.widget_id = widget_id;
    
    // Store on brightness or fallback to a default
        
    // Parameters may come in useful later on
    
    self.parameters = parameters;
    
    // Toggle needs to be referenced from self for the timeout function
    
    self.toggle = toggle;
    
    // Define callbacks for on click events
    // They are defined as functions below and can be any name as long as the
    // 'self'variables match the callbacks array below
    // We need to add them into the object for later reference
   
    self.OnButtonClick = OnButtonClick;
    
    if ("enable" in self.parameters && self.parameters.enable == 1)
    {
        var callbacks =
            [
                {"selector": '#' + widget_id + ' > span', "action": "click", "callback": self.OnButtonClick},
            ]
    }            
    else
    {
        var callbacks = []
    }        
    // Define callbacks for entities - this model allows a widget to monitor multiple entities if needed
    // Initial will be called when the dashboard loads and state has been gathered for the entity
    // Update will be called every time an update occurs for that entity
     
    self.OnStateAvailable = OnStateAvailable
    self.OnStateUpdate = OnStateUpdate
    
    var monitored_entities = 
        [
            {"entity": parameters.entity, "initial": self.OnStateAvailable, "update": self.OnStateUpdate},
        ];
    
    // Finally, call the parent constructor to get things moving
    
    WidgetBase.call(self, widget_id, url, skin, parameters, monitored_entities, callbacks)  

    // Function Definitions
    
    // The StateAvailable function will be called when 
    // self.state[<entity>] has valid information for the requested entity
    // state is the initial state
    
    function OnStateAvailable(self, state)
    {        
        self.state = state.state;
        self.full_state = state
        set_view(self, self.state)
    }
    
    // The OnStateUpdate function will be called when the specific entity
    // receives a state update - it's new values will be available
    // in self.state[<entity>] and returned in the state parameter
    
    function OnStateUpdate(self, state)
    {
        if (!("ignore_state" in self.parameters) || self.parameters.ignore_state == 0)
        {
            self.state = state.state;
            self.full_state = state
            set_view(self, self.state)
        }
    }
    
    function OnButtonClick(self)
    {
        if (self.state == self.parameters.state_active)
        {
            args = self.parameters.post_service_inactive
        }
        else
        {
            args = self.parameters.post_service_active
        }
        self.call_service(self, args);
        toggle(self);
        if ("momentary" in self.parameters)
        {
            setTimeout(function() { self.toggle(self) }, self.parameters["momentary"])
        }
    }
    
    function toggle(self)
    {
        if (self.state == self.parameters.state_active)
        {
            self.state = self.parameters.state_inactive;
        }
        else
        {
            self.state = self.parameters.state_active;
        }
        set_view(self, self.state)
    }
    
    // Set view is a helper function to set all aspects of the widget to its 
    // current state - it is called by widget code when an update occurs
    // or some other event that requires a an update of the view
    
    function set_view(self, state, level)
    {
        if (state == self.parameters.state_active || ("active_map" in self.parameters && self.parameters.active_map.includes(state)))
        {
            self.set_icon(self, "icon", self.icons.icon_on);
            self.set_field(self, "icon_style", self.css.icon_style_active)
        }
        else
        {
            self.set_icon(self, "icon", self.icons.icon_off);
            self.set_field(self, "icon_style", self.css.icon_style_inactive)
        }
        if ("state_text" in self.parameters && self.parameters.state_text == 1)
        {
            self.set_field(self, "state_text", self.map_state(self, state))
        }
        if ("state_text" in self.parameters && self.parameters.state_text == 2)
        {
            datetimestr = self.full_state["last_changed"]
            timestr = datetimestr.substr(11, 8)
            self.set_field(self, "state_text", self.map_state(self,timestr))
        }
    }
}

now you can use the option

    state_text: 2

in the binary sensor widget and in the switch and input_boolean widgets.

1 Like

Thank you @ReneTode that works awesomely. Although it leads me to another problem now, its seems all my times are 1 hour behind. And its in HA that way,

updated%20time

its currently 1:54am now, and just restarted HA 9 minutes ago, when I checked my system time,

 pi@hassbian:~ $ date
Thu 21 Jun 01:46:01 BST 2018

Its late, iā€™ll look into it tomorrow, and see if there is anyway to get state map: 1 displayed as well at the same time.

I just notice too that in the Custom_ui in HA is shows it in x minutes since last trigger. Would it be easy to change the code / modify the code so that it did the same in the dashboard ?

Sorry for being a pain.

off course it is possible, but i am not experienced enough in javascript to tell you how without starting to google.
its this line:

timestr = datetimestr.substr(11, 8)

that takes the time out of the datetime.
feel free to start googling for ā€œjavascript minutes gone by since datetimeā€

you can try out as much as you like and when it doesnt work then just set the original line back.

1 Like

thank you so much!

Thank you @ReneTode Iā€™ll have a play around when I get a chance and see if I can work it out.

hey cee, give a try on that in the javascript

    if ("state_text" in self.parameters && self.parameters.state_text == 2)
    {
        datetimestr = self.full_state["last_changed"]
		time = new Date(datetimestr).toLocaleTimeString();
		timestr = "since:" + time;		
		
        self.set_field(self, "state_text", self.map_state(self,timestr))
    }
2 Likes

Thank you for giving this a try @Stiff04

I have just got back from 4 days of work, so super tired, I just cut and paste the lines of code over the other, but now I am getting this instead,

new%20motion%20trigger

Not sure if I messed up something somewhere. Got to see what I can, but as I said, super tired, so will probably just go to bed and try again in the morning.

Hey Cee

due to perfomrmance Issues I cant recommend to calculate back in running time.
Additionally you will have to refresh the dashboard to recalculate the time.

But here you will find how to calculate the time difference

1 Like

thank you @Stiff04 I will see if I can make head or tail of it, unfortunately programming was never my strong point, always a hardware guy instead.

I am guessing the way the the custom UI in HA does it, is different to the way AD would do it ?

yeah its different in HA because thats not javascript :wink:

what would you EXACTLY like to see?

1 Like

Sorry maybe I didnā€™t explain it properly, in HA i have this ā€œx time since last triggeredā€

time%20since%20last

So the 2 minutes ago, 10 hours ago, etc.

Was wondering if it was possible to have the same thing on the sensorā€™s on HADashboard, so it would look something like this really quick photoshop I just did,

Many thanks in advance @ReneTode

that would be hard to do, because you have to update the widget based on time and now its only updated if something in the entity has changed.

that would need an invisible clock widget inside each widget or some general javascript that would compare the stuf (in theory possible inside a custom skin)

1 Like

Well if you are having trouble thinking of a solution, then I have no chance :smiley: It wouldnā€™t necessarily need to be updated constantly, as you could have the dashboard on a reload through fully kiosk, so it would just updated every 10 minutes or so, I just think it looks nicer on the eye that way, rather than just a time.

if you have the idea that the reload moment would be sufficient.
but then it would be bad to have seconds ago and minutes ago, because if it shows 2 minutes ago and it keeps that for 10 minutes it will be highly inaccurate.

i would then suggest like
< 1 hour
1 hour
2 hours
3 hours
23 hours
1 day
2 days

i am not that experienced in JS at all as i like to be.
the function would be something like:

    if ("state_text" in self.parameters && self.parameters.state_text == 2)
    {
        datetimestr = self.full_state["last_changed"]
		time = new Date(datetimestr);
        now = new Date()
        difference = now - time
        if (difference<3600){
           str = "< 1 hour"
        }
        elif (difference < (3600 * 24){
           calculate the hour from difference
           str = hour + " hours"
        }    
		
        self.set_field(self, "state_text", self.map_state(self,str))
    }

and for days the same. maybe that @Stiff04 can come up with something more complete in a short time.

1 Like

Thanks , @jpez for sharing this , you Rock!!!

Hey all I would like to ask you for a new little support :slight_smile:

Iā€™m looking for a widget like the climate control with + and - (slider does not work good on my wall mounted tablet) to control the lights bright of my rf controlled lights. So Iā€™m looking for an Option to switch on and off the light and controll brightness with +&- in a single widget :slight_smile: What do you think?

second I like to have an enhanced cover widget with the three controlls (Up, Stop, Down)

@ReneTode do you have an Idea?

best regards