frugal-iot-server 0.3.5 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALLATION.md +305 -122
- package/README.md +6 -6
- package/config.d/logger.yaml +16 -0
- package/config.d/schema/modules.yaml +66 -1
- package/config.d/schema/topics.yaml +184 -2
- package/config.d/server.yaml +24 -0
- package/extras/mosquitto.conf +9 -1
- package/frugal-iot-server.js +52 -5
- package/lib/api-routes.js +3 -0
- package/lib/data-loader.js +11 -4
- package/lib/housekeeping.js +251 -0
- package/lib/logger-client.js +16 -0
- package/package.json +7 -3
- package/public/service-worker.js +1 -1
- package/scripts/addorganization.zsh +4 -4
- package/scripts/check-schema.js +127 -0
- package/scripts/copy-schema-to-examples.zsh +55 -0
- package/scripts/diagnostic.zsh +109 -16
- package/scripts/init.zsh +4 -4
- package/scripts/prerelease.zsh +125 -0
- package/scripts/setpassword.zsh +3 -3
package/INSTALLATION.md
CHANGED
|
@@ -5,40 +5,61 @@ an MQTT broker (Mosquitto), the Frugal IoT server, the logger that writes sensor
|
|
|
5
5
|
and the web UI. Once installed, the Pi works **offline** — your sensor nodes talk to the Pi,
|
|
6
6
|
and you view the data from a phone or laptop on the same Wi-Fi. No internet needed after setup.
|
|
7
7
|
|
|
8
|
-
Two hardware paths are covered:
|
|
9
|
-
|
|
10
|
-
* [Raspberry Pi 4](#part-a--raspberry-pi-4) — the recommended, tested path.
|
|
11
|
-
* [Raspberry Pi Zero W](#part-b--raspberry-pi-zero-w) — smaller and cheaper, **not yet tested**, see the open questions in that section.
|
|
12
|
-
|
|
13
8
|
If you already have a working Linux server (not a Pi), you do not need this document —
|
|
14
9
|
see [README.md](https://github.com/mitra42/frugal-iot-server/blob/main/README.md) instead.
|
|
15
10
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
>
|
|
11
|
+
**Read the steps in order.** Anything specific to one board is marked in the step it belongs to,
|
|
12
|
+
like this:
|
|
13
|
+
|
|
14
|
+
> **Pi Zero W:** extra detail that only applies to a Zero W. Skip these on a Pi 4.
|
|
15
|
+
|
|
16
|
+
> **Status:** followed on hardware — a Raspberry Pi 4 through step 9, and a Pi Zero W through step 8
|
|
17
|
+
> (see [Tested on](#tested-on)) — and corrected from what those runs found. HTTPS/OTA in step 10 is
|
|
18
|
+
> not written yet. Remaining uncertainties are under [Open questions](#open-questions) — please add
|
|
19
|
+
> your findings there as you go.
|
|
20
20
|
|
|
21
21
|
**Already have a Frugal IoT server running and just want a newer version?** Skip everything below
|
|
22
22
|
and go to [Upgrading](#upgrading).
|
|
23
23
|
|
|
24
|
+
**If a step does not do what it says here**, once you reach step 4 you can run
|
|
25
|
+
`npx --no frugal-iot-diagnostic` from your install directory — it inspects the whole installation and
|
|
26
|
+
reports what looks wrong. See [When something does not work](#when-something-does-not-work).
|
|
27
|
+
|
|
24
28
|
---
|
|
25
29
|
|
|
26
|
-
##
|
|
30
|
+
## Which Raspberry Pi
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
Any of these work. What differs is only how long the install takes, and how much of a fight it is:
|
|
33
|
+
|
|
34
|
+
| Board | Install | Notes |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| **Pi 4** (or Pi 5, Pi 3) | About half an hour | The straightforward path. 64-bit, everything installs as ready-made binaries. |
|
|
37
|
+
| **Pi Zero 2 W** | Expect longer | 64-bit, so it should avoid the long compile below, but shares the Zero's 512 MB. Not yet tested. |
|
|
38
|
+
| **Pi Zero W** (the original) | Allow an afternoon | 32-bit ARMv6. One dependency has to be compiled — about 40 minutes — and 512 MB of RAM is not enough without adding swap. Tested and works. |
|
|
39
|
+
|
|
40
|
+
A Zero W runs the server perfectly well once installed. It is *installing* that is slow, because a
|
|
41
|
+
single 1 GHz core has to unpack several hundred packages and compile one of them.
|
|
42
|
+
|
|
43
|
+
### 0. What you need before you start
|
|
29
44
|
|
|
30
45
|
**Hardware**
|
|
31
46
|
|
|
32
|
-
* Raspberry Pi
|
|
33
|
-
|
|
47
|
+
* A Raspberry Pi, per the table above. Any RAM size — a running server uses around 250 MB.
|
|
48
|
+
(Measured on a 4 GB Pi 4: 231 MB in use with the server running.)
|
|
34
49
|
* A microSD card. 8 GB is enough for the system and software — a working install occupies about
|
|
35
50
|
5 GB — but sensor data accumulates on this card for as long as the server runs, so 16 GB or larger
|
|
36
51
|
is the safer choice. Class 10 / A1 or better.
|
|
37
|
-
* The official Raspberry Pi
|
|
38
|
-
random reboots and corrupted SD cards — this is the single most
|
|
52
|
+
* The official Raspberry Pi power supply for your board — USB-C on a Pi 4, micro-USB on a Zero.
|
|
53
|
+
Phone chargers frequently cause random reboots and corrupted SD cards — this is the single most
|
|
54
|
+
common cause of "it doesn't work".
|
|
39
55
|
* A way to write the SD card from your laptop: a built-in SD slot or a USB card reader.
|
|
40
56
|
* Note that you will often need an adapter from the SD format the Pi uses to the SD format of most laptop readers.
|
|
41
57
|
|
|
58
|
+
> **Pi Zero W:** its Wi-Fi is 2.4 GHz only, so it cannot see a 5 GHz-only network. It has no
|
|
59
|
+
> Ethernet socket either, so the cable trick in step 2 is unavailable — have the micro-HDMI cable
|
|
60
|
+
> and a keyboard to hand instead. Note micro-USB for power and a micro-USB OTG adapter for the
|
|
61
|
+
> keyboard: different cables from a Pi 4.
|
|
62
|
+
|
|
42
63
|
**Software and information**
|
|
43
64
|
|
|
44
65
|
* A laptop or desktop (Mac, Windows or Linux) with [Raspberry Pi Imager](https://www.raspberrypi.com/software/) installed.
|
|
@@ -56,18 +77,20 @@ and go to [Upgrading](#upgrading).
|
|
|
56
77
|
**Have these to hand in case the headless setup does not come up**
|
|
57
78
|
|
|
58
79
|
* An Ethernet cable from the Pi to your router — the simplest way in if the Pi does not appear on
|
|
59
|
-
the Wi-Fi, and you can then sort the Wi-Fi out over SSH (step
|
|
80
|
+
the Wi-Fi, and you can then sort the Wi-Fi out over SSH (step 2).
|
|
60
81
|
* A micro-HDMI to HDMI cable plus a monitor, and a USB keyboard — for when the Pi is nowhere near the
|
|
61
82
|
router, or you want to see boot messages.
|
|
62
83
|
|
|
63
|
-
###
|
|
84
|
+
### 1. Write the operating system to the SD card
|
|
64
85
|
|
|
65
|
-
We use **Raspberry Pi OS Lite
|
|
86
|
+
We use **Raspberry Pi OS Lite** — the version with no desktop. The Pi is a server;
|
|
66
87
|
a desktop would only consume memory and SD card space.
|
|
67
88
|
|
|
68
89
|
1. Insert the SD card into your laptop and start Raspberry Pi Imager.
|
|
69
|
-
2. **Choose Device** →
|
|
90
|
+
2. **Choose Device** → your board.
|
|
70
91
|
3. **Choose OS** → *Raspberry Pi OS (other)* → *Raspberry Pi OS Lite (64-bit)*.
|
|
92
|
+
* **On a Pi Zero W choose *Raspberry Pi OS Lite (32-bit)*** — the 64-bit images will not boot on
|
|
93
|
+
its ARMv6 processor. (A Pi Zero **2** W is 64-bit, so it takes the 64-bit image like a Pi 4.)
|
|
71
94
|
4. **Choose Storage** → your SD card. Check the size shown matches your card — this erases it.
|
|
72
95
|
5. Click **Next**. When asked *"Would you like to apply OS customisation settings?"*, choose
|
|
73
96
|
**Edit Settings** — everything below depends on it.
|
|
@@ -81,7 +104,7 @@ a desktop would only consume memory and SD card space.
|
|
|
81
104
|
produces a key that fails even though the password was right.
|
|
82
105
|
* If the Pi does not join the network, a mistyped SSID or password is much the likeliest cause -
|
|
83
106
|
neither is echoed back to you here, and Imager combines the two into a key, so a slip in either
|
|
84
|
-
looks the same later. Step
|
|
107
|
+
looks the same later. Step 2 fixes it in a couple of minutes with `nmtui`.
|
|
85
108
|
* A WPA3 network cannot use the key Imager derives at all, so on one of those expect to finish the
|
|
86
109
|
Wi-Fi setup with `nmtui` regardless.
|
|
87
110
|
10. Enable SSH, either choose *Use password authentication* or paste your public key if you already use SSH keys.
|
|
@@ -95,7 +118,7 @@ Eject the card, put it in the Pi, connect power.
|
|
|
95
118
|
The first boot resizes the filesystem and reboots itself. Give it **two to three minutes** before
|
|
96
119
|
expecting it to answer.
|
|
97
120
|
|
|
98
|
-
###
|
|
121
|
+
### 2. Log in over the network
|
|
99
122
|
|
|
100
123
|
From your laptop's terminal:
|
|
101
124
|
|
|
@@ -105,6 +128,8 @@ ssh pi@frugaliot.local
|
|
|
105
128
|
|
|
106
129
|
Say `yes` to the fingerprint question, then give the password you set in Imager.
|
|
107
130
|
|
|
131
|
+
**If that logged you in, go straight to step 3.** The rest of this step is for when it did not.
|
|
132
|
+
|
|
108
133
|
**If `frugaliot.local` is not found**, the `.local` (mDNS) name is not reaching you. In order of ease:
|
|
109
134
|
|
|
110
135
|
* Wait another minute and try again — the Pi may still be on its first boot.
|
|
@@ -114,7 +139,7 @@ Say `yes` to the fingerprint question, then give the password you set in Imager.
|
|
|
114
139
|
up an address, and `ssh pi@frugaliot.local` then works over the cable. This is the least effort
|
|
115
140
|
way in if the Pi is within reach of the router, and once you are logged in you can sort the Wi-Fi
|
|
116
141
|
out over SSH with `nmtui` as below, no monitor or keyboard needed. Unplug the cable afterwards and
|
|
117
|
-
check that Wi-Fi alone still gets you in.
|
|
142
|
+
check that Wi-Fi alone still gets you in. (Not an option on a Pi Zero — no Ethernet socket.)
|
|
118
143
|
* Plug in the HDMI and keyboard, log in at the console, and run `ip addr` to read the IP address,
|
|
119
144
|
and `sudo journalctl -b | grep -i wpa` to see why Wi-Fi failed. Use this when the Pi is nowhere
|
|
120
145
|
near the router, or when you want to see boot messages.
|
|
@@ -150,7 +175,9 @@ the password — either way `nmtui` is the fix, and it is not worth more time th
|
|
|
150
175
|
(`sudo nmcli device wifi list` shows each nearby network's SSID and whether it is WPA2 or WPA3;
|
|
151
176
|
WPA3 cannot use a derived key at all.)
|
|
152
177
|
|
|
153
|
-
|
|
178
|
+
### 3. Update the operating system and install the prerequisites
|
|
179
|
+
|
|
180
|
+
Logged in, bring the system up to date and reboot:
|
|
154
181
|
|
|
155
182
|
```
|
|
156
183
|
sudo apt update
|
|
@@ -174,49 +201,138 @@ which you may not have the password for.
|
|
|
174
201
|
address does not change. Sensor nodes and phones then have something stable to talk to even where
|
|
175
202
|
`.local` names do not work.
|
|
176
203
|
|
|
177
|
-
|
|
204
|
+
Now the packages the server needs.
|
|
205
|
+
|
|
206
|
+
**On a Pi 4** (or any 64-bit board):
|
|
178
207
|
|
|
179
208
|
```
|
|
180
209
|
sudo apt install -y nodejs npm sqlite3 zsh
|
|
181
210
|
node -v
|
|
182
211
|
```
|
|
183
212
|
|
|
213
|
+
**On a Pi Zero W**, three more packages, because a 32-bit machine has to compile part of the server
|
|
214
|
+
in step 4 and a Lite image has no compiler:
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
sudo apt install -y nodejs npm sqlite3 zsh build-essential python3-dev python3-setuptools
|
|
218
|
+
node -v
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
What each is for:
|
|
222
|
+
|
|
184
223
|
* `nodejs` — the server needs **Node 18 or later**. Current Raspberry Pi OS (Debian 13, trixie)
|
|
185
|
-
provides 20.19.2, which is fine. Older images shipped Node 18, also
|
|
186
|
-
anything below 18, install a current version from
|
|
224
|
+
provides 20.19.2, which is fine, on 32-bit as well as 64-bit. Older images shipped Node 18, also
|
|
225
|
+
fine. If `node -v` reports anything below 18, install a current version from
|
|
187
226
|
[NodeSource](https://github.com/nodesource/distributions) instead.
|
|
188
227
|
* `npm` — installs the server; it is a separate package from `nodejs` on Debian.
|
|
189
228
|
* `sqlite3` — the database the server keeps its accounts in.
|
|
190
|
-
* `zsh` — the setup commands in step
|
|
191
|
-
|
|
192
|
-
|
|
229
|
+
* `zsh` — the setup commands in step 6 are zsh scripts.
|
|
230
|
+
* `build-essential`, `python3-dev`, `python3-setuptools` — only needed where something has to be
|
|
231
|
+
compiled. `python3-setuptools` is the non-obvious one: the build uses node-gyp 8, which imports
|
|
232
|
+
Python's `distutils`, removed in Python 3.12, and setuptools puts an importable `distutils` back.
|
|
233
|
+
Without it step 4 ends in `ModuleNotFoundError: No module named 'distutils'`.
|
|
234
|
+
|
|
235
|
+
Now two settings that make the SD card last longer. A card wears out from being written to, and
|
|
236
|
+
these are the two places the system writes constantly without being asked to:
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
# Cap the systemd journal, which by default is allowed to grow to a tenth of the card
|
|
240
|
+
sudo mkdir -p /etc/systemd/journald.conf.d
|
|
241
|
+
printf '[Journal]\nSystemMaxUse=16M\nSystemMaxFileSize=4M\n' | sudo tee /etc/systemd/journald.conf.d/frugal-iot.conf
|
|
242
|
+
sudo systemctl restart systemd-journald
|
|
243
|
+
|
|
244
|
+
# Swap out to the card only when there is genuinely no alternative
|
|
245
|
+
echo 'vm.swappiness=1' | sudo tee /etc/sysctl.d/99-frugal-iot-swappiness.conf
|
|
246
|
+
sudo sysctl --system | grep swappiness
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
The `grep` should print `vm.swappiness = 1`. Both survive a reboot. There is more about what wears a
|
|
250
|
+
card out, and how to see whether yours is being written to hard, under
|
|
251
|
+
[Wear and tear on the SD card](#wear-and-tear-on-the-sd-card) — but nothing else there needs doing
|
|
252
|
+
during the install.
|
|
253
|
+
|
|
254
|
+
> **Pi Zero W: add swap before going on.** 512 MB is not enough to unpack what step 4 downloads, and
|
|
255
|
+
> running out does not fail cleanly — the board stops answering SSH and ping, and has to have its
|
|
256
|
+
> power pulled. Raspberry Pi OS enables zram, which is **not** sufficient here, because compressed
|
|
257
|
+
> RAM does not help when the working set is genuinely large. Add a real swap file (`dphys-swapfile`
|
|
258
|
+
> is not on the Trixie Lite image, so make it directly):
|
|
259
|
+
>
|
|
260
|
+
> ```
|
|
261
|
+
> sudo fallocate -l 2G /swapfile
|
|
262
|
+
> sudo chmod 600 /swapfile
|
|
263
|
+
> sudo mkswap /swapfile
|
|
264
|
+
> sudo swapon /swapfile
|
|
265
|
+
> free -h # should show 2.0Gi of swap
|
|
266
|
+
> echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
|
|
267
|
+
> ```
|
|
268
|
+
>
|
|
269
|
+
> **No reboot needed** — `swapon` takes effect at once, which the `free -h` line confirms. The
|
|
270
|
+
> `/etc/fstab` entry only matters later, so that the swap comes back after a reboot rather than
|
|
271
|
+
> having to be turned on by hand. Go straight on to step 4.
|
|
272
|
+
>
|
|
273
|
+
> Swapping to an SD card is slow, and wears it. That is the trade: the install takes longer, but it
|
|
274
|
+
> finishes instead of hanging. The `vm.swappiness=1` set above keeps the swap file available for
|
|
275
|
+
> emergencies like this one without it being used routinely afterwards.
|
|
276
|
+
|
|
277
|
+
### 4. Install the Frugal IoT server
|
|
193
278
|
|
|
194
279
|
The server is an npm package. Make a directory for this server to live in and install it there —
|
|
195
280
|
that directory will hold your configuration, your data, and your database, while npm looks after
|
|
196
281
|
the software itself underneath it in `node_modules`.
|
|
197
282
|
|
|
283
|
+
**On a Pi 4** (or any 64-bit board) — a few minutes, everything arrives as ready-made binaries and
|
|
284
|
+
nothing is compiled:
|
|
285
|
+
|
|
198
286
|
```
|
|
199
287
|
mkdir ~/frugal-iot
|
|
200
288
|
cd ~/frugal-iot
|
|
201
289
|
npm install frugal-iot-server
|
|
202
290
|
```
|
|
203
291
|
|
|
204
|
-
|
|
205
|
-
|
|
292
|
+
**On a Pi Zero W** — the extra flags make npm do one thing at a time, which lowers the peak memory
|
|
293
|
+
as well as being kinder to the SD card. This is the slow part; leave it running:
|
|
206
294
|
|
|
207
295
|
```
|
|
208
|
-
|
|
296
|
+
mkdir ~/frugal-iot
|
|
297
|
+
cd ~/frugal-iot
|
|
298
|
+
npm install --maxsockets 1 --no-audit --no-fund frugal-iot-server
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
That pulls in the web UI (`frugal-iot-client`) and the logger (`frugal-iot-logger`) as well.
|
|
302
|
+
|
|
303
|
+
> **Pi Zero W: check that the compiled part actually built.** npm can report success while leaving
|
|
304
|
+
> it out, and nothing else looks wrong when that happens — the server just refuses to start later.
|
|
305
|
+
>
|
|
306
|
+
> ```
|
|
307
|
+
> node -e "require('sqlite3'); console.log('sqlite3 native module loads OK')"
|
|
308
|
+
> ```
|
|
309
|
+
>
|
|
310
|
+
> If that throws `Could not locate the bindings file`, build just that package:
|
|
311
|
+
>
|
|
312
|
+
> ```
|
|
313
|
+
> time npm rebuild sqlite3 --foreground-scripts
|
|
314
|
+
> ```
|
|
315
|
+
>
|
|
316
|
+
> **This takes around 40 minutes on a Zero W** — it is compiling SQLite itself on one slow core. As
|
|
317
|
+
> long as it is producing output it is working; `--foreground-scripts` is what lets you see that. If
|
|
318
|
+
> the board locks up, pull the power, boot it, and run the same command again: work already done is
|
|
319
|
+
> kept, so each attempt gets further.
|
|
320
|
+
>
|
|
321
|
+
> Most of what is being installed is not Frugal IoT. The logger depends on `firebase-admin`, which
|
|
322
|
+
> brings in the Google Cloud SDK — around 40 packages and 30 MB — and that is what the board
|
|
323
|
+
> struggles with. It is only used by organizations that configure a `firebase:` section.
|
|
324
|
+
> TODO make that dependency optional in frugal-iot-logger, so small boards can skip it.
|
|
325
|
+
|
|
326
|
+
Then set the directory up:
|
|
327
|
+
|
|
328
|
+
```
|
|
329
|
+
npx --no frugal-iot-init
|
|
209
330
|
```
|
|
210
331
|
|
|
211
332
|
This copies in the configuration files, creates the `data`, `ota` and `config.d/organizations`
|
|
212
333
|
directories, and creates the database. It never overwrites anything already there, so it is also
|
|
213
334
|
what you run after an upgrade to pick up newly added configuration.
|
|
214
335
|
|
|
215
|
-
> On a 64-bit Raspberry Pi OS this installs ready-made binaries and compiles nothing. If it ever
|
|
216
|
-
> does stop while building `sqlite3`, no binary was available for your platform, so install the
|
|
217
|
-
> compiler toolchain and try again: `sudo apt install -y build-essential python3` then
|
|
218
|
-
> `npm install frugal-iot-server`.
|
|
219
|
-
|
|
220
336
|
Everything from here on is run from `~/frugal-iot`, and `npx` is how you run the server's commands
|
|
221
337
|
without having to know where npm put them.
|
|
222
338
|
|
|
@@ -240,10 +356,10 @@ works on the Pi.
|
|
|
240
356
|
> `frugaliot.local` is known to work from a laptop and from an iPhone. Android phones generally
|
|
241
357
|
> cannot resolve `.local` names, so if you will view the dashboard on Android, put the Pi's IP
|
|
242
358
|
> address here instead — `broker: ws://192.168.1.42:9012`, using the address `ping -c1
|
|
243
|
-
> frugaliot.local` reported in step
|
|
359
|
+
> frugaliot.local` reported in step 3 — and reserve that address in your router if you can, so it
|
|
244
360
|
> does not change under you.
|
|
245
361
|
|
|
246
|
-
###
|
|
362
|
+
### 5. Install and configure the MQTT broker (Mosquitto)
|
|
247
363
|
|
|
248
364
|
Sensor nodes publish their readings to an MQTT broker; the Frugal IoT logger subscribes to it and
|
|
249
365
|
writes the readings to disk; the web UI subscribes to it to show live values. On an offline Pi,
|
|
@@ -265,6 +381,12 @@ sudo cp extras/mosquitto.conf /etc/mosquitto/conf.d/frugal-iot.conf
|
|
|
265
381
|
(Everything in `/etc/mosquitto/conf.d/` is read in addition to the packaged
|
|
266
382
|
`/etc/mosquitto/mosquitto.conf`, which keeps its own settings for logging and persistence.)
|
|
267
383
|
|
|
384
|
+
That file also turns off the broker's per-connection logging, because a node on a weak signal
|
|
385
|
+
reconnects constantly and each of those lines is a write to the SD card. Nothing is lost — the
|
|
386
|
+
readings themselves are recorded by the server, and everything else the broker says, including why
|
|
387
|
+
it refused to start, still goes to `/var/log/mosquitto/mosquitto.log`. If you are chasing a node
|
|
388
|
+
that keeps dropping off the network, comment out `connection_messages false` and restart the broker.
|
|
389
|
+
|
|
268
390
|
That configuration names a password file, and Mosquitto will not start if the file is missing, so
|
|
269
391
|
create an empty one. The accounts inside it get created for you in the next step:
|
|
270
392
|
|
|
@@ -279,7 +401,7 @@ instead of a `touch`, a `chown` and a `chmod`.
|
|
|
279
401
|
> to whoever opened it, and the broker runs as the `mosquitto` user — so the file belongs to
|
|
280
402
|
> `mosquitto`, and it lives under `/var/lib/mosquitto` (which that user owns) rather than
|
|
281
403
|
> `/etc/mosquitto` (which root owns). `mosquitto_passwd` also writes a temporary backup file
|
|
282
|
-
> alongside it, so it needs to write to that directory too, not just to the file. Step
|
|
404
|
+
> alongside it, so it needs to write to that directory too, not just to the file. Step 6 runs it as
|
|
283
405
|
> the right user for you.
|
|
284
406
|
|
|
285
407
|
Start the broker and have it start at every boot:
|
|
@@ -309,19 +431,24 @@ mosquitto_sub -h localhost -u nobody -P wrong -t '#'
|
|
|
309
431
|
```
|
|
310
432
|
|
|
311
433
|
`Connection Refused: not authorised` is the **success** case here — the broker answered and
|
|
312
|
-
requires an account. There are no accounts yet; step
|
|
434
|
+
requires an account. There are no accounts yet; step 6 creates the first one, and there is a
|
|
313
435
|
fuller test at the end of it.
|
|
314
436
|
|
|
315
|
-
|
|
437
|
+
> If Mosquitto did not start, `npx --no frugal-iot-diagnostic` will tell you why in one step — most often
|
|
438
|
+
> that the password file its configuration names does not exist. Note that `systemctl status` and
|
|
439
|
+
> the journal only show an exit code; the actual reason is in Mosquitto's own log, which the
|
|
440
|
+
> diagnostic reads for you. See [When something does not work](#when-something-does-not-work).
|
|
316
441
|
|
|
317
|
-
|
|
442
|
+
### 6. Create your accounts and your organization
|
|
443
|
+
|
|
444
|
+
The database was created by `npx --no frugal-iot-init` in step 4, holding two accounts. One is
|
|
318
445
|
`everyone`, which nobody logs in as — it exists so that permissions granted to all logged-in users
|
|
319
446
|
have somewhere to live. The other is `superuser`, this server's administrator, which is given admin
|
|
320
447
|
rights over every organization you create. It starts with no password and cannot be logged into
|
|
321
448
|
until you give it one:
|
|
322
449
|
|
|
323
450
|
```
|
|
324
|
-
npx frugal-iot-setpassword superuser "<a-good-password>"
|
|
451
|
+
npx --no frugal-iot-setpassword superuser "<a-good-password>"
|
|
325
452
|
```
|
|
326
453
|
|
|
327
454
|
Use the same command later if you ever need to reset a password — for `superuser` or for any
|
|
@@ -330,19 +457,18 @@ other account.
|
|
|
330
457
|
Frugal IoT groups devices as **organization → project → device**. Create yours:
|
|
331
458
|
|
|
332
459
|
```
|
|
333
|
-
npx frugal-iot-addorganization
|
|
460
|
+
npx --no frugal-iot-addorganization myfarm "My Farm" you@example.com +61123456789 "<broker-password>"
|
|
334
461
|
```
|
|
335
462
|
|
|
336
463
|
The arguments are: organization id, display name, your email, your phone (`+` and digits only),
|
|
337
|
-
and a password. That one command writes `config.d/organizations/
|
|
338
|
-
named after the organization (`
|
|
464
|
+
and a password. That one command writes `config.d/organizations/myfarm.yaml`, creates a login account
|
|
465
|
+
named after the organization (`myfarm`), grants it admin rights, creates its OTA directory, **and adds
|
|
339
466
|
the organization's account to the broker's password file** — which is why the broker had to be
|
|
340
467
|
installed first.
|
|
341
468
|
|
|
342
|
-
* **Organization id `
|
|
469
|
+
* **Organization id `myfarm`** — must be 1–10 lower-case letters or digits. It becomes the first part
|
|
343
470
|
of every MQTT topic, so it must match what your sensor nodes are configured to publish to.
|
|
344
|
-
|
|
345
|
-
* **The password** goes into `config.d/organizations/dev.yaml` as `mqtt_password` and into the
|
|
471
|
+
* **The password** goes into `config.d/organizations/myfarm.yaml` as `mqtt_password` and into the
|
|
346
472
|
broker's password file, so it is a *machine* credential: the server's logger, your sensor nodes,
|
|
347
473
|
and any browser showing this organization's dashboard all authenticate to the broker with it.
|
|
348
474
|
Treat it as shared, not personal.
|
|
@@ -353,45 +479,47 @@ Tell Mosquitto to re-read the password file, so the new account works:
|
|
|
353
479
|
sudo systemctl restart mosquitto
|
|
354
480
|
```
|
|
355
481
|
|
|
356
|
-
**Give your login its own password.** That command set the `
|
|
482
|
+
**Give your login its own password.** That command set the `myfarm` *web login* password to the same
|
|
357
483
|
string as the broker password. They serve completely different purposes, so change the login one
|
|
358
484
|
now to something only you know — the broker credential is unaffected, and nothing needs to be kept
|
|
359
485
|
in step:
|
|
360
486
|
|
|
361
487
|
```
|
|
362
|
-
npx frugal-iot-setpassword
|
|
488
|
+
npx --no frugal-iot-setpassword myfarm "<your-own-login-password>"
|
|
363
489
|
```
|
|
364
490
|
|
|
365
491
|
**Now the full broker test.** In your SSH session subscribe as the organization, using the broker
|
|
366
492
|
password you chose above:
|
|
367
493
|
|
|
368
494
|
```
|
|
369
|
-
mosquitto_sub -h localhost -u
|
|
495
|
+
mosquitto_sub -h localhost -u myfarm -P '<broker-password>' -t '#' -v
|
|
370
496
|
```
|
|
371
497
|
|
|
372
498
|
It should sit there silently — no error, no exit. Open a **second** SSH session to the Pi and
|
|
373
499
|
publish something:
|
|
374
500
|
|
|
375
501
|
```
|
|
376
|
-
mosquitto_pub -h localhost -u
|
|
502
|
+
mosquitto_pub -h localhost -u myfarm -P '<broker-password>' -t 'myfarm/test/hello' -m '42'
|
|
377
503
|
```
|
|
378
504
|
|
|
379
|
-
`
|
|
505
|
+
`myfarm/test/hello 42` appearing in the first window proves the account, the password file and the
|
|
380
506
|
port 1883 listener your sensor nodes use are all working. The WebSocket listener on 9012 gets
|
|
381
|
-
exercised by the browser in step
|
|
507
|
+
exercised by the browser in step 7. Leave the subscriber running if you like — it is a useful
|
|
382
508
|
window onto what your nodes are doing. (`Ctrl-C` stops it.)
|
|
383
509
|
|
|
384
510
|
If you get `Connection Refused: not authorised`, the password does not match the one in
|
|
385
|
-
`config.d/organizations/
|
|
511
|
+
`config.d/organizations/myfarm.yaml`, or Mosquitto has not re-read the file since it changed.
|
|
512
|
+
`npx --no frugal-iot-diagnostic` checks this for every organization you have, and reports which ones the
|
|
513
|
+
broker actually accepts.
|
|
386
514
|
|
|
387
|
-
###
|
|
515
|
+
### 7. Start the server by hand and check it
|
|
388
516
|
|
|
389
517
|
From your install directory — `npx` looks for the server in the current directory's `node_modules`,
|
|
390
518
|
so this only works there:
|
|
391
519
|
|
|
392
520
|
```
|
|
393
521
|
cd ~/frugal-iot
|
|
394
|
-
npx frugal-iot-server
|
|
522
|
+
npx --no frugal-iot-server
|
|
395
523
|
```
|
|
396
524
|
|
|
397
525
|
> If npx answers with `Need to install the following packages: frugal-iot-server` and asks to
|
|
@@ -404,7 +532,7 @@ It lists each configuration file as it reads it, then:
|
|
|
404
532
|
readYamlConfigFile ./config.yaml
|
|
405
533
|
readYamlConfigDir ./config.d
|
|
406
534
|
... one line per configuration file ...
|
|
407
|
-
Broker ws://frugaliot.local:9012 - organizations:
|
|
535
|
+
Broker ws://frugaliot.local:9012 - organizations: myfarm
|
|
408
536
|
Doing OTA updates at /ota_update from /home/pi/frugal-iot/ota
|
|
409
537
|
Serving /node_modules from ./node_modules
|
|
410
538
|
User Database exists
|
|
@@ -416,16 +544,16 @@ Mounted API routes at /api
|
|
|
416
544
|
Added API error handler
|
|
417
545
|
Serving /data from ./data
|
|
418
546
|
Server starting on port 8080
|
|
419
|
-
mqtt
|
|
420
|
-
mqtt
|
|
421
|
-
Subscribing topic
|
|
547
|
+
mqtt myfarm connecting
|
|
548
|
+
mqtt myfarm connect
|
|
549
|
+
Subscribing topic myfarm/# 0
|
|
422
550
|
```
|
|
423
551
|
|
|
424
552
|
Check the `Broker` line names your own broker and your organization. The lines that matter most are
|
|
425
|
-
the last three: `mqtt
|
|
426
|
-
`Subscribing topic
|
|
427
|
-
`mqtt
|
|
428
|
-
`config.d/mqtt.yaml` and that the password in `config.d/organizations/
|
|
553
|
+
the last three: `mqtt myfarm connect` means the server reached the broker and authenticated, and
|
|
554
|
+
`Subscribing topic myfarm/#` means it is listening for your nodes. If instead you see repeated
|
|
555
|
+
`mqtt myfarm close`, `offline`, or `Not authorized`, the broker URL or the password is wrong — recheck
|
|
556
|
+
`config.d/mqtt.yaml` and that the password in `config.d/organizations/myfarm.yaml` matches the `myfarm`
|
|
429
557
|
broker account.
|
|
430
558
|
|
|
431
559
|
Once nodes are reporting, each reading is logged as it arrives, so this output keeps scrolling.
|
|
@@ -442,7 +570,7 @@ http://frugaliot.local:8080
|
|
|
442
570
|
> local networks"* the first time. **Allow it** — without that permission the browser cannot look up
|
|
443
571
|
> `frugaliot.local`, nor reach the broker at that name, so the page and the live data both fail.
|
|
444
572
|
|
|
445
|
-
You land on the Frugal IoT home page. Click **Dashboard**, and log in as username `
|
|
573
|
+
You land on the Frugal IoT home page. Click **Dashboard**, and log in as username `myfarm` with the
|
|
446
574
|
login password you set with `frugal-iot-setpassword` — not the broker password. (`superuser` and its
|
|
447
575
|
password work too.)
|
|
448
576
|
|
|
@@ -454,12 +582,17 @@ actually resolve: a phone that cannot look up `.local` names needs the Pi's IP a
|
|
|
454
582
|
|
|
455
583
|
Until a sensor node reports in there will be no data to look at, but the dashboard should load.
|
|
456
584
|
|
|
585
|
+
> Anything wrong here — the server not starting, `mqtt myfarm close` instead of `connect`, the page not
|
|
586
|
+
> loading, the MQTT status not reaching *connected* — is worth a `npx --no frugal-iot-diagnostic` in
|
|
587
|
+
> another terminal before digging in by hand. It tests the same chain from the Pi's side: broker
|
|
588
|
+
> logins, the three ports, and the web server.
|
|
589
|
+
|
|
457
590
|
Stop the server with `Ctrl-C` before continuing.
|
|
458
591
|
|
|
459
|
-
###
|
|
592
|
+
### 8. Run the server as a service
|
|
460
593
|
|
|
461
594
|
So that it starts automatically at boot and restarts if it crashes. The file that
|
|
462
|
-
`npx frugal-iot-init` put in `extras/` already describes this installation — user `pi`, installed
|
|
595
|
+
`npx --no frugal-iot-init` put in `extras/` already describes this installation — user `pi`, installed
|
|
463
596
|
into `/home/pi/frugal-iot` — so it needs no editing:
|
|
464
597
|
|
|
465
598
|
```
|
|
@@ -478,7 +611,7 @@ systemctl status frugaliot
|
|
|
478
611
|
> `sudo systemctl restart frugaliot`. `WorkingDirectory` is the important one: it is where the
|
|
479
612
|
> server looks for its configuration and database.
|
|
480
613
|
|
|
481
|
-
To watch its log output, which is where the `mqtt
|
|
614
|
+
To watch its log output, which is where the `mqtt myfarm connect` and incoming-reading messages now go:
|
|
482
615
|
|
|
483
616
|
```
|
|
484
617
|
journalctl -u frugaliot -f
|
|
@@ -487,7 +620,7 @@ journalctl -u frugaliot -f
|
|
|
487
620
|
Reboot the Pi (`sudo reboot`), wait a couple of minutes, and check `http://frugaliot.local:8080`
|
|
488
621
|
still answers. Your server is now installed.
|
|
489
622
|
|
|
490
|
-
###
|
|
623
|
+
### 9. Point your sensor nodes at the Pi
|
|
491
624
|
|
|
492
625
|
Your ESP8266/ESP32 nodes are told which broker to use in their sketch — `main.cpp`, or the `.ino`
|
|
493
626
|
file if you build in the Arduino IDE. Look for a line like:
|
|
@@ -499,29 +632,29 @@ frugal_iot.configure_mqtt("frugaliot.naturalinnovation.org", "dev", "public");
|
|
|
499
632
|
and point it at your Pi instead:
|
|
500
633
|
|
|
501
634
|
```cpp
|
|
502
|
-
frugal_iot.configure_mqtt("frugaliot.local", "
|
|
635
|
+
frugal_iot.configure_mqtt("frugaliot.local", "myfarm", "<broker-password>");
|
|
503
636
|
```
|
|
504
637
|
|
|
505
638
|
The three arguments are the broker's host, the organization, and that organization's broker
|
|
506
|
-
password. The organization must be the one you created in step
|
|
639
|
+
password. The organization must be the one you created in step 6, because it is the first part of
|
|
507
640
|
every topic the node publishes to, and the password is the *broker* password from that step — not
|
|
508
641
|
the login password. Then rebuild and flash the node as usual.
|
|
509
642
|
|
|
510
643
|
> If the node does not connect, try the Pi's IP address in place of `frugaliot.local`. Resolving
|
|
511
644
|
> `.local` names needs mDNS support in the firmware, which is not something this guide has
|
|
512
|
-
> confirmed; an IP address avoids the question entirely, which is why step
|
|
645
|
+
> confirmed; an IP address avoids the question entirely, which is why step 3 suggests reserving one
|
|
513
646
|
> for the Pi in your router.
|
|
514
647
|
|
|
515
|
-
You can confirm nodes are reporting without involving the UI, using the subscriber from step
|
|
648
|
+
You can confirm nodes are reporting without involving the UI, using the subscriber from step 6:
|
|
516
649
|
|
|
517
650
|
```
|
|
518
|
-
mosquitto_sub -h localhost -u
|
|
651
|
+
mosquitto_sub -h localhost -u myfarm -P '<broker-password>' -t '#' -v
|
|
519
652
|
```
|
|
520
653
|
|
|
521
654
|
Every reading from every node should scroll past. Seeing anything here also proves the broker's
|
|
522
655
|
port 1883 is reachable from off the Pi, which is what the nodes need.
|
|
523
656
|
|
|
524
|
-
###
|
|
657
|
+
### 10. HTTPS and over-the-air firmware updates
|
|
525
658
|
|
|
526
659
|
**To be written.** Everything above gives you a plain HTTP server on your local network, which is
|
|
527
660
|
all an offline installation needs. HTTPS matters for two things:
|
|
@@ -563,6 +696,80 @@ the time of the phone or laptop viewing it, so it could hand that to the server,
|
|
|
563
696
|
it whenever its own clock looks implausible (a date far in the past). Not accurate to the second,
|
|
564
697
|
but close enough for sensor data.
|
|
565
698
|
|
|
699
|
+
---
|
|
700
|
+
### Wear and tear on the SD card
|
|
701
|
+
|
|
702
|
+
SD cards wear out from being written to, and a server recording sensor readings writes all the time.
|
|
703
|
+
We have not yet seen a card fail, but plan for one eventually: keep a copy of `config.d/` and
|
|
704
|
+
`frugal-iot.db` somewhere else, and treat the readings in `data/` as valuable but not irreplaceable.
|
|
705
|
+
|
|
706
|
+
A new installation is set up to write as little as it reasonably can, and the settings are worth
|
|
707
|
+
knowing about, because turning one of them back on for debugging and forgetting is easy to do:
|
|
708
|
+
|
|
709
|
+
| What | Where | Shipped as |
|
|
710
|
+
| ---- | ----- | ---------- |
|
|
711
|
+
| A line logged for every MQTT message received | `verbose:` in `config.d/logger.yaml` | `false` |
|
|
712
|
+
| Readings held in memory and written out periodically instead of one at a time | `flushseconds:` in `config.d/logger.yaml` | `300` (5 minutes) |
|
|
713
|
+
| A line logged for every web request | `morgan:` in `config.d/server.yaml` | `false` |
|
|
714
|
+
| Old readings compressed, and deleted if the disk fills | `housekeeping:` in `config.d/server.yaml` | compress after 2 days, never delete, keep 10% free |
|
|
715
|
+
| A line logged for every device connect and disconnect | `connection_messages` in `extras/mosquitto.conf` | `false` |
|
|
716
|
+
| A capped systemd journal, and swapping only as a last resort | `/etc/systemd/journald.conf.d/` and `/etc/sysctl.d/`, both set in step 3 | 16 MB journal, `vm.swappiness=1` |
|
|
717
|
+
|
|
718
|
+
Nothing in that table needs doing — step 3 and step 5 set all of it up. It is here because turning
|
|
719
|
+
one of them back on for debugging and then forgetting is easy to do.
|
|
720
|
+
|
|
721
|
+
`flushseconds` is the one with a cost attached: readings that have not been written out yet are only
|
|
722
|
+
in memory, so pulling the power loses up to five minutes of them. Stopping the server properly
|
|
723
|
+
(`sudo service frugaliot stop`, or a restart) writes them out first, and so does looking at a graph.
|
|
724
|
+
|
|
725
|
+
On a Pi 4 there should be very little swapping in any case — the server and Mosquitto together are a
|
|
726
|
+
small load for 1 GB or more. The Pi Zero W is the one to watch, since step 3 adds a 2 GB swap file to
|
|
727
|
+
get through the install. To see what is actually happening on your board:
|
|
728
|
+
|
|
729
|
+
```
|
|
730
|
+
cd ~/frugal-iot
|
|
731
|
+
npx --no frugal-iot-diagnostic
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
and read the **Wear on the SD card** section, which reports how much has been written since boot,
|
|
735
|
+
whether the machine is swapping, and whether each of the settings above is in force. Run it twice a
|
|
736
|
+
few days apart — the interesting number is the rate, not the total.
|
|
737
|
+
|
|
738
|
+
## When something does not work
|
|
739
|
+
|
|
740
|
+
From your install directory:
|
|
741
|
+
|
|
742
|
+
```
|
|
743
|
+
cd ~/frugal-iot
|
|
744
|
+
npx --no frugal-iot-diagnostic
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
It only looks — it changes nothing — and it ends with a **Summary** of anything it recognises as
|
|
748
|
+
broken. It covers most of the checks scattered through this guide, in one pass:
|
|
749
|
+
|
|
750
|
+
* the machine, the OS, free memory and disk, and whether the clock is synchronized
|
|
751
|
+
* the versions of node, npm, sqlite3, mosquitto, and of the three Frugal IoT packages
|
|
752
|
+
* what this directory holds: configuration, database, accounts, organizations
|
|
753
|
+
* Mosquitto's configuration, **which password file it names and whether that file exists**, who owns
|
|
754
|
+
it, and the accounts in it
|
|
755
|
+
* whether Mosquitto and the `frugaliot` service are running, with the last lines of the journal
|
|
756
|
+
**and of Mosquitto's own log**, which is where its startup errors actually appear
|
|
757
|
+
* whether the broker refuses a wrong password, and accepts each organization's real one
|
|
758
|
+
* whether ports 1883, 9012 and 8080 are listening, and whether the web server answers
|
|
759
|
+
* whether the broker host in `config.d/mqtt.yaml` resolves from this machine
|
|
760
|
+
* how much data the logger has written
|
|
761
|
+
|
|
762
|
+
Two things to know:
|
|
763
|
+
|
|
764
|
+
* Mosquitto's log belongs to the `mosquitto` user. The script reads it with `sudo` where it can; if
|
|
765
|
+
it says it could not, run the whole thing as `sudo npx --no frugal-iot-diagnostic`.
|
|
766
|
+
* The output is safe to paste into a bug report. Passwords are deliberately not printed — the
|
|
767
|
+
password file is listed by account name only, and organizations by name.
|
|
768
|
+
|
|
769
|
+
If you have not reached step 4 yet, the command does not exist. Copy
|
|
770
|
+
[scripts/diagnostic.zsh](https://github.com/mitra42/frugal-iot-server/blob/main/scripts/diagnostic.zsh)
|
|
771
|
+
to the Pi and run `zsh diagnostic.zsh` instead.
|
|
772
|
+
|
|
566
773
|
---
|
|
567
774
|
|
|
568
775
|
## Upgrading
|
|
@@ -572,7 +779,7 @@ To move an existing server to a newer release, from the directory you installed
|
|
|
572
779
|
```
|
|
573
780
|
cd ~/frugal-iot
|
|
574
781
|
npm update frugal-iot-server
|
|
575
|
-
npx frugal-iot-init
|
|
782
|
+
npx --no frugal-iot-init
|
|
576
783
|
sudo systemctl restart frugaliot
|
|
577
784
|
```
|
|
578
785
|
|
|
@@ -603,68 +810,43 @@ sudo cp extras/mosquitto.conf /etc/mosquitto/conf.d/frugal-iot.conf && sudo syst
|
|
|
603
810
|
sudo cp extras/frugaliot.service /etc/systemd/system/ && sudo systemctl daemon-reload && sudo systemctl restart frugaliot
|
|
604
811
|
```
|
|
605
812
|
|
|
606
|
-
> It does not compare `config.yaml`, `config.d/mqtt.yaml
|
|
607
|
-
> hold your own settings and would differ every time. If a
|
|
608
|
-
> one of them, compare it yourself:
|
|
813
|
+
> It does not compare `config.yaml`, `config.d/mqtt.yaml`, `config.d/logger.yaml` or
|
|
814
|
+
> `config.d/server.yaml`, because those hold your own settings and would differ every time. If a
|
|
815
|
+
> release note mentions a new setting in one of them, compare it yourself:
|
|
609
816
|
> `diff config.d/server.yaml node_modules/frugal-iot-server/config.d/server.yaml`
|
|
610
817
|
|
|
818
|
+
Because your own configuration is left alone, an upgraded server goes on behaving exactly as it did,
|
|
819
|
+
which for the settings under [Wear and tear on the SD card](#wear-and-tear-on-the-sd-card) means it
|
|
820
|
+
goes on writing as often as it did. A server that has been running since before those settings
|
|
821
|
+
existed keeps logging every message and every web request, and writing every reading as it arrives —
|
|
822
|
+
deliberately, since quietening somebody's server without being asked is not a thing an upgrade should
|
|
823
|
+
do. On a Pi, compare the two files above and copy across the settings you want.
|
|
824
|
+
|
|
611
825
|
Your organizations, accounts, database and logged data are untouched by an upgrade — they live in
|
|
612
826
|
this directory, not in `node_modules`.
|
|
613
827
|
|
|
614
828
|
---
|
|
615
829
|
|
|
616
|
-
## Part B — Raspberry Pi Zero W
|
|
617
|
-
|
|
618
|
-
**Not yet tested — do not follow this section expecting it to work.** It records what is known
|
|
619
|
-
and what has to be checked.
|
|
620
|
-
|
|
621
|
-
First, work out which board you have, because they are very different:
|
|
622
|
-
|
|
623
|
-
* **Raspberry Pi Zero 2 W** — 64-bit ARM (Cortex-A53), 512 MB RAM. Should follow **Part A**
|
|
624
|
-
almost unchanged: choose *Raspberry Pi Zero 2 W* in Imager, and everything else applies. Running
|
|
625
|
-
the server needs about 250 MB, so 512 MB should be enough; the pinch point is more likely to be
|
|
626
|
-
`npm install`, which is far hungrier than the running server.
|
|
627
|
-
* **Raspberry Pi Zero W** (the original) — 32-bit ARMv6 (BCM2835), 512 MB RAM. This is the
|
|
628
|
-
awkward one: it needs the 32-bit Raspberry Pi OS, and **the official Node.js builds no longer
|
|
629
|
-
support ARMv6**. Unofficial ARMv6 builds exist at
|
|
630
|
-
[unofficial-builds.nodejs.org](https://unofficial-builds.nodejs.org/download/release/), but
|
|
631
|
-
which versions are available, and whether one recent enough for this server exists, needs checking.
|
|
632
|
-
|
|
633
|
-
Differences to expect on either Zero:
|
|
634
|
-
|
|
635
|
-
* Wi-Fi is 2.4 GHz only on the original Zero W — it cannot see a 5 GHz-only network.
|
|
636
|
-
* 512 MB of RAM is tight for `npm install`. Increasing the swap file is likely to be necessary.
|
|
637
|
-
* Micro-USB power and micro-USB OTG, not USB-C and USB-A — different cables from the Pi 4.
|
|
638
|
-
* No Ethernet socket, so the Ethernet fallback in Part A is unavailable. (The original Zero W can
|
|
639
|
-
be reached as a USB gadget over the data port, which is an alternative worth documenting.)
|
|
640
|
-
* Everything will be slow. `npm install` may take a long time, especially if `sqlite3` has to be
|
|
641
|
-
compiled from source — which is likely on ARMv6, since no ready-made binaries are published.
|
|
642
|
-
|
|
643
|
-
**Both boards are to be tested**, one of each having been ordered for the purpose. This section gets
|
|
644
|
-
written once we know how they behave — in particular whether a usable Node exists for the original
|
|
645
|
-
Zero W's ARMv6.
|
|
646
|
-
|
|
647
|
-
---
|
|
648
|
-
|
|
649
830
|
## Open questions
|
|
650
831
|
|
|
651
832
|
Things this guide currently states with less confidence than the rest, to be resolved by
|
|
652
833
|
following it on real hardware. Please correct them in place, and delete them from this list, as
|
|
653
834
|
they get settled.
|
|
654
835
|
|
|
655
|
-
**
|
|
836
|
+
**To check while installing**
|
|
656
837
|
|
|
657
|
-
1. **`.local` from an Android phone** (
|
|
838
|
+
1. **`.local` from an Android phone** (steps 3, 4) - confirmed working from a laptop (with the
|
|
658
839
|
local-network permission granted on a Mac) and from an iPhone. Android is expected to fail, which
|
|
659
|
-
is what the note in
|
|
840
|
+
is what the note in step 4 assumes; worth confirming on a real Android phone.
|
|
660
841
|
|
|
661
842
|
**Needs information I do not have**
|
|
662
843
|
|
|
663
|
-
2. **Pi Zero W
|
|
664
|
-
|
|
844
|
+
2. **Pi Zero 2 W** - the Zero W notes come from a real install; the Zero 2 W is untested. Being
|
|
845
|
+
64-bit it should take the 64-bit image and avoid the `sqlite3` compile entirely, which is the slow
|
|
846
|
+
part, but it has the same 512 MB and so probably still needs the swap file in step 3.
|
|
665
847
|
3. **Bridging to the shared server** — the local broker could optionally bridge to
|
|
666
848
|
naturalinnovation.org so data also reaches the shared server. Not covered here; a later task.
|
|
667
|
-
4. **Organization naming** — this guide sets up exactly one organization named `
|
|
849
|
+
4. **Organization naming** — this guide sets up exactly one organization named `myfarm`, because that
|
|
668
850
|
is the node firmware's default. Is that the right default for a farm installation, or should the
|
|
669
851
|
guide encourage a meaningful organization id (which then has to be set in the node firmware too)?
|
|
670
852
|
|
|
@@ -674,4 +856,5 @@ What the guide has actually been proven against — add a row for each run:
|
|
|
674
856
|
|
|
675
857
|
| Date | Board | OS image | Node | Server | Result |
|
|
676
858
|
| --- | --- | --- | --- | --- | --- |
|
|
677
|
-
| 2026-
|
|
859
|
+
| 2026-08-17 | Pi Zero W (original), 512 MB | Raspberry Pi OS Lite **32-bit**, Debian 13 (trixie), kernel 6.18.39+rpt-rpi-v6 | 20.19.2 and npm 9.2.0, both from `apt` — they run on ARMv6 | frugal-iot-server 0.3.5 from npm | Steps 1-8 completed. `sqlite3` had to be compiled: about 40 minutes, after `build-essential python3-dev python3-setuptools` (without setuptools it fails on `distutils`). A 2 GB swap file was required — zram alone was not enough and the board locked up hard without it — and `npm install` was run with `--maxsockets 1`. Step 9 (sensor nodes) not exercised on this board, but the broker publish/subscribe tests in step 6 passed. |
|
|
860
|
+
| 2026-08-16 | Pi 4 Model B, 4GB | Raspberryy Pi OS Lite 64-bit, Debian 13.6 (trixie) | 20.19.2 and npm 9.2.0, both from `apt` | frugal-iot-server 0.3.5 from npm | Steps 1-9 completed, plus upgrade over top. Dashboard reached over `frugaliot.local` from a Mac (Chrome, after allowing local network access) and from an iPhone, MQTT status *connected*. 10 (HTTPS/OTA) not exercised.
|