Skip to content

Commit 37f7038

Browse files
feat: Add more validations
1 parent d38414b commit 37f7038

File tree

4 files changed

+103
-8
lines changed

4 files changed

+103
-8
lines changed

config/config.js.sample

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ let config = {
104104
broadcastNewsUpdates: true
105105
}
106106
},
107-
// Example Sense HAT module configuration:
107+
// Example Sense HAT module configuration.
108+
// Uncomment this block on a Raspberry Pi with a Sense HAT installed:
108109
// {
109110
// module: "sensehat",
110111
// position: "top_right",

modules/default/sensehat/README.md

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,72 @@ How it works
6060

6161
Troubleshooting
6262

63-
- If you see warnings about "sense_hat library not available", ensure the package python3-sense-hat is installed and you are on a Raspberry Pi.
64-
- If LED text rendering blocks updates, remember that show_message scrolls the text; it will finish and allow the next poll. Reduce updateInterval or avoid text mode if you prefer continuous updates.
63+
1. Check that the Sense HAT is detected by the kernel
64+
65+
```
66+
ls -l /dev/i2c*
67+
dmesg | grep -i "sense"
68+
```
69+
70+
You should see:
71+
72+
- /dev/i2c-1 present
73+
- A line like: fb1: RPi-Sense FB frame buffer device
74+
- A joystick device entry for the Sense HAT
75+
76+
2. Probe I²C bus 1
77+
78+
```
79+
sudo i2cdetect -y 1
80+
```
81+
82+
On a working Sense HAT, you should see several non-"--" addresses (e.g. 1c, 39, 5c, 5f, 6a). If everything shows "--", the HAT may not be seated correctly or could be faulty.
83+
84+
3. Test using the official Python library
85+
86+
```
87+
python3 - << 'PY'
88+
from sense_hat import SenseHat
89+
90+
sh = SenseHat()
91+
92+
print("Temperature:", sh.get_temperature())
93+
print("Humidity :", sh.get_humidity())
94+
print("Pressure :", sh.get_pressure())
95+
PY
96+
```
97+
98+
- If you get numeric values, the sensors are working.
99+
- If you see errors like `OSError: Humidity Init Failed`, there may be a contact problem on the header or a sensor issue.
100+
101+
4. Check the LED matrix
102+
103+
```
104+
python3 - << 'PY'
105+
from sense_hat import SenseHat
106+
from time import sleep
107+
108+
sh = SenseHat()
109+
sh.clear()
110+
sh.show_message("HI", text_colour=(0, 255, 0), scroll_speed=0.07)
111+
sleep(1)
112+
sh.clear()
113+
PY
114+
```
115+
116+
If you don’t see LEDs:
117+
118+
- Power off the Raspberry Pi.
119+
- Firmly press the Sense HAT onto the 40-pin header (common on new boards).
120+
- Boot again and re-run the test.
121+
122+
5. What the MagicMirror module will show
123+
124+
- "Loading Sense HAT data…" → Python helper hasn’t delivered any data yet.
125+
- "Sense HAT: no sensor data (check hardware or drivers)" → helper runs, but all sensor fields are null.
126+
- "Sense HAT error: …" → helper reported an explicit error (library missing, init failure, etc.).
127+
128+
If the Python tests fail, the issue is with hardware/OS/driver rather than this MagicMirror module.
65129

66130
License
67131
MIT (follow the MagicMirror² project license)

modules/default/sensehat/node_helper.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ module.exports = NodeHelper.create({
7070
const data = JSON.parse(stdout.trim());
7171
if (data && data.error) {
7272
Log.warn(`[sensehat] Python reported error: ${data.error}`);
73+
// Forward error payload to frontend so UI can display it
74+
this.sendSocketNotification("SENSEHAT_DATA", data);
7375
return;
7476
}
7577
this.sendSocketNotification("SENSEHAT_DATA", data);

modules/default/sensehat/sensehat.js

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,41 @@ Module.register("sensehat", {
2323
start () {
2424
this.sensorData = null;
2525
this.ready = false;
26-
// Send configuration to node_helper
2726
this.sendSocketNotification("SENSEHAT_CONFIG", this.config);
2827
},
2928

3029
getDom () {
3130
const wrapper = document.createElement("div");
3231
wrapper.className = "sensehat";
3332

34-
if (!this.sensorData) {
33+
// Loading state
34+
if (this.sensorData === null) {
3535
wrapper.innerHTML = "Loading Sense HAT data...";
3636
return wrapper;
3737
}
3838

3939
const data = this.sensorData;
4040

41+
// Error state from backend
42+
if (data && typeof data.error === "string" && data.error.trim() !== "") {
43+
wrapper.innerHTML = `Sense HAT error: ${data.error}`;
44+
return wrapper;
45+
}
46+
47+
const hasAnyValue
48+
= typeof data.temperature === "number"
49+
|| typeof data.humidity === "number"
50+
|| typeof data.pressure === "number"
51+
|| (data.orientation
52+
&& (typeof data.orientation.pitch === "number"
53+
|| typeof data.orientation.roll === "number"
54+
|| typeof data.orientation.yaw === "number"));
55+
56+
if (!hasAnyValue) {
57+
wrapper.innerHTML = "Sense HAT: no sensor data (check hardware or drivers)";
58+
return wrapper;
59+
}
60+
4161
// Temperature
4262
if (this.config.showTemperature && typeof data.temperature === "number") {
4363
const t = this.config.temperatureUnit === "F" ? (data.temperature * 9) / 5 + 32 : data.temperature;
@@ -91,13 +111,21 @@ Module.register("sensehat", {
91111

92112
// Optional LED status logic
93113
if (this.config.ledMatrixEnabled && this.config.ledMode !== "text") {
114+
// Only act when we have real numeric data and no error
115+
const hasNumeric = typeof payload.temperature === "number" || typeof payload.humidity === "number";
116+
if (!(hasNumeric) || (payload && typeof payload.error === "string" && payload.error.trim() !== "")) {
117+
return;
118+
}
94119
const { temperatureHigh, temperatureLow, humidityHigh, humidityLow } = this.config.criticalThresholds || {};
95120
let color = this.config.ledColor || [0, 255, 0];
96121

97-
// Danger if out of range
98122
if (
99-
(typeof payload.temperature === "number" && (((temperatureHigh !== null && temperatureHigh !== undefined) && payload.temperature > temperatureHigh) || ((temperatureLow !== null && temperatureLow !== undefined) && payload.temperature < temperatureLow)))
100-
|| (typeof payload.humidity === "number" && (((humidityHigh !== null && humidityHigh !== undefined) && payload.humidity > humidityHigh) || ((humidityLow !== null && humidityLow !== undefined) && payload.humidity < humidityLow)))
123+
(typeof payload.temperature === "number"
124+
&& (((temperatureHigh !== null && temperatureHigh !== undefined) && payload.temperature > temperatureHigh)
125+
|| ((temperatureLow !== null && temperatureLow !== undefined) && payload.temperature < temperatureLow)))
126+
|| (typeof payload.humidity === "number"
127+
&& (((humidityHigh !== null && humidityHigh !== undefined) && payload.humidity > humidityHigh)
128+
|| ((humidityLow !== null && humidityLow !== undefined) && payload.humidity < humidityLow)))
101129
) {
102130
color = [255, 0, 0]; // red
103131
} else {

0 commit comments

Comments
 (0)