Does floorplan have the ability to detect a long press?

Is it possible to long press something in floorplan and have it do something. for instance I want to give the user more control over lets say a fan. So you’d press the fan to turn it on or off, or you long press on the fan to have a menu come up with more control, like a high setting, medium and low setting.

is that possible?

You can certainly toggle a switch on and off, for example

    - name: Panic Button
      entities:
        - switch.sirenstrobe_switch
      states:
         - state: 'on'
           class: 'alarm-on'
         - state: 'off'
           class: 'alarm-off'
      action:
        domain: homeassistant
        service: toggle       

and if you go to the “share your floorplan” you’ll find some very creative things people have done to make it more functional.

thanks for the info! I’m browsing it now.
I for some reason just realized i can just use jquery to do a long press in floorplan on an element.

Were you able to get anything working with long presses in a floorplan? If so, could you share any code changes you needed to make?

Not yet I’ll be figuring it out here in the next 2 weeks or so, I’m about at that point.

In case it helps I was able to get something working. It isn’t very eloquent but it’s doing the job while I work on other things.

I added https://github.com/untill/jquery.longclick/blob/master/plugin/jquery.longclick-1.0.js to my lib/ directory and changed the .on() events to include touch and tap for tablets

jquery.longclick-1.0.js

( function( $) {

    // -- variables --
    var  defaults = {
      NS: 'jquery.longclick-',
      delay: 400
    };
  
  
    // -- function --
    $.fn.mayTriggerLongClicks = function( options) {
      // alter settings according to options
      var settings = $.extend( defaults, options);
      // define long click based on mousedown and mouseup
      var timer;
      var haveLongClick;
      return $( this).on( 'mousedown tapstart touchstart', function() {
        haveLongClick = false;
        timer = setTimeout( function( elm) {
      haveLongClick = true;
      $( elm).trigger( 'longClick');
        }, settings.delay, this);
      } ).on( 'mouseup tapend touchend', function() {
        clearTimeout( timer);
      } ).on( 'click tap touch', function( evt) {
        if( haveLongClick)
      evt.stopImmediatePropagation();
      } );
    }  // $.fn.mayTriggerLongClicks
    
  } )( jQuery);

ha-floorplan.html
added 1 line near the top

<script src="lib/jquery.longclick-1.0.js"></script>

commented out 1 line in loadFloorPlan(callback)

$(svgElement).on('click', this.instance.onElementClick.bind({ instance: this.instance, elementId: elementId }));

added 1 line under it

$(svgElement).mayTriggerLongClicks().on('longClick', this.instance.onElementClick.bind({ instance: this.instance, elementId: elementId }));

that seems to work for the time being. I have long presses toggling on layers that contain other entities and clicks working as normal. If you come up with a better solution please let me know

2 Likes

Thanks to the help of tknp, I got this working, and I decided I wanted the option to short press or long press an element, so I made some further modifications to the ha-floorplan.html file. Now if you use longs: instead of elements:, you can create two different actions- one for short press and one for long press. If anyone stumbles across this post looking for a simple way to implement this, you can check out my github branch of the ha-floorplan here: FloorplanWithLongPress

There is information in the “toggling visibility of entities” section of the README, and you should be able to just copy and paste the ha-floorplan.html and the jquery.longclick-1.0.js

And thanks again tknp!

2 Likes

That is awesome :slight_smile:
Can you please tell me what changes you did to the ha-floorplan.html file?
I have some other implementations in that file, so would be easier just to copy in the changes.

Edit: just forget it, saw the changes you have made in the history :slight_smile:

1 Like

Glad you found that! Let me know if you run into any bumps setting it up!

Is it possible to toggle anything else than elements? What I really want, is to have a long-click show the pop-up menu of the entity/group, and short click to toggle the entity on/off.

At the moment it only allows elements to be toggled- so for my floorplan I have short clicks toggle and then I made my own popup with brightness, separate lights, info, etc that triggers on a long click. I can look into adding support for entities as well though!

1 Like

Yes, it is a good feature, good work! But you seem to know html pretty well, so if you could figure it out to support entities as well, so we could get the pop-up menu, that would be awesome! I think others than me also would like that feature :blush: What I use now is one element to toggle a script for on/off, and one element for the more-info, which is kind of annoying. That feature would have been really nice for lights that can be dimmed, hue lights, thermostats etc.

Well done everyone. This means we are finally closer to dimmer support.

Does anybody have an idea, how to add this to lovelace-floorplan? I tried, but wasn’t successful.
I want to switch e.g. a light with short press and open more-info with long press (to dim, color, …).

I am also interested. Thanks

Ok so I kinda made it work (just a few seconds ago - so I haven’t gone over all the case scenarios). My aim was to turn on and off the lights with a short click and open MoreInfo with a long press.

The way I did it was to modify floorplan-card.js to load the jquery longclick script and modify floorplan.js to include the modifications to the behaviour.

So floorplan-js, I had to modify the loading of scripts using promises since trying to load the jquery-longclick.js WITH jQuery would throw an error. I did this by adding a ‘then’ deferred function to load the longclick script after the first 3 main scripts are loaded.

loadScripts() {
    this.isScriptsLoading = true;

    const promises = [];

    promises.push(this.loadScript(`/local/floorplan/lib/floorplan.js?v=${this.version}`, true));
    promises.push(this.loadScript('/local/floorplan/lib/yaml.min.js', true));
    promises.push(this.loadScript('/local/floorplan/lib/jquery-3.4.1.min.js', true));

    return Promise.all(promises)
      .then(() => { this.loadScript('/local/floorplan/lib/jquery.longclick.js', true); })
      .then(() => {
        this.isScriptsLoading = false;
        this.isScriptsLoaded = true;
      });
  }

I then modified the function initEntityRule(rule, svg, svgElements) and replace the line

$svgElement.off('click').on('click', this.onEntityClick.bind({ instance: this, svgElementInfo: svgElementInfo, entityId: entityId, rule: ruleInfo.rule }));

with

$svgElement
  .mayTriggerLongClicks({ delay: 600 })
  .on('longClick', this.onEntityLongClick.bind({ instance: this, entityId: entityId }))
  .on('click', this.onEntityClick.bind({ instance: this, svgElementInfo: svgElementInfo, entityId: entityId, rule: ruleInfo.rule })); 

The above new code references a new function which I added in the eventHandlers section of the script just above onEntityClick(e) {. This is the function:

    onEntityLongClick(e) {
      e.stopPropagation();
      this.instance.openMoreInfo(this.entityId);
    }

Flush browser cache and reload. Clicking on an element will call the action defined for that element, while long press will open more-info for the entity attached to that element. Just for reference (i’m using lovelace_gen), this is the yaml I’m using for the lights:

      - action:
          service: homeassistant.toggle
        element: {{ lightname }}
        entity: {{ lightname }}
        class_template: 'bulb state-${entity.state} brightness-${Math.ceil(entity.attributes.brightness / 51)}'
        more_info: false

Disclaimer: I’m a backend architect and developer by profession, but my frontend skills are poor; so I’m 100% certain that there’s a better way of doing this. Feel free to leave constructive criticism.