瀏覽代碼

Adressable LED Strip and many more changes.

Joshua Rutschmann 6 年之前
父節點
當前提交
bb03c7dc4f
共有 8 個檔案被更改,包括 346 行新增11 行删除
  1. 11
    0
      config/automations.yaml
  2. 76
    4
      config/configuration.yaml
  3. 10
    0
      config/customize.yaml
  4. 5
    0
      config/groups.yaml
  5. 24
    0
      config/known_devices.yaml
  6. 17
    6
      config/ui-lovelace.yaml
  7. 201
    0
      config/www/gauge-card.js
  8. 2
    1
      docker-compose.yml

+ 11
- 0
config/automations.yaml 查看文件

88
   action:
88
   action:
89
     service: switch.turn_off
89
     service: switch.turn_off
90
     entity_id: switch.subwoofer    
90
     entity_id: switch.subwoofer    
91
+- alias: "Porch Animation Speed"
92
+  initial_state: True
93
+  hide_entity: True
94
+  trigger:
95
+    - platform: state
96
+      entity_id: input_number.porch_animation_speed
97
+  action:
98
+    - service: mqtt.publish
99
+      data_template:
100
+        topic: "bruh/porch/set"
101
+        payload: '{"transition":{{ trigger.to_state.state | int }}}'

+ 76
- 4
config/configuration.yaml 查看文件

21
 frontend:
21
 frontend:
22
   themes: !include midnight.yaml
22
   themes: !include midnight.yaml
23
 
23
 
24
+#logger:
25
+#  default: critical
26
+#  logs:
27
+#    homeassistant.components.http.ban: warning
28
+  
24
 # Enables configuration UI
29
 # Enables configuration UI
25
 config:
30
 config:
26
 
31
 
32
+octoprint:
33
+  host: 192.168.1.163
34
+  port: 5000
35
+  api_key: 4C627EC30E884B1D9B65A7058FC67925
36
+
27
 weather:
37
 weather:
28
   - platform: openweathermap
38
   - platform: openweathermap
29
     name: Weather
39
     name: Weather
31
 
41
 
32
 map:
42
 map:
33
 
43
 
44
+ffmpeg:
45
+  ffmpeg_bin: /usr/bin/ffmpeg
46
+
34
 camera:
47
 camera:
35
-  - platform: local_file
36
-    name: Webcam
37
-    file_path: /var/lib/motion/lastsnap.jpg
48
+   - platform: ffmpeg
49
+     ffmpeg_bin: /usr/bin/ffmpeg
50
+     name: Webcam
51
+     input: -i /dev/video0
52
+     extra_arguments: -f video4linux2
38
 
53
 
39
 homekit:
54
 homekit:
40
   filter:
55
   filter:
50
 
65
 
51
 history:
66
 history:
52
 
67
 
68
+input_number:
69
+  porch_animation_speed:
70
+    name: LED Strip Animation Speed
71
+    initial: 150
72
+    min: 1
73
+    max: 150
74
+    step: 10
75
+
53
 device_tracker:
76
 device_tracker:
54
   - platform: fritz
77
   - platform: fritz
78
+    host: 192.168.2.1
55
     new_device_defaults:
79
     new_device_defaults:
56
       track_new_devices: False
80
       track_new_devices: False
57
       hide_if_away: False
81
       hide_if_away: False
69
   password: Mindabew1
93
   password: Mindabew1
70
 
94
 
71
 sensor:
95
 sensor:
96
+  - platform: cpuspeed
72
   - platform: dht
97
   - platform: dht
73
     sensor: DHT22
98
     sensor: DHT22
74
     pin: 18
99
     pin: 18
76
       - temperature
101
       - temperature
77
       - humidity
102
       - humidity
78
   - platform: fritzbox_callmonitor
103
   - platform: fritzbox_callmonitor
104
+    host: 192.168.2.1
79
     name: Phone
105
     name: Phone
80
     username: homeassistant
106
     username: homeassistant
81
     password: !secret fritz_password
107
     password: !secret fritz_password
101
     refresh: 60
127
     refresh: 60
102
   humidity:
128
   humidity:
103
     name: Humidity
129
     name: Humidity
130
+    refresh: 60
104
     entities:
131
     entities:
105
       - sensor.dht_sensor_humidity
