-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathMMM-YouLess2.js
More file actions
180 lines (151 loc) · 5.62 KB
/
Copy pathMMM-YouLess2.js
File metadata and controls
180 lines (151 loc) · 5.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* Magic Mirror
* Module: MMM-YouLess2
*
* By M. Eckert
* MIT Licensed.
*/
Module.register("MMM-YouLess2", {
// Module config defaults.
defaults: {
// required settings
youlessHost: "192.168.178.77", // or youless.home.network.nl
updateInterval: 30 * 1000, // every 30 seconds
// optional settings
totalGauge: 5000, // max watt for drawing circle
gaugeUniqueId: "YouLess2_Gauge_1", // must be unique, if you have multiple instances, rename the second one, e.g.: YouLess2_Gauge_2
gaugeValueLabel: "Watt", // gauge value label, directly after the value
gaugeLabel: "Stromlast", // gauge label in bottom of the gauge
gaugeStyle: "Arch", // possible Options: Full | Arch | Semi
// change it, if you know what you do
initialLoadDelay: 0, // 0 seconds delay
retryDelay: 2 * 1000, // retry after 2 seconds
gaugeStripe: 0, // possible Options: 0 | 1
gaugeSize: 250, // size of the gauge
gaugeColor: "#ffffff", // color of the active gauge
gaugeBackColor: "rgba(255,255,255,.3)", // color of the inactive gauge
gaugeCircleWidth: 16, // with of the gauge circle
gaugeAnimationstep: 0, // filling gauge with or without animation
gaugeAnimateCircleColors: false, // animate circle colors
gaugeAnimateTextColors: false, // animate texte colors
gaugeLabelColor: "#ffffff", // label color
gaugeTextSize: .11 // text size
},
start: function () {
this.loaded = false;
this.powerUsage = -1;
Log.info("Starting module: " + this.name);
this.scheduleUpdate(this.config.initialLoadDelay);
},
getStyles: function () {
return [
this.file("public/css/styles.css"),
"font-awesome.css",
];
},
getScripts: function () {
return [
"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js", // this file will be loaded from the jquery servers.
this.file("public/js/GaugeMeter.js"),
];
},
getDom: function () {
var wrapper = jQuery(document.createElement("div")).addClass("GaugeMeter").attr("id", this.config.gaugeUniqueId);
var obj = {
percent: ((this.powerUsage / this.config.totalGauge) * 100),
size: this.config.gaugeSize,
color: this.config.gaugeColor,
back: this.config.gaugeBackColor,
width: this.config.gaugeCircleWidth,
style: this.config.gaugeStyle,
stripe: this.config.gaugeStripe,
animationstep: this.config.gaugeAnimationstep,
animate_gauge_colors: this.config.gaugeAnimateCircleColors,
animate_text_colors: this.config.gaugeAnimateTextColors,
label: this.config.gaugeLabel,
label_color: this.config.gaugeLabelColor,
text: this.powerUsage,
text_size: this.config.gaugeTextSize
}
wrapper.data(obj);
wrapper.gaugeMeter();
return wrapper[0];
},
updatePowerUsage: function () {
var self = this;
this.sendSocketNotification("QUERY");
// Use default timeout if already loaded, else use the retryDelay if module hasn't loaded yet
self.scheduleUpdate((self.loaded) ? -1 : self.config.retryDelay);
},
processPowerUsage: function (data) {
if (data) {
var spanSeletor = "#" + this.config.gaugeUniqueId + " span";
var oldWatt = jQuery(spanSeletor).text();
jQuery(spanSeletor).attr("data-after", this.config.gaugeValueLabel);
this.powerUsageHigh = this.powerUsageHigh < data.pwr ? data.pwr : this.powerUsageHigh;
this.powerUsage = data.pwr;
this.loaded = true;
jQuery("#" + this.config.gaugeUniqueId).gaugeMeter({
percent: ((this.powerUsage / this.config.totalGauge) * 100)
});
this.animateValue(spanSeletor, oldWatt, this.powerUsage, 500);
}
},
/* scheduleUpdate()
* Schedule next update.
*
* argument delay number - Milliseconds before next update. If empty, this.config.updateInterval is used.
*/
scheduleUpdate: function (delay) {
var nextLoad = this.config.updateInterval;
if (typeof delay !== "undefined" && delay >= 0) {
nextLoad = delay;
}
var self = this;
setTimeout(function () {
self.updatePowerUsage();
}, nextLoad);
},
notificationReceived: function (notification, payload, sender) {
if (notification === "DOM_OBJECTS_CREATED") {
this.loaded = true;
this.sendSocketNotification("CONFIG", this.config);
}
},
socketNotificationReceived: function (notification, payload) {
var self = this;
var responseReceived = function (payload) {
self.processPowerUsage(JSON.parse(payload));
};
var acceptedNotifications = {
"RESPONSE": responseReceived,
};
// Call appropriate handler for socket notification
acceptedNotifications[notification] && typeof acceptedNotifications[notification] === "function" && acceptedNotifications[notification](payload);
},
animateValue: function (element, start, end, duration) {
// assumes integer values for start and end
var obj = jQuery(element);
var range = end - start;
// no timer shorter than 50ms (not really visible any way)
var minTimer = 50;
// calc step time to show all interediate values
var stepTime = Math.abs(Math.floor(duration / range));
// never go below minTimer
stepTime = Math.max(stepTime, minTimer);
// get current time and calculate desired end time
var startTime = new Date().getTime();
var endTime = startTime + duration;
var timer;
function run() {
var now = new Date().getTime();
var remaining = Math.max((endTime - now) / duration, 0);
var value = Math.round(end - (remaining * range));
obj.html(value);
if (value == end) {
clearInterval(timer);
}
}
timer = setInterval(run, stepTime);
run();
}
});