HA SwitchPlate HASPone: DIY In-Wall Touchscreen Home Assistant Controller

I hear you man, and venting is encouraged :smiley:

The current dev build has a lot of additional code around stabilizing WiFi and MQTT connections, better handling of failures, and to provide more information when failures cannot be handled automatically.

rc=0, according to the docs, is in fact supposed to mean a successful connection. However, what I’ve found is that it also the error that is reported when it cannot connect at all. That might be true in the following situations:

  • Using dns/mdns hostname and the name didn’t resolve
  • IP address is incorrect
  • Port is incorrect
  • Something about the negotiation w/ TLS didn’t work
  • The HASP ran out of memory in the middle of the connection process

The new code hopes to provide more feedback to the user if any of the above is happening.

Not sure if any of the above helps you out right now on the existing codebase (maybe check that list above and confirm everything is cool). Know that your concerns are being heard, and venting here helps me understand the problems you’re running into and to try and address them on the code side to make it less annoying when you run into it.

The frustrating part is sometimes it connects and other times it doesn’t using the same configuration. Can the dev code be used with the old yaml file configuration or do you have to use blueprints?

100% blueprints. Worse, the blueprints today are all being re-written for the eventual release (target: first week of March), so anything deployed on dev today will need to be re-deployed in a week or two.

Not a great answer, but that’s where things sit today.

That’s what I thought. Started working again on a new D1 mini (think the other one is flakey). Took awhile for the configuration page to finally respond, but I was finally able to get it configured and running. Watching your video with Dr Zzs on the new stuff.

1 Like

And again with another question. This time about the PCB. Can you tell me the spacing of the mounting holes? I know I can measure it, but always better to get the design spec if possible.

The holes are 36mm x 56mm on center. The PCB itself is 60x40, with the holes being inset by 2mm.

My kitchen is still in the process of being gutted and rebuilt but at least I found the perfect spot to install the HASP. Although I’ve read through much that I can find on it, I still have a few questions:

  1. The HASP has three pages which can be selected from the screen. How does one control which page is displayed by default?
  2. Can I program a page so that every Monday, for example, it displays a section that tells me whether the recycling pick-up is cardboard or plastic?
  3. Can I program it so that if I set my alarm, the page that shows is the keypad page for disarming but when the alarm is not set it shows something else?
  4. Can I program the HASP so that on a specific day of week the content of a page changes?

I guess, in general, how dynamic are the HASP pages and how difficult is it to program? Thanks.

Just got mine in off your Tindie store! I’ve edited the yamls under packages/plate01 and have some lights and a media player working just fine with volume and all, except the play/pause icon disappears and just shows as a white box (still plays and pauses though). Any idea what might be going on? Here is my media player yaml.