132
       - sensor.dht_sensor_humidity
106
     hours_to_show: 12
133
     hours_to_show: 12
134
+  octoprint:
135
+    name: OctoPrint
136
+    refresh: 1
137
+    entities:
138
+      - sensor.octoprint_actual_bed_temp
139
+      - sensor.octoprint_actual_tool0_temp
140
+      - sensor.octoprint_target_bed_temp
141
+      - sensor.octoprint_target_tool0_temp
142
+    hours_to_show: 1
143
+  
107
   
144
   
145
+
108
 lock:
146
 lock:
109
   - platform: template
147
   - platform: template
110
     name: Schloss
148
     name: Schloss
139
         turn_off:
177
         turn_off:
140
           service: switch.turn_off
178
           service: switch.turn_off
141
           entity_id: switch.lightrelay
179
           entity_id: switch.lightrelay
180
+  - platform: mqtt_json
181
+    name: "WS2812B Strip"
182
+    state_topic: "bruh/porch"
183
+    command_topic: "bruh/porch/set"
184
+    effect: true
185
+    effect_list:
186
+      - bpm
187
+      - candy cane  
188
+      - confetti  
189
+      - cyclon rainbow  
190
+      - dots  
191
+      - fire  
192
+      - glitter  
193
+      - juggle  
194
+      - lightning
195
+      - noise  
196
+      - police all  
197
+      - police one  
198
+      - rainbow  
199
+      - rainbow with glitter  
200
+      - ripple  
201
+      - sinelon  
202
+      - solid  
203
+      - twinkle  
204
+    brightness: true
205
+    flash: true
206
+    rgb: true
207
+    optimistic: false
208
+    qos: 0
142
 
209
 
143
 switch:
210
 switch:
144
   - platform: wake_on_lan
211
   - platform: wake_on_lan
193
   turn_on_hdmi: 'echo vcgencmd display_power 1 | ssh pi@192.168.1.179'
260
   turn_on_hdmi: 'echo vcgencmd display_power 1 | ssh pi@192.168.1.179'
194
   turn_off_hdmi: 'echo vcgencmd display_power 0 | ssh pi@192.168.1.179'
261
   turn_off_hdmi: 'echo vcgencmd display_power 0 | ssh pi@192.168.1.179'
195
 
262
 
196
-      
197
 api:
263
 api:
198
 
264
 
199
 alexa:
265
 alexa:
203
         - automation
269
         - automation
204
         - group
270
         - group
205
       exclude_entities:
271
       exclude_entities:
272
+        - sensor.octoprint_target_bed_temp
273
+        - sensor.octoprint_target_tool0_temp
206
         - switch.coverdirection
274
         - switch.coverdirection
207
         - switch.coverenable
275
         - switch.coverenable
208
         - switch.lightrelay
276
         - switch.lightrelay
210
 http:
278
 http:
211
   api_password: !secret http_password
279
   api_password: !secret http_password
212
   base_url: https://home.rutschmann.tech
280
   base_url: https://home.rutschmann.tech
281
+  server_port: 443
282
+  ssl_profile: intermediate
283
+  ssl_certificate: /config/ssl/fullchain.pem
284
+  ssl_key: /config/ssl/privkey.pem
213
 
285
 
214
 ifttt:
286
 ifttt:
215
   key: !secret webhooks_key
287
   key: !secret webhooks_key

+ 10
- 0
config/customize.yaml 查看文件

18
   hidden: true
18
   hidden: true
19
 binary_sensor.pir:
19
 binary_sensor.pir:
20
   friendly_name: Movement
20
   friendly_name: Movement
21
+sensor.octoprint_actual_bed_temp:
22
+  friendly_name: Bed Temperature
23
+sensor.octoprint_actual_tool0_temp:
24
+  friendly_name: Hotend Temperature
25
+sensor.octoprint_target_bed_temp:
26
+  friendly_name: Target Bed Temperature
27
+sensor.octoprint_target_tool0_temp:
28
+  friendly_name: Target Hotend Temperature
29
+sensor.dht_sensor_temperature:
30
+  friendly_name: Temperature

+ 5
- 0
config/groups.yaml 查看文件

7
     entities:
7
     entities:
8
       - sensor.dht_sensor_temperature
8
       - sensor.dht_sensor_temperature
