TileBoard - New dashboard for Homeassistant

Yes, I’ve done that… :slight_smile:
Thanks.

I use Fully on a Nexus 9. I’m not getting flickering, but I do have an issue that crops up several times a day. Sometimes when the screen comes up due to approaching the tablet, the layout is all messed up (see below), refreshing/reloading fixes it. Any ideas?

ISSUE:

NORMAL:

Here’s my config:

var groupWidth = 12; // count of tiles horizontally
var tileMargin = 3; // px
var groupMargin = 0; // px

var tileSize = getTileSize(groupWidth, tileMargin, groupMargin);

function getTileSize (groupWidth, tileMargin, groupMargin) {
   var width = window.innerWidth;
   width -= groupMargin * 2 + tileMargin * (groupWidth - 1);
   return +(width / groupWidth).toFixed(1);
}

var CONFIG = {
   customTheme: CUSTOM_THEMES.COMPACT, //CUSTOM_THEMES.MOBILE, //null, //CUSTOM_THEMES.TRANSPARENT
   transition: TRANSITIONS.SIMPLE, //ANIMATED_GPU,
   tileSize: tileSize,
   tileMargin: 2,
   timeFormat: 12,
   groupMarginCss: '2px',
   serverUrl: "[REDACTED]",
   wsUrl: "[REDACTED]",
   authToken: "[REDACTED]",
  //  passwordType: PASSWORD_TYPES.PROMPT_AND_SAVE,
   // password: null,
   //googleApiKey: "XXXXXXXXXX", // Required if you are using Google Maps for device tracker
   events: [],
   menuPosition: MENU_POSITIONS.BOTTOM, // or BOTTOM
   hideScrollbar: false, // horizontal scrollbar
   groupsAlign: GROUP_ALIGNS.HORIZONTALLY,
// DEFAULT HEADER \\
   header: {
      styles: {
         padding: '10px 10px 0',
         fontSize: '16px'
      },
      left: [
         {
            type: HEADER_ITEMS.DATETIME,
            dateFormat: 'EEEE, LLLL dd', //https://docs.angularjs.org/api/ng/filter/date
            styles: {
               margin: '0'
            }
         }
      ],
      right: []
   },
   pages: [
      {
// PAGE ONE \\
         title: 'Main page',
         bg: 'images/bg3.jpg',
         icon: 'mdi-home-outline', // home icon
         groups: [
            {
// COLUMN 1 \\
               title: '',
               // width: 4,
               height:7,
               items: [
// WEATHER \\
                 {
                    position: [0, 0],
                    width: 4,
                    height: 2,
                    classes: ['-compact'],
                    type: TYPES.WEATHER,
                    id: 'group.weather',
                    title: '',
                    state: false,
                    customStyles: {'background-color':'transparent','overflow':'hidden'},
                    fields: {
                      icon: '&sensor.dark_sky_icon.state',
                      iconMap: {
                         'clear-day': 'clear',
                         'clear-night': 'nt-clear',
                         'cloudy': 'cloudy',
                         'rain': 'rain',
                         'sleet': 'sleet',
                         'snow': 'snow',
                         'wind': 'hazy',
                         'fog': 'fog',
                         'partly-cloudy-day': 'partlycloudy',
                         'partly-cloudy-night': 'nt-partlycloudy'
                      },
                      temperature: '&sensor.dark_sky_temperature.state',
                      temperatureUnit: '&sensor.dark_sky_temperature.attributes.unit_of_measurement',

                      list: [
                         // summary
                         '&sensor.dark_sky_summary.state',
                         // apparent temp
                         'Feels like '
                                     + '&sensor.dark_sky_apparent_temperature.state'
                                     + '&sensor.dark_sky_apparent_temperature.attributes.unit_of_measurement',
                        // rain chance
                         '&sensor.dark_sky_precip_probability.state'
                            + '&sensor.dark_sky_precip_probability.attributes.unit_of_measurement'
                            + ' chance of rain',

                         '   ',
                        // Hi/lo
                         'Hi '
                            + '&sensor.dark_sky_daytime_high_temperature.state'
                            + '&sensor.dark_sky_daytime_high_temperature.attributes.unit_of_measurement'
                            + ' / Lo '
                            + '&sensor.dark_sky_daytime_high_temperature.state'
                            + '&sensor.dark_sky_daytime_high_temperature.attributes.unit_of_measurement',
                      ]
                    },
                 },
// CAM FRONT \\
                  {
                     position: [0, 2.5],
                     id: {},
                     title: '',
                     type: TYPES.CAMERA,
                     bgSize: 'cover',
                     width: 4,
                     height: 2,
                     state: false,
                     filter: function(url) {return "[REDACTED]"},
                     fullscreen: {
                       type: TYPES.CAMERA,
                       bgSize: 'contain',
                       // refresh: 15000,
                       filter: function(url) {return "[REDACTED]"},
                   },
                     refresh: 1000,
                  },
// CAM REAR \\
                  {
                     position: [0, 4.5],
                     id: {},
                     title: '',
                     type: TYPES.CAMERA,
                     bgSize: 'cover',
                     width: 4,
                     height: 2,
                     state: false,
                     filter: function(url) {return "[REDACTED]"},
                     fullscreen: {
                       type: TYPES.CAMERA,
                       bgSize: 'contain',
                       // refresh: 15000,
                       filter: function(url) {return "[REDACTED]"},
                   },
                     refresh: 1000,
                  },
// ALARM | DOORS \\
                  {
                   position: [1, 6.5],
                   width: 2,
                   height: 1,
                   type: TYPES.ALARM,
                   title: 'Alarm',
                   id: 'alarm_control_panel.adt_pulse',
                   icons: {
                      disarmed: 'mdi-bell-off',
                      pending: 'mdi-bell',
                      armed_home: 'mdi-bell-plus',
                      armed_away: 'mdi-bell',
                      // triggered: 'mdi-bell-ring'
                   },
                   states: {
                      disarmed: 'Disarmed',
                      pending: 'Pending',
                      armed_home: 'Armed home',
                      armed_away: 'Armed away',
                      // triggered: 'Triggered'
                   },
                   classes: [CLASS_MICRO],
                   customStyles: {'background-color':'#a3495f'},
                  },
                  {
                     position: [0, 6.5],
                     type: TYPES.SENSOR_ICON,
                     title: 'Entry',
                     id: 'binary_sensor.z1_entry_doors',
                     states: {
                       on: "open",
                       off: "closed"
                     },
                     icons: {
                        on: 'mdi-door-open',
                        off: 'mdi-door-closed'
                     },
                     customStyles: {'background-color':'#7a4e7f'},
                     classes: [CLASS_MICRO,"-mysmall-entity"],
                  },
                  {
                     position: [3, 6.5],
                     type: TYPES.SENSOR_ICON,
                     title: 'Rear',
                     id: 'binary_sensor.z5_back_doors',
                     states: {
                        on: "open",
                        off: "closed"
                     },
                     icons: {
                       on: 'mdi-door-open',
                       off: 'mdi-door-closed'
                     },
                     customStyles: {'background-color':'#7a4e7f'},
                     classes: [CLASS_MICRO,"-mysmall-entity"],
                  },
               ]
            },
// COLUMN 2 \\
            {
               title: 'Music Stream',
               // width: 4,
               height: 6,
               items: [
// HVAC \\
                 // {
                 //    position: [0, 0.75],
                 //    width: 2,
                 //    height: 2,
                 //    title: 'Downstairs',
                 //    id: "climate.main_floor",
                 //    type: TYPES.CLIMATE,
                 //    state: function (item, entity) {
                 //       return 'Current '
                 //          + entity.attributes.current_temperature
                 //          + entity.attributes.unit_of_measurement;
                 //     },
                 //     customStyles: {'opacity':'0.9'}
                 // },
                 // {
                 //    position: [2, 0.75],
                 //    width: 2,
                 //    height: 2,
                 //    title: 'Upstairs',
                 //    id: "climate.upstairs",
                 //    type: TYPES.CLIMATE,
                 //    state: function (item, entity) {
                 //       return 'Current '
                 //          + entity.attributes.current_temperature
                 //          + entity.attributes.unit_of_measurement;
                 //     },
                 //     customStyles: {'opacity':'0.9'}
                 // },
// MPD \\
                 {
                    position: [0, 0],
                    width: 4,
                    height: 7,
                    id: {},
                    type: TYPES.TEXT_LIST,
                    customStyles: {'background-color':'#3e3e3e'},
                 },
                  // {
                  //    position: [0, 3.75],
                  //    width: 4,
                  //    height: 2,
                  //    id: 'media_player.music_stream',
                  //    type: TYPES.MEDIA_PLAYER,
                  //    hideMuteButton: true,
                  //    hideSource: true,
                  //    title: '@attributes.media_artist',
                  //    subtitle: '@attributes.media_title',
                  //    customStyles: {'background-color':'#667584','overflow':'hidden'},
                  //    classes: [CLASS_MICRO,"-no-volume"],
                  // },
                  {
                     position: [0, 0],
                     type: TYPES.IFRAME,
                     id: {},
                     width: 4,
                     height: 4.83,
                     refresh: 10000, // 10 seconds
                     url: '[REDACTED]'
                   },
// VOLUME \\
                  {
                     position: [0, 0.4],
                     width: 4,
                     height: 2,
                     id: 'input_number.google_volume',
                     type: TYPES.SLIDER,
                     title: 'Volume',
                     subtitle: 'Volume',
                     slider: {max: 10, min: 0, step: 0.5},
                     customStyles: {'background-color':'#667584'},
                     classes: [CLASS_MICRO,"-mid-slider"],
                     filter: function (value) {return null},
                     bgOpacity: 0.0,
                  },
// STREAM SELECTOR \\
                  {
                     position: [0, 4.80],
                     width: 2,
                     height: 1.20,
                     type: TYPES.INPUT_SELECT,
                     id: 'input_select.stream_source',
                     title: 'Music Source',
                     subtitle: '',
                     state: false,
                     customStyles: {'background-color':'#596877'},
                     classes: [CLASS_MICRO,"-mysmall-entity"],
                  },
                  {
                     position: [2, 4.80],
                     width: 2,
                     height: 1.20,
                     type: TYPES.INPUT_SELECT,
                     id: 'input_select.stream_selection',
                     title: 'Stream',
                     subtitle: '',
                     state: false,
                     customStyles: {'background-color':'#596877'},
                     classes: [CLASS_MICRO,"-mysmall-entity"]
                  },
// SPKR SELECTOR \\
                  {
                     position: [0, 6],
                     width: 1,
                     type: TYPES.INPUT_BOOLEAN,
                     id: 'input_boolean.office_mp',
                     title: 'Office',
                     icons: {
                        on: "mdi-stop",
                        off: "mdi-play",
                     },
                     customStyles: {'background-color':'#596877'}, //#668483
                     classes: [CLASS_MICRO,"-mysmall-entity"],
                     states: {
                        on: "playing",
                        off: "off"
                     },
                     // state: function (item, entity) {return media_player.office_speaker.state},
                  },
                  {
                     position: [1, 6],
                     width: 1,
                     type: TYPES.INPUT_BOOLEAN,
                     id: 'input_boolean.frontroom_mp',
                     title: 'Frnt Rm',
                     icons: {
                        on: "mdi-stop",
                        off: "mdi-play",
                     },
                     customStyles: {'background-color':'#596877'},
                     classes: [CLASS_MICRO,"-mysmall-entity"],
                     states: {
                        on: "playing",
                        off: "off"
                     },
                  },
                  {
                     position: [2, 6],
                     width: 1,
                     type: TYPES.INPUT_BOOLEAN,
                     id: 'input_boolean.entry_gp',
                     title: 'Entry',
                     icons: {
                        on: "mdi-stop",
                        off: "mdi-play",
                     },
                     customStyles: {'background-color':'#596877'},
                     classes: [CLASS_MICRO,"-mysmall-entity"],
                     states: {
                        on: "playing",
                        off: "off"
                     },
                  },
                  {
                     position: [3, 6],
                     width: 1,
                     type: TYPES.INPUT_BOOLEAN,
                     id: 'input_boolean.livingrooms_gp',
                     title: 'Liv. Rms',
                     icons: {
                        on: "mdi-stop",
                        off: "mdi-play",
                     },
                     customStyles: {'background-color':'#596877'},
                     classes: [CLASS_MICRO,"-mysmall-entity"],
                     states: {
                        on: "playing",
                        off: "off"
                     },
                  }
               ]
            },
// COLUMN 3 \\
            {
               title: 'Switches & Devices',
               // width: 4,
               height: 6,
               items: [
// DINETTE LIGHT \\
                  {
                     position: [2, 0],
                     width: 2,
                     height: 2,
                     type: TYPES.LIGHT,
                     id: 'light.dinette_light_level',
                     subtitle: 'Dinette',
                     title: 'Light',
                     state: switchPercents('brightness', 255, true),
                     icons: {
                        on: "mdi-lightbulb-on",
                        off: "mdi-lightbulb",
                     },
                     sliders: [
                        {
                           title: 'Brightness',
                           field: 'brightness',
                           max: 255,
                           min: 0,
                           step: 5,
                           formatValue: function (conf) {
                             var value = parseFloat(conf.value);
                             if(isNaN(value)) return conf.value;
                             value = Math.round((value / conf.max * 100));
                             return value + '%';
                           },
                           request: {
                              type: "call_service",
                              domain: "light",
                              service: "turn_on",
                              field: "brightness"
                           }
                        }
                    ],
                  },
// KITCHEN LIGHT \\
                  {
                    position: [0, 0],
                    width: 2,
                    height: 1,
                    type: TYPES.LIGHT,
                    id: 'light.cabinets_top',
                    subtitle: 'Kitchen',
                    title: 'Over Cabinet',
                    state: switchPercents('brightness', 255, true),
                    icons: {
                      on: "mdi-lightbulb-on",
                      off: "mdi-lightbulb",
                    },
                    classes: [CLASS_MICRO],
                    sliders: [
                      {
                          title: 'Brightness',
                          field: 'brightness',
                          max: 255,
                          min: 0,
                          step: 5,
                          formatValue: function (conf) {
                            var value = parseFloat(conf.value);
                            if(isNaN(value)) return conf.value;
                            value = Math.round((value / conf.max * 100));
                            return value + '%';
                          },
                          request: {
                            type: "call_service",
                            domain: "light",
                            service: "turn_on",
                            field: "brightness"
                          }
                      }
                  ],
                  },
                  {
                  position: [0, 1],
                  width: 2,
                  height: 1,
                  type: TYPES.LIGHT,
                  id: 'light.cabinets_btm',
                  subtitle: 'Kitchen',
                  title: 'Under Cabinet',
                  state: switchPercents('white_value', 255, true),
                  field: 'white_value',
                  icons: {
                      on: "mdi-lightbulb-on",
                      off: "mdi-lightbulb",
                  },
                  classes: [CLASS_MICRO],
                  sliders: [
                      {
                        title: 'Brightness',
                        field: 'white_value',
                        max: 255,
                        min: 0,
                        step: 5,
                        formatValue: function (conf) {
                          var value = parseFloat(conf.value);
                          if(isNaN(value)) return conf.value;
                          value = Math.round((value / conf.max * 100));
                          return value + '%';
                        },
                        request: {
                            type: "call_service",
                            domain: "light",
                            service: "turn_on",
                            field: "white_value"
                        }
                      }
                  ],
                  },
// FAM RM FAN \\
                 {
                    position: [0, 2],
                    width: 2,
                    height: 2,
                    id: {},
                    type: TYPES.TEXT_LIST,
                    customStyles: {'background-color':'#913e65'},
                 },
                 {
                   position: [0, 2],
                   width: 2,
                   height: 1,
                   type: TYPES.INPUT_SELECT,
                   id: 'input_select.fan_speed',
                   title: 'Fan',
                   subtitle: 'Select Speed',
                   state: function (item, entity) {return entity.state},
                   customStyles: {'background-color':'#913e65'},
                   filter: function (value) {return null},
                 },
                 {
                    position: [0, 3],
                    width: 2,
                    height: 1,
                    type: TYPES.SWITCH,
                    id: 'switch.fanlight_familyroom',
                    title: 'Light',
                    subtitle: 'Fan',
                    states: {
                       on: "on",
                       off: "off"
                    },
                    icons: {
                       on: "mdi-lightbulb-on",
                       off: "mdi-lightbulb",
                    },
                    customStyles: {'background-color':'#913e65'},
                    classes: [CLASS_MICRO]
                 },
// FAM RM LAMP \\
                 {
                    position: [2, 2],
                    width: 2,
                    height: 2,
                    type: TYPES.LIGHT,
                    id: 'light.corner_lamp_dimmer_level',
                    subtitle: 'Corner',
                    title: 'Lamp',
                    state: switchPercents('brightness', 255, true),
                    icons: {
                       on: "mdi-lightbulb-on",
                       off: "mdi-lightbulb",
                    },
                    sliders: [
                       {
                          title: 'Brightness',
                          field: 'brightness',
                          max: 255,
                          min: 0,
                          step: 5,
                          formatValue: function (conf) {
                            var value = parseFloat(conf.value);
                            if(isNaN(value)) return conf.value;
                            value = Math.round((value / conf.max * 100));
                            return value + '%';
                          },
                          request: {
                             type: "call_service",
                             domain: "light",
                             service: "turn_on",
                             field: "brightness"
                          }
                       }
                   ],
                 },
// FRNT RM STEREO \\
                 {
                    position: [0, 4],
                    width: 2,
                    height: 2,
                    id: {},
                    type: TYPES.TEXT_LIST,
                    customStyles: {'background-color':'#7a4e7f'},
                 },
                 {
                    position: [0, 4],
                    width: 2,
                    height: 1,
                    type: TYPES.SWITCH,
                    id: 'switch.sonoff_switch_01',
                    title: 'Stereo',
                    subtitle: 'Front Rm',
                    states: {
                       on: "on",
                       off: "off"
                    },
                    icon: "mdi-speaker",
                    classes: [CLASS_MICRO]
                 },
// RECORDS LIGHT \\
                {
                  position: [0, 5],
                  width: 2,
                  height: 1,
                  type: TYPES.LIGHT,
                  id: 'light.records_display',
                  subtitle: 'Records',
                  title: 'Light',
                  // state: switchPercents('brightness', 255, true),
                  icons: {
                    on: "mdi-lightbulb-on",
                    off: "mdi-lightbulb",
                  },
                  classes: [CLASS_MICRO],
                  sliders: [
                    {
                        title: 'Brightness',
                        field: 'brightness',
                        max: 255,
                        min: 0,
                        step: 5,
                        formatValue: function (conf) {
                          var value = parseFloat(conf.value);
                          if(isNaN(value)) return conf.value;
                          value = Math.round((value / conf.max * 100));
                          return value + '%';
                        },
                        request: {
                          type: "call_service",
                          domain: "light",
                          service: "turn_on",
                          field: "brightness"
                        }
                    }
                ],
                },
// SOUNDBAR VOL \\
                 {
                    position: [2, 4],
                    type: TYPES.SCRIPT,
                    id: 'script.soundbar_voldn',
                    title: 'Vol Dn',
                    subtitle: '',
                    icon: 'mdi-volume-minus',
                    customStyles: {'background-color':'#3d567f'},
                    classes: [CLASS_MICRO,"-mysmall-entity"],
                    state: false
                 },
                 {
                    position: [3, 4],
                    type: TYPES.SCRIPT,
                    id: 'script.soundbar_volup',
                    title: 'Vol Up',
                    subtitle: '',
                    icon: 'mdi-volume-plus',
                    customStyles: {'background-color':'#3d567f'},
                    classes: [CLASS_MICRO,"-mysmall-entity"],
                    state: false
                 },
                 {
                    position: [2, 5],
                    type: TYPES.SCRIPT,
                    width: 2,
                    id: 'script.soundbar_mute',
                    title: 'Mute',
                    subtitle: '',
                    icon: 'mdi-volume-mute',
                    customStyles: {'background-color':'#3d567f'},
                    classes: [CLASS_MICRO],
                    state: false
                 },
// TV ON|OFF \\
                // {
                //    position: [0, 6],
                //    width: 2,
                //    height: 1,
                //    type: TYPES.SWITCH,
                //    title: "TV",
                //    id: 'switch.tv_main_pwr',
                //    icon: "mdi-television",
                //    classes: [CLASS_MICRO],
                // },
// SLEEP SHUTDOWN \\
                {
                  position: [0, 6],
                  width: 2,
                  height: 1,
                  type: TYPES.SCRIPT,
                  title: 'Sleep Shutdown',
                  id: 'script.sleep_shutdown',
                  icon: "mdi-sleep",
                  classes: [CLASS_MICRO],
                  customStyles: {'background-color':'#275462','opacity':'0.4'},
                  state: false
               },
// RELOAD \\
                {
                   position: [2, 6],
                   width: 2,
                   height: 1,
                   type: TYPES.CUSTOM,
                   title: 'Reload',
                   id: {},
                   icon: 'mdi-refresh',
                   classes: [CLASS_MICRO],
                   customStyles: {'background-color':'#275462','opacity':'0.4'},
                   action: function(item, entity) {
                        window.location.reload(true);
                   }
                },
               ]
            },
         ]
      },
   ],
}

