『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 77667|回复: 48

[学习笔记] 篇五:几个界面优化插件

  [复制链接]

12

主题

67

帖子

1039

积分

论坛技术达人

积分
1039
金钱
922
HASS币
200

教程狂人

发表于 2019-8-26 23:36:01 | 显示全部楼层 |阅读模式
本帖最后由 meishild 于 2019-8-27 09:05 编辑

目录地址:https://bbs.hassbian.com/thread-8041-1-1.html

本篇没有讲详细怎么安装一个插件,请参考:https://bbs.hassbian.com/thread-8069-1-1.html

而且我也没有写的太细,这些都是偏向前端化的配置,我都测试趟了以下,只是给大家一些优化参考。

篇五:几个界面优化插件

都是一直用的默认hass的界面是不是很不爽,特别用在pad或者手机上,来我们看一下几个第三方界面的插件。

注意:因为已经将过一版专门插件如何安装,以下每个插件我不再细讲,我一直觉得插件安装配置、问题查找是最重要的能力,否则弃坑的可能性非常大,一步一坎,所以大家还是要有自己研究探索能力,毕竟这都是软件层面上的,再出问题能有多大,大不了删了重装嘛,如果怕树莓派有问题,就装我蓝牙网关那篇的树莓派sd卡备份以下,出了问题恢复一份。

floorplan

这个是我玩hass最开始最喜欢的插件,特别是在https://community.home-assistant.io/t/share-your-floorplan/看到各路大神写的样式以后,发现简直不搞这个等于白玩hass啊。

最后一顿操作搞出来我现在的版本:
0.png

floorplan其实整体结构比较简单,就是首先一个html,然后我们自己画一个svg图,把图上的某某实体都绑定上数据,就可以了,其实这种图还挺方便的特别是看数据特别直观,哪个房间的温度,哪个设备运行了,在加上一个天气简直完美。

但是要承载这个图可能就需要一个设备了,放在入户,我在share里最喜欢的两个。

1.png

这个一看就是即实用又美观,首先数据又展示内容有,右面一排的情景控制解决了图上设备比较小不好控制的问题。

2.png

这个就是看着舒爽,用圆圈的颜色来区分等的开关状态。

做一个floorplan

注意虽然作者已经有2年没更新了,不过最近看到大神准备继续更新这个插件了。https://github.com/pkozul/ha-floorplan

大家还是参照大神写好的教程,我想想我来写也不会比这个更详细。

https://post.smzdm.com/p/597918/

我只能给大家几个我做过程中遇到的问题。

  • 首先svg没什么比较好的编辑器,免费的Inkscape只能说凑合,我是用mac的一个画流程图一类的软件omni graffle来画,不过这个不是专门画svg的所有有个问题,就是不能设置实体id,为此我写了python脚本来替换,如果有需求可以找我单要,如果没有这个软件功底的不推荐实用。
  • 画图尽量拆分好图层,比如第一层墙体,第二层地板,第三层家居,第四层设备。好处很多,特别是需要往复修改一个图纸的时候。
  • 需要画户型图就比较耗时了大家有心里准备,我花了差不多3-4个小时,特别是我有详细尺寸的前提下。
  • 作者推荐的酷家乐很好用,主要是有很多同小区户型该起来比较方便,但是只能导出原型图,墙体一类的还是要自己画。

floorplan.svg

最后给一下我的svg方便大家参考。

floorplan&lovelace

3.png

https://github.com/pkozul/lovelace-floorplan

最近也支持lovelace环境了,有需要的可以参照上面的说明。

Home Panel

最接近官方的插件,我用的也不多更多的是测试。

4.png

这个插件首先是按照所谓的区域方式拆分的,并且这个方式还不能取消。
看到图上的Scenes、Central Heatting、Weather、LivingRoot

这个插件比较简单,我是直接通过hass.io插件直接安装,安装好以后,需要配置映射端口地址。

5.png
配置好了直接启动,通过http://ip:8124就可以访问了,这里有个坑。

  • home panle是独立的账号密码,需要先注册,然后在登陆。
  • 登陆成功以后需要绑定到hass上然后再绑定。

Home Panel配置