9
       - sensor.dht_sensor_humidity
9
       - sensor.dht_sensor_humidity
10
+      - binary_sensor.pir
11
+      - binary_sensor.door
12
+      - weather.weather
10
       - history_graph.humidity
13
       - history_graph.humidity
11
       - history_graph.temperature
14
       - history_graph.temperature
15
+      - history_graph.octoprint
12
       - group.switches
16
       - group.switches
13
       - group.all_automations
17
       - group.all_automations
14
       - group.lights
18
       - group.lights
22
       - switch.anet
26
       - switch.anet
23
       - switch.subwoofer
27
       - switch.subwoofer
24
       - switch.desktop
28
       - switch.desktop
29
+      - light.hdmi
25
 
30
 
26
 lights:
31
 lights:
27
     name: Lights
32
     name: Lights

+ 24
- 0
config/known_devices.yaml 查看文件

262
   name: b827eb023229
262
   name: b827eb023229
263
   picture:
263
   picture:
264
   track: false
264
   track: false
265
+
266
+9060f1190d31:
267
+  hide_if_away: false
268
+  icon:
269
+  mac: 90:60:F1:19:0D:31
270
+  name: 9060f1190d31
271
+  picture:
272
+  track: false
273
+
274
+b49d0b5f53ed:
275
+  hide_if_away: false
276
+  icon:
277
+  mac: B4:9D:0B:5F:53:ED
278
+  name: b49d0b5f53ed
279
+  picture:
280
+  track: false
281
+
282
+18fe3498a0b0:
283
+  hide_if_away: false
284
+  icon:
285
+  mac: 18:FE:34:98:A0:B0
286
+  name: 18fe3498a0b0
287
+  picture:
288
+  track: false

+ 17
- 6
config/ui-lovelace.yaml 查看文件

1
 title: Tannenhof
1
 title: Tannenhof
2
 
2
 
3
+resources:
4
+  - url: /local/gauge-card.js?v=1
5
+    type: js
6
+
3
 views:
7
 views:
4
     # View tab title.
8
     # View tab title.
5
   - title: Josh's Room
9
   - title: Josh's Room
13
     cards:
17
     cards:
14
       - id: 698b0d61c8d64ee9a0b762080adbd009  # Automatically created id
18
       - id: 698b0d61c8d64ee9a0b762080adbd009  # Automatically created id
15
         type: weather-forecast
19
         type: weather-forecast
16
-        entity: weather.openweathermap
20
+        entity: weather.weather
17
       - id: b900d5426e5d465bb4b5d92e590da361  # Automatically created id
21
       - id: b900d5426e5d465bb4b5d92e590da361  # Automatically created id
18
         type: entities
22
         type: entities
19
         title: Joshs Room
23
         title: Joshs Room
24
           - cover.blinds
28
           - cover.blinds
25
           - media_player.spotify
29
           - media_player.spotify
26
         # The markdown card will render markdown text.
30
         # The markdown card will render markdown text.
27
-      - id: 84fa7b0ae50d4c6fa2a7cea147859cb0  # Automatically created id
28
-        type: markdown
29
-        title: Lovelace
30
-        content: >
31
-          Welcome to your **Lovelace UI**.
31
+      - type: custom:gauge-card
32
+        title: Temperature
33
+        entity: sensor.dht_sensor_temperature
34
+        min: -20
35
+        max: 35
36
+      - type: custom:gauge-card
37
+        title: Printer Hotend
38
+        entity: sensor.octoprint_actual_tool0_temp
39
+        severity:
40
+          red: 50
41
+          green: 0
42
+          amber: 40

+ 201
- 0
config/www/gauge-card.js 查看文件