My is flickering and half of the screen is black sometimes.

there are 2 types of flickering i noticed over time with tablets.

  1. usage from power is bigger then the loading device can deliver or battery is getting week. i have noticed that with my samsung galaxy 4, when the power gets beneath a certain level. normally my dashboards (with cam) work fine, but at that point it starts flickering. other apps and websites work fine
  2. usage from cpu is bigger then the tablet can handle. with some tablets i cant run live cam without flickering. 1 second updated frames is no problem.

in almost all cases i came across here, flickering is a sign that the user asks a bit more from the tablet then it can handle. it can be helpfull to try:

  1. backgrounds that are simple (small filesize)
  2. reduce contrast between elements (avoid deep black and white)
  3. reduce cam usage
  4. reduce brightness
  5. dont run other stuff in the background
  6. dont use the tablet cam at the same time
  7. etc.
1 Like

Awesome dashboard @resoai. Thanks a lot for sharing.

I’ve managed to create a dashboard and intend to run this on a Raspberry Pi with the official 7’ screen. When testing on Chrome with the same 800x480 resolution, it doesn’t scale nicely. See pic.

Is there anything I can tweak?

slider
two problems:

  1. how can I remove the decimal after the dot.
    2 it is possible to set the value only after mouseup?
    now the value changes as I scroll the slider. and this was not good for me

