diff --git a/scenes/pribor-uyep/sch3-view.gd b/scenes/pribor-uyep/sch3-view.gd index b057192..1bc4aae 100644 --- a/scenes/pribor-uyep/sch3-view.gd +++ b/scenes/pribor-uyep/sch3-view.gd @@ -12,19 +12,25 @@ extends 'res://scenes/контроль/элемент-я.gd' @export var base_holding_address: = 0 ## Базовый адрес регистров хранения @export var regs_input_count: = 5 ## Количество регистров входов @export var regs_holding_count: = 4 ## Количество регистров хранения -@export var modbus_address: = 3 ## Адрес устройства на шине Modbus -@export var request_period: = 1.0 ## Период отправки команд на шину Modbus -@export var reconnect_period: = 5.0 ## Период переподключения +@export var modbus_address: = 7 ## Адрес устройства на шине Modbus +@export var request_period: = 0.2 ## Период в секундах отправки команд на шину Modbus +@export var reconnect_period: = 3.0 ## Период в секундах var regs_input: = {} ## Регистры входные var regs_holding: = {} ## Регистры хранения var write_stack: = [] ## Стек команд для записи -var holding_stack: = [] ## Стек команд для чтения регистров хранения -var input_stack: = [] ## Стек команд для чтения регистров входов -var read_step: = 0 var switches_sync: = false var timer = Timer.new() var timer_reconnect = Timer.new() +var step_fsm: = Sch3Fsm.CONNECT + + +enum Sch3Fsm { + READ_INPUT, + READ_HOLDING, + WRITE, + CONNECT, + CONNECT_WAIT } class StackItem: @@ -39,34 +45,24 @@ func on_data_received(_data: PackedByteArray): pass ## Обработчик таймера func _on_timeout(unit_sch3) -> void: - if write_stack.size(): - var ad = write_stack.pop_front() - if not unit_sch3.write(ad.addr, ad.data): - write_stack.push_back(ad) - if (read_step == 0) and (input_stack.size() == 0): - var ad = StackItem.new(base_input_address, regs_input_count) - input_stack.push_back(ad) - elif (read_step == 1) and (holding_stack.size() == 0): - var ad = StackItem.new(base_holding_address, regs_holding_count) - holding_stack.push_back(ad) - if input_stack.size(): - var ad = input_stack.pop_front() - if not unit_sch3.read_input(ad.addr, ad.data): - input_stack.push_back(ad) - if holding_stack.size(): - var ad = holding_stack.pop_front() - if not unit_sch3.read_holding(ad.addr, ad.data): - holding_stack.push_back(ad) - read_step += 1 - read_step %= 2 - - -func _on_timeout_recconect(unit_sch3): - var unit_key = settings.get_unit_key(unit_sch3.name) - var mbc = network.mbcs[unit_key] - mbc.try_reconnect() - var mb_data = {'code': 'read_holding', 'data': [0, 4], 'unit': 0} - mbc.send_to(mb_data) + if step_fsm == Sch3Fsm.WRITE: + if write_stack.size(): + var ad = write_stack.pop_front() + if not unit_sch3.write(ad.addr, ad.data): + write_stack.push_back(ad) + step_fsm = Sch3Fsm.READ_INPUT + elif step_fsm == Sch3Fsm.READ_INPUT: + unit_sch3.read_input(base_input_address, regs_input_count) + step_fsm = Sch3Fsm.READ_HOLDING + elif step_fsm == Sch3Fsm.READ_HOLDING: + unit_sch3.read_holding(base_holding_address, regs_holding_count) + step_fsm = Sch3Fsm.WRITE + elif step_fsm == Sch3Fsm.CONNECT: + var unit_key = settings.get_unit_key(unit_sch3.name) + var mbc = network.mbcs[unit_key] + mbc.flush() + mbc.try_reconnect() + mbc.request_read(base_input_address, regs_input_count) ## Вызывается при изменении состояния выключателя[br] @@ -109,14 +105,10 @@ func _ready() -> void: timer.connect('timeout', _on_timeout.bind(unit_sch3)) add_child(timer) timer.start(request_period) - timer_reconnect.connect('timeout', _on_timeout_recconect.bind(unit_sch3)) - add_child(timer_reconnect) func on_command_fail(unit_sch3): unit_sch3.cmd_state = unit.Unit.CmdState.DONE - timer.stop() - timer_reconnect.start(reconnect_period) ## Вызывается, когда состояния прибора Щ3 "на связи" изменяется[br] @@ -125,20 +117,21 @@ func on_line_changed(unit_sch3: sch_3.Sch3): for item in get_tree().get_nodes_in_group('bits_items_good'): item.texture = textures[STATE_VAL.NONE] if not unit_sch3.online: + timer.wait_time = reconnect_period for item in get_tree().get_nodes_in_group('bits_items_switch'): item.disabled = true regs_holding.clear() regs_input.clear() write_stack.clear() - input_stack.clear() - holding_stack.clear() switches_sync = false $margin/vbox/grid1/lbl_freq.text = '<нет данных>' $margin/vbox/grid1/state_freq.texture = textures[STATE_VAL.NONE] $margin/vbox/grid/state.texture = textures[STATE_VAL.NONE] + timer.wait_time = reconnect_period + step_fsm = Sch3Fsm.CONNECT else: - timer_reconnect.stop() - timer.start(request_period) + timer.wait_time = request_period + step_fsm = Sch3Fsm.WRITE ## Вызывается по сигналу "приняты данные чтения регистров хранения"[br] diff --git a/scripts/network.gd b/scripts/network.gd index adc4ba5..ae8b07c 100644 --- a/scripts/network.gd +++ b/scripts/network.gd @@ -66,9 +66,11 @@ class Modbus extends ModbusClientRtu: close() var rc = open(port, params[0], params[1], params[2], params[3], params[4]) if rc != Error.OK: - push_error('ошибка: \"%s\" - не открывается' % port) + push_error('%s:%s %s' % [unit_name, port, params]) + return false set_indication_timeout(params[5]) thread_run() + return true var poll_sockets: Array[Socket] @@ -131,9 +133,10 @@ func create_modbus(nm, mbc_unit) -> Modbus: mbc.connect('read', mbc_unit.on_read) mbc.connect('read_input', mbc_unit.on_read_input) mbc.connect('write', mbc_unit.on_write) - var _rc = mbc.open(port, params[0], params[1], params[2], params[3], params[4]) - mbc.thread_run() mbc.unit_name = nm + mbc.try_reconnect() + mbc.set_indication_timeout(params[5]) + mbc.thread_run() return mbc