1
+class GaugeCard extends HTMLElement {
2
+  constructor() {
3
+    super();
4
+    this.attachShadow({ mode: 'open' });
5
+  }
6
+  setConfig(config) {
7
+    if (!config.entity) {
8
+      throw new Error('Please define an entity');
9
+    }
10
+
11
+    const root = this.shadowRoot;
12
+    if (root.lastChild) root.removeChild(root.lastChild);
13
+
14
+    const cardConfig = Object.assign({}, config);
15
+    if (!cardConfig.scale) cardConfig.scale = "50px";
16
+    if (!cardConfig.min) cardConfig.min = 0;
17
+    if (!cardConfig.max) cardConfig.max = 100;
18
+
19
+    const entityParts = this._splitEntityAndAttribute(cardConfig.entity);
20
+    cardConfig.entity = entityParts.entity;
21
+    if (entityParts.attribute) cardConfig.attribute = entityParts.attribute;
22
+
23
+    const card = document.createElement('ha-card');
24
+    const shadow = card.attachShadow({ mode: 'open' });
25
+    const content = document.createElement('div');
26
+    const style = document.createElement('style');
27
+    style.textContent = `
28
+      ha-card {
29
+        --base-unit: ${cardConfig.scale};
30
+        height: calc(var(--base-unit)*3);
31
+        position: relative;
32
+      }
33
+      .container{
34
+        width: calc(var(--base-unit) * 4);
35
+        height: calc(var(--base-unit) * 2);
36
+        position: absolute;
37
+        top: calc(var(--base-unit)*1.5);
38
+        left: 50%;
39
+        overflow: hidden;
40
+        text-align: center;
41
+        transform: translate(-50%, -50%);
42
+      }
43
+      .gauge-a{
44
+        z-index: 1;
45
+        position: absolute;
46
+        background-color: var(--primary-background-color);
47
+        width: calc(var(--base-unit) * 4);
48
+        height: calc(var(--base-unit) * 2);
49
+        top: 0%;
50
+        border-radius:calc(var(--base-unit) * 2.5) calc(var(--base-unit) * 2.5) 0px 0px ;
51
+      }
52
+      .gauge-b{
53
+        z-index: 3;
54
+        position: absolute;
55
+        background-color: var(--paper-card-background-color);
56
+        width: calc(var(--base-unit) * 2.5);
57
+        height: calc(var(--base-unit) * 1.25);
58
+        top: calc(var(--base-unit) * 0.75);
59
+        margin-left: calc(var(--base-unit) * 0.75);
60
+        margin-right: auto;
61
+        border-radius: calc(var(--base-unit) * 2.5) calc(var(--base-unit) * 2.5) 0px 0px ;
62
+      }
63
+      .gauge-c{
64
+        z-index: 2;
65
+        position: absolute;
66
+        background-color: var(--label-badge-yellow);
67
+        width: calc(var(--base-unit) * 4);
68
+        height: calc(var(--base-unit) * 2);
69
+        top: calc(var(--base-unit) * 2);
70
+        margin-left: auto;
71
+        margin-right: auto;
72
+        border-radius: 0px 0px calc(var(--base-unit) * 2) calc(var(--base-unit) * 2) ;
73
+        transform-origin: center top;
74
+        transition: all 1.3s ease-in-out;
75
+      }
76
+      .gauge-data{
77
+        z-index: 4;
78
+        color: var(--primary-text-color);
79
+        line-height: calc(var(--base-unit) * 0.3);
80
+        position: absolute;
81
+        width: calc(var(--base-unit) * 4);
82
+        height: calc(var(--base-unit) * 2.1);
83
+        top: calc(var(--base-unit) * 1.2);
84
+        margin-left: auto;
85
+        margin-right: auto;
86
+        transition: all 1s ease-out;
87
+      }
88
+      .gauge-data #percent{
89
+        font-size: calc(var(--base-unit) * 0.55);
90
+      }
91
+      .gauge-data #title{
92
+        padding-top: calc(var(--base-unit) * 0.15);
93
+        font-size: calc(var(--base-unit) * 0.30);
94
+      }
95
+    `;
96
+    content.innerHTML = `
97
+      <div class="container">
98
+        <div class="gauge-a"></div>
99
+        <div class="gauge-b"></div>
100
+        <div class="gauge-c" id="gauge"></div>
101
+        <div class="gauge-data"><div id="percent"></div><div id="title"></div></div>
102
+      </div>
103
+    `;
104
+    card.appendChild(content);
105
+    card.appendChild(style);
106
+    card.addEventListener('click', event => {
107
+      this._fire('hass-more-info', { entityId: cardConfig.entity });
108
+    });
109
+    root.appendChild(card);
110
+    this._config = cardConfig;
111
+  }
112
+
113
+  _splitEntityAndAttribute(entity) {
114
+      let parts = entity.split('.');
115
+      if (parts.length < 3) {
116
+          return { entity: entity };
117
+      }
118
+
119
+      return { attribute: parts.pop(), entity: parts.join('.') };
120
+  }
121
+
122
+  _fire(type, detail, options) {
123
+    const node = this.shadowRoot;
124
+    options = options || {};
125
+    detail = (detail === null || detail === undefined) ? {} : detail;
126
+    const event = new Event(type, {
127
+      bubbles: options.bubbles === undefined ? true : options.bubbles,
128
+      cancelable: Boolean(options.cancelable),
129
+      composed: options.composed === undefined ? true : options.composed
130
+    });
131
+    event.detail = detail;
132
+    node.dispatchEvent(event);
133
+    return event;
134
+  }
135
+
136
+  _translateTurn(value, config) {
137
+    return 5 * (value - config.min) / (config.max - config.min)
138
+  }
139
+
140
+  _computeSeverity(stateValue, sections) {
141
+    let numberValue = Number(stateValue);
142
+    const severityMap = {
143
+      red: "var(--label-badge-red)",
144
+      green: "var(--label-badge-green)",
145
+      amber: "var(--label-badge-yellow)",
146
+      normal: "var(--label-badge-blue)",
147
+    }
148
+    if (!sections) return severityMap["normal"];
149
+    let sortable = [];
150
+    for (let severity in sections) {
151
+      sortable.push([severity, sections[severity]]);
152
+    }
153
+    sortable.sort((a, b) => { return a[1] - b[1] });
154
+
155
+    if (numberValue >= sortable[0][1] && numberValue < sortable[1][1]) {
156
+      return severityMap[sortable[0][0]]
157
+    }
158
+    if (numberValue >= sortable[1][1] && numberValue < sortable[2][1]) {
159
+      return severityMap[sortable[1][0]]
160
+    }
161
+    if (numberValue >= sortable[2][1]) {
162
+      return severityMap[sortable[2][0]]
163
+    }
164
+    return severityMap["normal"];
165
+  }
166
+
167
+  _getEntityStateValue(entity, attribute) {
168
+    if (!attribute) {
169
+      return entity.state;
170
+    }
171
+
172
+    return entity.attributes[attribute];
173
+  }
174
+
175
+  set hass(hass) {
176
+    const config = this._config;
177
+    const entityState = this._getEntityStateValue(hass.states[config.entity], config.attribute);
178
+    let measurement = "";
179
+    if (config.measurement == null)
180
+      measurement = hass.states[config.entity].attributes.unit_of_measurement;
181
+    else
182
+      measurement = config.measurement;
183
+
184
+    const root = this.shadowRoot;
185
+    if (entityState !== this._entityState) {
186
+      root.getElementById("percent").textContent = `${entityState} ${measurement}`;
187
+      root.getElementById("title").textContent = config.title;
188
+      const turn = this._translateTurn(entityState, config) / 10;
189
+      root.getElementById("gauge").style.transform = `rotate(${turn}turn)`;
190
+      root.getElementById("gauge").style.backgroundColor = this._computeSeverity(entityState, config.severity);
191
+      this._entityState = entityState;
192
+    }
193
+    root.lastChild.hass = hass;
194
+  }
195
+
196
+  getCardSize() {
197
+    return 1;
198
+  }
199
+}
200
+
201
+customElements.define('gauge-card', GaugeCard);

+ 2
- 1
docker-compose.yml 查看文件

4
     container_name: home-assistant
4
     container_name: home-assistant
5
     image: homeassistant/raspberrypi3-homeassistant
5
     image: homeassistant/raspberrypi3-homeassistant
6
     restart: always
6
     restart: always
7
+    devices:
8
+      - /dev/video0:/dev/video0
7
     volumes:
9
     volumes:
8
       - ./config:/config
10
       - ./config:/config
9
       - ./keys:/root/.ssh/
11
       - ./keys:/root/.ssh/
10
       - /etc/localtime:/etc/localtime:ro
12
       - /etc/localtime:/etc/localtime:ro
11
-      - /var/lib/motion:/var/lib/motion
12
       - /dev/mem:/dev/mem
13
       - /dev/mem:/dev/mem
13
     restart: always
14
     restart: always
14
     privileged: true
15
     privileged: true

Loading…
取消
儲存