Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open-close function #539

Open
tjarb opened this issue Dec 21, 2023 · 11 comments
Open

Open-close function #539

tjarb opened this issue Dec 21, 2023 · 11 comments

Comments

@tjarb
Copy link

tjarb commented Dec 21, 2023

Hi All,

I try to implement the TCP method this for a Homey device with multiple SUB-devices. Because of that I need the connection to be closed after data exchange.
Is there a way to open and close the client from within a interval function?

Best regards

@yaacov
Copy link
Owner

yaacov commented Dec 21, 2023

hi, thank you for the issue, I added help wanted label in case someone knows an answer to this quiestion

@yaacov
Copy link
Owner

yaacov commented Dec 21, 2023

p.s.
You can look at the examples:
https://github.com/yaacov/node-modbus-serial/blob/master/examples

I think this one may be helpful for your question:
https://github.com/yaacov/node-modbus-serial/blob/master/examples/polling_TCP.js

try to close the connection after each data collection, wait for the connection to close and then re connect.

@tjarb
Copy link
Author

tjarb commented Dec 21, 2023

Hi @yaacov ,

I now use the following:

const client = new ModbusRTU();
let self = this;

self.pollingInterval_fast = self.homey.setInterval(() => {  
     client.connectTCP(self.getSetting('address'), { port: 502 }).then( function(){	

                client.setID(1);
		client.setTimeout( self.getSetting('polling') * 1000 );
																	
		client.readHoldingRegisters(10, 1, function(err, data) {
				if(data.data) self.log("10 " + data.data);
				else self.log(err);
		});
     });	
   /* >>>client seems to have connection closed here <<< */
}, self.getSetting('polling') * 1000);

Perhaps I should add the client.close, but when testing the client for connection it's already 'disconnected'.
Your examples are interesting, thanks for sharing.

Best regards,

@tjarb
Copy link
Author

tjarb commented Dec 21, 2023

Hi @yaacov ,

it's very strange. If I use the:

while(){
   let  ModbusRTU = require("modbus-serial");
   let client = new ModbusRTU();
   client.setTimeout( 1000 );
   client.connectTCP(){
      client.readHoldingRegisters()
   }

   client.close();
}

Then there never happens, no data. When I remove the client.close it opens (and keeps open) connections until the modbus server rans out of connections (always 16 sessions).

@yaacov
Copy link
Owner

yaacov commented Dec 21, 2023

did you try closing the connection after using the read data ?
client.readHoldingRegisters( ... ).then( ... close() )

@tjarb
Copy link
Author

tjarb commented Dec 21, 2023

Hi @yaacov ,

Here the snipped:

const modbus = require('jsmodbus');

class DucoMasterModbusDevice extends Device {
	/*constructor?*/
    async onInit() {
        let self = this;
		
		let i=0;
		const  ModbusRTU = require("modbus-serial");
		
		self.pollingInterval_fast = self.homey.setInterval(() => {  
					self.log("####### "+ i++ +" poll to connect socket  ################");			

					let client = new ModbusRTU();		

					client.setTimeout( 1000 );
					
					client.connectTCP("192.168.2.137", { port: 502 })
						.then( function(){					
							client.setTimeout( 1000 );
							client.setID(1);				
							
							client.readHoldingRegisters(10, 1)
							.then( function(data){
								 self.log("10 " + data.data);			
							})
							.catch(function(e){		
								self.log(e);
							});	
                                                      //#1					
						
					})	
					.catch(function(e){		
						self.log(e);
					});						
				
                                      //#2
					
		}, 2000);	//end of pollingInterval_fast
		
	});	
}

module.exports = DucoMasterModbusDevice;

If I place the client.close() directly after the read, on position #1, then I only get TransactionTimedOutErrors, none succeeds.

If I place the client.close() directly after the read, on position #2, then I 16 transaction successes, after than only TransactionTimedOutErrors.

@yaacov
Copy link
Owner

yaacov commented Dec 21, 2023

try to move the close to after the self.log(...) in readHoldingRegisters

@tjarb
Copy link
Author

tjarb commented Dec 21, 2023

hi @yaacov ,

I need more reads. The modbus registers are spread.

  1. open

  2. read holding page 10, 4long

  3. read holding page 16, 4long

  4. read inputregs page 10, 4long

  5. read inputregs page 16, 4long

  6. close

Closing after the first read is nog desired.

@yaacov
Copy link
Owner

yaacov commented Dec 21, 2023

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

can you collect all reads, and then close after the last one is finished?

@tjarb
Copy link
Author

tjarb commented Dec 21, 2023

Hi @yaacov ,

thank you for your reply. I tried that, but returned an error that the body could not be read.

I'll try it again later today as suggested in the reference.

best regards,

@tjarb
Copy link
Author

tjarb commented Dec 21, 2023

Hi @yaacov ,

Bingo. I just past 100 reads.

const  ModbusRTU = require("modbus-serial");
let i=0;
let self = this;

self.pollingInterval_fast = self.homey.setInterval(() => {  
			
			let client = new ModbusRTU();
			self.log("####### "+ i++ +" poll to connect socket "+self.getSetting('address') +" ################");			
				client.setTimeout( 1000 );
				
				client.connectTCP( "192.168.2.173" , { port: 502 }).then( function(){					
					client.setTimeout( 1000 );
					client.setID(1);				
					
					Promise.all([
						client.readHoldingRegisters(10, 1),								
						client.readHoldingRegisters(15, 2),
						client.readHoldingRegisters(19, 1),
						client.readInputRegisters (10, 3),
						client.readInputRegisters(13, 3),
						client.readInputRegisters(19, 1)	
					]).then((data) => {
							self.log(data);
							client.close();
					}).catch((err) => {
					
						self.log(err);
					})							
											
				})	//client.close(); here the Modbus client is closed again
				.catch(function(e){		
					self.log(e);
				});	
									
}, 2000);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants