Project

General

Profile

Actions

Javascript » History » Revision 21

« Previous | Revision 21/28 (diff) | Next »
Torbjorn Carlqvist Admin, 01/12/2023 09:27 AM


Javascript guide for DTXr code IDE

Shows the various commands and events that can be used to build automation scripts.

Commands
Events


Commands

    //Set this to THIS device id.
    //The var is used in commands below for convinience.
    var gThisDeviceId = 123456;   
    //Set this to A REMOTE device id on your network.
    //The var is used in commands below for convinience.
    var gRemoteDeviceId = 121212;   

    /** LOG/DEBUG **/

    //Prints to console log window as well as autmation.log
    //Note that automation.js is also written to by various services in DTX by
    //default, not only what you do with print() in your code.
    //Consider this as a volatile log where you debug and then clear from time to time.
    //10Mbyte is max then it will rollover to time-stamped zip file and automation.js is cleared.
    print("hello");

    //Prints to automation_user.log
    //This statement is the only source for loggin in this file.
    //Consider this to be a persistant log of important process matters.
    //10Mbyte is max then it will rollover to time-stamped zip file anf automation-user.js is cleared.
    Controller.printToUserLog("hello user log");

    /** BACnet related **/

    //Translation helper for BACnet object ID->NAME
    //Many even arguments are enumerated where theese function can help
    print(getObjectTypeById(4)); //Binary Output
    print(getPropertyTypeById(85)); //presentValue

    // *** Write a value to an object property ***
    Controller.writeProperty(gThisDeviceId,analogValue,0,presentValue,priority_1,active);
    Controller.writeProperty(gRemoteDeviceId,analogValue,0,presentValue,priority_1,active);

    // *** Read a value from a property. *** 
    //Will return both primitiv and constructed (JSON) values

    //Primitive
    print(Controller.readProperty(gThisDeviceId,analogValue,0,presentValue));
    print(Controller.readProperty(gRemoteDeviceId,analogValue,0,presentValue));

    //Constructed (always JSON format from complex values)
    //A priorityArray property is one example of constructed result
    print(Controller.readProperty(gThisDeviceId,analogValue,0,statusFlags));

    // *** COV Subscribtion ***

    //With auto incremented process id, sensitivity (increment) of 1 (analog values) and subscription lifetime of 300s
    Controller.COVSubscribe(covProcIncr,gRemoteDeviceId,analogValue,instance_0,noCovConfirmation,presentValue,1 /*sensitivity*/,300 /*lifetime (s)*/);

    //With fixed process id 123, sensitivity (increment) no sesnitivity (binary values) and subscription lifetime of 300s
    Controller.COVSubscribe(123,gRemoteDeviceId,analogValue,instance_0,noCovConfirmation,presentValue,null,300 /*lifetime (s)*/);

    //UN-Subscribe with specific process id 10
    Controller.COVSubscribe(123,gRemoteDeviceId,analogValue,instance_0,null,presentValue,defaultIncrement,null);

    // *** Intrinsic Reporting (Alarms and Events) ***

    //Remote Event Subscribe
    Controller.eventSubscribe(gRemoteDeviceId/*device id*/,instance_0/*Notification Class*/);

    //Enable event/alarm reporting on object
    Controller.enableIntrinsicReporting(0/*NotificationClass*/,3/*delay*/,3/*delayNormal*/,analogValue,instance_0,notifyTypeEvent);

    Controller.writeProperty(analogValue,instance_0,presentValue,priority_1,50);
    //TextMessage
    Controller.sendTextMessage(gThisDeviceId,"SOME_TYPE_OF_MSG","hello myself, what's up?");

    //Acknowledge alarm and events
    Controller.acknowledgeAlarm(gThisDeviceId,analogValue,instance_0,processIdZero,
                        ackNormal,1584383651150,"Toca",new Date().getTime());

    //Issue an alert for a specific object via an Alert Enrollment Object
    //The recipients in the notification class connected to the shosen alert enrollment object will receive the alert
    var alertEnrollmentObjectInstance = 0;
    var propretaryEventType = 666;
    Controller.issueAlert(alertEnrollmentObjectInstance,analogValue,0,"To high!",propretaryEventType);     

    Controller.getEnrollmentSummary(gThisDeviceId);

    //Send event notif local or remote nodes
    //DeviceId,NotificationClass,AckRequired,Message
    Controller.sendNotification(gThisDeviceId,0,1,"Coffe anyone?");

    //Get all alarms for a specific device. Return JSON
    resp =  print(Controller.getAlarmSummary(gThisDeviceId));

    //Get all events for a specific device. Return JSON
    resp =  print(Controller.getEventSummary(gThisDeviceId));

    // *** Special Object Types *** //

    //Read a range of datapoints from a TrendLog object
    //The response is JSON with an array of value/timestamp
    Controller.readRange(gThisDeviceId,trendLogMultiple,0);

    // *** HTTP REST and Web Socket ***

    //HTTP GET Request. Returns respons as string
    resp = Controller.HTTP_GET('https://httpbin.org','get','Accept:application/json|Content-Type:application/json','myparam=hello');

    //HTTP POST(also PUT and PATCH) Request. Return response as string
    resp = Controller.HTTP_POST('https://httpbin.org/post'
                ,'Accept:application/json|Content-Type:application/json'
                ,'myparam=hello'
                ,'any payload string data');  

    //Web socket call to any webpage in the project file
    //This require that the page has loaded the Ws.js import.
    //Se HTTP Websocket template from the project tree sub menu
    Controller.sendToWS("mypage","Hello My Page this is a payload"); 

    //Connect to a Web Socket
    //DTX has a built in single web socket client.
    //Connect
    Controller.connectWebSocket("wss://any.websocket.host");
    //Send a message once connection is established
    Controller.sendWebSocketText("Hello");

    // *** SQL relational database access ***

    //Note, SQL db is not embedded so JDBC config is made in settings in advance.
    //Only PostgresSQL is supported for the moment!

    //Simple query. Result (if any) will always be JSON!
    print(Controller.sqlExecuteQuery("select * from anytable"));

    //Inserts and updates are preferably solved with functions or procedures on
    //the databas side. The CALL statement can then be utilized:
    Controller.sqlExecuteQuery("CALL upsert_anytable("+name+",'"+age+"')");

    //But of course a simple insert can also be sent...
    print(Controller.sqlExecuteQuery("insert into anytable values('kalle','13')"));

    // *** Timers and Schedulers ***

    //Show all current jobs (including system jobs)
    Controller.schedulerSummary();

    //Pause all jobs
    Controller.pauseAllJobs();

    //Pause a specific job
    Controller.pauseJob("JobA");

    //Resume all jobs
    Controller.resumeAllJobs();

    //Resume a specific job
    Controller.resumeJob("JobA");

    //Start job
    //Eg. executes function myCallbackFunction() with argument "df" after 10 seconds
    Controller.startJob('Job1',10,'myCallbackFunction("df")');
    //Eg. executes function myCallbackFunction() repeatedly every minute
    //with a start delay of 5 seconds
    Controller.startJob('Job2',5,60,'myCallbackFunction');

    //Eg. start a CRON job that executes myCallbackFunction
    //at 00:10 AM (10 minute past midnight) every day
    Controller.startCronJob("Job3",'0 10 0 ? * * *','myCallbackFunction');
    //Note: CRON can be difficult to construct. 
    //Use the below link to both crete and also verify your CRON strings.
    //https://www.freeformatter.com/cron-expression-generator-quartz.html

    //Cancel a job by using the name provided above
    Controller.cancelJob("Job3");

    //Cancel all jobs
    Controller.cancelAllJobs();        

    //Cancel a specific jobs
    Controller.cancelJob("JobG");        

    //This is a special function where you can schedule the execution of
    //a code snippet.
    //Arg1: Som job identifier - To use when pause/cancel the job if neccesary.
    //Arg2: start delay (s) - Time until first exec
    //Arg3: period(s) - Time between exec, set to 0 if no repetition is required/wanted.
    //Arg4: repeates - Number of repeates, null if infinit, 0 if no repeat
    //Arg5: code - Any Javascript
    Controller.scheduleExecution("wait05",5,0,0,"print('print once in 5 sec');");

    // *** MISC ***

    //Send an email. Note, needs smtp-server config first
    Controller.SendEmail("torbjorn.carlqvist@davitor.com","anysubject","some body");

    // *** Embedded JSON storage ***

    //Perfect to use when automation settings, states, structures etc must be persisted and
    //the use of an external SQL database is unnecessary

    //Push a string to spcified queue (queue will be created if not exist)
    //This queue is persistant during reboot of the evice
    //All queues and records are stored in the collection "jsonstore.json" which can be found in project folder
    Controller.JSONPush("toca","msg5");
    //Pop a string from the specified queue. FIFO!
    //Returns null if no strings found
    print(Controller.JSONPop("toca"));

    print(Controller.JSONPersist("nisse"));
    print(Controller.JSONPersist("1588058754445","palle"));

    print(Controller.JSONRestore("1588058754445"));

    print(Controller.JSONBrowse("toca"));

    //Change name on multiple local objects
    //This can be used when a group of objects need to have save name prefix.
    //eg. when a sensor has multiple object and you want them to share same sensor name.
    Controller.updateLocalObjectNames("TestBI","newname");

    //This method should be used when javascript forms a link between
    //an external interaface and the object stack.
    //Typically when a button on a HMI should update an binaryInput or
    //a reception of a BLE Beacon should update an analogInput.
    //This method will create an object if no object exists with same profilName property
    Controller.createOrUpdateLocalObject(analogInput,null,"MyObjectName",123);

    //As an addition use this function to control the reliability of the obejct in real time.
    //This will create events and alarms accordingly of intrinsic reporting is enanbled.
    Controller.setLocalObjectReliability(binaryOutput,0,'shorted-loop');
    Controller.setLocalObjectReliability(binaryOutput,0,'no-fault-detected');

    //Yet another addition is this function to set the overridden flag on local objects.
    //The meaning of this flag is to tell BACnet that this physical point is not 
    //longer reliable or commandable.
    Controller.setLocalObjectOverridden(binaryOutput,0,true);
    Controller.setLocalObjectOverridden(binaryOutput,0,false);

    // *** File access ***/

    //Basic file R/W/List for files in project folder (and sub folders)
    Controller.writeFile("file_rw_test.txt","Hello file handling!");
    print(Controller.readFile("file_rw_test.txt"));
    print(Controller.listFiles(".txt",null));
    print(Controller.listFiles(".json","mysubfolder"));    
    print(Controller.removeFiles(".txt",null));    

    // *** OS operations ***/

    //Run commands on host operatice system
    //Result is JSON string
    //The exit_code tells if successful or not.
    //There is a built in timeout if you accedently start a job that does not 
    //stop of it's own. Like doing unlimited ping on Linux
    //No, there is no way to stop a command with Ctrl-C from JS.
    //Note, the process is running in foreground so if DTX dies the process dies too.
    print(Controller.execCommand("ping -n 3 google.com"));

    // *** Serial Ports ***/

    //List all connected serial ports. The response is JSON and can tell a lot
    //about the serial port. For example in which USB socket it is connected.
    print(Controller.listSerialPorts());

    //Connect to a serial port (multiple connection is allowed)
    //Use the serial port name from the response from listSerialPorts() above.
    //As argument form a JSON according to specification.
    //Example of setting up a serial connection to ttyACM0 that handles 
    //delimited responses with a "Return(0d)" at the END with a speed of 115200baud
    //Note that if a connection already occurs in this name it will be closed automatically
    Controller.setupSerialPort("ttyACM0",'{"msgDelim":true,"baudrate":115200,"delimPattern":"0d","delimPosition":"end"}');

    //Send ASCII data to the connected port
    Controller.writeSerialAscii("ttyACM0","hello");

    //Send HEX data to the serial port
    Controller.writeSerialHex("ttyACM0","03"); //Eg. Ctrl-C in HEX

    //Close serial port
    Controller.closeSerialPort("ttyACM0");

    //NOTE: all received serial data enters the event callback "onSerialReceive" 

    /*** MODBUS ***/

    /* Modbus TCP */

    //If needed, use this to simulate a slave on THIS device for test purpose. 
    //Will setup a demo image of regs and coils
    Controller.modbusTCPCreateSlave();

    //Read coils (true/false)
    //Args: Slave IP, Slave Port, Start Addr, Count
    //Return: JSON Array with result
    print(Controller.modbusTCPReadCoils("localhost",502,1,1));

    //Reading input discretes (true/false)
    //Args: Slave IP, Slave Port, Start Addr, Count
    //Return: JSON Array with result
    print(Controller.modbusTCPReadInputDiscretes("localhost",502,1,5));

    //Reading input registers (Analog Inputs)
    //Can be either signed or unsigned 16-bit values.
    //Args: Slave IP, Slave Port, Start Addr, Count
    //Return: JSON Array with result
    print(Controller.modbusTCPReadInputRegisters("localhost",502,1,5));

    //Reading holding registers (Analog Outputs)
    //Can be either signed or unsigned 16-bit values.
    //Args: Slave IP, Slave Port, Start Addr, Count
    //Return: JSON Array with result
    print(Controller.modbusTCPReadHoldingRegisters("localhost",502,1,5));

    //Write to coil (!CAUTION!)
    //Note, always returns null
    //Args: Slave IP, Slave Port, Addr, Status (true=On/1, false=Off/0)
    Controller.modbusTCPWriteCoil("localhost",502,1,false);

    /* Modbus Serial */
    //Note, setting null as port settings defaults to 9600/8N1

    //A mock-up test slave for serial modbus
    //Args: Port, Port Settings, RTU
    Controller.modbusSerialCreateSlave("COM1",null,false);
    //Writing to a MODBUS slave coil via Serial RTU
    //Args: Port, Port Settings,RTU,reg address, value/state 
    Controller.modbusSerialWriteCoil("COM2",null,false,2,true);
    //Reading from a MODBUS slave coil via Serial RTU
    //Args: Port, Port Settings,RTU,reg address
    Controller.modbusSerialReadCoils("COM2",null,false,1,2);

    /*** Controller management ***/

    //Running reInit() will completly clear the JS-engine, stop all jobs and
    //re-actiavate the code and finally call the init() method.
    Controller.reInit();

