Ver código fonte

Removed unused stuff. Updated.

TheMultiplexer 6 anos atrás
pai
commit
60d7778a73

+ 16
- 1
config/configuration.yaml Ver arquivo

@@ -6,6 +6,8 @@ homeassistant:
6 6
   unit_system: metric
7 7
   time_zone: Europe/Berlin
8 8
   customize: !include customize.yaml
9
+  whitelist_external_dirs:
10
+    - '/snapshots'
9 11
 
10 12
 zone:  
11 13
   - name: HTWG
@@ -90,6 +92,13 @@ mqtt:
90 92
   password: Mindabew1
91 93
 
92 94
 sensor:
95
+  - platform: pi_hole
96
+    host: 192.168.1.3
97
+    monitored_conditions:
98
+      - ads_blocked_today
99
+      - dns_queries_today
100
+      - unique_clients
101
+      - unique_domains
93 102
   - platform: command_line
94 103
     name: CPU Temperature
95 104
     command: "cat /sys/class/thermal/thermal_zone0/temp"
@@ -156,6 +165,13 @@ history_graph:
156 165
     entities:
157 166
       - sensor.dht_sensor_humidity
158 167
     hours_to_show: 12
168
+  pihole:
169
+    name: Queries over the last 24 hours
170
+    refresh: 60
171
+    entities:
172
+      - sensor.pi_hole_ads_blocked_today
173
+      - sensor.pi_hole_dns_queries_today
174
+    hours_to_show: 24
159 175
   octoprint:
160 176
     name: OctoPrint
161 177
     refresh: 1
@@ -315,7 +331,6 @@ http:
315 331
   api_password: !secret http_password
316 332
   base_url: http://localhost:8123
317 333
   #base_url: https://home.rutschmann.tech
318
-  #server_port: 443
319 334
   #ssl_profile: intermediate
320 335
   #ssl_certificate: /config/ssl/fullchain.pem
321 336
   #ssl_key: /config/ssl/privkey.pem

+ 16
- 0
config/known_devices.yaml Ver arquivo

@@ -606,3 +606,19 @@ pc_e0_b5_2d_ed_ba_31:
606 606
   name: PC-E0-B5-2D-ED-BA-31
607 607
   picture:
608 608
   track: false
609
+
610
+raspberrypi:
611
+  hide_if_away: false
612
+  icon:
613
+  mac: DC:A6:32:03:C6:56
614
+  name: raspberrypi
615
+  picture:
616
+  track: false
617
+
618
+raspberrypi_2:
619
+  hide_if_away: false
620
+  icon:
621
+  mac: DC:A6:32:03:C6:57
622
+  name: raspberrypi
623
+  picture:
624
+  track: false

+ 0
- 249
config/www/circle-sensor-card.js Ver arquivo

