Project

General

Profile

Javascript » History » Revision 21

Revision 20 (Torbjorn Carlqvist Admin, 12/02/2022 02:30 PM) → Revision 21/28 (Torbjorn Carlqvist Admin, 01/12/2023 09:27 AM)

h1. Javascript guide for DTXr code IDE 

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

 [[#Commands|Commands]] 
 [[#Events|Events]] 

 --- 

 h2. Commands 

 <pre><code class="javascript"> 
     
 //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.enableIntrinsicReporting(0/*NotificationClass*/,3/*delay*/,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 paus/cancel the job if neccesary. 
     job. 
 //Arg2: start delay (s) - Time until first exec 
     
 //Arg3: period(s) - Time between exec, set to 0 if no repetition is required/wanted. 
     required. 
 //Arg4: repeates - Number of repeates, null if infinit, 0 if no repeat 
     
 //Arg5: code - Any Javascript 
     Controller.scheduleExecution("wait05",5,0,0,"print('print 
 Controller.scheduleExecution(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(); 
 </code></pre> 


 h2. Events 

 h3. *eventNotificationReceived* - Called when an intrinsic report notification is received. 

 <pre><code class="javascript"> 
 /*********************************************************************************************** 
  * @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. 
 } 
 </code></pre>