Events

eventNotificationReceived - Called when an intrinsic report notification is received.

/***********************************************************************************************
 * @param {Number} processIdentifier - Event process on the caller side
 * @param {Number} initiatingDevice - The device that send the event
 * @param {Number} object - The source object in readable format 
 * @param {Number} objectType - The source object of the event
 * @param {Number} objectInstance - The instance of source object
 * @param {String} timeStampUTC - Event timestamp in UTC format
 * @param {Number} notificationClass - The NC handling this event on remote node
 * @param {Number} priority - Event priority
 * @param {Number} eventType - The type of event received
 * @param {String} messageText - Readable notification message
 * @param {Number} notifyType - Type of notification [0:Event,1:Alamr,2:AckNotif]
 * @param {Boolean} ackRequired - true if ack is required to clear this event on the remote node
 * @param {String} fromState - The previous state
 * @param {String} toState - The current state after the change
 * @param {Object} eventValues - A map of specific map of values for the particular eventType
 ***********************************************************************************************/
function eventNotificationReceived(processIdentifier,initiatingDevice,object,objectType,objectInstance,timeStampUTC,notificationClass,priority,eventType,messageText,notifyType,ackRequired,fromState,toState,eventValues){
//Use this event to act on notifications that is set to be subscribed by this device.
}

Updated by Torbjorn Carlqvist Admin almost 2 years ago · 21 revisions