Fully Kiosk Browser

you use HASSIO?

Nope. Just the official docker image. Why?

I am in hassio trying to figure how to run the script (newb here)

For those who are interested, I’ve created the initial version of a platform and component:

9 Likes

Hi, this is really cool, do you also have a way to close the more-info dialog via command?
Thanks JKW

This thread is awesome! Building upon these posts, I was able to get this working without using curl, control the tablet display using a light template (on, off, brightness). I can select which dashboard (appdaemon/hadashboard) to display with input select and templated rest_command

Video demo

packages/tablet_master_bedroom.yaml

homeassistant:
  customize:
    sensor.tablet_mbr_screen_brightness:
      hidden: true
    binary_sensor.tablet_mbr_screen_on:
      hidden: true
    input_number.tablet_mbr_temp_screen_brightness:
      hidden: true

light:
  - platform: template
    lights:
      tablet_mbr_screen:
        friendly_name: "Master Bedroom Tablet"
        level_template: "{{ states('sensor.tablet_mbr_screen_brightness') }}"
        value_template: "{{ is_state('binary_sensor.tablet_mbr_screen_on', 'on') }}"
        turn_on:
          service: rest_command.tablet_mbr_screen_on
        turn_off:
          service: rest_command.tablet_mbr_screen_off
        set_level:
          service: script.tablet_mbr_screen_value
          data_template:
            brightness: "{{ brightness }}"

rest_command:
  tablet_mbr_screen_on:
    url: 'http://KioskIP:2323/?cmd=screenOn&type=json&password=KisokPassword'
    method: post
  tablet_mbr_screen_off:
    url: 'http://KioskIP:2323/?cmd=screenOff&type=json&password=KisokPassword'
    method: post
  tablet_mbr_screen_value:
    url: 'http://KioskIP:2323/?cmd=setStringSetting&key=screenBrightness&value={{states("input_number.tablet_mbr_temp_screen_brightness") | int }}&type=json&password=KisokPassword'
    method: post

  tablet_mbr_url_bed:
    url: 'http://KioskIP:2323/?cmd=loadURL&url=http://DashboardIP/{{ states("input_select.tablet_mbr_dash_select") }}&type=json&password=KisokPassword'
    method: post

input_select:
  tablet_mbr_dash_select:
    name: Dash Display
    icon: mdi:tablet
    initial: "-"
    options:
    - "-"
    - bedroom
    - laundry
    - doorbell
    - fire_menu
    - den

input_number:
  tablet_mbr_temp_screen_brightness:
    name: tablet_mbr_temp_screen_brightness
    initial: 128
    min: 0
    max: 255
    step: 1

sensor:
  - platform: rest
    name: tablet_mbr_battery_level
    json_attributes:
      - batteryLevel
    resource: http://KioskIP:2323/?cmd=deviceInfo&type=json&password=KisokPassword
    value_template: '{{ value_json.batteryLevel }}'
    unit_of_measurement: '%'

  - platform: rest
    name: tablet_mbr_screen_brightness
    json_attributes:
      - screenBrightness
    resource: http://KioskIP:2323/?cmd=deviceInfo&type=json&password=KisokPassword
    value_template: '{{ value_json.screenBrightness }}'

binary_sensor:
  - platform: rest
    name: tablet_mbr_screen_on
    json_attributes:
      - isScreenOn
    resource: http://KioskIP:2323/?cmd=deviceInfo&type=json&password=KisokPassword
    value_template: '{{ value_json.isScreenOn }}'

  - platform: rest
    name: tablet_mbr_plugged_in
    json_attributes:
      - plugged
    resource: http://KioskIP:2323/?cmd=deviceInfo&type=json&password=KisokPassword
    value_template: '{{ value_json.plugged }}'

media_player:
  - platform: mpd
    name: mbr_tablet_mpd
    host: KioskIP

