Здравствуйте!
Есть задача:
1. Есть ПК-сервер (Windows 10) с программой на Java.
2. Есть Овен ПР200 (Программируемое реле)
3. Есть модем iRZ MC55iT
4. Есть компьютер-клиент с установленным Owen OPC Server и Scada
Должен быть двухсторонний диалог между ПР200 (через модем) с ПК-клиентом через ПК-сервер.
То есть, если данные обновляются на ПР200, то они приходят через модем на ПК-сервер и обновляются на ПК-клиенте в Owen OPC Server (через Modbus TCP/IP).
И в обратную сторону.
С Owen OPC Server данные будут вытягиваться в Scada.
Код программы на ПК-сервере:
public static void main(String[] args) {
// Создаем два Modbus сервера для двух портов (1 - OPC Server, 2 - ПР200)
ModbusServer opcServer = new ModbusServer();
opcServer.setPort(502);
ModbusServer pr200Server = new ModbusServer();
pr200Server.setPort(1502);
// Читаем из базы данных последние данные и загружаем в Modbus Holding Registers
opcServer.holdingRegisters = readFromDatabase();
pr200Server.holdingRegisters = readFromDatabase();
// Запускаем сервера в отдельных потоках
new Thread(() -> startServer(opcServer, "OPC Server")).start();
new Thread(() -> startServer(pr200Server, "PR200")).start();
// Устанавливаем обработчики изменений регистров
pr200Server.setNotifyHoldingRegistersChanged(() -> {
System.out.println("Изменились данные у ПР200 -> записываем в БД и отправляем на OPC Server");
printWithoutFirstElement(
pr200Server.holdingRegisters,
"\nДанные с ПР200: "
);
writeToDatabase("PR200", pr200Server.holdingRegisters);
opcServer.holdingRegisters = pr200Server.holdingRegisters;
printWithoutFirstElement(
opcServer.holdingRegisters,
"\nДанные с ПР200 на OPC Server: "
);
});
opcServer.setNotifyHoldingRegistersChanged(() -> {
System.out.println("Изменились данные у OPC Server -> записываем в БД и отправляем на ПР200");
printWithoutFirstElement(
opcServer.holdingRegisters,
"\nДанные с OPC Server: "
);
writeToDatabase("OPC_Server", opcServer.holdingRegisters);
pr200Server.holdingRegisters = opcServer.holdingRegisters;
printWithoutFirstElement(
pr200Server.holdingRegisters,
"\nДанные с OPC Server на ПР200: "
);
});
}
// Метод для запуска Modbus сервера
private static void startServer(ModbusServer server, String name) {
try {
server.Listen();
server.setClientConnectionTimeout(500000);
System.out.println("\n" + name + " запущен на порту " + server.getPort());
} catch (IOException e) {
e.printStackTrace();
}
}
Сейчас если ПК-сервер и ПК-клиент находятся в одной сети, то, используя программу-клиент на ПК-сервере, я могу передавать данные с этой программы-клиента через ПК-сервер на ПК-клиент с Owen OPC Server.
То есть, обновляю данные на ПК-клиенте с Owen OPC Server, они обновляются и в программе-клиенте.
И в обратную сторону.
После проброса портов через Микротик, это должно работать с любой сети.
Тут данные - числа, которые хранятся в регистрах Holding Registers.
Общая схема:
Код временной программы-клиента для теста (которая будет заменена на ПР200):
private static boolean askServer = true; // флаг для опроса сервера
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
final ModbusClient client = new ModbusClient("127.0.0.1", 1502);
while (true) {
System.out.println("\nМеню:");
System.out.println("1 - Подключиться к серверу");
System.out.println("2 - Отправить данные");
System.out.println("3 - Отключиться от сервера");
System.out.println("exit - Выйти");
System.out.print("Выберите действие: ");
String input = scanner.nextLine();
if (input.equals("exit")) {
break;
}
if ("1".equals(input)) {
try {
client.Connect();
askServer = true; // включаем опрос сервера
System.out.println("Подключено к серверу " + "127.0.0.1" + ":" + 1502);
new Thread(new Runnable() {
@Override
public void run() {
while (askServer) { // читаем данные пока идет опрос
try {
int[] receivedData = client.ReadHoldingRegisters(0, 8);
System.out.println("Данные получены от OPC Server: " + Arrays.toString(receivedData));
} catch (ModbusException e) {
System.out.println("Ошибка получения данных от OPC Server (Modbus): " + e.getMessage());
} catch (IOException e) {
System.out.println("Ошибка получения данных от OPC Server: " + e.getMessage());
}
try {
Thread.sleep(5000); // период опроса в мс
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
} catch (IOException e) {
System.out.println("Ошибка подключения: " + e.getMessage());
}
} else if ("2".equals(input)) {
if (!client.isConnected()) {
System.out.println("Сначала подключитесь к серверу (нажмите 1)");
continue;
}
try {
int[] testData = {100, 102, 104, 106, 108, 110, 112, 114};
client.WriteMultipleRegisters(0, testData);
System.out.println("Данные отправлены в OPC Server: " + Arrays.toString(testData));
} catch (Exception e) {
System.out.println("Ошибка отправки: " + e.getMessage());
}
} else if ("3".equals(input)) {
try {
client.Disconnect();
askServer = false; // отмена опроса сервера
System.out.println("Отключено от сервера");
} catch (IOException e) {
System.out.println("Ошибка отключения: " + e.getMessage());
}
} else {
System.out.println("Неверная команда");
}
}
System.out.println("Клиент завершил работу");
scanner.close();
}
На ПК-клиенте в Owen OPC Server тестовые данные, которые приходят выглядят так:

На ПР200 переменные будут с 512 регистра, в коде программы сервера и на Owen OPC Server это тоже будет обновлено.
Мне нужно настроить модем iRZ MC55iT (например, через PuTTY) так, чтобы заменить эту "программу-клиент" (которая временно на ПК-сервере для теста) на ПР200 с модемом.
Передача данных по GPRS.
Во всех вариантах настройки модема, которые я нашел, примерно одно и то же:
AT
AT+CIPSHUT // Сброс предыдущих соединений
AT+CIPMUX=0 // Одиночное соединение
AT+CGATT=1 // Подключение к GPRS
AT+CSTT="internet.mts.ru" // Задание точки доступа APN - поменять на нужный
AT+CIICR // Инициализация GPRS
AT+CIFSR // Получить IP модема (если всё ок — покажет IP)
AT+CIPSTART="TCP","0.0.0.0","1502" // Подключение к ПК-серверу - тут поменять на ip сервера
AT+CIPSEND // Отправка данных на сервер
ввести текст
Вопрос: как возможно настроить с помощью АТ команд модем, чтобы не с терминала отправлять данные, как тут:
AT+CIPSEND // Отправка данных на сервер
ввести текст
... а так, чтобы всегда, когда данные обновлялись на ПР200 (который будет подключен к порту RS-232 модема), они отправлялись через модем на ПК-сервер?
И в обратную сторону - когда обновленные данные приходят с сервера, чтобы они проходили через модем и через порт модема RS-232 на ПР200?
Буду благодарен за ответы, проясняющие ситуацию.
Спасибо.