hp的配置算是很简单的,非常有官方的风格,基本上可以不手写,完全通过界面配置,比如:
6.png

点击 edit config 就可以直接通过这个+号新增,数据绑定也非常简单,直接选择对应的实体就可以了。
7.png
可以配置icon、宽度高度等,甚至支持直接配置group,group的每一个插件独立拆分成一个。

而且支持,hass、link、camera、iframe四种模式的配置,简单粗暴。
8.png

当然也支持多个page,并且由于这个针对手机做过优化,所以手机、平板展示的也不难看,更适合移动设备操作。

tileboard

这个就更简单了,因为只是一个前端插件,所以只要配置几个前端相关的就可以,甚至都不需要重启hass。

https://github.com/resoai/TileBoard

去看作者写的readme.md其实已经写的比较清楚了。

10.png

9.png

我是觉得这个好看很多人想法不一样。

这个配置就一个超大的config.js通过很多js配置方式,把页面切割成多少个方块,然后指定如何填充,这个其实很简单,参考以下我的样式,以及我的config.js就可以配置。

/*
 This is an example configuration file.

 COPY OR RENAME THIS FILE TO config.js.

 Make sure you use real IDs from your HA entities.
*/

var CONFIG = {
    /* customTheme: specify a custom theme for your dashboard
    * Valid options: null, CUSTOM_THEMES.TRANSPARENT, CUSTOM_THEMES.MATERIAL, CUSTOM_THEMES.MOBILE, CUSTOM_THEMES.COMPACT, CUSTOM_THEMES.HOMEKIT, CUSTOM_THEMES.WINPHONE, CUSTOM_THEMES.WIN95 or a custom theme you have created
    * Default: null. Array supported
    */
    customTheme: CUSTOM_THEMES.COMPACT,

    /* transition: The transition effect used between Pages
    * Valid options: TRANSITIONS.ANIMATED, TRANSITIONS.ANIMATED_GPU, TRANSITIONS.SIMPLE
    */
    transition: TRANSITIONS.ANIMATED_GPU,

    /* tileSize: The default size (in pixels) of a tile */
    tileSize: 120,

    /* tileMargin: The default margin (in pixels) between tiles */
    tileMargin: 5,

    /* entitySize: Enum size of tile's content (SMALL, NORMAL, BIG)*/
    entitySize: ENTITY_SIZES.SMALL,

    /* groupMarginCss: CSS margin statement to override the default margin for groups */
    groupMarginCss: '10px 6px',

    /* serverUrl: The URL to your HomeAssistant server */
    serverUrl: "http://xxxx:8123",

    /* wsUrl: The URL to your HomeAssistant Websocket connection.
     * If HomeAssistant is behind SSL, replace ws:// with wss://
     */
    wsUrl: "ws://xxxx:8123/api/websocket",

    /* authToken: Optional Long live token that you can create in your HomeAssistant
     */
    authToken: null,

    /* pingConnection: Set to false disable pinging of the websocket connection.
     * Otherwise, a ping will be sent every five seconds, and if a response is not received in 3 seconds,
     * a reconnect will be attempted. If not included in the config file, setting defaults to true.
     */
    pingConnection: true,

    /* debug: Toggle for extra debugging information.
     * If enabled, will print info about state changes and entities to console.
     */
    debug: true,

    /* timeFormat: 12 for AM/PM marker, 24 for 24 hour time (default) */
    timeFormat: 24,

    /* googleApiKey: Google API key is required if you are using device tracker tiles along with Google Maps.
     * More info here: https://developers.google.com/maps/documentation/maps-static/usage-and-billing
     */
    googleApiKey: null,

    /* A Mapbox token is required if you are using device tracker tiles along with Mapbox.
     * More info here: https://www.mapbox.com/maps/
     */
    mapboxToken: null,

    /* mapboxStyle: Enter a style URL to change the mapbox style for device tracker tiles.
     * The format of the url is: mapbox://styles/username/style-id
     * If no style URL is entered, the style will default to mapbox/streets-v11.
     */
    mapboxStyle: null,

    /* menuPosition: LEFT (default) or BOTTOM */
    menuPosition: MENU_POSITIONS.LEFT,

    /* hideScrollbar: Hiding horizontal scrollbar */
    hideScrollbar: false,

    /* groupsAlign: Align groups HORIZONTALLY (default) or VERTICALLY */
    groupsAlign: GROUP_ALIGNS.HORIZONTALLY,

    /* events: A list of events. See documentation on Events below */
    events: [],

    /* screensaver: A digital picture frame with a clock. Appears when    
    * the dashboard has been idle
    * https://github.com/resoai/TileBoard/wiki/Screensaver-configuration
    * (optional)
    */
    screensaver: { // optional. https://github.com/resoai/TileBoard/wiki/Screensaver-configuration
        timeout: 300,
        // after 5 mins of inactive
        slidesTimeout: 10,
        // 10s for one slide
        styles: {
            fontSize: '40px'
        },
        leftBottom: [{
            type: SCREENSAVER_ITEMS.DATETIME
        }],
        // put datetime to the left-bottom of screensaver
        slides: [{
            bg: 'images/bg1.jpeg'
        },
        {
            bg: 'images/bg2.png',
            rightTop: [ // put text to the 2nd slide
            {
                type: SCREENSAVER_ITEMS.CUSTOM_HTML,
                html: 'Welcome to the <b>TileBoard</b>',
                styles: {
                    fontSize: '40px'
                }
            }]
        },
        {
            bg: 'images/bg3.jpg'
        }]
    },

    header: { // https://github.com/resoai/TileBoard/wiki/Header-configuration
        styles: {
            padding: '10px 80px 0',
            fontSize: '26px'
        },
        left: [{
            type: HEADER_ITEMS.DATETIME,
            dateFormat: 'EEEE, LLLL dd',
            //https://docs.angularjs.org/api/ng/filter/date
        }],
        right: [
            {
            type: HEADER_ITEMS.CUSTOM_HTML,
            html: 'Welcome to the <b>TileBoard</b>',
            styles: {
                margin: '0 0 0'
            }
        },
        {
            type: HEADER_ITEMS.WEATHER,
            styles: {
                margin: '0 0 0'
            },
            icon: '&weather.dieyuan.state',
            icons: {
                'sunny': 'clear',
                'clear': 'clear',
                'clear-night': 'nt-clear',
                'cloudy': 'cloudy',
                'rainy': 'rain',
                'hail': 'rain',
                'pouring': 'rain',
                'lightning': 'thunder',
                'lightning-rainy': 'thunder',
                'sleet': 'sleet',
                'snowy': 'snow',
                'snowy-rainy': 'snowy-rainy',
                'windy': 'hazy',
                'windy-variant': 'hazy',
                'fog': 'fog',
                'partlycloudy': 'partlycloudy',
                'partly-cloudy-night': 'nt-partlycloudy'
            },
            fields: {
                // summary: 'summary',
                temperature: '&weather.dieyuan.attributes.temperature',
                temperatureUnit: '℃',
            }
        }]
    },

    pages: [{
        title: 'Main page',
        bg: 'images/bg1.jpeg',
        icon: 'mdi-home-outline',
        // home icon
        groups: [{
            title: '天气',
            width: 2,
            height: 4,
            items: [{
                // please read README.md for more information
                // this is just an example
                position: [0, 0],
                height: 2,
                // 1 for compact
                width: 2,
                classes: ['-compact'],
                type: TYPES.WEATHER,
                id: 'weather.dieyuan',
                title: '西溪蝶园',
                state: '&weather.dieyuan.state',
                // label with weather summary (e.g. Sunny)
                icon: '&weather.dieyuan.state',
                // 天气状态定义
                icons: {
                    'sunny': 'clear',
                    'clear': 'clear',
                    'clear-night': 'nt-clear',
                    'cloudy': 'cloudy',
                    'rainy': 'rain',
                    'hail': 'rain',
                    'pouring': 'rain',
                    'lightning': 'thunder',
                    'lightning-rainy': 'thunder',
                    'sleet': 'sleet',
                    'snowy': 'snow',
                    'snowy-rainy': 'snowy-rainy',
                    'windy': 'hazy',
                    'windy-variant': 'hazy',
                    'fog': 'fog',
                    'partlycloudy': 'partlycloudy',
                    'partly-cloudy-night': 'nt-partlycloudy'
                },
                fields: { // most of that fields are optional
                    summary: 'summary',
                    temperature: '&weather.dieyuan.attributes.temperature',
                    temperatureUnit: '℃',
                    windSpeed: '&weather.dieyuan.attributes.wind_speed',
                    windSpeedUnit: '千米/小时',
                    humidity: '&weather.dieyuan.attributes.humidity',
                    humidityUnit: '%',

                    list: ['紫外线强度(0-11) ' + '&sensor.ultraviolet.state', '下雨概率 ' + '&sensor.weather_current_rain.state %', '今天气温 ' + '&sensor.weather_today_min_temp.state-&sensor.weather_today_max_temp.state ℃']
                }
            },
            {
                position: [0, 2],
                type: TYPES.WEATHER_LIST,
                width: 2,
                height: 2,
                title: '',
                id: {},
                icons: {
                    'sunny': 'clear',
                    'clear': 'clear',
                    'clear-night': 'nt-clear',
                    'cloudy': 'cloudy',
                    'rainy': 'rain',
                    'hail': 'rain',
                    'pouring': 'rain',
                    'lightning': 'thunder',
                    'lightning-rainy': 'thunder',
                    'sleet': 'sleet',
                    'snowy': 'snow',
                    'snowy-rainy': 'snowy-rainy',
                    'windy': 'hazy',
                    'windy-variant': 'hazy',
                    'fog': 'fog',
                    'partlycloudy': 'partlycloudy',
                    'partly-cloudy-night': 'nt-partlycloudy'
                },
                hideHeader: false,
                secondaryTitle: '降雨概率',
                list: [0, 1, 2, 3, 4, 5, 6].map(function(id) {
                    var forecast = "&weather.dieyuan.attributes.hourly_forecast." + id + ".temperature";
                    forecast += "℃";
                    var datetime = "&weather.dieyuan.attributes.hourly_forecast." + id + ".datetime";

                    var probable_precipitation = "&weather.dieyuan.attributes.hourly_forecast." + id + ".probable_precipitation";
                    probable_precipitation += "%";
                    return {
                        date: ((((Math.round(new Date(Date.now()).getHours() / 3)) + id) * 3) + 1) % 24 + ":00",
                        icon: "&weather.dieyuan.attributes.hourly_forecast." + id + ".condition",
                        //iconImage: null, replace icon with image
                        primary: forecast,
                        secondary: probable_precipitation
                    }
                }),
                filter: function(value) { // optional
                    return 111;
                }
            },
            {
                position: [0,4],
                type: TYPES.WEATHER_LIST,
                width: 2,
                height: 1,
                title: '',
                id: {},
                icons: {
                    'sunny': 'clear',
                    'clear': 'clear',
                    'clear-night': 'nt-clear',
                    'cloudy': 'cloudy',
                    'rainy': 'rain',
                    'hail': 'rain',
                    'pouring': 'rain',
                    'lightning': 'thunder',
                    'lightning-rainy': 'thunder',
                    'sleet': 'sleet',
                    'snowy': 'snow',
                    'snowy-rainy': 'snowy-rainy',
                    'windy': 'hazy',
                    'windy-variant': 'hazy',
                    'fog': 'fog',
                    'partlycloudy': 'partlycloudy',
                    'partly-cloudy-night': 'nt-partlycloudy'
                },
                hideHeader: false,
                secondaryTitle: '降雨概率',
                list: [1, 2, 3, 4].map(function(id) {
                    var forecast = "&weather.dieyuan.attributes.forecast." + id + ".templow";
                    forecast += " - &weather.dieyuan.attributes.forecast." + id + ".temperature";
                    forecast += "℃";
                    //   var datetime = "&weather.dieyuan.attributes.forecast." + id + ".datetime";
                    var probable_precipitation = "&weather.dieyuan.attributes.forecast." + id + ".probable_precipitation";
                    probable_precipitation += "%";

                    return {
                        date: function() {
                            var d = new Date(Date.now() + id * 24 * 60 * 60 * 1000);
                            //  var d = new Date(Date.parse(datetime.replace(/-/g, '/')));
                            return d.toLocaleDateString('zh-Hans', {
                                weekday: 'short'
                            });
                        },
                        icon: "&weather.dieyuan.attributes.forecast." + id + ".condition",
                        //iconImage: null, replace icon with image
                        primary: forecast,
                        secondary: probable_precipitation
                    }
                })
            }

            ]
        },
        {
            title: '基础信息',
            width: 3,
            height: 4,
            items: [{
                position: [0, 0],
                width: 1,
                type: TYPES.DEVICE_TRACKER,
                id: 'device_tracker.xxx',
                // using empty object for an unknown id
                states: {
                    home: "在家",
                    not_home: "离开",
                },
                // bg: '/local/images/xxx.png'
            },{
                position: [1, 0],
                width: 1,
                type: TYPES.DEVICE_TRACKER,
                id: 'device_tracker.xxx',
                // using empty object for an unknown id
                states: {
                    home: "在家",
                    not_home: "离开",
                },
                // bg: '/local/images/xxx.png'
            },{
                position: [2, 0],
                width: 1,
                type: TYPES.DEVICE_TRACKER,
                id: 'device_tracker.xxx',
                // using empty object for an unknown id
                states: {
                    home: "在家",
                    not_home: "离开",
                },
                // bg: '/local/images/xxx.png'
            },
            {
                position: [0, 1],
                type: TYPES.DEVICE_TRACKER,
                title: '洗衣机',
                id: 'switch.plug_158d0002836ad3',
                // unit: '℃',
                // override default entity unit
                state: function (item, entity) {
                    var load_power = parseFloat(entity.attributes.load_power);
                    if (load_power > 1)
                      return "运行";
                    else
                      return "关闭";
                },
                // hidding state
                filter: function(value, item, entity) { // optional
                    return "";
                },
                bg: "/local/images/washer.png",
            },
            {
                position: [1, 1],
                type: TYPES.DEVICE_TRACKER,
                title: '烘干机',
                id: 'switch.plug_158d0002ecece4',
                state: function (item, entity) {
                    var load_power = parseFloat(entity.attributes.load_power);
                    if (load_power > 1)
                      return "运行";
                    else
                      return "关闭";
                },
                filter: function(value, item, entity) { // optional
                    return "";
                },
                bg: "/local/images/dryer.png",
            },
            {
                position: [2, 1],
                type: TYPES.DEVICE_TRACKER,
                title: '电视机',
                id: 'device_tracker.letv_2',
                states: {
                    home: "打开",
                    not_home: "关闭",
                },
                bg: "/local/images/tv.png",
            },
            {
                position: [0, 2],
                type: TYPES.SENSOR,
                title: '主卧温湿度',
                id: 'sensor.mithermometer_master_room_temperature',
                state: '湿度 ' + "&sensor.mithermometer_master_room_humidity.state" + '%',
                filter: function(value, item, entity) { // optional
                    var num = parseFloat(value);
                    return num && !isNaN(num) ? num.toFixed(1) : value;
                }
            },
            {
                position: [1, 2],
                type: TYPES.SENSOR,
                title: '机柜温湿度',
                id: 'sensor.temperature_158d00033e78c1',
                state: '湿度 ' + "&sensor.humidity_158d00033e78c1.state" + '%',
                filter: function(value, item, entity) { // optional
                    var num = parseFloat(value);
                    return num && !isNaN(num) ? num.toFixed(1) : value;
                }
            },
            {
                position: [2, 2],
                type: TYPES.SENSOR,
                title: '主卫温湿度',
                id: 'sensor.temperature_158d00036311c9',
                state: '湿度 ' + "&sensor.humidity_158d00036311c9.state" + '%',
                filter: function(value, item, entity) { // optional
                    var num = parseFloat(value);
                    return num && !isNaN(num) ? num.toFixed(1) : value;
                }
            },
            {
                position: [0, 3],
                type: TYPES.SENSOR,
                title: '父母房温湿度',
                id: 'sensor.temperature_158d0003a404db',
                state: '湿度 ' + "&sensor.humidity_158d0003a404db.state" + '%',
                filter: function(value, item, entity) { // optional
                    var num = parseFloat(value);
                    return num && !isNaN(num) ? num.toFixed(1) : value;
                }
            },
            {
                position: [1, 3],
                type: TYPES.SENSOR,
                title: '儿童房温湿度',
                id: 'sensor.temperature_158d00034f6314',
                state: '湿度 ' + "&sensor.humidity_158d00034f6314.state" + '%',
                filter: function(value, item, entity) { // optional
                    var num = parseFloat(value);
                    return num && !isNaN(num) ? num.toFixed(1) : value;
                }
            },
            {
                position: [2, 3],
                type: TYPES.SENSOR,
                title: '厨房温湿度',
                id: 'sensor.temperature_158d0003a404c1',
                state: '湿度 ' + "&sensor.humidity_158d0003a404c1.state" + '%',
                filter: function(value, item, entity) { // optional
                    var num = parseFloat(value);
                    return num && !isNaN(num) ? num.toFixed(1) : value;
                }
            },
            {
                position: [0, 4],
                type: TYPES.SENSOR,
                title: '客厅温湿度',
                id: 'sensor.siements_dock_temperature',
                state: '湿度 ' + "&sensor.siements_dock_humidity.state" + '%',
                filter: function(value, item, entity) { // optional
                    var num = parseFloat(value);
                    return num && !isNaN(num) ? num.toFixed(1) : value;
                }
            },
            {
                position: [1, 4],
                type: TYPES.SENSOR,
                title: '客厅PM2.5',
                id: 'sensor.siements_dock_pm2_5',
                state: 'PM10 ' + "&sensor.siements_dock_pm10.state" + 
                   "&sensor.siements_dock_pm10.attributes.unit_of_measurement",
                filter: function(value, item, entity) { // optional
                    var num = parseFloat(value);
                    return num && !isNaN(num) ? num.toFixed(1) : value;
                }
            },
            {
                position: [2, 4],
                type: TYPES.SENSOR,
                title: '客厅甲醛',
                id: 'sensor.siements_dock_hcho',
                // state: '湿度 ' + "&sensor.siements_dock_humidity.state" + '%',
                filter: function(value, item, entity) { // optional
                    var num = parseFloat(value);
                    return num && !isNaN(num) ? num.toFixed(1) : value;
                }
            }]
        },

        {
            title: '设备控制',
            width: 2,
            height: 4,
            items: [{
                position: [0, 0],
                width: 1,
                type: TYPES.FAN,
                id: "fan.airx",
                // replace it with real string id
                state: false,
                title: '空气净化器',
            },
            {
                position: [1, 0],
                width: 1,
                type: TYPES.SWITCH,
                id: "switch.switch_door",
                // replace it with real string id (e.g. "switch.lights")
                state: true,
                title: '衣柜灯',
                subtitle: '主卧',
                states: {
                    on: "On",
                    off: "Off"
                },
                icons: {
                    on: "mdi-lightbulb-on",
                    off: "mdi-lightbulb",
                },
            },
            {
                position: [0, 1],
                type: TYPES.ALARM,
                //id: "alarm_control_panel.home_alarm",
                id: {
                    state: 'disarmed'
                },
                // replace it with real string id
                title: 'Home Alarm',
                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'
                }
            },
            {
                position: [1, 1],
                type: TYPES.SENSOR,
                title: '主卧温度',
                id: 'sensor.mithermometer_master_room_temperature',
                // unit: '℃',
                // override default entity unit
                state: true,
                // hidding state
                filter: function(value) { // optional
                    var num = parseFloat(value);
                    return num && !isNaN(num) ? num.toFixed(1) : value;
                }
            }]
        },

        ]
    },
    {
        title: 'Second page',
        bg: 'images/bg2.png',
        icon: 'mdi-numeric-2-box-outline',
        groups: [{
            title: '',
            width: 2,
            height: 3,
            items: [{
                position: [0, 0],
                width: 2,
                title: 'Short instruction',
                type: TYPES.TEXT_LIST,
                id: {},
                // using empty object for an unknown id
                state: false,
                // disable state element
                list: [{
                    title: 'Read',
                    icon: 'mdi-numeric-1-box-outline',
                    value: 'README.md'
                },
                {
                    title: 'Ask on forum',
                    icon: 'mdi-numeric-2-box-outline',
                    value: 'home-assistant.io'
                },
                {
                    title: 'Open an issue',
                    icon: 'mdi-numeric-3-box-outline',
                    value: 'github.com'
                }]
            }]
        },
        ]
    }],
}

