-
Notifications
You must be signed in to change notification settings - Fork 6
/
mqtt-subscription.html
292 lines (252 loc) · 8.18 KB
/
mqtt-subscription.html
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="mqtt-subscription-regestration-behaviour.html">
<!--
The mqtt-subscription element
creates a MQTT subscription to a MQTT topic. Place the element within a mqtt-connection to create the binding between
the connection and the subscription. The following example
<mqtt-connection >
<mqtt-subscription
topic="foo/bar"
number-of-messages="Infinity"
last-message="{{lastMessage}}"
messages="{{messages}}"
subscribed="{{subscribed}}"></mqtt-subscription>
</mqtt-connection>
creates a subscription to the topic "foo/bar" and stores all received messages within `messages`. The last messages will
be bound to `lastMessage`. `subscribed` indicates whether the subscription is subscribed or not.
@demo demo/index.html
-->
<dom-module id="mqtt-subscription">
<template>
</template>
</dom-module>
<script>
'use strict';
(function (scope) {
var MqttElements = scope.MqttElements = scope.MqttElements || {};
MqttElements.MqttSubscription = Polymer({
is: 'mqtt-subscription',
/**
* Fired when a subscription is subscribed .
*
* @event mqtt-subscription-subscribed
* @param {{
* topic: string,
* qos: number
* }}
*/
/**
* Fired when a subscription is unsubscribed .
*
* @event mqtt-subscription-unsubscribed
* @param {{
* topic: string,
* qos: number
* }}
*/
/**
* Fired when a message is receive for this subscription.
*
* @event mqtt-subscription-message
* @param {{
* topic: string,
* message: Object
* qos: number,
* retained: boolean,
* dub: boolean
* }}
*/
properties: {
/**
* Will be set to the last message received.
* @type Object
*/
lastMessage: {
type: Object,
readOnly: true,
notify: true,
},
/**
* An array of messages of the `numberOfMessages` number of messages received
* @type Array
*/
messages: {
type: Array,
readOnly: true,
notify: true,
value: function () {
return [];
}
},
/**
* The number of messages that are sored in `messages` use `<mqtt-subscription number-of-messages="Infinity">` to
* store every message.
* @type Number [1..Infinity]
*/
numberOfMessages: {
type: Number,
value: 1,
observer: '_numberOfMessagesChanged'
},
/**
* The payload of the mqtt.message is an `Uint8Array`. If the payload is an String use `String` otherwise use
* `Custom` as `payloadType` and provide a custom `payloadParseFunction`. If the subscription is generic use
* `Unknown` and the payload will not be parsed.
*/
payloadType: {
type: String,
value: "String",
observer: "_payloadTypeChanged"
},
/**
* The qos the subscription is made to
* @type Number
*/
qos: {
type: Number,
value: 0,
},
/**
* Indicating that the subscription is successfully subscribed with the mqtt broker
*/
subscribed: {
type: Boolean,
readOnly: true,
notify: true,
value: false,
},
/**
* The
* @type String
*/
topic: {
type: String,
},
/**
* The function that is used to parse the message payload
* @type Function
*/
payloadParseFunction: {
type: Function,
value: String.fromCharCode,
},
/**
* A private function to signal the subscription that it is subscribed
* @private
*/
_handelSubscriptionSubscribedFunc: {
type: Function,
readOnly: true,
value: function () {
return this._handelSubscriptionSubscribed.bind(this);
}
},
/**
* A private function to handel a message
* @private
*/
_handelMessageFunc: {
type: Function,
readOnly: true,
value: function () {
return this._handelMessage.bind(this);
}
}
},
behaviors: [MqttElements.MqttSubscriptionRegestrationBehaviour],
/**
* A change listener for `numberOfMessages` to validate the input
* @param numberOfMessages
* @param old
* @private
*/
_numberOfMessagesChanged: function (numberOfMessages, old) {
if(numberOfMessages <= 0) {
console.error("numberOfMessages must be higher than 0, setting back to 1");
this.numberOfMessages = 1;
}
},
/**
* A private function to set the right `payloadParseFunction` after the `payloadType` changed
* @param payloadType
* @param old
* @private
*/
_payloadTypeChanged: function (payloadType, old) {
switch (payloadType) {
case "Custom":
// don't do anything user has to supply a payloadParseFunction
break;
case "Unknown":
this.payloadParseFunction = function () {
};
break;
case "String":
this.payloadParseFunction = String.fromCharCode;
break;
default:
this.payloadParseFunction = String.fromCharCode;
}
},
/**
* Will be called from the `mqtt-connection` via this._handelSubscriptionSubscribedFunc with the correct this bound
* and fires a the `mqtt-subscription-subscribed` event
* @private
*/
_handelSubscriptionSubscribed: function () {
this._setSubscribedAndFire(true, "mqtt-subscription-subscribed");
},
/**
* Will be called from the `mqtt-connection` when the subscription is not subscribed any more for e.g. if the
* connection is disconnected of the subscription is removed intentionally abd fires the
* `mqtt-subscription-unsubscribed` event
* @private
*/
_handelSubscriptionUnsubscribed: function () {
this._setSubscribedAndFire(false, "mqtt-subscription-unsubscribed");
},
_setSubscribedAndFire: function (state, message) {
this._setSubscribed(state);
this.fire(message, {topic: this.topic, qos: this.qos});
},
/**
* A little helper function to parse the `Uint8Array` of the message.payload
*
* @param message
* @returns {*|{type, value}|string}
* @private
*/
_parseMessage: function (message) {
return this.payloadParseFunction.apply(null, message.message.payload);
},
/**
* Stores the message within `this.lastMessage` and `this.messages`
* @param message the mqtt message
* @private
*/
_storeMessage: function (message) {
message.parsedPayload = this._parseMessage(message);
if(this.messages.length >= this.numberOfMessages) {
this.shift("messages");
}
this.push("messages", message);
//noinspection JSUnresolvedFunction
this._setLastMessage(message);
this.fire("mqtt-subscription-message", message);
},
/**
* Will be called from the `mqtt-connection` via this._handelMessageFunc with the correct this bound
* @param message the mqtt message
* @param cb a function to signal mqtt.js that the message was handled
* @private
*/
_handelMessage: function (message, cb) {
this._storeMessage(message);
this._parentConnection._notifySubscriptionChanged(this);
if(cb) {
cb();
}
}
})
})(window);
</script>