extends Node2D ## Класс для отправки данных в сокет class Socket extends PacketPeerUDP: func send_to(addr: String, port: int, data: PackedByteArray): self.set_dest_address(addr, port) self.put_packet(data) var node_select: Node var soc_unicast: Socket var soc_brodcast: Socket var unit = yau07.YaU07.new('ЯУ07') var state = Constants.STATE.WAIT # Флаг для машины состояния var flag_online: bool = false # Флаг для подключения var flag_interval: bool = false # Флаг для включения непрерывной передачи с интервалом var flag_write_isa: bool = false # Флаг для записи в ИСА var flag_read_isa: bool = true # Флаг для чтения из ИСА var flag_two_ports: bool = false # Флаг наличия работы с двумя портами var ports_wr: Dictionary # Словарь с портами для записи var ports_wr_2: Dictionary var port_select: int = Constants.BASE_ADDR # Выбранный порд для чтения/записи var port_select_2: int = Constants.BASE_ADDR # Выбранный порд для чтения/записи var port: int var address: String var dt: float # Дельта var timer: Timer = Timer.new() var timeout: float = yau07.ONLINE_TIMEOUT var last_update_time: float = 0.0 func _ready(): self.add_child(timer) timer.connect('timeout', Callable(self, 'on_timer')) # Таблица 1 node_select = $scroll1/table1 draw_tabl(node_select, Constants.ROWS_REGS_DATA, Constants.ROWS_REGS_DATA.size()) node_select.set_columns_min_size([250, 160, 150, 190, 150]) node_select.set_node_text(0, 0, ' НЕТ СВЯЗИ С ЯУ-07') node_select.set_node_text(1, 0, ' IP-АДРЕС') node_select.set_node_text(2, 0, Constants.DEFAULT_ADDRESS) node_select.set_node_text(3, 0, ' IP-ПОРТ') node_select.set_node_text(4, 0, Constants.DEFAULT_PORT) node_select.set_node_text(0, 1, ' 1 ПОРТ ЯЧЕЙКИ (hex)') node_select.set_node_text(1, 2, ' ИНТЕРВАЛ') node_select.set_node_text(0, 3, ' 2 ПОРТ ЯЧЕЙКИ (hex)') # Поле для ввода (запись IP-адреса) var edit_ip = node_select.get_node2(2, 0) edit_ip.editable = true edit_ip.placeholder_text = 'Ввод значения' var edit_port = node_select.get_node2(4, 0) edit_port.editable = true edit_port.placeholder_text = 'Ввод значения' # Поле для ввода (запись в порт) var edit_node = node_select.get_node2(2, 1) edit_node.editable = true edit_node.placeholder_text = 'Ввод значения' edit_node.connect('text_submitted', Callable(self, '_on_written_port')) # Поле для ввода (запись в порт_2) var edit_node_2 = node_select.get_node2(2, 3) edit_node_2.editable = true edit_node_2.placeholder_text = 'Ввод значения' edit_node_2.connect('text_submitted', Callable(self, '_on_written_port_2')) $read_ISA.disabled = true $write_ISA.disabled = true $read_ISA2.disabled = true $write_ISA2.disabled = true # Поле для ввода (базовый порт) var edit_addr = node_select.get_node2(0, 2) edit_addr.editable = true edit_addr.text = '%x' % port_select edit_addr.connect('text_submitted', Callable(self, '_on_written_addres')) # Поле для ввода 2 (базовый порт №2) var edit_addr_2 = node_select.get_node2(0, 4) edit_addr_2.editable = true edit_addr_2.placeholder_text = 'Ввод -> Enter' edit_addr_2.connect('text_submitted', Callable(self, '_on_written_addres_2')) # Поле для ввода (интервал непрерывной записи) var edit_interval = node_select.get_node2(2, 2) edit_interval.editable = true edit_interval.placeholder_text = 'Ввод значения' edit_interval.connect('text_submitted', Callable(self, '_on_written_interval')) var node_select2 = $scroll2/table2 draw_tabl(node_select2, Constants.ROWS_BLOCK_DATA, Constants.ROWS_BLOCK_DATA.size()) node_select2.set_columns_min_size([250, 160, 150, 190, 150]) node_select2.set_node_text(0, 0, ' ЧТЕНИЕ ИСА БЛОКА') node_select2.set_node_text(1, 0, ' ПОРТ БЛОКА') node_select2.set_node_text(3, 0, ' ДЛИНА СЛОВ') # Привязка для принятия широковещательного канала soc_brodcast = Socket.new() var rc = soc_brodcast.bind(Constants.BROADCAST_PORT, '*') if rc != OK: print('Ошибка: Неудачная привязка широковещательного адреса') soc_unicast = Socket.new() rc = soc_unicast.bind(Constants.UNICAST_PORT, Constants.UNICAST_ADDRESS) if rc != OK: print('Ошибка: неудачная привязка адреса: ', address) unit.connect('line_changed', Callable(self, 'on_line_changed')) unit.connect('command_fail', Callable(self, 'on_command_fail')) unit.connect('command_done', Callable(self, 'on_command_done')) ## Рисует таблицу func draw_tabl(tbl, row: Array, count_row: int): for i_row in count_row: tbl.add_row(row[i_row]) func poll_receive(sock: Socket) -> bool: ## Приёмник if timeout - last_update_time > 0: while sock.get_available_packet_count() > 0: var rx_data = sock.get_packet() var addr_receive = sock.get_packet_ip() var port_receive = sock.get_packet_port() if rx_data: $BROADCAST.text = 'BROADCAST: ' + str(rx_data) $BROADCAST.modulate = Color(1, 1, 1, 1) var line_yau07_control = node_select.get_node2(0, 0) line_yau07_control.text = ' ЯУ-07Б НА СВЯЗИ' line_yau07_control.modulate = Constants.GREEN last_update_time = 0.0 if (address == addr_receive) and (port == port_receive) and flag_online: unit.parse(rx_data) else: if sock.get_available_packet_count(): last_update_time = 0.0 else: $BROADCAST.modulate = Color(0.5, 0.5, 0.5, 1) var line_yau07_control = node_select.get_node2(0, 0) line_yau07_control.text = ' НЕТ СВЯЗИ С ЯУ-07Б' line_yau07_control.modulate = Constants.RED return false func _process(delta) -> void: last_update_time += delta poll_receive(soc_brodcast) poll_receive(soc_unicast) if flag_online and not flag_interval: state_machine() var port_txt = node_select.get_node2(0, 1) if port_select != node_select.get_node2(0, 2).get_text().hex_to_int(): port_txt.text = ' 1 ПОРТ ЯЧЕЙКИ (hex)*' port_txt.modulate = Color.GREEN else: port_txt.text = ' 1 ПОРТ ЯЧЕЙКИ (hex)' port_txt.modulate = Color.WHITE if flag_two_ports: var port_txt_2 = node_select.get_node2(0, 3) if port_select_2 != node_select.get_node2(0, 4).get_text().hex_to_int(): port_txt_2.text = ' 2 ПОРТ ЯЧЕЙКИ (hex)*' port_txt_2.modulate = Color.GREEN else: port_txt_2.text = ' 2 ПОРТ ЯЧЕЙКИ (hex)' port_txt_2.modulate = Color.WHITE match unit.process(delta): Error.OK: soc_unicast.send_to(address, port, unit.tx_data.slice(0, unit.tx_len)) Error.FAILED: print('Ошибка отправки данных') dt = delta func on_timer() -> void: if flag_interval == true: if flag_online: flag_read_isa = true state_machine() var rc = unit.process(dt) if rc == Error.OK: soc_unicast.send_to(address, port, unit.tx_data.slice(0, unit.tx_len)) func on_line_changed(_unit) -> void: if unit.online: var line_yau07_control = node_select.get_node2(0, 0) line_yau07_control.modulate = Constants.GREEN else: var line_yau07_control = node_select.get_node2(0, 0) line_yau07_control.modulate = Constants.RED var light_interval = node_select.get_node2(1, 2) light_interval.modulate = Color(0.5, 0.5, 0.5, 1) var line_board_control = node_select.get_node2(0, 1) line_board_control.modulate = Constants.RED $Turn_on.button_pressed = false flag_online = false flag_interval = false ## Ессли отсутствует подключение к ячейке ЯУ-07 func on_command_fail(_unit) -> void: $Turn_on.button_pressed = false unit.cmd_state = unit.CmdState.UNCK ## Индикация чтения портов func on_command_done(_unit) -> void: if not unit.isa_ports.has(port_select): return var isa: Array = [] ports_wr[port_select] = unit.isa_ports[port_select] if (unit.isa_ports[port_select] == ports_wr[port_select]) and flag_online: for i in unit.isa_ports: isa.append('%x: %x' % [i, unit.isa_ports[i]]) $ISA.text = 'ISA: ' + str(isa) $ISA.modulate = Color(1, 1, 1, 1) else: $ISA.modulate = Constants.RED func state_machine() -> void: var fl_done = (unit.cmd_state == unit.CmdState.DONE) if state == Constants.STATE.WAIT and fl_done: if flag_two_ports: $write_ISA2.disabled = false $read_ISA2.disabled = false node_select.set_node_text(3, 3, ' ПРОЧИТАНО ИЗ %x' % port_select_2) node_select.set_node_text(1, 3, ' ЗАПИСАТЬ В %x' % port_select_2) var line_board_control_2 = node_select.get_node2(0, 3) var nubre_from_port_2 = 'ffff' if unit.isa_ports.has(port_select_2): nubre_from_port_2 = '%x' % unit.isa_ports[port_select_2] line_board_control_2.modulate = Constants.RED if nubre_from_port_2 == 'ffff' else Constants.GREEN node_select.set_node_text(4, 3, nubre_from_port_2) $write_ISA.disabled = false $read_ISA.disabled = false node_select.set_node_text(3, 1, ' ПРОЧИТАНО ИЗ %x' % port_select) node_select.set_node_text(1, 1, ' ЗАПИСАТЬ В %x' % port_select) var line_board_control = node_select.get_node2(0, 1) var nubre_from_port = 'ffff' if unit.isa_ports.has(port_select): nubre_from_port = '%x' % unit.isa_ports[port_select] line_board_control.modulate = Constants.RED if nubre_from_port == 'ffff' else Constants.GREEN node_select.set_node_text(4, 1, nubre_from_port) if flag_write_isa: flag_write_isa = false state = Constants.STATE.WRITE elif flag_read_isa: flag_read_isa = false state = Constants.STATE.READ else: state = Constants.STATE.WAIT elif state == Constants.STATE.READ and fl_done: ## Чтение из ИСА if flag_two_ports: unit.send_isa(unit.CmdCode.READ_ISA, [port_select, port_select_2]) else: unit.send_isa(unit.CmdCode.READ_ISA, [port_select]) state = Constants.STATE.WAIT elif state == Constants.STATE.WRITE and fl_done: ## Запись в ИСА if flag_two_ports: unit.send_isa(unit.CmdCode.WRITE_ISA, [port_select, ports_wr[port_select], port_select_2, ports_wr_2[port_select_2]]) else: unit.send_isa(unit.CmdCode.WRITE_ISA, [port_select, ports_wr[port_select]]) state = Constants.STATE.WAIT ## Выставить адресс для записи func _on_written_addres(write_addres) -> void: port_select = write_addres.hex_to_int() if ports_wr.has(port_select) != true: ports_wr[port_select] = 0 node_select.set_node_text(0, 2, '%x' % port_select) ## Выставить адресс для записи №2 func _on_written_addres_2(write_addres_2) -> void: flag_two_ports = true port_select_2 = write_addres_2.hex_to_int() if ports_wr_2.has(port_select_2) != true: ports_wr_2[port_select_2] = 0 node_select.set_node_text(0, 4, '%x' % port_select_2) ## Запись числа порт func _on_written_port(write_addres_data) -> void: var is_hex = true for chr in write_addres_data: if chr.to_upper() < '0' or chr.to_upper() > 'F': is_hex = false break ports_wr[port_select] = write_addres_data.hex_to_int() if is_hex else 0xffff flag_read_isa = true flag_write_isa = true # Запись ## Запись числа порт №2 func _on_written_port_2(write_addres_data_2): var is_hex = true for chr in write_addres_data_2: if chr.to_upper() < '0' or chr.to_upper() > 'F': is_hex = false break ports_wr_2[port_select_2] = write_addres_data_2.hex_to_int() if is_hex else 0xffff flag_read_isa = true flag_write_isa = true # Запись func _on_written_interval(write_interval) -> void: timer.start(float(write_interval)) flag_interval = true var light_interval = node_select.get_node2(1, 2) light_interval.modulate = Constants.GREEN ## Подключение func _on_button_pressed(turn_on) -> void: if turn_on: address = node_select.get_node2(2,0).text port = int(node_select.get_node2(4,0).text) flag_read_isa = false # Чтение flag_online = true save_settings() else: flag_online = false flag_interval = false var light_interval = node_select.get_node2(1, 2) light_interval.modulate = Color(1,1,1,1) func _on_button_read() -> void: port_select = node_select.get_node2(0, 2).text.hex_to_int() flag_read_isa = true func _on_button_read_2() -> void: port_select_2 = node_select.get_node2(0, 4).text.hex_to_int() flag_read_isa = true func _on_button_write() -> void: port_select = node_select.get_node2(0, 2).text.hex_to_int() _on_written_port(node_select.get_node2(2, 1).text) flag_write_isa = true func _on_button_write_2() -> void: port_select_2 = node_select.get_node2(0, 4).text.hex_to_int() _on_written_port_2(node_select.get_node2(2, 3).text) flag_write_isa = true func save_settings(): var file = FileAccess.open("user://constants.txt", FileAccess.WRITE) if file: file.store_line(address) # Сохранить IP-адрес file.store_line(str(port)) # Сохранить порт file.store_line(str(port_select)) # Сохранить базовый адрес file.close()