automation:
  - id: tablet_mbr_change_url
    alias: Tablet Master Bedroom Change URL
    trigger:
      platform: state
      entity_id: input_select.tablet_mbr_dash_select
    condition:
      condition: template
      value_template: '{{ not is_state("input_select.tablet_mbr_dash_select", "-") }}'
    action:
    - service: rest_command.tablet_mbr_url_bed
      entity_id: rest_command.tablet_mbr_url_bed
    - service: input_select.select_option
      data:
        entity_id: input_select.tablet_mbr_dash_select
        option: "-"

  - id: tablet_mbr_display_doorbell
    alias: Display in Master Bedroom when doorbell activated
    trigger:
      platform: state
      entity_id: binary_sensor.door_bell
      to: 'on'
    action:
    - service: input_select.select_option
      data:
        entity_id: input_select.tablet_mbr_dash_select
        option: "doorbell"

script:
  tablet_mbr_screen_value:
    sequence:
      - service: input_number.set_value
        data_template:
          entity_id: input_number.tablet_mbr_temp_screen_brightness
          value: "{{ brightness }}"
      - service: rest_command.tablet_mbr_screen_value

group:
  tablet_mbr:
    name: Tablet Master Bedroom
    control: hidden
    entities:
      - light.tablet_mbr_screen
      - input_select.tablet_mbr_dash_select
      - sensor.tablet_mbr_battery_level
      - binary_sensor.tablet_mbr_plugged_in
13 Likes

I put a Sonoff in it

Wrote this audomation
if <30 turn it on >99 turn it off

- action:
  - data:
      entity_id: switch.kitchen_tablet
    service: switch.turn_off
  alias: Kitchen Charger Off
  condition:
  - condition: state
    entity_id: switch.kitchen_tablet
    state: 'ON'
  id: '1518744680799'
  trigger:
  - above: '99'
    entity_id: sensor.display_kitchen_tablet_battery
    platform: numeric_state
- action:
  - data:
      entity_id: switch.kitchen_tablet
    service: switch.turn_on
  alias: Kitchen Charger On
  condition: []
  id: '1520537778107'
  trigger:
  - below: '30'
    entity_id: sensor.display_kitchen_tablet_battery
    platform: numeric_state

Do like the way you passing difference dashboard to the tablet :beer: Now Thats thing out side the Square

2 Likes

Aw that nice, right now I’m passing them via automation but all the tablets change at the same time on the same dashboard

I like that post! Gonna read it deeper tonight :slight_smile: tks

You need to specify null as entityId.

1 Like

sound like you have all your tablet point to the same “input_select”

Fantastic, thanks

Anyone having issues with fully on a fire tab no longer dimming the screen. I think the last update has broken it for me.

The screen saver still starts but the screen does not dim.

1 Like

I’m using the below as a value template for a screensaver activation switch. (Thanks @RagingComputer & @xstrex for examples). It triggers instantly but lags in reflecting its current state. Anybody know of a better way of doing it?

Sensor

- platform: rest
  name: master_bedroom_panel_screensaver_state
  json_attributes:
- currentFragment
  resource: !secret master_bedroom_panel_rest
  value_template: '{{ value_json.currentFragment }}'

Switch

  - platform: template
    switches:
      master_bedroom_panel_screen:
        value_template: "{{ is_state('sensor.master_bedroom_panel_screensaver_state', '') }}"
        turn_on:
          service: rest_command.master_bedroom_panel_screen_on
        turn_off:
          service: rest_command.master_bedroom_panel_screen_off

Good day, has anyone managed to pull the motion sensor event using the javascript interface?
https://www.ozerov.de/fully-kiosk-browser/

TLDR: there is a dedicated fire os version of fully now. https://www.ozerov.de/fully-kiosk-browser/#download-box

I was amazed by the fully browser and decided to buy a dedicated tablet as wall panel.
The fire 8.0 was very cheap these days and I gave it a go. It turned out that most functions didn’t work on fire os as they did on pure Android.
So I asked the developer if he can improve fire os support. It turned out that he didn’t have a fire os device but that we both live in Germany.
So I sent him my tablet about a month ago.
He returned it yesterday and published a link to a improved fire os version that works significantly better on my tablet.
Thought I let you know, as this is a dedicated APK that will never make it into the Playstore update. https://www.ozerov.de/fully-kiosk-browser/#download-box

6 Likes

Whats the best tablet and wallmount to get for this usage ?

This is the gear I ended up using for mine.

1 Like

