Бесконечный создатель · Infinite Creator ⌜ voidsp.com ⌟ ⌜ github.com/voidspawner ⌟ ⌜ donationalerts.com/r/voidspawner ⌟
Он учится на примерах людей, целый GitHub в его распоряжении. Я учусь на его примерах. Лучше оставлю все эти форумы в прошлом, как страшный сон.
Так вот это и проверим. А то мне несколько лет назад один чел доказывал, что переводчик Гугла лучше Дипла, пока я его носом не ткнул.
Я с ним уже научился работать. Задавать запросы небольшими блоками, а потом их связывать. Мне от него нужно понимание, как то или иное действие работает. Лопатить тонны мукалатуры, чтобы узнать, у меня совершенно нет желания. На примерах учиться гораздо быстрее.
Отлично. Значит запустить можешь. Дальше допиливай уточнениями. Хоть узнал, что это за говно такое Oracle. А то в банке с ним работал, через UI.
Ясно, но ты всё равно молодец, что чела дотащил.
Так работает код или нет? Ты его запускал? Я не ипу в Oracle.
Ну, неплохо. Можно и так развлекаться. Но лучше бы в Стим залил.
Ответ ЖПТ
Если без бюрократии — да, за 5 минут можно накидать рабочий коннектор 😄
Не «промышленный комбайн», а реальный минимально-рабочий мост Modbus TCP → Oracle DB, который ты дальше допилишь под себя.
Ниже — Python-коннектор, потому что:
Modbus TCP в Python делается быстро (pymodbus)
Oracle — через cx_Oracle / oracledb
Отлично подходит для демона / сервиса
Архитектура (коротко)
[PLC / Modbus TCP]
↓
pymodbus
↓
Python mapping
↓
Oracle DB (INSERT / MERGE)
Зависимости
pip install pymodbus oracledb
Если Oracle 12c+ — лучше oracledb (новый драйвер)
Пример таблицы в Oracle
CREATE TABLE modbus_data (
device_ip VARCHAR2(50),
register_id NUMBER,
value NUMBER,
ts TIMESTAMP DEFAULT SYSTIMESTAMP,
CONSTRAINT modbus_pk PRIMARY KEY (device_ip, register_id)
);
Коннектор Modbus TCP → Oracle
from pymodbus.client import ModbusTcpClient
import oracledb
import time
# ---------- CONFIG ----------
MODBUS_IP = "192.168.1.10"
MODBUS_PORT = 502
UNIT_ID = 1
REGISTER_START = 0
REGISTER_COUNT = 10
ORACLE_DSN = "localhost/orclpdb1"
ORACLE_USER = "modbus"
ORACLE_PASSWORD = "password"
POLL_INTERVAL = 5 # seconds
# ----------------------------
def oracle_connect():
return oracledb.connect(
user=ORACLE_USER,
password=ORACLE_PASSWORD,
dsn=ORACLE_DSN
)
def read_modbus():
client = ModbusTcpClient(MODBUS_IP, port=MODBUS_PORT)
client.connect()
result = client.read_holding_registers(
address=REGISTER_START,
count=REGISTER_COUNT,
slave=UNIT_ID
)
client.close()
if result.isError():
raise RuntimeError(result)
return result.registers
def write_oracle(values):
conn = oracle_connect()
cur = conn.cursor()
sql = """
MERGE INTO modbus_data t
USING (SELECT :device_ip device_ip,
:reg_id register_id,
:val value FROM dual) s
ON (t.device_ip = s.device_ip AND t.register_id = s.register_id)
WHEN MATCHED THEN
UPDATE SET t.value = s.value, t.ts = SYSTIMESTAMP
WHEN NOT MATCHED THEN
INSERT (device_ip, register_id, value)
VALUES (s.device_ip, s.register_id, s.value)
"""
for i, val in enumerate(values):
cur.execute(sql, {
"device_ip": MODBUS_IP,
"reg_id": REGISTER_START + i,
"val": val
})
conn.commit()
cur.close()
conn.close()
def main():
while True:
try:
values = read_modbus()
write_oracle(values)
print("OK:", values)
except Exception as e:
print("ERROR:", e)
time.sleep(POLL_INTERVAL)
if __name__ == "__main__":
main()
Что уже умеет этот коннектор
✔ Modbus TCP
✔ Holding Registers
✔ Oracle INSERT / UPDATE
✔ Работает как сервис
✔ Не теряет значения (MERGE)
Что обычно добавляют дальше (по опыту)
Если нужно — сделаю сразу:
🔄 Авто-reconnect
📊 Scaling (INT → FLOAT, pressure, temp)
🧱 Register map из JSON
🧵 Мультипоточность (несколько PLC)
🕒 Буферизация при падении Oracle
🐳 Docker
🧠 Alarm-логика (out of range)
Вопросы, которые влияют на финальную версию
Ответь коротко, и я сразу дам production-вариант:
Oracle: 11g / 12c / 19c / Autonomous?
Modbus: holding / input / coils?
Типы: int16 / int32 / float / endian?
Один PLC или много?
Нужен realtime (<1s) или polling ок?
Хочешь — следующим шагом сделаем C-версию или Java (JDBC + Netty), если Python не заходит.
так пример-то будет конкретный?
Стоит обосрать кого-то и такие бусты на главной.