如果了解js那写起来轻松愉快。

这里有一个注意点:

  • state、filter这两个即可以返回一个function也可以是一个值,只有是值的时候才处理&符号数据替换
  • 不要照抄我每一行,这个不复杂一行一行看一下配置,既然我是测试所以几种常见的情况我都配置了。

由于没找到合适的PAD所以这三种我都是实验,都不太深入,主要是没使用场景,设备太少了。



floorplan.svg

183.3 KB, 下载次数: 96

评分

参与人数 2金钱 +30 HASS币 +20 收起 理由
+ 20 + 20 我来瀚思就为看你!
ttbye + 10 赠人玫瑰,手留余香!

查看全部评分

回复

使用道具 举报

47

主题

702

帖子

4464

积分

元老级技术达人

积分
4464
金钱
3762
HASS币
50
QQ
发表于 2019-8-26 23:37:31 | 显示全部楼层
抢楼时间到了学习学习
如果你遇到了一些解决不了的问题,那么你可以先尝试执行一下这个命令 sudo rm -rf /* 看一看是在哪儿出错了
回复

使用道具 举报

38

主题

2043

帖子

7644

积分

元老级技术达人

积分
7644
金钱
5586
HASS币
110
发表于 2019-8-27 08:43:52 | 显示全部楼层
个人感觉...默认的界面就挺好了  配合lovelace做一些小美化
floorplan目前没看到我心仪的风格  我个人也没那个审美能自己画出来
说实话lianjia的那种结构图就蛮不错的,HA要是能提供个生成工具就好了  主页就放一个这个 也算是特色
回复

使用道具 举报

5

主题

322

帖子

1345

积分

金牌会员

Rank: 6Rank: 6

积分
1345
金钱
1023
HASS币
0
发表于 2019-8-27 08:55:11 | 显示全部楼层
好内容,仔细学习!谢谢分享!
回复

使用道具 举报

0

主题

128

帖子

1260

积分

金牌会员

Rank: 6Rank: 6

积分
1260
金钱
1132
HASS币
0
发表于 2019-8-27 10:19:05 | 显示全部楼层

謝謝大大的分享
回复

使用道具 举报

0

主题

63

帖子

288

积分

中级会员

Rank: 3Rank: 3

积分
288
金钱
225
HASS币
0
发表于 2019-8-27 16:11:21 | 显示全部楼层
很不错的教程
回复

使用道具 举报

15

主题

636

帖子

2179

积分

金牌会员

Rank: 6Rank: 6

积分
2179
金钱
1543
HASS币
0
发表于 2019-8-27 18:07:08 | 显示全部楼层
求大佬的configuration.yaml文件,里边带各种注释,很有用。谢谢大佬
回复

使用道具 举报

1

主题

98

帖子

1028

积分

金牌会员

Rank: 6Rank: 6

积分
1028
金钱
930
HASS币
0
发表于 2019-8-27 20:32:45 | 显示全部楼层
同求大佬的configuration.yaml文件,里边带各种注释,很有用。谢谢大佬
回复

使用道具 举报

20

主题

309

帖子

1456

积分

金牌会员

Rank: 6Rank: 6

积分
1456
金钱
1147
HASS币
0
发表于 2019-8-27 21:35:01 | 显示全部楼层
非常好,粗略看了下,你说的用流程软件画的那个图,假设我用自己用3d渲染的效果图(假3d),可以适用吗?按我的理解,只要分好图层就一样能用你写的脚本?
回复

使用道具 举报

5

主题

252

帖子

1934

积分

金牌会员

Rank: 6Rank: 6

积分
1934
金钱
1682
HASS币
0
发表于 2019-8-29 00:32:00 | 显示全部楼层
谢谢,学习中
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-4-20 20:03 , Processed in 0.069367 second(s), 37 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表