@@ -1,249 +0,0 @@
1
-import {
2
-  LitElement, html
3
-} from 'https://unpkg.com/@polymer/lit-element@^0.5.2/lit-element.js?module';
4
-
5
-class CircleSensorCard extends LitElement {
6
-  static get properties() {
7
-    return {
8
-      hass: Object,
9
-      config: Object,
10
-      state: Object,
11
-      dashArray: String
12
-    }
13
-  }
14
-
15
-  _render({ state, dashArray, config }) {
16
-    return html`
17
-      <style>
18
-          :host {
19
-            cursor: pointer;
20
-          }
21
-
22
-          .container {
23
-            position: relative;
24
-            height: 100%;
25
-            display: flex;
26
-            flex-direction: column;
27
-          }
28
-
29
-          .labelContainer {
30
-            position: absolute;
31
-            top: 0;
32
-            left: 0;
33
-            width: 100%;
34
-            height: 100%;
35
-            display: flex;
36
-            flex-direction: column;
37
-            align-items: center;
38
-            justify-content: center;
39
-          }
40
-          
41
-          #label {
42
-            display: flex;
43
-            line-height: 1;
44
-          }
45
-          
46
-          #label.bold {
47
-            font-weight: bold;
48
-          }
49
-          
50
-          #label, #name {
51
-            margin: 1% 0;
52
-          }
53
-
54
-          .text, #name {
55
-            font-size: 100%;
56
-          }
57
-          
58
-          .unit {
59
-            font-size: 75%;
60
-          }
61
-
62
-      </style>
63
-      <div class="container" id="container" on-click="${() => this._click()}">
64
-        <svg viewbox="0 0 200 200" id="svg">
65
-          <circle id="circle" cx="50%" cy="50%" r="45%"
66
-            fill$="${config.fill || 'rgba(255, 255, 255, .75)'}"
67
-            stroke$="${config.stroke_color || '#03a9f4'}"
68
-            stroke-dasharray$="${dashArray}"
69
-            stroke-width$="${config.stroke_width || 6}" 
70
-            transform="rotate(-90 100 100)"/>
71
-        </svg>
72
-        <span class="labelContainer">
73
-          ${config.name != null ? html`<span id="name">${config.name}</span>` : ''}
74
-          <span id="label" class$="${!!config.name ? 'bold' : ''}">
75
-            <span class="text">
76
-              ${config.attribute ? state.attributes[config.attribute] : state.state}
77
-            </span>
78
-            <span class="unit">
79
-              ${config.show_max
80
-                ? html`&nbsp/ ${config.attribute_max ? state.attributes[config.attribute_max] : config.max}`
81
-                : (config.units ? config.units : state.attributes.unit_of_measurement)}
82
-            </span>
83
-          </span>
84
-        </span>
85
-      </div>
86
-    `;
87
-  }
88
-
89
-  _createRoot() {
90
-    const shadow = this.attachShadow({ mode: 'open' })
91
-    if (!this.config.show_card) {
92
-      return shadow;
93
-    }
94
-    const card = document.createElement('ha-card');
95
-    shadow.appendChild(card);
96
-    return card;
97
-  }
98
-
99
-  _didRender() {
100
-    this.circle = this._root.querySelector('#circle');
101
-    if (this.config) {
102
-      this._updateConfig();
103
-    }
104
-  }
105
-
106
-  setConfig(config) {
107
-    if (!config.entity) {
108
-      throw Error('No entity defined')
109
-    }
110
-    this.config = config;
111
-    if (this.circle) {
112
-      this._updateConfig();
113
-    }
114
-  }
115
-
116
-  getCardSize() {
117
-    return 3;
118
-  }
119
-
120
-  _updateConfig() {
121
-    const container = this._root.querySelector('.labelContainer');
122
-    container.style.color = 'var(--primary-text-color)';
123
-
124
-    if (this.config.font_style) {
125
-      Object.keys(this.config.font_style).forEach((prop) => {
126
-        container.style.setProperty(prop, this.config.font_style[prop]);
127
-      });
128
-    }
129
-  }
130
-
131
-  set hass(hass) {
132
-    this.state = hass.states[this.config.entity];
133
-
134
-    if (this.config.attribute) {
135
-      if (!this.state.attributes[this.config.attribute] ||
136
-          isNaN(this.state.attributes[this.config.attribute])) {
137
-        console.error(`Attribute [${this.config.attribute}] is not a number`);
138
-        return;
139
-      }
140
-    } else {
141
-      if (!this.state || isNaN(this.state.state)) {
142
-        console.error(`State is not a number`);
143
-        return;
144
-      }
145
-    }
146
-
147
-    const state = this.config.attribute
148
-      ? this.state.attributes[this.config.attribute]
149
-      : this.state.state;
150
-    const r = 200 * .45;
151
-    const min = this.config.min || 0;
152
-    const max = this.config.attribute_max
153
-      ? this.state.attributes[this.config.attribute_max]
154
-      : (this.config.max || 100);
155
-    const val = this._calculateValueBetween(min, max, state);
156
-    const score = val * 2 * Math.PI * r;
157
-    const total = 10 * r;
158
-    this.dashArray = `${score} ${total}`;
159
-
160
-    let colorStops = {};
161
-    colorStops[min] = this.config.stroke_color || '#03a9f4';
162
-    if (this.config.color_stops) {
163
-      Object.keys(this.config.color_stops).forEach((key) => {
164
-        colorStops[key] = this.config.color_stops[key];
165
-      });
166
-    }
167
-
168
-    if (this.circle) {
169
-      const stroke = this._calculateStrokeColor(state, colorStops);
170
-      this.circle.setAttribute('stroke', stroke);
171
-    }
172
-  }
173
-
174
-  _click() {
175
-    this._fire('hass-more-info', { entityId: this.config.entity });
176
-  }
177
-
178
-  _calculateStrokeColor(state, stops) {
179
-    const sortedStops = Object.keys(stops).map(n => Number(n)).sort((a, b) => a - b);
180
-    let start, end, val;
181
-    const l = sortedStops.length;
182
-    if (state <= sortedStops[0]) {
183
-      return stops[sortedStops[0]];
184
-    } else if (state >= sortedStops[l - 1]) {
185
-      return stops[sortedStops[l - 1]];
186
-    } else {
187
-      for (let i = 0; i < l - 1; i++) {
188
-        const s1 = sortedStops[i];
189
-        const s2 = sortedStops[i + 1];
190
-        if (state >= s1 && state < s2) {
191
-          [start, end] = [stops[s1], stops[s2]];
192
-          if (!this.config.gradient) {
193
-            return start;
194
-          }
195
-          val = this._calculateValueBetween(s1, s2, state);
196
-          break;
197
-        }
198
-      }
199
-    }
200
-    return this._getGradientValue(start, end, val);
201
-  }
202
-
203
-  _calculateValueBetween(start, end, val) {
204
-    return (val - start) / (end - start);
205
-  }
206
-
207
-  _getGradientValue(colorA, colorB, val) {
208
-    const v1 = 1 - val;
209
-    const v2 = val;
210
-    const decA = this._hexColorToDecimal(colorA);
211
-    const decB = this._hexColorToDecimal(colorB);
212
-    const rDec = Math.floor((decA[0] * v1) + (decB[0] * v2));
213
-    const gDec = Math.floor((decA[1] * v1) + (decB[1] * v2));
214
-    const bDec = Math.floor((decA[2] * v1) + (decB[2] * v2));
215
-    const rHex = this._padZero(rDec.toString(16));
216
-    const gHex = this._padZero(gDec.toString(16));
217
-    const bHex = this._padZero(bDec.toString(16));
218
-    return `#${rHex}${gHex}${bHex}`;
219
-  }
220
-
221
-  _hexColorToDecimal(color) {
222
-    let c = color.substr(1);
223
-    if (c.length === 3) {
224
-      c = `${c[0]}${c[0]}${c[1]}${c[1]}${c[2]}${c[2]}`;
225
-    }
226
-
227
-    const [r, g, b] = c.match(/.{2}/g);
228
-    return [parseInt(r, 16), parseInt(g, 16), parseInt(b, 16)];
229
-  }
230
-
231
-  _padZero(val) {
232
-    if (val.length < 2) {
233
-      val = `0${val}`;
234
-    }
235
-    return val.substr(0, 2);
236
-  }
237
-
238
-  _fire(type, detail) {
239
-    const event = new Event(type, {
240
-      bubbles: true,
241
-      cancelable: false,
242
-      composed: true
243
-    });
244
-    event.detail = detail || {};
245
-    this.shadowRoot.dispatchEvent(event);
246
-    return event;
247
-  }
248
-}
249
-customElements.define('circle-sensor-card', CircleSensorCard);

