Browse Source

add sensors, credentials.js file

Thomas Buck 1 year ago
parent
commit
eba973df0e
4 changed files with 185 additions and 26 deletions
  1. 1
    0
      .gitignore
  2. 9
    1
      README.md
  3. 172
    20
      lights/index.html
  4. 3
    5
      lights/lights.js

+ 1
- 0
.gitignore View File

1
+lights/credentials.js

+ 9
- 1
README.md View File

2
 
2
 
3
 Simple Bootstrap webinterface to control room lights via MQTT.
3
 Simple Bootstrap webinterface to control room lights via MQTT.
4
 
4
 
5
-Run `localtest.py` and open `http://localhost:8080` to access local test instance.
5
+## Quick started
6
+
7
+To set up the MQTT broker credentials, run the following commands:
8
+
9
+    echo "const mqttUsername = 'MQTT_USERNAME'" > lights/credentials.js
10
+    echo "const mqttPassword = 'MQTT_PASSWORD'" >> lights/credentials.js
11
+    echo "const mqttUrl = 'wss://MQTT_HOST:MQTT_PORT'" >> lights/credentials.js
12
+
13
+Then run `localtest.py` and open `http://localhost:8080` to access local test instance.
6
 
14
 
7
 ## Sources
15
 ## Sources
8
 
16
 

+ 172
- 20
lights/index.html View File

19
 
19
 
20
             <nav>
20
             <nav>
21
                 <div class="nav nav-tabs" id="nav-tab" role="tablist">
21
                 <div class="nav nav-tabs" id="nav-tab" role="tablist">
22
+                    <button class="nav-link" id="nav-livingroom-tab" data-bs-toggle="tab" data-bs-target="#nav-livingroom" type="button" role="tab" aria-controls="nav-livingroom" aria-selected="false">
23
+                        Livingroom
24
+                    </button>
22
                     <button class="nav-link active" id="nav-bathroom-tab" data-bs-toggle="tab" data-bs-target="#nav-bathroom" type="button" role="tab" aria-controls="nav-bathroom" aria-selected="true">
25
                     <button class="nav-link active" id="nav-bathroom-tab" data-bs-toggle="tab" data-bs-target="#nav-bathroom" type="button" role="tab" aria-controls="nav-bathroom" aria-selected="true">
23
                         Bathroom
26
                         Bathroom
24
                     </button>
27
                     </button>
25
-                    <button class="nav-link" id="nav-livingroom-tab" data-bs-toggle="tab" data-bs-target="#nav-livingroom" type="button" role="tab" aria-controls="nav-livingroom" aria-selected="false">
26
-                        Livingroom
28
+                    <button class="nav-link" id="nav-help-tab" data-bs-toggle="tab" data-bs-target="#nav-help" type="button" role="tab" aria-controls="nav-help" aria-selected="false">
29
+                        Help
27
                     </button>
30
                     </button>
28
                 </div>
31
                 </div>
29
             </nav>
32
             </nav>
38
                 <div class="tab-pane fade show active" id="nav-bathroom" role="tabpanel" aria-labelledby="nav-bathroom-tab" tabindex="0">
41
                 <div class="tab-pane fade show active" id="nav-bathroom" role="tabpanel" aria-labelledby="nav-bathroom-tab" tabindex="0">
39
                     <div class="row">
42
                     <div class="row">
40
                         <div class="col">
43
                         <div class="col">
41
-                            Lights
44
+                            <h2>Actors</h2>
45
+                        </div>
46
+                    </div>
47
+
48
+                    <div class="row">
49
+                        <div class="col">
50
+                            <p>Lights</p>
42
                         </div>
51
                         </div>
43
                         <div class="col">
52
                         <div class="col">
44
                             <div class="btn-group" role="group">
53
                             <div class="btn-group" role="group">
45
-                                <input type="radio" class="btn-check" name="btnradio" id="bathroomlightauto" autocomplete="off">
54
+                                <input type="radio" class="btn-check" name="bathroomradio" id="bathroomlightauto" autocomplete="off">
46
                                 <label class="btn btn-outline-primary" for="bathroomlightauto">
55
                                 <label class="btn btn-outline-primary" for="bathroomlightauto">
47
                                     Auto
56
                                     Auto
48
                                 </label>
57
                                 </label>
49
-                                <input type="radio" class="btn-check" name="btnradio" id="bathroomlightbig" autocomplete="off">
58
+                                <input type="radio" class="btn-check" name="bathroomradio" id="bathroomlightbig" autocomplete="off">
50
                                 <label class="btn btn-outline-success" for="bathroomlightbig">
59
                                 <label class="btn btn-outline-success" for="bathroomlightbig">
51
                                     Big
60
                                     Big
52
                                 </label>
61
                                 </label>
53
-                                <input type="radio" class="btn-check" name="btnradio" id="bathroomlightsmall" autocomplete="off">
62
+                                <input type="radio" class="btn-check" name="bathroomradio" id="bathroomlightsmall" autocomplete="off">
54
                                 <label class="btn btn-outline-info" for="bathroomlightsmall">
63
                                 <label class="btn btn-outline-info" for="bathroomlightsmall">
55
                                     Small
64
                                     Small
56
                                 </label>
65
                                 </label>
57
-                                <input type="radio" class="btn-check" name="btnradio" id="bathroomlightoff" autocomplete="off">
66
+                                <input type="radio" class="btn-check" name="bathroomradio" id="bathroomlightoff" autocomplete="off">
58
                                 <label class="btn btn-outline-dark" for="bathroomlightoff">
67
                                 <label class="btn btn-outline-dark" for="bathroomlightoff">
59
                                     Off
68
                                     Off
60
                                 </label>
69
                                 </label>
61
                             </div>
70
                             </div>
62
                         </div>
71
                         </div>
63
                     </div>
72
                     </div>
73
+
74
+                    <div class="row">
75
+                        <div class="col">
76
+                            <hr>
77
+                        </div>
78
+                    </div>
79
+
80
+                    <div class="row">
81
+                        <div class="col">
82
+                            <h2>Sensors</h2>
83
+                        </div>
84
+                    </div>
85
+
86
+                    <div class="row">
87
+                        <div class="col">
88
+                            <p>Temperature</p>
89
+                        </div>
90
+                        <div class="col" id="bathtemp">
91
+                            <p>Unknown</p>
92
+                        </div>
93
+                    </div>
94
+
95
+                    <div class="row">
96
+                        <div class="col">
97
+                            <p>Relative Humidity</p>
98
+                        </div>
99
+                        <div class="col" id="bathhumid">
100
+                            <p>Unknown</p>
101
+                        </div>
102
+                    </div>
103
+
104
+                    <div class="row">
105
+                        <div class="col">
106
+                            <p>tVOC</p>
107
+                        </div>
108
+                        <div class="col" id="bathtvoc">
109
+                            <p>Unknown</p>
110
+                        </div>
111
+                    </div>
112
+
113
+                    <div class="row">
114
+                        <div class="col">
115
+                            <p>eCo2</p>
116
+                        </div>
117
+                        <div class="col" id="batheco2">
118
+                            <p>Unknown</p>
119
+                        </div>
120
+                    </div>
121
+
122
+                    <div class="row">
123
+                        <div class="col">
124
+                            <p>Air Pressure</p>
125
+                        </div>
126
+                        <div class="col" id="bathpress">
127
+                            <p>Unknown</p>
128
+                        </div>
129
+                    </div>
64
                 </div>
130
                 </div>
65
 
131
 
66
                 <div class="tab-pane fade" id="nav-livingroom" role="tabpanel" aria-labelledby="nav-livingroom-tab" tabindex="0">
132
                 <div class="tab-pane fade" id="nav-livingroom" role="tabpanel" aria-labelledby="nav-livingroom-tab" tabindex="0">
69
                             <p>No controls available yet.</p>
135
                             <p>No controls available yet.</p>
70
                         </div>
136
                         </div>
71
                     </div>
137
                     </div>