automation:
  # Initialize button text/font for media controls on start
  - alias: hasp_plate01_p8_MediaInit
    trigger:
      - platform: state
        entity_id: "binary_sensor.plate01_connected"
        to: "on"
      - platform: homeassistant
        event: start
    action:
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/p[8].b[6].font"
          payload: "4"
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/p[8].b[7].font"
          payload: "4"
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/p[8].b[8].font"
          payload: "4"
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/p[8].b[6].txt"
          payload: '"9"'
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/p[8].b[7].txt"
          payload: '";"'
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/p[8].b[8].txt"
          payload: '":"'

  # Play/Pause button action
  - alias: hasp_plate01_p8_MediaPauseButton7
    trigger:
      platform: mqtt
      topic: "hasp/plate01/state/p[8].b[7]"
      payload: "ON"
    action:
      service: media_player.media_play_pause
      entity_id: media_player.office

  # Prev Track button action
  - alias: hasp_plate01_p8_MediaPrevTrackButton6
    trigger:
      platform: mqtt
      topic: "hasp/plate01/state/p[8].b[6]"
      payload: "ON"
    action:
      service: media_player.media_previous_track
      entity_id: media_player.office

  # Next Track button action
  - alias: hasp_plate01_p8_MediaNextTrackButton8
    trigger:
      platform: mqtt
      topic: "hasp/plate01/state/p[8].b[8]"
      payload: "ON"
    action:
      service: media_player.media_next_track
      entity_id: media_player.office

  # Scale media information fonts to fit
  # 0 consolas 24 - 20 chars x 2 lines (wrapped)
  # 1 consolas 32 - 15 chars x 2 lines (wrapped)
  # 2 consolas 48 - 10 chars x 1 line
  # 3 consolas 80 - 6 chars x 1 line
  - alias: hasp_plate01_p8_MediaArtist
    trigger:
      - platform: state
        entity_id: sensor.media_player_artist
      - platform: state
        entity_id: "binary_sensor.plate01_connected"
        to: "on"
      - platform: homeassistant
        event: start
    action:
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/p[8].b[4].font"
          payload_template: >-
            {% if states('sensor.media_player_artist')|length <= 6 -%}3{% elif (states('sensor.media_player_artist')|length > 6) and (states('sensor.media_player_artist')|length <= 10) %}2{% elif (states('sensor.media_player_artist')|length > 10) and (states('sensor.media_player_artist')|length <= 15) %}1{% else %}0{%- endif %}
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/p[8].b[4].txt"
          payload_template: >-
            "{{ states('sensor.media_player_artist')|wordwrap(20, wrapstring="\\r") }}"

  - alias: hasp_plate01_p8_MediaTitle
    trigger:
      - platform: state
        entity_id: sensor.media_player_title
      - platform: state
        entity_id: "binary_sensor.plate01_connected"
        to: "on"
      - platform: homeassistant
        event: start
    action:
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/p[8].b[5].font"
          payload_template: >-
            {% if states('sensor.media_player_title')|length <= 6 -%}3{% elif (states('sensor.media_player_title')|length > 6) and (states('sensor.media_player_title')|length <= 10) %}2{% elif (states('sensor.media_player_title')|length > 10) and (states('sensor.media_player_title')|length <= 15) %}1{% else %}0{%- endif %}
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/p[8].b[5].txt"
          payload_template: >-
            "{{ states('sensor.media_player_title')|wordwrap(20, wrapstring="\\r") }}"

  - alias: hasp_plate01_p8_MediaPlayPause
    trigger:
      - platform: state
        entity_id: media_player.office
      - platform: state
        entity_id: "binary_sensor.plate01_connected"
        to: "on"
      - platform: homeassistant
        event: start
    action:
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/p[8].b[7].txt"
          payload_template: >-
            "{%- if is_state('media_player.media_player', 'playing') %};{% elif is_state('media_player.media_player', 'paused') %}4{% endif -%}"

  # Volume slider value published, apply published state
  - alias: hasp_plate01_p8_MediaVolSliderUpdateHass
    trigger:
      platform: mqtt
      topic: "hasp/plate01/state/p[8].b[9].val"
    action:
      - service: media_player.volume_set
        data_template:
          entity_id: media_player.office
          volume_level: "{{ (trigger.payload|int) / 100 }}"

  # Volume slider value changed by hass, update HASP
  - alias: hasp_plate01_p8_MediaVolSliderUpdateHASP
    trigger:
      - platform: state
        entity_id: sensor.media_player_volume
      - platform: state
        entity_id: "binary_sensor.plate01_connected"
        to: "on"
      - platform: homeassistant
        event: start
    action:
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/p[8].b[9].val"
          payload_template: "{{ (states('sensor.media_player_volume') | float * 100) | int }}"

##############################################################################
# Automations to set colors on HASP Page 8
  - alias: hasp_plate01_p8_ColorConfig_selectedforegroundcolor
    trigger:
      - platform: state
        entity_id: "binary_sensor.plate01_connected"
        to: "on"
      - platform: homeassistant
        event: start
      - platform: state
        entity_id: input_number.hasp_plate01_selectedforegroundcolor
    action:
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/json"
          payload_template: >-
            [{%- for i in range(4,9) -%}"p[8].b[{{i}}].pco={{ states('input_number.hasp_plate01_selectedforegroundcolor')|int }}"{% if not loop.last %},{% endif %}{%- endfor -%}]

  - alias: hasp_plate01_p8_ColorConfig_selectedbackgroundcolor
    trigger:
      - platform: state
        entity_id: "binary_sensor.plate01_connected"
        to: "on"
      - platform: homeassistant
        event: start
      - platform: state
        entity_id: input_number.hasp_plate01_selectedbackgroundcolor
    action:
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/json"
          payload_template: >-
            [{%- for i in range(4,9) -%}"p[8].b[{{i}}].bco={{ states('input_number.hasp_plate01_selectedbackgroundcolor')|int }}"{% if not loop.last %},{% endif %}{%- endfor -%}]

  - alias: hasp_plate01_p8_ColorConfig_unselectedforegroundcolor
    trigger:
      - platform: state
        entity_id: "binary_sensor.plate01_connected"
        to: "on"
      - platform: homeassistant
        event: start
      - platform: state
        entity_id: input_number.hasp_plate01_unselectedforegroundcolor
    action:
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/json"
          payload_template: >-
            [{%- for i in range(4,9) -%}"p[8].b[{{i}}].pco2={{ states('input_number.hasp_plate01_unselectedforegroundcolor')|int }}",{%- endfor -%}
            "p[8].b[9].pco={{ states('input_number.hasp_plate01_unselectedforegroundcolor')|int }}"]

  - alias: hasp_plate01_p8_ColorConfig_unselectedbackgroundcolor
    trigger:
      - platform: state
        entity_id: "binary_sensor.plate01_connected"
        to: "on"
      - platform: homeassistant
        event: start
      - platform: state
        entity_id: input_number.hasp_plate01_unselectedbackgroundcolor
    action:
      - service: mqtt.publish
        data:
          topic: "hasp/plate01/command/json"
          payload_template: >-
            [{%- for i in range(4,9) -%}"p[8].b[{{i}}].bco2={{ states('input_number.hasp_plate01_unselectedbackgroundcolor')|int }}",{%- endfor -%}
            "p[8].b[9].bco={{ states('input_number.hasp_plate01_unselectedbackgroundcolor')|int }}"]

You have the ability to utilize an automation like this to have the HASP go back to a default page after some period of inactivity. That page doesn’t need to be assigned to one of the three page buttons for most people, so it’s something like a 4th page that you can access for “free”.

The answer to all of these questions is “yes”! You can think of HASP as a dumb display device. When it powers on, it has nothing to display. Then, home assistant automations fire up and send text to appear on the screen on each page. So, for any set of events that home assistant can be triggered on (alarm is “armed”, day is “monday”, etc), you can create a home assistant automation to display new things on the screen.

With the current release this involves wading into a bunch of existing automations in YAML and modifying them to do the thing you want. How hard that is depends on your familiarity with YAML-based automation.

The next release will have much better integration with the Home Assistant GUI workflows, so you can use the in-browser automation editor to interact with the HASP. I think that will make several use cases a lot easier. Expect to see that released within two weeks, after the March release of Home Assistant.

This is the key bit of the automation that handles the play/pause button p[8].b[7]. We’re using the “wingdings” font (font 4) which is assigned in the first automation you pasted. Then, this automation is listening to state changes on media_player.office. The goal is to determine if the state is “playing”, in which case we should show a pause button (; in wingdings), otherwise show a play button (4 in wingdings).

I suspect your problem is that last line with the template. You’re triggering on state changes of media_player.office, but then the template is looking at media_player.media_player. Change media_player.media_player to media_player.office in both places it appears on that line and I bet you’ll be good to go!

I was watching your video with Dr Zzs and had a question about the new blueprints. If I want to a different layout, I’m guessing I would have to rework the core blueprint for the layout for available pages. Is this all that would be needed for the most part? Would most of the other blueprints be usable as is? Just trying to get an idea of how much work I have to look forward to.

The answer is a pretty big “depends”. If you retain the 3 page buttons as b1-b3 on each page, keep page 0 from the original project, and keep the sendme command on each page’s pre-init script, then core blueprint should work reasonably well. If you change the total number of pages, there’s a fair bit more work to do as the “11 pages” assumption is cooked into a lot of the code you see in that blueprint.

There are 4 blueprints that have “with icon” in the description, and placing that icon is a matter of setting x,y coords which probably won’t align with your new design. So, those 4 are probably out. There are some blueprints which are fixed to a specific page layout (alarm and media control), so if you modify those pages by changing the number of buttons then those blueprints might not work (just changing the size of the buttons won’t impact anything).