Maybe he’d be willing to put it in the Amazon store? Fire tablets go on sale quite frequently but I’ve held off on buying one because I don’t want to mess around with a browser that doesn’t quite work. I also don’t want to side-load apps, it’s just too easy to forget about updates or you end up getting malware installed.

Plus, I’d even be willing to pay a buck or two if it helps out the developer.

Great app.

I can’t get sensor state as a TTS from my tablet. Here is my two switch:

  - platform: command_line
    switches:
      hosgeldiniz:
        command_on: curl -X POST "http://192.168.86.135:2323/?cmd=textToSpeech&text=Belek+evine+hoş+geldiniz&password=1234"
        friendly_name: Hoşgeldin Mesajı

  - platform: command_line
    switches:
      isiyisoyle:
        command_on: curl -X POST "http://192.168.86.135:2323/?cmd=textToSpeech&text={{ states('sensor.broadlink_sensor_temperature') }}&password=1234"
        friendly_name: Belek Isısı

First one is working well. But second one is getting error on Hass.io logs:

Command failed: curl -X POST "http://192.168.86.135:2323/?cmd=textToSpeech&text={{ states('sensor.broadlink_sensor_temperature') }}&password=1234"

Any advice?

Thank you.

This is the JavaScript motion-detection code I use in my fully documented setup, set inside variables.yaml of my active theme. It posts to (and auto-creates) a binary sensor, first by setting it to false then setting it to true. Otherwise a state change would not occur nor be recorded if you only send true all the time.

body_includes:
 - |
    <script>
    /**
     * Send motion detection event to Home Assistant API
     *
     * It turns off the sensor before turning it on again, to make sure that
     * any change is registered. A bit dirty, but it works!
     */
    if (typeof fully != 'undefined') {
      function reportKioskMotion() {
        var xhttp = new XMLHttpRequest();
        xhttp.open('POST', 'http://hassio.local:8123/api/states/binary_sensor.kiosk_motion', false);
        xhttp.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
        xhttp.send(JSON.stringify({
          'state': 'off',
          'attributes': {
            'friendly_name': 'Kiosk Motion'
          }
        }));
        xhttp.open('POST', 'http://hassio.local:8123/api/states/binary_sensor.kiosk_motion', false);
        xhttp.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
        xhttp.send(JSON.stringify({
          'state': 'on',
          'attributes': {
            'friendly_name': 'Kiosk Motion'
          }
        }));
      }
      fully.bind('onMotion', 'reportKioskMotion();');
    }
    </script>

The binary sensor is then interpreted by a template sensor here to give it a 3-minute delay based on the last state change as the tablet only reports motion, not a lack thereof.

#
# Fully Kiosk Browser motion sensor
#
# The Fully app can only send "onMotion" events as it is stateless. Instead of
# coming up with a complicated yet fragile Javascript state-handler that would
# calculate the last time any motion was detected and then send an "off" signal
# and would survive across URL changes (but would fail if the Android device is
# offline or if the app is forced-closed), an extra server-side sensor is much
# sturdier, if a bit less accurate. It should turn off within 3-4 minutes after
# the last change.
#
# The "binary_sensor.kiosk_motion" is dynamically created by the first
# "onMotion" event call for a custom Javascript declared in all dashboards using
# the "Modern" theme. Two API calls are done sequentially, one to turn off the
# binary sensor, then other to turn it right  back on. This way the sensor state
# is guaranteed to change, and the  "last_changed" and "last_updated" timestamps
# along with it.
#
# @see /appdaemon/custom_css/modern/variables.yaml
#
- platform: template
  sensors:
    kiosk_motion_auto:
      friendly_name: Kiosk Motion
      device_class: motion
      entity_id:
        - sensor.time
        - binary_sensor.kiosk_motion
      delay_off:
        seconds: 5
      value_template: >-
        {{ is_state('binary_sensor.kiosk_motion', 'on')
           and (180 >= as_timestamp(now()) - as_timestamp(states.binary_sensor.kiosk_motion.last_changed)) }}

Finally, I use this kiosk motion detection info to update a state card, giving me this:

Security Status

This setup works well for me! :slight_smile:

6 Likes