Skip to content

Commit 3eed96f

Browse files
committed
Merge branch 'dev/health_check'
2 parents 96f3b31 + 6e04984 commit 3eed96f

File tree

3 files changed

+167
-71
lines changed

3 files changed

+167
-71
lines changed

octoprint_pi_support/__init__.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,20 @@ def get_additional_bundle_files(self, *args, **kwargs):
366366
else:
367367
return {}
368368

369+
##~~ Additional health checks hook
370+
371+
def get_additional_health_checks(self):
372+
from .health_checks import all_checks
373+
374+
def health_check_factory(clz):
375+
def factory(settings):
376+
return clz(self, settings)
377+
378+
factory.key = clz.key
379+
return factory
380+
381+
return [health_check_factory(clz) for clz in all_checks]
382+
369383
# ~~ EnvironmentDetectionPlugin
370384

371385
def get_additional_environment(self):
@@ -605,6 +619,11 @@ def _check_throttled_state(self):
605619
self._throttle_state.as_dict(),
606620
)
607621

622+
if hasattr(octoprint.events.Events, "PLUGIN_HEALTH_CHECK_UPDATE_HEALTHCHECK"):
623+
self._event_bus.fire(
624+
octoprint.events.Events.PLUGIN_HEALTH_CHECK_UPDATE_HEALTHCHECK
625+
)
626+
608627

609628
def register_custom_events(*args, **kwargs):
610629
return [
@@ -646,6 +665,7 @@ def __plugin_load__():
646665
"octoprint.events.register_custom_events": register_custom_events,
647666
"octoprint.access.permissions": __plugin_implementation__.get_additional_permissions,
648667
"octoprint.systeminfo.additional_bundle_files": __plugin_implementation__.get_additional_bundle_files,
668+
"octoprint.plugin.health_check.get_additional_checks": __plugin_implementation__.get_additional_health_checks,
649669
}
650670

651671
global __plugin_helpers__

octoprint_pi_support/health_checks.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from . import (
2+
_UNRECOMMENDED_MODELS,
3+
get_proc_dt_model,
4+
has_default_password,
5+
is_model_any_of,
6+
)
7+
8+
try:
9+
import octoprint.plugins.health_check.checks as checks
10+
except ImportError:
11+
try:
12+
# in case we extract it into a standalone plugin in the future...
13+
import octoprint_health_check.checks as checks
14+
except ImportError:
15+
# apparently the plugin is disabled
16+
checks = None
17+
18+
if checks is not None:
19+
20+
class PiSupportHealthCheck(checks.HealthCheck):
21+
def __init__(self, plugin, settings: dict):
22+
super().__init__(settings)
23+
self._plugin = plugin
24+
25+
class PiUndervoltageHealthCheck(PiSupportHealthCheck):
26+
key = "pi_undervoltage"
27+
28+
def perform_check(self, force=False):
29+
state = self._plugin.get_throttle_state()
30+
31+
if state["current_undervoltage"]:
32+
return checks.CheckResult(result=checks.Result.ISSUE, context=state)
33+
elif state["past_undervoltage"]:
34+
return checks.CheckResult(result=checks.Result.WARNING, context=state)
35+
36+
class PiUnsupportedHealthCheck(PiSupportHealthCheck):
37+
key = "pi_unsupported"
38+
39+
def perform_check(self, force=False):
40+
model = get_proc_dt_model()
41+
if is_model_any_of(model, *_UNRECOMMENDED_MODELS):
42+
return checks.CheckResult(result=checks.Result.WARNING)
43+
44+
class PiDefaultPasswordHealthCheck(PiSupportHealthCheck):
45+
key = "pi_default_password"
46+
47+
def perform_check(self, force=False):
48+
if has_default_password():
49+
return checks.CheckResult(result=checks.Result.WARNING)
50+
51+
all_checks = [
52+
PiUndervoltageHealthCheck,
53+
PiUnsupportedHealthCheck,
54+
PiDefaultPasswordHealthCheck,
55+
]
56+
57+
else:
58+
all_checks = []

octoprint_pi_support/static/js/pi_support.js

