篇五:几个界面优化插件 |
您所在的位置:网站首页 › 开淘宝店的整个流程图怎么画好看 › 篇五:几个界面优化插件 |
篇五:几个界面优化插件
都是一直用的默认hass的界面是不是很不爽,特别用在pad或者手机上,来我们看一下几个第三方界面的插件。 注意:因为已经将过一版专门插件如何安装,以下每个插件我不再细讲,我一直觉得插件安装配置、问题查找是最重要的能力,否则弃坑的可能性非常大,一步一坎,所以大家还是要有自己研究探索能力,毕竟这都是软件层面上的,再出问题能有多大,大不了删了重装嘛,如果怕树莓派有问题,就装我蓝牙网关那篇的树莓派sd卡备份以下,出了问题恢复一份。 floorplan这个是我玩hass最开始最喜欢的插件,特别是在https://community.home-assistant.io/t/share-your-floorplan/看到各路大神写的样式以后,发现简直不搞这个等于白玩hass啊。 最后一顿操作搞出来我现在的版本:
0.png (177.45 KB, 下载次数: 9) 下载附件 2019-8-26 23:31 上传 floorplan其实整体结构比较简单,就是首先一个html,然后我们自己画一个svg图,把图上的某某实体都绑定上数据,就可以了,其实这种图还挺方便的特别是看数据特别直观,哪个房间的温度,哪个设备运行了,在加上一个天气简直完美。 但是要承载这个图可能就需要一个设备了,放在入户,我在share里最喜欢的两个。
1.png (274.47 KB, 下载次数: 3) 下载附件 2019-8-26 23:31 上传 这个一看就是即实用又美观,首先数据又展示内容有,右面一排的情景控制解决了图上设备比较小不好控制的问题。
2.png (357.47 KB, 下载次数: 3) 下载附件 2019-8-26 23:31 上传 这个就是看着舒爽,用圆圈的颜色来区分等的开关状态。 做一个floorplan注意虽然作者已经有2年没更新了,不过最近看到大神准备继续更新这个插件了。https://github.com/pkozul/ha-floorplan 大家还是参照大神写好的教程,我想想我来写也不会比这个更详细。 https://post.smzdm.com/p/597918/ 我只能给大家几个我做过程中遇到的问题。 首先svg没什么比较好的编辑器,免费的Inkscape只能说凑合,我是用mac的一个画流程图一类的软件omni graffle来画,不过这个不是专门画svg的所有有个问题,就是不能设置实体id,为此我写了python脚本来替换,如果有需求可以找我单要,如果没有这个软件功底的不推荐实用。 画图尽量拆分好图层,比如第一层墙体,第二层地板,第三层家居,第四层设备。好处很多,特别是需要往复修改一个图纸的时候。 需要画户型图就比较耗时了大家有心里准备,我花了差不多3-4个小时,特别是我有详细尺寸的前提下。 作者推荐的酷家乐很好用,主要是有很多同小区户型该起来比较方便,但是只能导出原型图,墙体一类的还是要自己画。最后给一下我的svg方便大家参考。 floorplan&lovelace
3.png (45.67 KB, 下载次数: 3) 下载附件 2019-8-26 23:31 上传 https://github.com/pkozul/lovelace-floorplan 最近也支持lovelace环境了,有需要的可以参照上面的说明。 Home Panel最接近官方的插件,我用的也不多更多的是测试。
4.png (332.2 KB, 下载次数: 1) 下载附件 2019-8-26 23:31 上传 这个插件首先是按照所谓的区域方式拆分的,并且这个方式还不能取消。 看到图上的Scenes、Central Heatting、Weather、LivingRoot 这个插件比较简单,我是直接通过hass.io插件直接安装,安装好以后,需要配置映射端口地址。
5.png (78.48 KB, 下载次数: 0) 下载附件 2019-8-26 23:31 上传 配置好了直接启动,通过http://ip:8124就可以访问了,这里有个坑。 home panle是独立的账号密码,需要先注册,然后在登陆。 登陆成功以后需要绑定到hass上然后再绑定。 Home Panel配置hp的配置算是很简单的,非常有官方的风格,基本上可以不手写,完全通过界面配置,比如:
6.png (74.8 KB, 下载次数: 0) 下载附件 2019-8-26 23:31 上传 点击 edit config 就可以直接通过这个+号新增,数据绑定也非常简单,直接选择对应的实体就可以了。
7.png (151.79 KB, 下载次数: 0) 下载附件 2019-8-26 23:31 上传 可以配置icon、宽度高度等,甚至支持直接配置group,group的每一个插件独立拆分成一个。而且支持,hass、link、camera、iframe四种模式的配置,简单粗暴。
8.png (62.27 KB, 下载次数: 0) 下载附件 2019-8-26 23:31 上传 当然也支持多个page,并且由于这个针对手机做过优化,所以手机、平板展示的也不难看,更适合移动设备操作。 tileboard这个就更简单了,因为只是一个前端插件,所以只要配置几个前端相关的就可以,甚至都不需要重启hass。 https://github.com/resoai/TileBoard 去看作者写的readme.md其实已经写的比较清楚了。
10.png (160.92 KB, 下载次数: 0) 下载附件 2019-8-26 23:34 上传
9.png (465.91 KB, 下载次数: 1) 下载附件 2019-8-26 23:31 上传 我是觉得这个好看很多人想法不一样。 这个配置就一个超大的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所以这三种我都是实验,都不太深入,主要是没使用场景,设备太少了。 |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |