Skip to content

Commit b4f528a

Browse files
authored
1.1.3 (#189)
* added `@TASMOTAON <ip> <indx>` and `@TASMOTAOFF <ip> <indx>` gcode commands to resolve issues with firmware that errors with M80/M81 commands, resolves #178 * make polling_interval float to allow for sub-minute polling * change from tooltip to popover, thanks to @ManuelMcLure * added theme support to power graph
1 parent 6ae0536 commit b4f528a

File tree

5 files changed

+107
-19
lines changed

5 files changed

+107
-19
lines changed

octoprint_tasmota/__init__.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ def on_startup(self, host, port):
148148

149149
def on_after_startup(self):
150150
self._logger.info("Tasmota loaded!")
151-
if self._settings.get_boolean(["polling_enabled"]) and self._settings.get_int(["polling_interval"]) > 0:
152-
self.poll_status = RepeatedTimer(int(self._settings.get_int(["polling_interval"])) * 60,
151+
if self._settings.get_boolean(["polling_enabled"]) and self._settings.get_float(["polling_interval"]) > 0:
152+
self.poll_status = RepeatedTimer(float(self._settings.get_float(["polling_interval"])) * 60,
153153
self.check_statuses)
154154
self.poll_status.start()
155155

@@ -226,7 +226,7 @@ def on_settings_save(self, data):
226226
self.poll_status.cancel()
227227

228228
if new_polling_value:
229-
self.poll_status = RepeatedTimer(int(self._settings.get(["pollingInterval"])) * 60, self.check_statuses)
229+
self.poll_status = RepeatedTimer(self._settings.get_float(["pollingInterval"]) * 60, self.check_statuses)
230230
self.poll_status.start()
231231

232232
def get_settings_version(self):
@@ -304,7 +304,7 @@ def get_assets(self):
304304

305305
def get_template_configs(self):
306306
return [
307-
{'type': "navbar", 'custom_bindings': True},
307+
{'type': "navbar", 'custom_bindings': True, 'classes': ["hide_popover_content"]},
308308
{'type': "settings", 'custom_bindings': True},
309309
{'type': "tab", 'custom_bindings': True},
310310
{'type': "sidebar", 'icon': "plug", 'custom_bindings': True, 'data_bind': "visible: show_sidebar",
@@ -841,13 +841,34 @@ def processAtCommand(self, comm_instance, phase, command, parameters, tags=None,
841841
if command == 'TASMOTAIDLEON':
842842
self.powerOffWhenIdle = True
843843
self._reset_idle_timer()
844-
if command == 'TASMOTAIDLEOFF':
844+
elif command == 'TASMOTAIDLEOFF':
845845
self.powerOffWhenIdle = False
846846
self._stop_idle_timer()
847847
if self._abort_timer is not None:
848848
self._abort_timer.cancel()
849849
self._abort_timer = None
850850
self._timeout_value = None
851+
elif command == 'TASMOTAON':
852+
plugip, plugidx = parameters.split(" ")
853+
self._tasmota_logger.debug("Received TASMOTAON command, attempting power on of %s:%s." % (plugip, plugidx))
854+
plug = self.plug_search(self._settings.get(["arrSmartplugs"]), "ip", plugip, "idx", plugidx)
855+
self._tasmota_logger.debug(plug)
856+
if plug and plug["gcodeEnabled"]:
857+
t = threading.Timer(int(plug["gcodeOnDelay"]), self.gcode_on, [plug])
858+
t.daemon = True
859+
t.start()
860+
return None
861+
elif command == 'TASMOTAOFF':
862+
plugip, plugidx = parameters.split(" ")
863+
self._tasmota_logger.debug("Received TASMOTAOFF command, attempting power off of %s:%s." % (plugip, plugidx))
864+
plug = self.plug_search(self._settings.get(["arrSmartplugs"]), "ip", plugip, "idx", plugidx)
865+
self._tasmota_logger.debug(plug)
866+
if plug and plug["gcodeEnabled"]:
867+
t = threading.Timer(int(plug["gcodeOffDelay"]), self.gcode_off, [plug])
868+
t.daemon = True
869+
t.start()
870+
return None
871+
851872
if command in ["TASMOTAIDLEON", "TASMOTAIDLEOFF"]:
852873
self._plugin_manager.send_plugin_message(self._identifier,
853874
dict(powerOffWhenIdle=self.powerOffWhenIdle, type="timeout",

octoprint_tasmota/static/css/tasmota.css

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,29 @@ input[type="datetime-local"].alert-error {
8181
.navbar .nav > li > a.tasmota_button {
8282
float: left;
8383
}
84+
85+
/* For popover */
86+
#navbar_plugin_tasmota div.popover {
87+
width: auto !important;
88+
max-width: 100em;
89+
}
90+
#navbar_plugin_tasmota div.popover table {
91+
width: auto !important;
92+
table-layout: auto !important;
93+
}
94+
#navbar_plugin_tasmota div.popover td {
95+
width: auto !important;
96+
white-space: nowrap;
97+
}
98+
#navbar_plugin_tasmota div.popover td:last-child {
99+
padding-left: 1em;
100+
}
101+
#navbar_plugin_tasmota div.popover h3.popover-title {
102+
white-space: nowrap;
103+
}
104+
#navbar_plugin_tasmota a.hide_popover_content + div.popover > h3.popover-title {
105+
border: none;
106+
}
107+
#navbar_plugin_tasmota a.hide_popover_content + div.popover > div.popover-content {
108+
display: none;
109+
}

octoprint_tasmota/static/js/tasmota.js

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,34 @@ $(function() {
187187
}
188188
};
189189

190+
self.getDefaultBackground = function() {
191+
// have to add to the document in order to use getComputedStyle
192+
var div = document.createElement("div");
193+
document.head.appendChild(div);
194+
var bg = window.getComputedStyle(div).backgroundColor;
195+
document.head.removeChild(div);
196+
return bg;
197+
};
198+
199+
self.getInheritedBackgroundColor = function(el) {
200+
// get default style for current browser
201+
if (!self.defaultStyle) {
202+
self.defaultStyle = self.getDefaultBackground(); // typically "rgba(0, 0, 0, 0)"
203+
}
204+
205+
// get computed color for el
206+
var backgroundColor = window.getComputedStyle(el).backgroundColor;
207+
208+
// if we got a real value, return it
209+
if (backgroundColor !== self.defaultStyle) return backgroundColor;
210+
211+
// if we've reached the top parent el without getting an explicit color, return default
212+
if (!el.parentElement) return self.defaultStyle;
213+
214+
// otherwise, recurse and try again on parent element
215+
return self.getInheritedBackgroundColor(el.parentElement);
216+
};
217+
190218
self.plotEnergyData = function(){
191219
$.ajax({
192220
url: API_BASEURL + "plugin/tasmota",
@@ -232,14 +260,20 @@ $(function() {
232260
}
233261
}
234262

263+
var background_color = (self.getInheritedBackgroundColor(document.getElementById('tab_plugin_tasmota')) == 'rgba(0, 0, 0, 0)') ? '#FFFFFF' : self.getInheritedBackgroundColor(document.getElementById('tab_plugin_tasmota'));
264+
var foreground_color = ($('.tab-content').css('color') == 'rgba(0, 0, 0, 0)') ? '#FFFFFF' : $('#tabs_content').css('color');
265+
235266
var layout = {
236267
autosize: true,
237268
showlegend: false,
238269
/* legend: {"orientation": "h"}, */
239270
xaxis: { type:"date", /* tickformat:"%H:%M:%S", */ automargin: true, title: {standoff: 0},linecolor: 'black', linewidth: 2, mirror: true},
240271
yaxis: { type:"linear", automargin: true, title: {standoff: 0},linecolor: 'black', linewidth: 2, mirror: true },
241-
margin: {l:35,r:30,b:0,t:20,pad:5}
242-
}
272+
margin: {l:35,r:30,b:0,t:20,pad:5},
273+
plot_bgcolor: background_color,
274+
paper_bgcolor: background_color,
275+
font: {color: foreground_color}
276+
};
243277

244278
var options = {
245279
showLink: false,
@@ -248,7 +282,7 @@ $(function() {
248282
displayModeBar: false,
249283
editable: false,
250284
showTips: false
251-
}
285+
};
252286

253287
Plotly.react('tasmota_graph', traces, layout, options);
254288
});
@@ -391,18 +425,25 @@ $(function() {
391425
console.log('plug data:'+ko.toJSON(plug));
392426
}
393427

394-
var tooltip = plug.label();
395-
if(data.sensor_data) {
396-
for(let k in data.sensor_data) {
397-
tooltip += '<br>' + k + ': ' + data.sensor_data[k]
428+
429+
var tooltip = '';
430+
if (data.sensor_data || data.energy_data) {
431+
tooltip += '<table style="width: 100%"><thead></thead><tbody>';
432+
if(data.sensor_data) {
433+
for(let k in data.sensor_data) {
434+
tooltip += '<tr><td>' + k + ':</td><td>' + data.sensor_data[k] + '</td></tr>';
435+
}
398436
}
399-
}
400-
if(data.energy_data) {
401-
for(let k in data.energy_data) {
402-
tooltip += '<br>' + k + ': ' + data.energy_data[k]
437+
if(data.energy_data) {
438+
for(let k in data.energy_data) {
439+
tooltip += '<tr><td>' + k + ':</td><td>' + data.energy_data[k] + '</td></tr>';
440+
}
403441
}
442+
tooltip += '</tbody></table>';
443+
$(('#tasmota_button_link_'+data.ip+'_'+data.idx).replace(/[.:]/g,'_')).removeClass('hide_popover_content');
444+
} else {
445+
$(('#tasmota_button_link_'+data.ip+'_'+data.idx).replace(/[.:]/g,'_')).addClass('hide_popover_content');
404446
}
405-
//plug.label_extended = ko.observable(tooltip);
406447
try {
407448
self.arrSmartplugsTooltips.set(data.ip+'_'+data.idx, tooltip);
408449
} catch (error) {

octoprint_tasmota/templates/tasmota_navbar.jinja2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!-- ko foreach: settings.settings.plugins.tasmota.arrSmartplugs -->
2-
<a class="tasmota_button" href="#" data-toggle="tooltip" data-html="true" data-bind="click: $root.toggleRelay,visible: $root.loginState.loggedIn(), tooltip: {title: $root.arrSmartplugsTooltips.get(ip()+'_'+idx()), placement: 'bottom'}" style="display: none;"><i class="icon" data-bind="css: [$root.arrSmartplugsStates.get(ip()+'_'+idx())(), icon(),(($root.processing().indexOf(ip()) > -1) ? 'icon-spin' : '')].join(' '), style: {color: $root.get_color($data)}" aria-hidden="true"></i><div class="tasmota_label" data-bind="text: $data.label_extended"></div></a>
2+
<a class="tasmota_button hide_popover_content" href="#" data-bind="click: $root.toggleRelay,visible: $root.loginState.loggedIn(), popover: {title: $data.label, html: true, content: $root.arrSmartplugsTooltips.get(ip()+'_'+idx()), placement: 'bottom', trigger: 'hover'}, attr: { id: ('tasmota_button_link_'+ip()+'_'+idx()).replace(/[.:]/g, '_')}" style="display: none;"><i class="icon" data-bind="css: [$root.arrSmartplugsStates.get(ip()+'_'+idx())(), icon(),(($root.processing().indexOf(ip()) > -1) ? 'icon-spin' : '')].join(' '), style: {color: $root.get_color($data)}" aria-hidden="true"></i><div class="tasmota_label" data-bind="text: $data.label_extended"></div></a>
33
<!-- /ko -->
44
<div id="TasmotaWarning" data-bind="with: selectedPlug" class="modal hide fade">
55
<div class="modal-header">

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
plugin_name = "OctoPrint-Tasmota"
1515

1616
# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
17-
plugin_version = "1.1.2"
17+
plugin_version = "1.1.3"
1818

1919
# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
2020
# module

0 commit comments

Comments
 (0)