365 lines
15 KiB
GDScript
365 lines
15 KiB
GDScript
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:
|
||
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()
|