+ 0
- 1899
config/www/circle-sensor-card.js.htm
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 0
- 179
config/www/surveillance-card.js Ver arquivo

@@ -1,179 +0,0 @@
1
-import {
2
-  LitElement, html
3
-} from 'https://unpkg.com/@polymer/lit-element@^0.5.2/lit-element.js?module';
4
-
5
-import { repeat } from 'https://unpkg.com/lit-html@0.10.2/lib/repeat.js?module';
6
-
7
-class SurveillanceCard extends LitElement {
8
-  /* eslint-disable indent,object-curly-newline */
9
-  _render({ imageSources, currentCamera, lastMotion, updateInterval }) {
10
-    const accessToken = currentCamera && this._hass.states[currentCamera].attributes.access_token;
11
-    const template = html`
12
-    <style>
13
-      .container {
14
-        height: 100%;
15
-        width: 100%;
16
-        display: flex;
17
-        align-items: stretch;
18
-        position: absolute;
19
-        background: #000;
20
-      }
21
-
22
-      .thumbs {
23
-        flex: 1;
24
-        overflow-y: auto;
25
-        position:relative;
26
-      }
27
-
28
-      .thumb > img {
29
-        width: 100%;
30
-        height: auto;
31
-        border: 1px solid var(--primary-color);
32
-      }
33
-
34
-      .thumb {
35
-        width: calc(100% - 9px);
36
-        padding: 2px 4px;
37
-        position: relative;
38
-      }
39
-
40
-      .thumb.motion > img {
41
-        border-color: var(--accent-color);
42
-      }
43
-
44
-      img {
45
-        display: block;
46
-      }
47
-
48
-      .mainImage {
49
-        flex: 3;
50
-        height: 100%;
51
-        position: relative;
52
-        display: flex;
53
-        align-items: center;
54
-        justify-content: center;
55
-        overflow: hidden;
56
-      }
57
-
58
-      .mainImage > img {
59
-        display: inline-block;
60
-        max-width: 100%;
61
-        max-height: 100%;
62
-      }
63
-
64
-      .loading {
65
-        color: #FFF;
66
-        text-align: center;
67
-        font-size: 1.2rem;
68
-        margin-top: 3rem;
69
-      }
70
-    </style>
71
-    <div class="container">
72
-      <div class="thumbs">
73
-        ${imageSources ? repeat(this.cameras, (camera) => {
74
-          const thumbClass = lastMotion && lastMotion === camera.motion ? 'thumb motion' : 'thumb';
75
-          const source = this.imageSources[camera.entity];
76
-          return html`
77
-            <div class$="${thumbClass}" on-click="${() => { this.currentCamera = camera.entity; }}">
78
-              <img src="${source || ''}" />
79
-            </div>
80
-          `;
81
-        }) : html`<div class="loading">Loading Cameras...</div>`}
82
-      </div>
83
-      <div class="mainImage">
84
-        <img src$="${currentCamera ? `/api/camera_proxy_stream/${currentCamera}?token=${accessToken}&interval=${updateInterval}` : ''}" />
85
-      </div>
86
-    </div>
87
-    `;
88
-
89
-    return template;
90
-  }
91
-  /* eslint-enable indent,object-curly-newline */
92
-
93
-  static get properties() {
94
-    return {
95
-      _hass: Object,
96
-      cameras: Array,
97
-      currentCamera: String,
98
-      imageSources: Object,
99
-      lastMotion: String,
100
-      thumbInterval: Number,
101
-      updateInterval: Number
102
-    };
103
-  }
104
-
105
-  setConfig(config) {
106
-    this.cameras = config.cameras.map(c => ({
107
-      entity: c.entity,
108
-      motion: c.motion_entity
109
-    }));
110
-    this.currentCamera = this.cameras[0].entity;
111
-    this.thumbInterval = (config.thumb_interval || 10) * 1000;
112
-    this.updateInterval = config.update_interval || 1;
113
-    this.focusMotion = config.focus_motion !== false;
114
-  }
115
-
116
-  set hass(hass) {
117
-    this._hass = hass;
118
-
119
-    for (const cam of this.cameras) {
120
-      const { motion } = cam;
121
-      if ((motion in hass.states) && hass.states[motion].state === 'on') {
122
-        if (this.focusMotion && this.lastMotion !== motion) {
123
-          this.currentCamera = cam.entity;
124
-        }
125
-        this.lastMotion = motion;
126
-        return;
127
-      }
128
-    }
129
-    this.lastMotion = null;
130
-  }
131
-
132
-  connectedCallback() {
133
-    super.connectedCallback();
134
-    this.thumbUpdater = setInterval(() => this._updateThumbs(), this.thumbInterval);
135
-  }
136
-
137
-  disconnectedCallback() {
138
-    super.disconnectedCallback();
139
-    clearInterval(this.thumbUpdater);
140
-    this.imageSources = null;
141
-    this.currentCamera = '';
142
-  }
143
-
144
-  _firstRendered() {
145
-    this._updateThumbs();
146
-  }
147
-
148
-  async _updateCameraImageSrc(entity) {
149
-    try {
150
-      const { content_type: contentType, content } = await this._hass.callWS({
151
-        type: 'camera_thumbnail',
152
-        entity_id: entity,
153
-      });
154
-
155
-      return {
156
-        entityId: entity,
157
-        src: `data:${contentType};base64, ${content}`
158
-      };
159
-    } catch (err) {
160
-      return {
161
-        entityId: entity,
162
-        src: null
163
-      };
164
-    }
165
-  }
166
-
167
-  _updateThumbs() {
168
-    const sources = {};
169
-    const promises = this.cameras.map(camera => this._updateCameraImageSrc(camera.entity));
170
-    Promise.all(promises).then((vals) => {
171
-      this.cameras.forEach((camera) => {
172
-        const target = vals.find(val => val.entityId === camera.entity);
173
-        sources[camera.entity] = target.src;
174
-      });
175
-      this.imageSources = sources;
176
-    });
177
-  }
178
-}
179
-customElements.define('surveillance-card', SurveillanceCard);

+ 2
- 1
docker-compose.yml Ver arquivo

@@ -2,12 +2,13 @@ version: '2.0'
2 2
 services:
3 3
   homeassistant:
4 4
     container_name: home-assistant
5
-    image: homeassistant/raspberrypi3-homeassistant:0.92.2
5
+    image: homeassistant/raspberrypi3-homeassistant:0.95.4
6 6
     restart: always
7 7
     devices:
8 8
       - /dev/video0:/dev/video0
9 9
     volumes:
10 10
       - ./config:/config
11
+      - ./snapshots:/snapshots
11 12
       - ./keys:/root/.ssh/
12 13
       - /etc/localtime:/etc/localtime:ro
13 14
       - /dev/mem:/dev/mem

Carregando…
Cancelar
Salvar