72
-                </div>
73
-            </div>
74
 
138
 
75
-            <div class="row">
76
-                <div class="col">
77
-                    <hr>
139
+                    <div class="row">
140
+                        <div class="col">
141
+                            <p>Workspace Lights</p>
142
+                        </div>
143
+                        <div class="col">
144
+                            <div class="btn-group" role="group">
145
+                                <input type="radio" class="btn-check" name="workspaceradio" id="workspaceon" autocomplete="off">
146
+                                <label class="btn btn-outline-primary" for="workspaceon">
147
+                                    On
148
+                                </label>
149
+                                <input type="radio" class="btn-check" name="workspaceradio" id="workspaceoff" autocomplete="off">
150
+                                <label class="btn btn-outline-dark" for="workspaceoff">
151
+                                    Off
152
+                                </label>
153
+                            </div>
154
+                        </div>
155
+                    </div>
156
+
157
+                    <div class="row">
158
+                        <div class="col">
159
+                            <p>TV Lights</p>
160
+                        </div>
161
+                        <div class="col">
162
+                            <div class="btn-group" role="group">
163
+                                <input type="radio" class="btn-check" name="tvradio" id="tvon" autocomplete="off">
164
+                                <label class="btn btn-outline-primary" for="tvon">
165
+                                    On
166
+                                </label>
167
+                                <input type="radio" class="btn-check" name="tvradio" id="tvoff" autocomplete="off">
168
+                                <label class="btn btn-outline-dark" for="tvoff">
169
+                                    Off
170
+                                </label>
171
+                            </div>
172
+                        </div>
173
+                    </div>
174
+
175
+                    <div class="row">
176
+                        <div class="col">
177
+                            <p>Kitchen Lights</p>
178
+                        </div>
179
+                        <div class="col">
180
+                            <div class="btn-group" role="group">
181
+                                <input type="radio" class="btn-check" name="kitchenradio" id="kitchenon" autocomplete="off">
182
+                                <label class="btn btn-outline-primary" for="kitchenon">
183
+                                    On
184
+                                </label>
185
+                                <input type="radio" class="btn-check" name="kitchenradio" id="kitchenoff" autocomplete="off">
186
+                                <label class="btn btn-outline-dark" for="kitchenoff">
187
+                                    Off
188
+                                </label>
189
+                            </div>
190
+                        </div>
191
+                    </div>
78
                 </div>
192
                 </div>
79
-            </div>
80
 
193
 
81
-            <div class="row">
82
-                <div class="col">
83
-                    <p>Please wait after opening the page until the buttons change to reflect the current state of the lights. If that doesn't happen after a couple of seconds, there is probably a connection problem.</p>
194
+                <div class="tab-pane fade" id="nav-help" role="tabpanel" aria-labelledby="nav-help-tab" tabindex="0">
195
+                    <div class="row">
196
+                        <div class="col">
197
+                            <p><a href=".">Refresh page</a></p>
198
+                        </div>
199
+                    </div>
200
+                    <div class="row">
201
+                        <div class="col">
202
+                            <p>Please wait after opening the page until the buttons change to reflect the current state of the lights. If that doesn't happen after a couple of seconds, there is probably a connection problem.</p>
203
+                        </div>
204
+                    </div>
205
+                    <div class="row">
206
+                        <div class="col">
207
+                            <p><b>Please note:</b> this only works when the MQTT broker and the NodeRED logic are working properly. Also not all web browsers support web socket connections to the MQTT broker. Firefox gives problems, so try a Chromium based browser instead.</p>
208
+                        </div>
209
+                    </div>
84
                 </div>
210
                 </div>
85
             </div>
211
             </div>
212
+
86
             <div class="row">
213
             <div class="row">
87
                 <div class="col">
214
                 <div class="col">
88
-                    <p><b>Please note:</b> this only works when the MQTT broker and the NodeRED logic are working properly. Also not all web browsers support web socket connections to the MQTT broker. Firefox gives problems, so try a Chromium based browser instead.</p>
215
+                    <hr>
89
                 </div>
216
                 </div>
