-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlegacy_stats.dart
181 lines (161 loc) · 7.09 KB
/
legacy_stats.dart
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
181
import 'dart:async';
import 'package:meta/meta.dart';
import 'package:homie_dart/homie_dart.dart';
///The $stats attribute got removed from homie 3.0.1 to 4.0.
///Adding this extension enables you to send stats just as you would have in homie versions lower 4.0.
class LegacyStats extends DeviceExtension {
String get version => '0.1.1';
String get extensionId => 'org.homie.legacy-stats';
List<String> get homieVersions => const <String>['4.x'];
final Map<Device, Timer> _statsSender;
final DeviceStats _deviceStats;
///The stats of this device are periodically published to the mqtt broker.
///The stats can be accessed and modified.
DeviceStats get deviceStats => _deviceStats;
///The intervall in seconds the [deviceStats] are published, as long as the [Device.deviceState] is [DeviceState.ready].
final int statsIntervall;
///Stats about a device are peroidically published. With this extension, this happens automatically.
///As long as the [Device.deviceState] of the [Device] this extension is added to
///is [DeviceState.ready] the stats will be published every [statsIntervall] seconds.
///This value must not be [null] and greater than 0.
///The [stats] give information about the device. You can preconfigure the [stats] with custom initial values and pass them here.
///If the [stats] are [null], a new [DeviceStats] object will be created.
///In this case, the uptime of [Device] objects using this extension object will be counted since creation of this extension object.
LegacyStats({@required int statsIntervall, DeviceStats stats})
: assert(statsIntervall != null),
assert(statsIntervall > 0),
this.statsIntervall = statsIntervall,
this._deviceStats = stats ?? new DeviceStats.sinceNow(),
this._statsSender = new Map<Device, Timer>();
Future<Null> onStateChange(Device device, DeviceState state) async {
if (state == DeviceState.init) {
await publish(
device, '${device.fullTopic}/\$stats/intervall', statsIntervall.toString());
await _sendStats(device);
} else if (state == DeviceState.ready) {
_statsSender[device] =
new Timer.periodic(new Duration(seconds: statsIntervall), (Timer t) async {
if (t.isActive) {
try {
await _sendStats(device);
} on DisconnectingError {
//ignore
}
}
});
} else if (state == DeviceState.alert || state == DeviceState.sleeping) {
_statsSender[device].cancel();
_statsSender[device]==null;
} else if (state == DeviceState.disconnected) {
_statsSender[device].cancel();
_statsSender[device]==null;
await publish(device, '${device.fullTopic}/\$stats/intervall', emptyPayload);
await _forgetStats(device);
}
}
Future<Null> _forgetStats(Device device) async {
String statsTopic = '${device.fullTopic}/\$stats';
await publish(device,'$statsTopic/uptime', emptyPayload);
await publish(device,'$statsTopic/signal', emptyPayload);
await publish(device,'$statsTopic/cputemp', emptyPayload);
await publish(device,'$statsTopic/cpuload', emptyPayload);
await publish(device,'$statsTopic/battery', emptyPayload);
await publish(device,'$statsTopic/freeheap', emptyPayload);
await publish(device,'$statsTopic/supply', emptyPayload);
}
Future<Null> _sendStats(Device device) async {
String statsTopic = '${device.fullTopic}/\$stats';
await publish(device,'$statsTopic/uptime', deviceStats.uptime.toString());
if (deviceStats.signalStrength != null) {
await publish(device,
'$statsTopic/signal', deviceStats.signalStrength.toString());
}
if (deviceStats.cpuTemperature != null) {
await publish(device,
'$statsTopic/cputemp', deviceStats.cpuTemperature.toString());
}
if (deviceStats.cpuLoad != null) {
await publish(device,'$statsTopic/cpuload', deviceStats.cpuLoad.toString());
}
if (deviceStats.batterLevel != null) {
await publish(device,
'$statsTopic/battery', deviceStats.batterLevel.toString());
}
if (deviceStats.freeHeap != null) {
await publish(device,
'$statsTopic/freeheap', deviceStats.freeHeap.toString());
}
if (deviceStats.powerSupply != null) {
await publish(device,
'$statsTopic/supply', deviceStats.powerSupply.toString());
}
}
}
///Used to represend the stats of a device.
class DeviceStats {
final DateTime _bootTime;
///Signal strength in %. Wired devices might have a strengh of 100. This property is optional and might be null.
int signalStrength;
///The cpu temperature in °C. This property is optional and might be null.
int cpuTemperature;
///The cpu load in %. This property is optional and might be null.
int cpuLoad;
///The battery level in %. This property is optional and might be null.
int batterLevel;
///Free heap in bytes. This property is optional and might be null.
int freeHeap;
///The power supply voltage in Volt. This property is optional and might be null.
double powerSupply;
///The uptime is the time that passed since the [bootTime] given in the constructor in seconds.
int get uptime => new DateTime.now().difference(_bootTime).inSeconds;
///Creates a new [DeviceStats] object with [new DateTime.now()] as [bootTime].
///See [new DeviceStats()] for an explanation of the other properties.
DeviceStats.sinceNow(
{int signalStrength,
int cpuTemperature,
int cpuLoad,
int batteryLevel,
int freeHeap,
double powerSupply})
: this(
bootTime: new DateTime.now(),
signalStrength: signalStrength,
cpuTemperature: cpuTemperature,
cpuLoad: cpuLoad,
batteryLevel: batteryLevel,
freeHeap: freeHeap,
powerSupply: powerSupply);
///Creates a new state object.
///
///The only required property is the [bootTime], it must not be null.
///Using the [bootTime] the [uptime] of the device is calculated.
///All not requried properties are optional and might be [null]. In this case, they are not published.
///
///[singalStrengh]: Signal strength in %. Wired devices might have a strengh of 100.
///
///[cpuTemperature]: The cpu temperature in °C. This property is optional and might be null.
///
///[cpuLoad]: The cpu load in %. This property is optional and might be null.
///
///[batteryLevel]: The battery level in %. This property is optional and might be null.
///
///[freeHeap]: Free heap in bytes. This property is optional and might be null.
///
///[powerSupply]: The power supply voltage in Volt. This property is optional and might be null.
DeviceStats(
{@required DateTime bootTime,
int signalStrength,
int cpuTemperature,
int cpuLoad,
int batteryLevel,
int freeHeap,
double powerSupply})
: assert(bootTime != null),
this._bootTime = bootTime,
this.signalStrength = signalStrength,
this.cpuTemperature = cpuTemperature,
this.cpuLoad = cpuLoad,
this.batterLevel = batteryLevel,
this.freeHeap = freeHeap,
this.powerSupply = powerSupply;
}