Most of the rest of the blueprints just deal with putting text on a button, and then responding when that button is pressed, and should work just fine on pretty much any design you cook up.

Hi Luma … has the PIR been implemented on the new Blueprint version? If yes how do we set up etc …

Prob should have a bit more info …

I have the new HASP with blueprint working fine … but want to switch off the backlight if no one nearby … I have tested the Motion Blueprint you created switching the backlight on and off based upon a Philips Hue motion detector and it works a treat …

Now I want to put a small PIR in the HASP enclusure and connect to D0 D1 like you suggested many moons ago in the full yanml version …

So in summary … how do we connect a PIR to D0 or D1 and get it working in blueprint version of HASP?
Cheers
Gary

I had completely forgotten about that! Let me take a look at this this weekend, I want to get the firmware released here soon, so I’ll start with some aspects of how the motion sensor is surfaced and then we can work on blueprints. Good catch @Wag5659, it’s not a feature I use so I didn’t really have it on my roadmap.

A question about HASP device names

I need to call the ball on a design concern that I could see going one of two ways, and both have merit. HASP is now making use of the Home Assistant device registry to tie all the various entities it relies on. Blueprints and automations will all point back to the device and the device view allows you to work with all the associated components in one place.

With that in place, I’m left with a functionality question:

What should happen when you rename your HASP?

We have two options:

HASP rename retains the same device

If you go to the HASP web page and rename the HASP, we can set it up so everything else just stays the same. Blueprints will carry over, lovelace view doesn’t need fiddlin, you just rename and now the HASP has a new name but everything else stays the same. Self-made automations (not using blueprints) may still need to be adjusted to the new name depending on how they were built.

HASP rename creates a new device

This is a little bit how HASP works today. If you rename your HASP, it becomes a new device. Your existing automations for the old name no longer work. I like this approach because it makes testing and development easier with a single device - you can take a HASP named “bedroom” and rename it to “dev” to work on some blueprints or whatever, and it will ignore all of the “bedroom” automations. When done, rename it back to “bedroom” and then it picks up where it left off.


Anyone have any thoughts one way or the other?

My view on it is that rename doesn’t create a new entity. Just like renaming a file. No new file is created. But based on your description of how it is currently working, I like that better. So, guess that doesn’t help. :slight_smile:

2 Likes

I’m kind of siding towards the “new name == new device” simply because there are edge cases where the “rename the device” thing won’t work smoothly, particularly if you’re creating your own automations outside of the blueprint flow (which people should totally do!).

My 2c, I change the names of my automations all the time because we don’t have a folders/tagging concept. If changing the name, changes the device then how do I “refactor” my automations so I can organize them? Maybe I am missing something?

1 Like

Another thing that I have been contemplating is management of plates. It’s one this thing to setup 1 or 2 devices but the effort to manage/develop becomes problematic especially because there is no way to organize automations into folders.

Spit balling here, I would like the Core automation/blueprint to represent the physical device and then the automations for each button relate to the Core automation. This would allow us to change the Core device to say a development device, do your development and then point it back at the device in the wall. The other thing I would like is to be able to create one “template” that would then apply to one or more devices. This would allow the development of a single app that would be deployed to multiple devices.

1 Like

Have you considered making the firmware a ESPHome component? The benefit’s as I see it are:

  1. You get to use other components. I already see people saying could you integrate x temp/humidity component. If this was implemented in ESPHome, people can put things together how they like.
  2. ESPHome has rudimentary management tools for doing centralized updates/development/logging etc.
  3. Templates and Packages could be created with “common” menu structures, scripts and configurations. This would allow us to create a single substitution or package that can be deployed across multiple devices.
  4. Development of packages/substitution could take be done on a development device and then deployed OTA. It’s slightly different than what you are doing right now but in the long run will be considerably more flexible.

There is a PR in the wings right now that has all the bit’s needed to accomplish what you are doing right now. I recognize that by using MQTT, this is not specific to HA which is the big downside of going with the ESPHome approach.

1 Like