90
             </div>
217
             </div>
218
+
91
         </div>
219
         </div>
92
 
220
 
93
         <!--<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>-->
221
         <!--<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>-->
94
         <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"></script>
222
         <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"></script>
95
         <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
223
         <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
224
+
225
+        <script src="credentials.js"></script>
96
         <script src="lights.js"></script>
226
         <script src="lights.js"></script>
97
 
227
 
98
         <script>
228
         <script>
99
-            const btns = document.querySelectorAll("#bathroomlightauto, #bathroomlightbig, #bathroomlightsmall, #bathroomlightoff")
229
+            const btnsBath = document.querySelectorAll("#bathroomlightauto, #bathroomlightbig, #bathroomlightsmall, #bathroomlightoff")
100
 
230
 
101
             // handle changes to bathroom lights
231
             // handle changes to bathroom lights
102
             subscribeTopic("bathroom/force_light", function (msg) {
232
             subscribeTopic("bathroom/force_light", function (msg) {
103
                 // clear all buttons
233
                 // clear all buttons
104
-                for (const btn of btns) {
234
+                for (const btn of btnsBath) {
105
                     btn.checked = false
235
                     btn.checked = false
106
                 }
236
                 }
107
 
237
 
124
             })
254
             })
125
 
255
 
126
             // set new bathroom light state
256
             // set new bathroom light state
127
-            for (const btn of btns) {
257
+            for (const btn of btnsBath) {
128
                 btn.addEventListener('change', function (e) {
258
                 btn.addEventListener('change', function (e) {
129
                     if (this.checked) {
259
                     if (this.checked) {
130
                         if (this == document.querySelector("#bathroomlightauto")) {
260
                         if (this == document.querySelector("#bathroomlightauto")) {
141
                     }
271
                     }
142
                 })
272
                 })
143
             }
273
             }
274
+
275
+            // handle bathroom sensors
276
+            subscribeTopic("bathroom/temperature", function (msg) {
277
+                const txt = document.querySelector("#bathtemp")
278
+                txt.innerHTML = "<p>" + msg + " °C</p>"
279
+            })
280
+            subscribeTopic("bathroom/humidity", function (msg) {
281
+                const txt = document.querySelector("#bathhumid")
282
+                txt.innerHTML = "<p>" + msg + " %</p>"
283
+            })
284
+            subscribeTopic("bathroom/pressure", function (msg) {
285
+                const txt = document.querySelector("#bathpress")
286
+                txt.innerHTML = "<p>" + msg + " Pa</p>"
287
+            })
288
+            subscribeTopic("bathroom/tvoc", function (msg) {
289
+                const txt = document.querySelector("#bathtvoc")
290
+                txt.innerHTML = "<p>" + msg + "</p>"
291
+            })
292
+            subscribeTopic("bathroom/eco2", function (msg) {
293
+                const txt = document.querySelector("#batheco2")
294
+                txt.innerHTML = "<p>" + msg + " ppm</p>"
295
+            })
144
         </script>
296
         </script>
145
     </body>
297
     </body>
146
 </html>
298
 </html>

+ 3
- 5
lights/lights.js View File

6
  */
6
  */
7
 
7
 
8
 const options = {
8
 const options = {
9
-    // Clean session
10
     clean: true,
9
     clean: true,
11
     connectTimeout: 4000,
10
     connectTimeout: 4000,
12
-    // Auth
13
     clientId: 'lights-web',
11
     clientId: 'lights-web',
14
-    username: 'USER_HERE',
15
-    password: 'PW_HERE',
12
+    username: mqttUsername,
13
+    password: mqttPassword,
16
 }
14
 }
17
 const callbacks = []
15
 const callbacks = []
18
-const client  = mqtt.connect('wss://iot.fritz.box:8083', options)
16
+const client  = mqtt.connect(mqttUrl, options)
19
 
17
 
20
 client.on('connect', function () {
18
 client.on('connect', function () {
21
     console.log('MQTT Connected')
19
     console.log('MQTT Connected')

Loading…
Cancel
Save