Erro no Driver Modbus Serial na versão do ScadaBR 1.1.0-RC do Branches


#1

Ajuda urgente para aquisição de dados com Modbus Serial ScadaBR.

Descarreguei e compilei a versão do ScadaBR 1.1.0-RC do Branches e pus a rodar numa máquina windows 7.

Até aqui tudo bem o problema é que necessito de utilizar o driver Modbus Serial para adquirir dados de diversos sensores meteorológicos de uma planta solar.
As configurações Modbus estão todas corretas uma vez que antes de passar para o ScadaBR foram testadas com ajuda de um OPC Modbus.

Após programar o data source e os respectivos data points no ScadaBR, ao ativar o data source aparece o seguinte erro:
com.serotonin.io.serial.SerialParameters cannot be cast to com.serotonin.modbus4j.serial.SerialPortWrapper” e não deixa que o data source seja iniciado (erro: http://prntscr.com/fsr8p8).

Se usar o Modbus node Scan o Point Locator ou o Modbus read data tenho a o seguinte erro: “Scanner could not be started. No comm port” (http://prntscr.com/fsr9vb).

Já testei também a versão ScadaBR 1.0CE e quando configuro tudo e tento ler os dados aparece a mensagem “O valor do ponto não é confiavel” e não aparece dado nenhum.

Alguém na comunidade me poderia ajudar.


Script Instalação Raspberry Pi 3
#2

A versão 1.1 ainda não está funcionando o modus serial.

Quanto a 1.0 deve estar alguma configuração que está dando conflito.

Neste canal, há alguns vídeos ensinando modbus serial e também modbus ip. Estou estudando aplicações para usar o modbus ip pois facilita a configuração:

https://www.youtube.com/channel/UCnteH-Hmie3VgpAsft_Mgfw


#3

Obrigado pela resposta,

Mas a configuração do Modbus esta correta pois eu utilizo programas para poder testar antes de passar para o Scada.

A versão 1.0 eu consigo programar o ponto e se realizar a leitura manual consigo obter o dado correctamente conforme se pode verificar na imagem http://prntscr.com/fsune1.

O problema é quando activo todos os pontos existe algum problema no driver modbus que fa com que o valor do ponto não sejá mostrado a mesagem “O valor do ponto não é confiavel” - http://prntscr.com/fsuo9z.

Neste caso necessitava mesmo de utilizar o ScadaBR para realizar este sistema visto ser o teste de partida deste sistema para a aceitação na firma onde trabalho.


#4

me mostra todas as configurações do modbus pra eu entender.


#5

Configuração do Data Source com leitura do ponto - http://prntscr.com/fsuztr

Configuração do Data Point - http://prntscr.com/fsv0ej

A configuração esta correta.
Pela análise que fiz ao código que esta no driver modbus da versão do ScadaBR 1.0 este possui um campo no qual faz faz referência a este tipo de erro que é de o data point ficar neste valor indefinido e não apresentar valores.
Extrato do código que falo esta no ficheiro “MOdbusDataSource.java”

				dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, true);
			} else {
				**/***

** * When an event is raised from the Callback**
** * receivedException() interface, points are updated with**
** * false or 0; The event is usually a NoKeyFound in the**
** * WaitingRoom, due to previous timeout.**


** * The eventRaised flag prevents data being writen with**
** * invalid values in those cases.**


** * Note: This usually avoids first poll if previous**
** * DataSource Exception Event was raised, but afterwards**
** * it´s effective. TODO: Treat this type of exception**
** * only… but how?!**
** /*
LOG.trace("Point: " + locator.getVO().getOffset()
+ " eventRaised: " + eventRaised);
if (!eventRaised) {
returnToNormal(POINT_READ_EXCEPTION_EVENT, time);
dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, false);
updatePointValue(dataPoint, locator, result, time);
slaveStatuses.put(locator.getVO().getSlaveId(), true);
}


#6

Boa noite Jonathanl,

Consegui dar a volta a questão utilizando conversores RS485 to Ethernet da Moxa.

Neste momento tenho a aplicação a adquirir dados de minuto a minuto utilizando o driver Modbus TCP/IP.

Peço desculpa pois não me apresentei, aqui vai:
Eu trabalho numa multinacional no ramo das energias renováveis (Vento, Solar, Hídrica e Biomassa) com mais incidência no Solar de momento, com sede em Portugal, Trabalho em Automação industrial a 5 anos. neste momento estou no departamento de Aquisição de dados.
Faço desde o protejo de Automação,definição de todo o equipamento a instalar para realizar a comunicação com os diversos equipamentos, acompanhamento de obra, configuração da rede de comunicação, instalação, programação e configuração do sistema de monitorização.

Se alguém souber como se pode resolver a questão do driver Modbus Serial agradecia a ajuda.

Não sei se pode interessar mas a cerca de 2 Anos desenvolvi um driver para o ScadaBR o Qual se encontra em funcionamento num Parque Solar sem nenhum problema.
Posso afirmar que o ScadaBR é robusto.

cumprimentos a todos,


#7

Boa tarde Augusto_Casais

Eu estou enfrentando o mesmo problema utilizando modbus serial.
Conseguiu resolver?


#8

@Juliano_Perotto

já existe uma versão em análise corrigindo esse problema. Acho que nas próximas semanas vai sair a versão corrigida para download.


#9

@farmsid

Muitíssimo obrigado pela informação, estarei aguardando, enquanto isso estarei me dedicando a outros conhecimentos.


#10

Boas,

Sim consegui dar a volta ao problema. É necessário realizar uma pequena alteração no código fonte do Modbus serial.
neste momento esta a funcionar.
Existe uma função que não esta a ser utilizada no driver, a qual devera ser utilizada.

Fica aqui o código fonte que que alterei e que esta a trabalhar para este caso.

Versão do scadabr Branches 1794:
alterações são no ficheiro “com.serotonin.mango.rt.dataSource.modbus”.

Qualquer questão estou ao dispor.

/*
Mango - Open Source M2M - http://mango.serotoninsoftware.com
Copyright © 2006-2011 Serotonin Software Technologies Inc.
@author Matthew Lohbihler

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/
package com.serotonin.mango.rt.dataSource.modbus;

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.SerialPort;

import java.util.Enumeration;

import com.serotonin.io.serial.SerialParameters;
import com.serotonin.mango.rt.dataSource.DataSourceRT;
import com.serotonin.mango.vo.dataSource.modbus.ModbusSerialDataSourceVO;
import com.serotonin.mango.vo.dataSource.modbus.ModbusSerialDataSourceVO.EncodingType;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.web.i18n.LocalizableMessage;

public class ModbusSerialDataSource extends ModbusDataSource {

private final ModbusSerialDataSourceVO configuration;
ModbusMaster modbusMaster;
private Enumeration<?> portList;
private boolean connProblem = false;
private boolean firstTime = true;

private int timeoutPort = 10000;

public ModbusSerialDataSource(ModbusSerialDataSourceVO configuration) {
	super(configuration);
	this.configuration = configuration;

}

//
// /
// / Lifecycle
// /
//
@Override
public void initialize() {
	SerialParameters params = new SerialParameters();
	params.setCommPortId(configuration.getCommPortId());
	params.setPortOwnerName("Mango Modbus Serial Data Source");
	params.setBaudRate(configuration.getBaudRate());
	params.setFlowControlIn(configuration.getFlowControlIn());
	params.setFlowControlOut(configuration.getFlowControlOut());
	params.setDataBits(configuration.getDataBits());
	params.setStopBits(configuration.getStopBits());
	params.setParity(configuration.getParity());

	SerialPortWrapperImpl wrapper = new SerialPortWrapperImpl(
			params.getCommPortId(), params.getBaudRate(),
			params.getFlowControlIn(), params.getFlowControlOut(),
			params.getDataBits(), params.getStopBits(), params.getParity(),
			timeoutPort);

	if (configuration.getEncoding() == EncodingType.ASCII)
		modbusMaster = new ModbusFactory().createAsciiMaster(wrapper);
	else
		modbusMaster = new ModbusFactory().createRtuMaster(wrapper);

	super.initialize(modbusMaster);

}

@Override
protected void doPoll(long time) {

	portList = CommPortIdentifier.getPortIdentifiers();

	// System.out.println("Configuration List Port " + portList);
	// System.out.println("");

	if (!verifyPort(configuration.getCommPortId())) {
		// System.out.println("Porta nao detectada !");
		if (firstTime) {
			System.out.println("First Time !");
			modbusMaster.destroy();
			firstTime = false;
		}
		connProblem = true;
		return;
	}
	if (connProblem) {
		connProblem = false;
		firstTime = true;
		initialize();
	}
	super.doPoll(time);
}

public SerialPort getPort(String port, int timeout) {

	SerialPort serialPort = null;

	while (portList.hasMoreElements()) {
		CommPortIdentifier portId = (CommPortIdentifier) portList
				.nextElement();
		if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
			if (portId.getName().equals(port)) {
				try {
					serialPort = (SerialPort) portId.open(
							configuration.getCommPortId(), timeout);
				} catch (Exception e) {
					e.printStackTrace();
					// System.out.println("Erro ao abrir a porta !");
				}
			}
		}
	}
	return serialPort;
}

public boolean verifyPort(String port) {

	boolean p = false;

	while (portList.hasMoreElements()) {
		CommPortIdentifier portId = (CommPortIdentifier) portList
				.nextElement();
		if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
			if (portId.getName().equals(port)) {
				p = true;
				getPort(port, timeoutPort);
				break;
			} else
				p = false;
		}
	}
	return p;
}

@Override
protected LocalizableMessage getLocalExceptionMessage(Exception e) {
	if (e instanceof ModbusInitException) {
		Throwable cause = e.getCause();
		if (cause instanceof NoSuchPortException)
			return new LocalizableMessage("event.serial.portOpenError",
					configuration.getCommPortId());
	}

	return DataSourceRT.getExceptionMessage(e);
}

}


#11

@Augusto_Casais

Gostaria de lhe agradecer pelo empenho, o problema foi solucionado completamente, meus parabéns!


#12

Nossa, eu também quero agradecer.
A comunidade já precisava disso faz tempo.

Parabens. Ganhou meu joinha.


#13

Boa tarde @Augusto_Casais. Parabéns pelo erro corrigido, você ajudou à comunidade ScadaBR. O programa está com o ModBus serial com um bug e, em algum tempo, lançará o ScadaBR com o ModBus serial em funcionamento, com todos os erros corrigidos, e você ajudou muito com isso!

É um prazer conhecê-lo, estou recém lançando minha empresa, e já sou integrador ScadaBR com muito orgulho. Sou apaixonado em automação e quero focar minha empresa em Residencial, corporativa e industrial.
Gostaria de uma conversa contigo para mais informações sobre seu trabalho. Estou aprendendo bastante e isso pode contribuir com minhas habilidades pra melhorar minha empresa. Grande abraço e muito sucesso!


#14

Obrigado a todos,

Fico contente por ter ajudado.
Existe ainda algumas correções que deveriam ser feitas neste driver, como o caso de teste aos pontos.

Não tenho tido tempo para me dedicar mais ao ScadaBR e poder contribuir mais.

No entanto tenho algumas sugestões que poderiam ser de grande valia para este sistema. Estas sugestões são fruto da experiência do dia a dia onde lido com diferentes sistemas de monitorização desde SCADAS a dataloggers para recolha de dados.

Neste momento tenho um novo driver que poderia ser integrado numa futura versão do ScadaBR, mas não sei a quem falar para poder compartilhar esse driver.

Estou a desenvolver outro driver para leitura de contadores através de porta Serial e Ethernet uma vez que na atualidade esse é um ponto fundamental quando utilizamos sistemas de aquisição em sistema de produção de energia.

Cumprimentos a todos.


#15

@Augusto_Casais,
Toda a sua ajuda é bem vinda.
Com a informação adequada posso levar sua sugestão diretamente para os programadores e incluir sua contribuição.
Aguardo contato em privado.
farmsid@gmail.com


#16

Obrigado Sidney.

Assim farei.


#17

Augusto

Poderia compartilhar a classe SerialPortWrapperImpl ?
A classe que eu encontrei em: https://github.com/IOT-DSA/dslink-java-modbus/blob/master/src/main/java/modbus/SerialPortWrapperImpl.java não possui todos os argumentos que voce utiliza.


#18

Boas Carlos,

Claro que sim.
Caso necessite de mais alguma coisa é só dizer.

Aqui esta a classe SerialPortWrapperImpl completa:

package com.serotonin.mango.rt.dataSource.modbus;

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.serotonin.modbus4j.serial.SerialPortWrapper;

/**
*

  • This class is not finished
  • @author Terry Packer

*/
public class SerialPortWrapperImpl implements SerialPortWrapper {
private SerialPort serialPort;
private String commPortId;
private int baudRate;
private int flowControlIn;
private int flowControlOut;
private int dataBits;
private int stopBits;
private int parity;
private int timeOutComPort;

public SerialPortWrapperImpl() {
	super();
}

public SerialPortWrapperImpl(String commPortId, int baudRate,
		int flowControlIn, int flowControlOut, int dataBits, int stopBits,
		int parity, int timeOutComPort) {
	this.commPortId = commPortId;
	this.baudRate = baudRate;
	this.flowControlIn = flowControlIn;
	this.flowControlOut = flowControlOut;
	this.dataBits = dataBits;
	this.stopBits = stopBits;
	this.parity = parity;
	this.timeOutComPort = timeOutComPort;
}

public String getCommPortId() {
	return commPortId;
}

public void setCommPortId(String commPortId) {
	this.commPortId = commPortId;
}

public void setBaudRate(int baudRate) {
	this.baudRate = baudRate;
}

public void setFlowControlIn(int flowControlIn) {
	this.flowControlIn = flowControlIn;
}

public void setFlowControlOut(int flowControlOut) {
	this.flowControlOut = flowControlOut;
}

public void setDataBits(int dataBits) {
	this.dataBits = dataBits;
}

public void setStopBits(int stopBits) {
	this.stopBits = stopBits;
}

public void setParity(int parity) {
	this.parity = parity;
}

@Override
public void close() throws Exception {
	if (serialPort != null) {
		serialPort.close();
		serialPort = null;
	}
}

@Override
public void open() throws Exception {
	// System.out.println(commPortId);
	CommPortIdentifier portIdentifier = CommPortIdentifier
			.getPortIdentifier(commPortId);

	// System.out.println(commPortId);
	CommPort commPort = portIdentifier.open(commPortId, timeOutComPort);

	if (commPort instanceof SerialPort) {
		serialPort = (SerialPort) commPort;
		try {
			serialPort.setSerialPortParams(this.getBaudRate(),
					this.getDataBits(), this.getStopBits(),
					this.getParity());
			serialPort.setFlowControlMode(this.getFlowControlIn()
					| this.getFlowControlOut());
		} catch (Exception e) {
			e.printStackTrace();
		}
		// System.out.println("Open " + this.commPortId + " sucessfully !");
		// return serialPort;
	} else {
		// System.out.println("aaaaaaaaaaaa");
	}
}

@Override
public InputStream getInputStream() {
	InputStream in = null;
	try {
		in = serialPort.getInputStream();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

	return in;
}

@Override
public OutputStream getOutputStream() {
	OutputStream out = null;
	try {
		out = serialPort.getOutputStream();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

	return out;
}

@Override
public int getBaudRate() {
	// TODO Auto-generated method stub
	return this.baudRate;
}

@Override
public int getStopBits() {
	// TODO Auto-generated method stub
	return this.stopBits;
}

@Override
public int getParity() {
	// TODO Auto-generated method stub
	return this.parity;
}

@Override
public int getFlowControlIn() {
	// TODO Auto-generated method stub
	return this.flowControlIn;
}

@Override
public int getFlowControlOut() {
	// TODO Auto-generated method stub
	return this.flowControlOut;
}

@Override
public int getDataBits() {
	// TODO Auto-generated method stub
	return this.dataBits;
}

}


#19

Estou com o mesmo problema. O data point fica : Valor do ponto pode não ser confiável.

Alguém conseguiu resolver ?


#20

Boas,

Se estiveres a trabalhar no código fonte do ScadaBR 1.1 o driver de Modbus possui um erro na classe “SerialPortWrapperImpl”, se copiares o código que coloquei no poste acima e substituires o código fonte por este nesta classe esse aviso vai desaparecer.

qualquer duvido é só dizeres.