Lines changed: 89 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,59 @@ $(function () {
22
function PiSupportViewModel(parameters) {
33
var self = this;
44

5+
const UNDERVOLTAGE_TITLE = gettext("Undervoltage detected");
6+
const UNDERVOLTAGE_WARNING = gettext(
7+
"Your Raspberry Pi is reporting insufficient power. " +
8+
"Switch to an adequate power supply or risk bad " +
9+
"performance and failed prints."
10+
);
11+
const UNDERVOLTAGE_FAQ = "https://faq.octoprint.org/pi-issues";
12+
13+
const ZERO_TITLE = gettext("Unsupported hardware detected");
14+
const ZERO_WARNING = gettext(
15+
"OctoPrint does not and never has supported the " +
16+
"RPi Zero or Zero W. Use at least a Raspberry Pi 3 or Zero 2, or " +
17+
"risk bad performance and failed prints."
18+
);
19+
const ZERO_DISABLE = gettext(
20+
"You can disable this message via Settings > " +
21+
"Pi Support > Disable warning about unsupported hardware"
22+
);
23+
const ZERO_FAQ = "https://faq.octoprint.org/recommended-hardware";
24+
25+
const PASSWORD_TITLE = gettext("Default system password not changed");
26+
const PASSWORD_WARNING = gettext(
27+
'The default password for the system user "pi" has not ' +
28+
"been changed. This is a security risk - please login to " +
29+
"your Pi via SSH and change the password."
30+
);
31+
const PASSWORD_DISABLE = gettext(
32+
"You can disable this message via Settings > " +
33+
"Pi Support > Disable warning about default system password"
34+
);
35+
const PASSWORD_FAQ = "https://faq.octoprint.org/pi-default-password";
36+
37+
const FAQ = gettext(
38+
'You can read more <a href="%(url)s" target="_blank">in the FAQ</a>.'
39+
);
40+
41+
const generateHtml = (warning, faq, disable) => {
42+
const html =
43+
"<p>" +
44+
warning +
45+
"</p><p>" +
46+
_.sprintf(FAQ, {
47+
url: faq
48+
}) +
49+
"</p>";
50+
51+
if (disable) {
52+
return html + "<p><small>" + disable + "</small></p>";
53+
} else {
54+
return html;
55+
}
56+
};
57+
558
self.loginState = parameters[0];
659
self.access = parameters[1];
760
self.settings = parameters[2];
@@ -35,34 +88,10 @@ $(function () {
3588
response.model_unrecommended &&
3689
!self.settings.settings.plugins.pi_support.ignore_unrecommended_model()
3790
) {
38-
var warning = gettext(
39-
"OctoPrint does not and never has supported the " +
40-
"RPi Zero or Zero W. Use at least a Raspberry Pi 3 or Zero 2, or " +
41-
"risk bad performance and failed prints."
42-
);
43-
var faq = gettext(
44-
"" +
45-
'You can read more <a href="%(url)s" target="_blank">in the FAQ</a>.'
46-
);
47-
var remove = gettext(
48-
"You can disable this message via Settings > " +
49-
"Pi Support > Disable warning about unsupported hardware"
50-
);
51-
5291
if (self.notifications.unrecommended === undefined) {
5392
self.notifications.unrecommended = new PNotify({
54-
title: gettext("Unsupported hardware detected"),
55-
text:
56-
"<p>" +
57-
warning +
58-
"</p><p>" +
59-
_.sprintf(faq, {
60-
url: "https://faq.octoprint.org/recommended-hardware"
61-
}) +
62-
"</p><p>" +
63-
"<small>" +
64-
remove +
65-
"</small></p>",
93+
title: ZERO_TITLE,
94+
text: generateHtml(ZERO_WARNING, ZERO_FAQ, ZERO_DISABLE),
6695
type: "error",
6796
hide: false
6897
});
@@ -96,27 +125,10 @@ $(function () {
96125
// Throttle state
97126
self.fromThrottleState(response.throttle_state);
98127
if (self.currentUndervoltage() || self.pastUndervoltage()) {
99-
var warning = gettext(
100-
"Your Raspberry Pi is reporting insufficient power. " +
101-
"Switch to an adequate power supply or risk bad " +
102-
"performance and failed prints."
103-
);
104-
var faq = gettext(
105-
"" +
106-
'You can read more <a href="%(url)s" target="_blank">in the FAQ</a>.'
107-
);
108-
109128
if (self.notifications.throttled === undefined) {
110129
self.notifications.throttled = new PNotify({
111-
title: gettext("Undervoltage detected"),
112-
text:
113-
"<p>" +
114-
warning +
115-
"</p><p>" +
116-
_.sprintf(faq, {
117-
url: "https://faq.octoprint.org/pi-issues"
118-
}) +
119-
"</p>",
130+
title: UNDERVOLTAGE_TITLE,
131+
text: generateHtml(UNDERVOLTAGE_WARNING, UNDERVOLTAGE_FAQ),
120132
type: "error",
121133
hide: false
122134
});
@@ -131,34 +143,14 @@ $(function () {
131143
response.default_password &&
132144
!self.settings.settings.plugins.pi_support.ignore_default_password()
133145
) {
134-
var warning = gettext(
135-
'The default password for the system user "pi" has not ' +
136-
"been changed. This is a security risk - please login to " +
137-
"your Pi via SSH and change the password."
138-
);
139-
var faq = gettext(
140-
"" +
141-
'You can read more <a href="%(url)s" target="_blank">in the FAQ</a>.'
142-
);
143-
var remove = gettext(
144-
"You can disable this message via Settings > " +
145-
"Pi Support > Disable warning about default system password"
146-
);
147-
148146
if (self.notifications.default_password === undefined) {
149147
self.notifications.default_password = new PNotify({
150-
title: gettext("Default system password not changed"),
151-
text:
152-
"<p>" +
153-
warning +
154-
"</p><p>" +
155-
_.sprintf(faq, {
156-
url: "https://faq.octoprint.org/pi-default-password"
157-
}) +
158-
"</p><p>" +
159-
"<small>" +
160-
remove +
161-
"</small></p>",
148+
title: PASSWORD_TITLE,
149+
text: generateHtml(
150+
PASSWORD_WARNING,
151+
PASSWORD_FAQ,
152+
PASSWORD_DISABLE
153+
),
162154
hide: false
163155
});
164156
}
@@ -326,6 +318,32 @@ $(function () {
326318
return false;
327319
}
328320
};
321+
322+
self.getAdditionalHealthCheckHandlers = function () {
323+
return {
324+
pi_undervoltage: (result, context) => {
325+
return {
326+
title: UNDERVOLTAGE_TITLE,
327+
html: generateHtml(UNDERVOLTAGE_WARNING, UNDERVOLTAGE_FAQ),
328+
result: result
329+
};
330+
},
331+
pi_unsupported: (result, context) => {
332+
return {
333+
title: ZERO_TITLE,
334+
html: generateHtml(ZERO_WARNING, ZERO_FAQ),
335+
result: result
336+
};
337+
},
338+
pi_default_password: (result, context) => {
339+
return {
340+
title: PASSWORD_TITLE,
341+
html: generateHtml(PASSWORD_WARNING, PASSWORD_FAQ),
342+
result: result
343+
};
344+
}
345+
};
346+
};
329347
}
330348

331349
OCTOPRINT_VIEWMODELS.push({

0 commit comments

Comments
 (0)