Project

General

Profile

Javascript » History » Version 27

Torbjorn Carlqvist Admin, 05/29/2023 07:05 PM

1 2 Torbjorn Carlqvist Admin
h1. Javascript guide for DTXr code IDE
2 1 Torbjorn Carlqvist Admin
3 9 Torbjorn Carlqvist Admin
Shows the various commands and events that can be used to build automation scripts.
4 1 Torbjorn Carlqvist Admin
5 12 Torbjorn Carlqvist Admin
[[#Commands|Commands]]
6
[[#Events|Events]]
7 10 Torbjorn Carlqvist Admin
8 25 Torbjorn Carlqvist Admin
9 26 Torbjorn Carlqvist Admin
+NOTE, the below spec is 100% compatible with version 3.1.7. Ask DAVITOR for compatibility with previous versions or update your device.+
10 25 Torbjorn Carlqvist Admin
11 11 Torbjorn Carlqvist Admin
---
12
13 6 Torbjorn Carlqvist Admin
h2. Commands
14
15 19 Torbjorn Carlqvist Admin
<pre><code class="javascript">
16 27 Torbjorn Carlqvist Admin
    //These two variable is used inside scratchPad function below for convinience.
17
    //Set gThisDeviceId to what you have set (or got) for bacnet device id in the network!
18
    //Set gRemoteDeviceId to any other device id on the network.
19
    
20 21 Torbjorn Carlqvist Admin
    var gThisDeviceId = 123456;   
21
    var gRemoteDeviceId = 121212;   
22
    
23
    /** LOG/DEBUG **/
24
    
25
    //Prints to console log window as well as autmation.log
26 27 Torbjorn Carlqvist Admin
    //Note that automation.log is also written to by various services in DTX by
27 21 Torbjorn Carlqvist Admin
    //default, not only what you do with print() in your code.
28
    //Consider this as a volatile log where you debug and then clear from time to time.
29 27 Torbjorn Carlqvist Admin
    //10Mbyte is max then it will rollover to time-stamped zip file and automation.log is cleared.
30 21 Torbjorn Carlqvist Admin
    print("hello");
31
    
32
    //Prints to automation_user.log
33
    //This statement is the only source for loggin in this file.
34
    //Consider this to be a persistant log of important process matters.
35 27 Torbjorn Carlqvist Admin
    //10Mbyte is max then it will rollover to time-stamped zip file anf automation-user.log is cleared.
36 21 Torbjorn Carlqvist Admin
    Controller.printToUserLog("hello user log");
37 1 Torbjorn Carlqvist Admin
        
38
    /** BACnet related **/
39
    
40 21 Torbjorn Carlqvist Admin
    //Translation helper for BACnet object ID->NAME
41 1 Torbjorn Carlqvist Admin
    //Many even arguments are enumerated where theese function can help
42 27 Torbjorn Carlqvist Admin
    print(getObjectTypeById(4)); //-> "binaryOutput"
43
    print(getPropertyNameById(85)); //-> "presentValue"
44 21 Torbjorn Carlqvist Admin
45
    // *** Write a value to an object property ***
46 27 Torbjorn Carlqvist Admin
    // As you can see there is no syntax difference writing to local or remote objects.
47
    
48
    //Local object
49 21 Torbjorn Carlqvist Admin
    Controller.writeProperty(gThisDeviceId,analogValue,0,presentValue,priority_1,active);
50 27 Torbjorn Carlqvist Admin
    //Remote object
51 21 Torbjorn Carlqvist Admin
    Controller.writeProperty(gRemoteDeviceId,analogValue,0,presentValue,priority_1,active);
52
    
53
    // *** Read a value from a property. *** 
54
    //Will return both primitiv and constructed (JSON) values
55
    
56
    //Primitive
57
    print(Controller.readProperty(gThisDeviceId,analogValue,0,presentValue));
58
    print(Controller.readProperty(gRemoteDeviceId,analogValue,0,presentValue));
59
    
60
    //Constructed (always JSON format from complex values)
61
    //A priorityArray property is one example of constructed result
62
    print(Controller.readProperty(gThisDeviceId,analogValue,0,statusFlags));
63
    
64
    // *** COV Subscribtion ***
65
    
66
    //With auto incremented process id, sensitivity (increment) of 1 (analog values) and subscription lifetime of 300s
67
    Controller.COVSubscribe(covProcIncr,gRemoteDeviceId,analogValue,instance_0,noCovConfirmation,presentValue,1 /*sensitivity*/,300 /*lifetime (s)*/);
68
    
69
    //With fixed process id 123, sensitivity (increment) no sesnitivity (binary values) and subscription lifetime of 300s
70
    Controller.COVSubscribe(123,gRemoteDeviceId,analogValue,instance_0,noCovConfirmation,presentValue,null,300 /*lifetime (s)*/);
71
    
72
    //UN-Subscribe with specific process id 10
73
    Controller.COVSubscribe(123,gRemoteDeviceId,analogValue,instance_0,null,presentValue,defaultIncrement,null);
74
    
75
    // *** Intrinsic Reporting (Alarms and Events) ***
76 1 Torbjorn Carlqvist Admin
77 21 Torbjorn Carlqvist Admin
    //Remote Event Subscribe
78
    Controller.eventSubscribe(gRemoteDeviceId/*device id*/,instance_0/*Notification Class*/);
79
    
80
    //Enable event/alarm reporting on object
81
    Controller.enableIntrinsicReporting(0/*NotificationClass*/,3/*delay*/,3/*delayNormal*/,analogValue,instance_0,notifyTypeEvent);
82
    
83
    Controller.writeProperty(analogValue,instance_0,presentValue,priority_1,50);
84
    //TextMessage
85
    Controller.sendTextMessage(gThisDeviceId,"SOME_TYPE_OF_MSG","hello myself, what's up?");
86
    
87
    //Acknowledge alarm and events
88
    Controller.acknowledgeAlarm(gThisDeviceId,analogValue,instance_0,processIdZero,
89
                        ackNormal,1584383651150,"Toca",new Date().getTime());
90
    
91
    //Issue an alert for a specific object via an Alert Enrollment Object
92
    //The recipients in the notification class connected to the shosen alert enrollment object will receive the alert
93
    var alertEnrollmentObjectInstance = 0;
94
    var propretaryEventType = 666;
95
    Controller.issueAlert(alertEnrollmentObjectInstance,analogValue,0,"To high!",propretaryEventType);     
96
    
97
    Controller.getEnrollmentSummary(gThisDeviceId);
98
                        
99
    //Send event notif local or remote nodes
100
    //DeviceId,NotificationClass,AckRequired,Message
101
    Controller.sendNotification(gThisDeviceId,0,1,"Coffe anyone?");
102
      
103
    //Get all alarms for a specific device. Return JSON
104
    resp =  print(Controller.getAlarmSummary(gThisDeviceId));
105 1 Torbjorn Carlqvist Admin
106 21 Torbjorn Carlqvist Admin
    //Get all events for a specific device. Return JSON
107
    resp =  print(Controller.getEventSummary(gThisDeviceId));
108 1 Torbjorn Carlqvist Admin
109 21 Torbjorn Carlqvist Admin
    // *** Special Object Types *** //
110
    
111
    //Read a range of datapoints from a TrendLog object
112
    //The response is JSON with an array of value/timestamp
113
    Controller.readRange(gThisDeviceId,trendLogMultiple,0);
114 1 Torbjorn Carlqvist Admin
115 21 Torbjorn Carlqvist Admin
    // *** HTTP REST and Web Socket ***
116
    
117
    //HTTP GET Request. Returns respons as string
118
    resp = Controller.HTTP_GET('https://httpbin.org','get','Accept:application/json|Content-Type:application/json','myparam=hello');
119
    
120
    //HTTP POST(also PUT and PATCH) Request. Return response as string
121
    resp = Controller.HTTP_POST('https://httpbin.org/post'
122
                ,'Accept:application/json|Content-Type:application/json'
123
                ,'myparam=hello'
124
                ,'any payload string data');  
125
                
126
    //Web socket call to any webpage in the project file
127
    //This require that the page has loaded the Ws.js import.
128
    //Se HTTP Websocket template from the project tree sub menu
129
    Controller.sendToWS("mypage","Hello My Page this is a payload"); 
130
              
131
    //Connect to a Web Socket
132
    //DTX has a built in single web socket client.
133
    //Connect
134
    Controller.connectWebSocket("wss://any.websocket.host");
135
    //Send a message once connection is established
136
    Controller.sendWebSocketText("Hello");
137
    
138
    // *** SQL relational database access ***
139
    
140
    //Note, SQL db is not embedded so JDBC config is made in settings in advance.
141
    //Only PostgresSQL is supported for the moment!
142
    
143
    //Simple query. Result (if any) will always be JSON!
144
    print(Controller.sqlExecuteQuery("select * from anytable"));
145
    
146
    //Inserts and updates are preferably solved with functions or procedures on
147
    //the databas side. The CALL statement can then be utilized:
148
    Controller.sqlExecuteQuery("CALL upsert_anytable("+name+",'"+age+"')");
149
    
150
    //But of course a simple insert can also be sent...
151
    print(Controller.sqlExecuteQuery("insert into anytable values('kalle','13')"));
152
    
153
    // *** Timers and Schedulers ***
154 1 Torbjorn Carlqvist Admin
155 21 Torbjorn Carlqvist Admin
    //Show all current jobs (including system jobs)
156
    Controller.schedulerSummary();
157
    
158
    //Pause all jobs
159
    Controller.pauseAllJobs();
160
    
161
    //Pause a specific job
162
    Controller.pauseJob("JobA");
163
    
164
    //Resume all jobs
165
    Controller.resumeAllJobs();
166
    
167
    //Resume a specific job
168
    Controller.resumeJob("JobA");
169
    
170
    //Start job
171
    //Eg. executes function myCallbackFunction() with argument "df" after 10 seconds
172
    Controller.startJob('Job1',10,'myCallbackFunction("df")');
173
    //Eg. executes function myCallbackFunction() repeatedly every minute
174
    //with a start delay of 5 seconds
175
    Controller.startJob('Job2',5,60,'myCallbackFunction');
176
    
177
    //Eg. start a CRON job that executes myCallbackFunction
178
    //at 00:10 AM (10 minute past midnight) every day
179
    Controller.startCronJob("Job3",'0 10 0 ? * * *','myCallbackFunction');
180
    //Note: CRON can be difficult to construct. 
181
    //Use the below link to both crete and also verify your CRON strings.
182
    //https://www.freeformatter.com/cron-expression-generator-quartz.html
183
    
184
    //Cancel a job by using the name provided above
185
    Controller.cancelJob("Job3");
186
    
187
    //Cancel all jobs
188
    Controller.cancelAllJobs();        
189
    
190
    //Cancel a specific jobs
191
    Controller.cancelJob("JobG");        
192 1 Torbjorn Carlqvist Admin
193 21 Torbjorn Carlqvist Admin
    //This is a special function where you can schedule the execution of
194
    //a code snippet.
195
    //Arg1: Som job identifier - To use when pause/cancel the job if neccesary.
196
    //Arg2: start delay (s) - Time until first exec
197
    //Arg3: period(s) - Time between exec, set to 0 if no repetition is required/wanted.
198
    //Arg4: repeates - Number of repeates, null if infinit, 0 if no repeat
199
    //Arg5: code - Any Javascript
200
    Controller.scheduleExecution("wait05",5,0,0,"print('print once in 5 sec');");
201 1 Torbjorn Carlqvist Admin
202 21 Torbjorn Carlqvist Admin
    // *** MISC ***
203
    
204
    //Send an email. Note, needs smtp-server config first
205
    Controller.SendEmail("torbjorn.carlqvist@davitor.com","anysubject","some body");
206
    
207
    // *** Embedded JSON storage ***
208
    
209
    //Perfect to use when automation settings, states, structures etc must be persisted and
210
    //the use of an external SQL database is unnecessary
211
    
212
    //Push a string to spcified queue (queue will be created if not exist)
213
    //This queue is persistant during reboot of the evice
214
    //All queues and records are stored in the collection "jsonstore.json" which can be found in project folder
215
    Controller.JSONPush("toca","msg5");
216
    //Pop a string from the specified queue. FIFO!
217
    //Returns null if no strings found
218
    print(Controller.JSONPop("toca"));
219 1 Torbjorn Carlqvist Admin
220 21 Torbjorn Carlqvist Admin
    print(Controller.JSONPersist("nisse"));
221
    print(Controller.JSONPersist("1588058754445","palle"));
222
    
223
    print(Controller.JSONRestore("1588058754445"));
224
    
225
    print(Controller.JSONBrowse("toca"));
226
    
227
    //Change name on multiple local objects
228
    //This can be used when a group of objects need to have save name prefix.
229
    //eg. when a sensor has multiple object and you want them to share same sensor name.
230
    Controller.updateLocalObjectNames("TestBI","newname");
231
    
232
    //This method should be used when javascript forms a link between
233
    //an external interaface and the object stack.
234
    //Typically when a button on a HMI should update an binaryInput or
235
    //a reception of a BLE Beacon should update an analogInput.
236
    //This method will create an object if no object exists with same profilName property
237
    Controller.createOrUpdateLocalObject(analogInput,null,"MyObjectName",123);
238
    
239
    //As an addition use this function to control the reliability of the obejct in real time.
240
    //This will create events and alarms accordingly of intrinsic reporting is enanbled.
241
    Controller.setLocalObjectReliability(binaryOutput,0,'shorted-loop');
242
    Controller.setLocalObjectReliability(binaryOutput,0,'no-fault-detected');
243
    
244
    //Yet another addition is this function to set the overridden flag on local objects.
245
    //The meaning of this flag is to tell BACnet that this physical point is not 
246
    //longer reliable or commandable.
247
    Controller.setLocalObjectOverridden(binaryOutput,0,true);
248
    Controller.setLocalObjectOverridden(binaryOutput,0,false);
249
    
250
    // *** File access ***/
251
    
252
    //Basic file R/W/List for files in project folder (and sub folders)
253
    Controller.writeFile("file_rw_test.txt","Hello file handling!");
254
    print(Controller.readFile("file_rw_test.txt"));
255
    print(Controller.listFiles(".txt",null));
256
    print(Controller.listFiles(".json","mysubfolder"));    
257
    print(Controller.removeFiles(".txt",null));    
258
    
259
    // *** OS operations ***/
260
    
261
    //Run commands on host operatice system
262
    //Result is JSON string
263
    //The exit_code tells if successful or not.
264
    //There is a built in timeout if you accedently start a job that does not 
265
    //stop of it's own. Like doing unlimited ping on Linux
266
    //No, there is no way to stop a command with Ctrl-C from JS.
267
    //Note, the process is running in foreground so if DTX dies the process dies too.
268
    print(Controller.execCommand("ping -n 3 google.com"));
269
    
270
    // *** Serial Ports ***/
271
    
272
    //List all connected serial ports. The response is JSON and can tell a lot
273
    //about the serial port. For example in which USB socket it is connected.
274
    print(Controller.listSerialPorts());
275
    
276
    //Connect to a serial port (multiple connection is allowed)
277
    //Use the serial port name from the response from listSerialPorts() above.
278
    //As argument form a JSON according to specification.
279
    //Example of setting up a serial connection to ttyACM0 that handles 
280
    //delimited responses with a "Return(0d)" at the END with a speed of 115200baud
281
    //Note that if a connection already occurs in this name it will be closed automatically
282
    Controller.setupSerialPort("ttyACM0",'{"msgDelim":true,"baudrate":115200,"delimPattern":"0d","delimPosition":"end"}');
283
    
284
    //Send ASCII data to the connected port
285
    Controller.writeSerialAscii("ttyACM0","hello");
286
    
287
    //Send HEX data to the serial port
288
    Controller.writeSerialHex("ttyACM0","03"); //Eg. Ctrl-C in HEX
289
    
290
    //Close serial port
291
    Controller.closeSerialPort("ttyACM0");
292
    
293
    //NOTE: all received serial data enters the event callback "onSerialReceive"
294
    
295
    /*** MODBUS ***/
296
    
297
    /* Modbus TCP */
298
    
299
    //If needed, use this to simulate a slave on THIS device for test purpose. 
300
    //Will setup a demo image of regs and coils
301
    Controller.modbusTCPCreateSlave();
302
    
303
    //Read coils (true/false)
304
    //Args: Slave IP, Slave Port, Start Addr, Count
305
    //Return: JSON Array with result
306
    print(Controller.modbusTCPReadCoils("localhost",502,1,1));
307 18 Torbjorn Carlqvist Admin
308 21 Torbjorn Carlqvist Admin
    //Reading input discretes (true/false)
309
    //Args: Slave IP, Slave Port, Start Addr, Count
310
    //Return: JSON Array with result
311
    print(Controller.modbusTCPReadInputDiscretes("localhost",502,1,5));
312
    
313
    //Reading input registers (Analog Inputs)
314
    //Can be either signed or unsigned 16-bit values.
315
    //Args: Slave IP, Slave Port, Start Addr, Count
316 1 Torbjorn Carlqvist Admin
    //Return: JSON Array with result
317
    print(Controller.modbusTCPReadInputRegisters("localhost",502,1,5));
318
    
319
    //Reading holding registers (Analog Outputs)
320
    //Can be either signed or unsigned 16-bit values.
321
    //Args: Slave IP, Slave Port, Start Addr, Count
322
    //Return: JSON Array with result
323
    print(Controller.modbusTCPReadHoldingRegisters("localhost",502,1,5));
324
325 21 Torbjorn Carlqvist Admin
    //Write to coil (!CAUTION!)
326
    //Note, always returns null
327
    //Args: Slave IP, Slave Port, Addr, Status (true=On/1, false=Off/0)
328 27 Torbjorn Carlqvist Admin
    //Return: JSON Array with result (confirm)
329
    print(Controller.modbusTCPWriteCoil("localhost",502,1,false));
330
331
    //Writing to a holding registers (Analog Outputs)
332
    //Can be either signed or unsigned 16-bit values.
333
    //Args: Slave IP, Slave Port, Start Addr, Count
334
    //Return: JSON Array with result (confirm)
335
    print(Controller.modbusTCPWriteHoldingRegister("localhost",502,1,123));
336
337 21 Torbjorn Carlqvist Admin
    /* Modbus Serial */
338
    //Note, setting null as port settings defaults to 9600/8N1
339
    
340
    //A mock-up test slave for serial modbus
341
    //Args: Port, Port Settings, RTU
342
    Controller.modbusSerialCreateSlave("COM1",null,false);
343
    //Writing to a MODBUS slave coil via Serial RTU
344
    //Args: Port, Port Settings,RTU,reg address, value/state 
345
    Controller.modbusSerialWriteCoil("COM2",null,false,2,true);
346
    //Reading from a MODBUS slave coil via Serial RTU
347
    //Args: Port, Port Settings,RTU,reg address
348
    Controller.modbusSerialReadCoils("COM2",null,false,1,2);
349
    
350
    /*** Controller management ***/
351
    
352
    //Running reInit() will completly clear the JS-engine, stop all jobs and
353
    //re-actiavate the code and finally call the init() method.
354
    Controller.reInit();
355 1 Torbjorn Carlqvist Admin
</code></pre>
356
357
358
h2. Events
359
360
h3. *eventNotificationReceived* - Called when an intrinsic report notification is received.
361
362
<pre><code class="javascript">
363 22 Torbjorn Carlqvist Admin
/**
364
 * Called when controller starts. Good place to do init stuff
365
 */
366
function init(){
367
    print("init!");
368
369
}
370
371
372 1 Torbjorn Carlqvist Admin
/***********************************************************************************************
373 23 Torbjorn Carlqvist Admin
 * Called when the controller receives a notification (intrinsic reporting) from this or another device
374
 * @param {processIdentifier} Can be used to process events/alarms different consumed. Users choice.
375
 * @param {Number} initiatingDevice - The device ID that send the event and the device where the triggered object belongs
376
 * @param {String} object - A convinient string to describe objectype:instance in text
377
 * @param {Number} objectType - The source object of the event
378 1 Torbjorn Carlqvist Admin
 * @param {Number} objectInstance - The instance of source object
379 23 Torbjorn Carlqvist Admin
 * @param {Number} timeStampUTC - EPOC type of timestamp where the event/alarm trigger fired
380
 * @param {Number} notificationClassInstance - An instance pointer to the connected class
381
 * @param {Number} priority - Priority of this event
382
 * @param {Number} eventType - The type of event received. Eg. 'outOfRange'
383
 * @param {String} messageText - Free text that can be used describing the event
384
 * @param {String} notifyType - Type of notification. Can be 'alarm' or 'event'
385
 * @param {Boolean} ackRequired - Tell wether this event/alarm needs acknowledgment or not
386 1 Torbjorn Carlqvist Admin
 * @param {String} fromState - The previous state
387
 * @param {String} toState - The current state after the change
388 23 Torbjorn Carlqvist Admin
 * @param {Object} eventValuesStr - A JSON object of specific values for this particular eventType 
389 1 Torbjorn Carlqvist Admin
 ***********************************************************************************************/
390 23 Torbjorn Carlqvist Admin
function eventNotificationReceived(processIdentifier,initiatingDevice,object,objectType,objectInstance,timeStampUTC,notificationClassInstance,priority,eventType,messageText,notifyType,ackRequired,fromState,toState,eventValuesStr){
391 22 Torbjorn Carlqvist Admin
392 23 Torbjorn Carlqvist Admin
    var eventDeviceName = Controller.readProperty(initiatingDevice,device,initiatingDevice,objectName);
393
    var ncObjectName = Controller.readProperty(initiatingDevice,ObjectType.notificationClass,notificationClassInstance,objectName);
394
    var eventObjectName = Controller.readProperty(initiatingDevice,objectType,objectInstance,objectName);
395 22 Torbjorn Carlqvist Admin
396 23 Torbjorn Carlqvist Admin
    var summary = "Received " +eventType+" "+notifyType+" from "+eventDeviceName+" for object "+eventObjectName+" at "+new Date(timeStampUTC).toTimeString();
397
    
398
    print(summary);
399
    
400
    print("Current state:");
401
    try{
402
        var eventValues = JSON.parse(eventValuesStr);
403 22 Torbjorn Carlqvist Admin
        
404
        
405 23 Torbjorn Carlqvist Admin
        for (var key in eventValues) {
406
            if (eventValues.hasOwnProperty(key)) {
407
                
408
                print(" - "+key + " " + eventValues[key]);
409
                
410
                /*** Tip, enter code here to act on a specific key/value ***/
411
                    
412
            }
413
        }
414 22 Torbjorn Carlqvist Admin
        
415 23 Torbjorn Carlqvist Admin
    }catch(e){
416
        print("eventValuesStr not JSON!")
417
    }
418
    
419
    if (notifyType === 'ackNotification' ){
420
        var ackedstate = " - Acked state "+toState;
421 22 Torbjorn Carlqvist Admin
        print(ackedstate);
422 23 Torbjorn Carlqvist Admin
        summary = summary + ackedstate;
423
    }else{
424 1 Torbjorn Carlqvist Admin
        var transistion = " - State changed from "+fromState+" to "+toState;
425
        print(transistion);
426
        summary = summary + transistion;
427
    }
428 23 Torbjorn Carlqvist Admin
    
429 22 Torbjorn Carlqvist Admin
    print(" - Priority "+priority);
430
    print(" - Ack required "+ackRequired);
431 23 Torbjorn Carlqvist Admin
    if ( messageText !== undefined && messageText !== "")
432
        print(" - Message "+messageText);
433
    print(" - Class "+ncObjectName)
434
    
435
    //Due to the standard, a notifying device does not save un-acked notifs
436
    //transitions during reboot so it is best practise to make persistant on
437 27 Torbjorn Carlqvist Admin
	//the receiver side.
438 24 Torbjorn Carlqvist Admin
    Controller.printToUserLog(summary);
439 27 Torbjorn Carlqvist Admin
    
440
    
441
    
442 22 Torbjorn Carlqvist Admin
}
443
444
/*******************************************************************************
445
 * Called when Change Of value Notification received from remote device
446
 * In order to receive Change Of value notification the remote device must first
447
 * be subscribed on the particular object instance. 
448
 * Eg. subscribe to Analog Input 0 on device 403
449
 * - Controller.remoteCOVSubscribe(403,0,0); 
450
 * It is also possible to subscribe on local objects and in case of a local 
451
 * notification the device argument is null.
452
 * Eg. subscribe on local Binary Value 1 and no increment (null)
453
 * - Controller.COVSubscribe(0,0,null); 
454
 * @param {Number} epoch - A timestamp (nb of sec since 1970 kind of timestamp.
455
 * @param {Number} processId - COV process id used by the requester in this subscription
456
 * @param {Number} deviceId - Remote device that sent the notification
457
 * @param {Number} objectType - The source object of the event
458
 * @param {Number} objectInstance - The instance of source object
459
 * @param {Number} propertyId - The instance of source object* 
460
 * @param {String} value - The new value.
461
 *******************************************************************************/
462
function covNotificationReceived(epoch,processId,deviceId,objectType,objectInstance,propertyId,value){
463
    print("covNotificationReceived - "+ "Process: " + processId +  " Device: " + deviceId + " ObjectType: " +
464
                objectType+" ObjectInstance: " + objectInstance + " propertyId: " + propertyId +
465
                " New Value: " + value + " Time: " + new Date(epoch*1000));
466
   
467
}
468
469
470
/**********************************************************
471
 * Called when the controller receives a HTTP GET request
472
 * @param {String} resource - The REST resource
473
 * @param {Object} params - The HTTP url parameters 
474
 *********************************************************/
475
function HTTP_GET(resource,params){
476
    print(new Date().toISOString() + " HTTP GET - Resource: " + resource + " Params:" + params);
477
}
478
479
/**********************************************************
480
 * Called when the controller receives a HTTP POST request
481
 * @param {String} resource - The complete URI in the request
482
 * @param {Object} payload - The HTTP header parameters
483
 *********************************************************/
484
function HTTP_POST(resource,payload){
485
    print("HTTP POST - Resource:" + resource + " Payload:" + payload);
486
}
487
488
/****************************************************************
489
 * Called when a Web Socket request is made from a Web Client.
490
 * 
491
 * @param {String} context - The key of the page
492
 * 
493
 * The context can be made up by three parts URI + APP + SESSION
494
 * where URI is the only mandatory part.
495
 *                           
496
 * @param {String} payloadTxt - The data sent from the WS-client
497
 *****************************************************************/
498
function receiveFromWs(context,payloadTxt){
499
    print("WS Callback from context "+context +" payload:\n" + payloadTxt);
500
    
501
    /** This is a snippet to listen on Web Page Demo Template **/
502
    /** Use it or remove it                                   **/
503
    if ( context.indexOf("page-demo") > 0 ) {
504
        
505
        try{
506
            var jsonObjPayload = JSON.parse(payloadTxt);
507
            print(jsonObjPayload.msg);
508
            print(jsonObjPayload.action);
509
            
510
            //Answer to web page using incoming context
511
            Controller.sendToWS(context,"Oh, Hi! I am a Web Socket request. Look for me in automation.js"); 
512
            
513
        }
514
        catch(e){
515
            print("Err"+e);
516
        }
517
        
518
    }
519
}
520
521
/**
522
 * Called when a BACnet object on this device changed.
523
 * @param {type} objectType
524
 * @param {type} objectInstance
525
 * @param {type} propertyId
526
 * @param {type} oldValue
527
 * @param {type} newValue
528
 * @returns {undefined}
529
 */
530
function localPropertyChanged(objectType,objectInstance,propertyId,oldValue,newValue){
531
    //print('property changed on '+objectType+':'+objectInstance+' for prop '+propertyId +' where old value is '+oldValue +' and new value is '+newValue);
532
}
533
534
/**************************************************************************************************
535
 * Callback when this controller receives a I Am notification from a remote device on the network
536
 * @param {Number} device - Remote device that says hello
537
 * @param {String} mac - The BACnet mac address of the sending device
538
 **************************************************************************************************/
539
function iAmReceived(device,mac){
540
    //print("IAM received from device:" + device + " MAC:"+mac);
541
}
542
543
/**************************************************************************************************
544
 * Callback when this controller receives a BACnet private message request
545
 * @param {Number} sourceDeviceId - Remote device that speeks
546
 * @param {String} messageClass - See BACnet standard for usage. Could be use as any string data
547
 * @param {String} messagePriority - See BACnet standard for usage. Could be use as any string data
548
 * @param {String} message - Send message data
549
 **************************************************************************************************/
550
function textMessageReceived(sourceDeviceId,messageClass,messagePriority,message){
551
    print("textMessageReceived:"+message);
552
}
553
554
/***********************************************************************************************
555
 * Called when the controller receives a write request from from a remote client
556
 * on one of the local objects.
557
 * @param {Number} objectType - The type of the object that is requested to be written
558
 * @param {Number} objectInstance - The instance of the object that is requested to be written
559
 * @param {Number} property - The property id that requested to be written
560
 * @param {Number} priority - The priority of the value that is requested to be written
561
 * @param {String} value - The new value
562
 ***********************************************************************************************/
563
function propertyWritten(objectType,objectInstance,property,priority,value){
564
    print("propertyWritten - ObjectType: "+objectType+" ObjectInstance: "+ objectInstance + " Property: "+ property + " Priority: "+ priority + " Value: "+value);
565
}
566
567
/***********************************************************************************************
568
 * Called when a file is put in file input directory
569
 * The file input directory path is configured in setting page and is by default empty
570
 * 
571
 * @param {String} fileName - The name of the file put in the file input directory
572
 * @param {String} fileContent - The content of the file
573
 * 
574
 * Note: There is special mapping for CSV file which are converted to JSON!
575
 *       Other file types are just received as is
576
 ***********************************************************************************************/   
577
function receivedFile(fileName,fileContent){
578
    print("Received file "+fileName+ " with content "+ fileContent);
579
}   
580
581
/***********************************************************************************************
582
 * Called receiving data on an activated serial port
583
 * 
584
 * Note, see Controller.setupSerialPort(..) for activate a serial port
585
 * 
586
 * @param {String} port - Wich port the data comes from
587
 * @param {String} payload - The data
588
 * 
589
 ***********************************************************************************************/   
590
function onSerialReceive(port, payload){
591
    
592
    print("Serial data received on port: "+port+" data: "+payload); 
593
}
594
595
596
/**************************************************************************
597
 * This callback catches unexpected runtime errors like timeouts when 
598
 * writing or subscribing to a remote device currently absent.
599
 * @param {String} type - Type or source of exception
600
 * @param {String} message - Short description of the issue in plain text
601
 * @param {String} details - Optional information in JSON format
602
 **************************************************************************/
603
function exceptionCatch(type,message,details){
604
    print("Exception catched, type:"+type+" message:" + message + " details:" + details );
605
}
606
607
/**
608
 * When supported by the platform and enabled in the setting "beacon Station under Bluetooth"
609
 * this method is invoked with advertisment from all Bluetooth LE devices nerby
610
 * 
611
 * @param {String} mac - The sending Bluetooth device MAC adress
612
 * @param {String} rssi - The signal strengh of the sending beacon
613
 * @param {String} bt_payload - The beacon data
614
 */
615
function onBTBeaconAdvertising(mac,rssi,bt_payload){
616
    
617
    //Example of whitelist filter
618
    if( mac.includes("38FE") || mac.includes("CD8E")){
619
        
620
        print("Beacon adv from mac: "+ mac + " rssi: "+rssi+" data:"+bt_payload);
621
        
622
        //Here you can parse the payload from the beacon as you wish
623
        //If the beacon is a Ruuvi, DTXr has a built in javascript library for the format 5
624
        //See documentation on DTXr wiki
625
        //https://collab.davitor.com/redmine/projects/dtxr/wiki
626
        //More info on Ruuvi format and how to parse here
627
        //https://ruuvi.com/custom-ruuvi-data-format-in-a-day/
628
        
629
                
630
    }
631
}
632
633
/**
634
 * Received an MQTT publish request
635
 * @param {type} topic
636
 * @param {type} payload
637
 */
638
function MQTTOnPublish(topic,payload){
639
    print("MQTT client published " + payload + " on topic " + topic);
640
}
641
642
/**
643
 * Received a web socket client text response
644
 * @param {type} text
645
 */
646 1 Torbjorn Carlqvist Admin
function WebsocketOnClientReceiveText(text){
647
    print("WebsocketOnClientReceiveText: "+text);
648
}
649
</code></pre>