Hi, I’d like to use multiple tablets in my home, each with a custom tileboard. What is the best way to set that up?

I got mine to work by adjusting the zoom down to 65-67%. Give that a try. All fits nicely.

filter: numberFilter(0),

Thanks @akkaria. I’ll give that a try!

1 Like

It works fine, but when slider is on “0”, it still appears as “0.0”. Does it have a fix?

works fine and looks very beautiful!

How can I change the colour of my lamps?
Is it possible to change the brightness and the white tone via the sliders by simply tapping the lamp and to change the colour by pressing the lamp for a long time?

Since setting up TileBoard i’ve been firing an event when my doorbell is rang. I’m sure this used to close automatically but it doesn’t seem to any more. Anybody know what I’m missing?

It stop flickering when I set nagivation and status bar to on i Fully Kiosk Mode, it doesn’t work in fullscreen… :expressionless:

Maybe need to buy me some new tablets…

or you could think about another app that shows your dashboard fullscreen (but that probably means you lose some fuctions, and will get other unexpected stuff)

its always hard when you try to override default android stuff.

Hey @resoai

In the https://github.com/resoai/TileBoard/commit/20d6d8a5c73e937a942a12b69b9d6e1b70232d2a you removed the GENERIC_ICON tile replacing it with VACUUM experiment, may I ask why?

I’m using generic icons to present battery state in my sensors, it was quite useful.

To be honest I don’t know why we haven’t removed it before, since it has become SENSOR_ICON almost imemdiately after I published TileBoard on GitHub. I’m sorry if I have confused someone with GENERIC_ICON (it wasn’t even documented though unlike SENSOR_ICON).

This is controlled by doorEntryTimeout:

var CONFIG = {
   doorEntryTimeout: 120,
   ....
};
2 Likes

Ahhh this is great. I was running an automation that would automatically go back to a certain page after a delay of running the doorEntry tile.

@resoai I’ve been having an issue with the weatherList tile. For some reason it doesnt seem to be updating the dates as the days go by. It will just stay on the what ever date was updated the first time tileBoard was loaded. Any reason why it’s not updating?

I’ve followed the example tile instruction and all is working fine except it updating.