From 7f3f457224a77afab321ca9fbaf233e6c0fe4c50 Mon Sep 17 00:00:00 2001 From: hakueon Date: Mon, 14 Apr 2025 09:49:57 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=ED=94=84=EB=A1=9C=EB=B3=B4=20=EC=BB=A4?= =?UTF-8?q?=EB=84=A5=ED=8A=B8=20=EB=9D=BC=EC=9D=B4=ED=8A=B8=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images/hw_lite/alux_proboconnect_lite.png | Bin 0 -> 52160 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/hw_lite/alux_proboconnect_lite.png diff --git a/images/hw_lite/alux_proboconnect_lite.png b/images/hw_lite/alux_proboconnect_lite.png new file mode 100644 index 0000000000000000000000000000000000000000..d40b0e34479460b46f6a0c1bf41126b6a9788f80 GIT binary patch literal 52160 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 D9+ Date: Mon, 14 Apr 2025 16:22:06 +0900 Subject: [PATCH 2/2] =?UTF-8?q?ProboConnectLite=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hardwareLite/block_alux_connect_lite.js | 5478 +++++++++++++++++ .../metadata_alux_connect_lite.json | 9 + 2 files changed, 5487 insertions(+) create mode 100644 src/playground/blocks/hardwareLite/block_alux_connect_lite.js create mode 100644 src/playground/blocks/hardwareLite/metadata_alux_connect_lite.json diff --git a/src/playground/blocks/hardwareLite/block_alux_connect_lite.js b/src/playground/blocks/hardwareLite/block_alux_connect_lite.js new file mode 100644 index 0000000000..a664da4c39 --- /dev/null +++ b/src/playground/blocks/hardwareLite/block_alux_connect_lite.js @@ -0,0 +1,5478 @@ +'use strict'; + +const _throttle = require('lodash/throttle'); + +(function() { + const CONNECT_INDEX = 0x32; //50 + const RELEASE_VERSION = 17; + const SERIAL_INTERVAL = 32; + const EVENT_INTERVAL = 16; + const SEND_PACKET_LENGTH = 22; + const RECEIVED_PACKET_LENGTH = 26; + Entry.ProboConnectLite = new (class ProboConnectLite { + constructor() { + this.id = '270101'; + this.name = 'ProboConnectLite'; + this.url = 'https://imssam.me'; + this.imageName = 'alux_proboconnect_lite.png'; + this.title = { + ko: '프로보 커넥트', + en: 'Probo Connect', + }; + this.portData = { + baudRate: 115200, + duration: SERIAL_INTERVAL, + dataBits: 8, + parity: 'none', + stopBits: 1, + bufferSize: 128, + connectionType: 'bytestream', + constantServing: 'ReadOnly', + }; + + this.Color = { + Red: { Min: 13, Max: 37 }, + Green: { Min: 38, Max: 62 }, + Blue: { Min: 63, Max: 87 }, + Yellow: { Min: 88, Max: 112 }, + Black: { Min: 113, Max: 137 }, + White: { Min: 138, Max: 162 }, + }; + this.MultiSwitch = { + Key1: { Min: 1, Max: 19 }, + Key2: { Min: 26, Max: 44 }, + Key3: { Min: 53, Max: 77 }, + Key4: { Min: 83, Max: 101 }, + Key5: { Min: 107, Max: 125 }, + Key6: { Min: 139, Max: 157 }, + Key7: { Min: 160, Max: 178 }, + Key8: { Min: 191, Max: 209 } + }; + this.Note = { + n32: 48, + n16: 96, n16d: 144, n16t: 64, + n8: 192, n8d: 288, n8t: 128, + n4: 384, n4d: 576, n4t: 256, + n2: 768, n2d: 1152, n2t: 512, + n1: 1536, + }; + this.Rgb = { + Off: 0, + On: { Red: 1, Yellow: 12, Green: 23, Cyan: 34, Blue: 45, Magenta: 56, White: 67 }, + Dimming: { + Red: 90, + Yellow: 91, + Green: 92, + Cyan: 93, + Blue: 94, + Magenta: 95, + White: 96 + } + }; + this.Melody = [0, 35391, 33405, 31530, 29760, 28090, 26513, 25025, 23621, 22295, 21044, 19863, 18748]; + this.Track = [ + [0x451F, 0x3D95, 0x36DD, 0x33C8, 0x2E22, 0x291A, 0x249E], // Start : size 7, + [0x228F, 0x249E, 0x291A, 0x2E22, 0x33C8, 0x36DD, 0x3D95, 0x451F], // End : size 8, + [0x228F, 0x1B6E, 0x1711, 0x1147 ], // LevelUp : size 4, + [0x1147, 0x1711, 0x1B6E, 0x228F ], // LevelDwon : size 4, + ]; + + const eventSetting = { + leading: true, + trailing: false + } + this.remoteEvent = _throttle( + () => { + Entry.engine.fireEvent('connectlite_event_remote_input'); + }, + EVENT_INTERVAL, + eventSetting + ); + this.digitalEvent = _throttle( + () => { + Entry.engine.fireEvent('connectlite_event_digital_input'); + } + , + EVENT_INTERVAL, + eventSetting + ); + + this.qRear = 0; + this.qFront = 0; + this.qSize = 128; + this.qBuffer = new Uint8Array(this.qSize + 2).fill(-1); + this.inputPacket = new Uint8Array(RECEIVED_PACKET_LENGTH).fill(-1); + this.pLength = 0; // packet length + this.process = false; // packet process + + this.version = 0; + this.sendFlag = true; + + this.blockMenuBlocks = [ + //dropdown + 'connectlite_dropdown_remote_key', + 'connectlite_dropdown_digital_key', + 'connectlite_dropdown_analog_key', + 'connectlite_dropdown_setting_sensor_key', + 'connectlite_dropdown_inNcom_sensor_key', + 'connectlite_dropdown_sensor_color_key', + 'connectlite_dropdown_rgb_color_key', + 'connectlite_dropdown_sensor_angle_key', + 'connectlite_dropdown_multikey_key', + 'connectlite_dropdown_extension_digital_key', + 'connectlite_dropdown_extension_analog_key', + 'connectlite_dropdown_dc_1_all_key', + 'connectlite_dropdown_port_1_4_key', + 'connectlite_dropdown_on_off_key', + 'connectlite_dropdown_velocity_key', + 'connectlite_dropdown_servo_position_key', + 'connectlite_dropdown_note_key', + 'connectlite_dropdown_time_1_key', + 'connectlite_dropdown_time_2_key', + 'connectlite_dropdown_time_3', + 'connectlite_dropdown_pitch_key', + 'connectlite_dropdown_melody_key', + + //event + 'connectlite_when_press_remote_key', + 'connectlite_when_input_digital_value', + + //setting + 'connectlite_set_sensor_setting', + + //input + 'connectlite_is_remote_key', + 'connectlite_is_digital_value', + 'connectlite_is_extension_digital_input', + 'connectlite_get_analog_value', + 'connectlite_get_extension_analog_input', + 'connectlite_get_tri_axis_acceler_x', + 'connectlite_get_tri_axis_acceler_y', + 'connectlite_get_tri_axis_acceler_z', + 'connectlite_get_value_mapping', + 'connectlite_is_color_value', + 'connectlite_get_color_value', + 'connectlite_set_infinite_setting', + 'connectlite_get_infinite_mm_diameter', + 'connectlite_get_infinite_transform_input', + 'connectlite_is_multi_sensor', + 'connectlite_is_multi_switch', + 'connectlite_set_eeprom_call', + 'connectlite_get_eeprom_address_value', + + //output + 'connectlite_set_dc_output', + 'connectlite_set_servo_output', + 'connectlite_set_s_dc_output', + 'connectlite_set_port_output', + 'connectlite_play_melody_note_output', + 'connectlite_play_melody_sec_output', + 'connectlite_play_melody_output', + 'connectlite_play_value_sec_output', + 'connectlite_play_value_output', + 'connectlite_play_melody_track_output', + 'connectlite_play_melody_off', + 'connectlite_set_rgbled_on_output', + 'connectlite_set_rgbled_off_output', + 'connectlite_set_rgbled_flashing_output', + 'connectlite_set_rgbled_dimming_output', + 'connectlite_set_fnd_output', + 'connectlite_set_fnd_off', + + //EEPROM + 'connectlite_set_eeprom_write', + ]; + } + + setLanguage() { + return { + ko: { + template: { + connectlite_item_switch: '스위치', + connectlite_item_infrared: '적외선', + connectlite_item_magnetic: '자석', + connectlite_item_rotation: '회전', + connectlite_item_color: '컬러', + connectlite_item_acceleration: '가속도', + connectlite_item_ultrasonic: '초음파', + connectlite_item_heart_rate: '심박', + connectlite_item_illuminance: '조도', + connectlite_item_temperature: '온도', + connectlite_item_sound: '소리', + connectlite_item_tilt: '기울기', + connectlite_item_pressure: '압력', + connectlite_item_multi_touch: '멀티키', + connectlite_item_compass: '나침반', + connectlite_item_tri_acceleration: '3가속', + connectlite_item_multi_switch: '분배기', + connectlite_item_infinite_rotation: '무한회전', + connectlite_item_extension_input: '확장입력', + connectlite_item_color_red: '빨간색', + connectlite_item_color_green: '초록색', + connectlite_item_color_blue: '파란색', + connectlite_item_color_cyan: '청녹색', + connectlite_item_color_magenta: '자홍색', + connectlite_item_color_yellow: '노란색', + connectlite_item_color_black: '검정색', + connectlite_item_color_white: '하얀색', + connectlite_item_value: '값', + connectlite_item_angle: '각도', + connectlite_item_absolute_angle: '절대각도', + connectlite_item_number_of_rotations: '회전 수', + connectlite_item_key_1: '키1', + connectlite_item_key_2: '키2', + connectlite_item_key_3: '키3', + connectlite_item_key_4: '키4', + connectlite_item_key_5: '키5', + connectlite_item_key_6: '키6', + connectlite_item_key_7: '키7', + connectlite_item_key_8: '키8', + connectlite_item_all: '모두', + connectlite_item_on: '켜기', + connectlite_item_off: '끄기', + connectlite_item_note_whole: '온', + connectlite_item_note_half: '2분', + connectlite_item_note_quarter: '4분', + connectlite_item_note_eighth: '8분', + connectlite_item_note_sixteenth: '16분', + connectlite_item_note_thirty_second: '32분', + connectlite_item_pitch_do: '도', + connectlite_item_pitch_do_sharp: '도#', + connectlite_item_pitch_re: '레', + connectlite_item_pitch_re_sharp: '레#', + connectlite_item_pitch_mi: '미', + connectlite_item_pitch_fa: '파', + connectlite_item_pitch_fa_sharp: '파#', + connectlite_item_pitch_sol: '솔', + connectlite_item_pitch_sol_sharp: '솔#', + connectlite_item_pitch_ra: '라', + connectlite_item_pitch_ra_sharp: '라#', + connectlite_item_pitch_si: '시', + connectlite_item_melody_start: '시작음', + connectlite_item_melody_end: '종료음', + connectlite_item_melody_level_up: '레벨 업', + connectlite_item_melody_level_down: '레벨 다운', + + connectlite_item_error: '오류', + connectlite_item_nothing: '없음', + + connectlite_when_press_remote_key: '%1 리모컨 %2 키를 눌렀을 때', + connectlite_when_input_digital_value: '%1 디지털 입력 %2 이(가) 들어왔을 때', + + connectlite_set_sensor_setting: '입력포트 %1 을(를) %2 센서로 설정 %3', + + connectlite_is_remote_key: '리모컨 입력 %1', + connectlite_is_digital_value: '디지털 입력 %1', + connectlite_is_extension_digital_input: '확장 디지털 입력 %1 의 %2', + connectlite_get_analog_value: '아날로그 입력 %1', + connectlite_get_extension_analog_input: '확장 아날로그 입력 %1 의 %2', + connectlite_get_tri_axis_acceler_x: '3가속도 %1의 X축', + connectlite_get_tri_axis_acceler_y: '3가속도 %1의 Y축', + connectlite_get_tri_axis_acceler_z: '3가속도 %1의 Z축', + connectlite_get_value_mapping: '%1 의 %2 ~ %3 값을 %4 ~ %5 (으)로 변환', + connectlite_is_color_value: '컬러 센서 %1 이(가) %2 인가?', + connectlite_get_color_value: '컬러 센서 %1 의 색상', + connectlite_set_infinite_setting: '%1 센서 %2 을 %3 값으로 정하기 %4', + connectlite_get_infinite_mm_diameter: '%1 센서 %2 지름 %3 의 mm 값', + connectlite_get_infinite_transform_input: '%1 센서 %2 의 %3', + connectlite_is_multi_sensor: '멀티키 센서 %1의 %2', + connectlite_is_multi_switch: '분배 스위치 %1의 %2', + connectlite_set_eeprom_call: 'EEPROM %1 주소의 값 호출하기 %2', + connectlite_get_eeprom_address_value: 'EEPROM 주소의 값', + + connectlite_set_port_output: '출력핀 %1 을(를) %2 %3', + connectlite_set_servo_output: '서보 모터 %1 의 위치를 %2 로 이동 %3', + connectlite_set_s_dc_output: 'S 모터 %1 을(를) %2 속도로 회전 %3', + connectlite_set_dc_output: 'DC 모터 %1 을(를) %2 속도로 회전 %3', + connectlite_play_melody_note_output: '%1 을(를) %2 음표로 연주하기 %3', + connectlite_play_melody_sec_output: '%1 을(를) %2 초 동안 연주하기 %3', + connectlite_play_melody_output: '%1 을(를) 연주하기 %2', + connectlite_play_value_sec_output: '%1 값을(를) %2 초 동안 연주하기 %3', + connectlite_play_value_output: '%1 값을(를) 연주하기 %2', + connectlite_play_melody_track_output: '%1 을(를) %2초 간격으로 재생하기 %3', + connectlite_play_melody_off: '멜로디 중지 %1', + connectlite_set_rgbled_on_output: 'RGB LED %1 을(를) %2 으로 켜기 %3', + connectlite_set_rgbled_off_output: 'RGB LED %1 을(를) 끄기 %2', + connectlite_set_rgbled_dimming_output: 'RGB LED %1 을(를) %2 으로 디밍 %3', + connectlite_set_rgbled_flashing_output: 'RGB LED %1 %2 으로 %3 초 간격 %4', + connectlite_set_fnd_output: 'FND를 %1 (으)로 설정 %2', + connectlite_set_fnd_off: 'FND 끄기 %1', + connectlite_set_eeprom_write: 'EEPROM %1 주소에 %2 값 설정하기 %3', + }, + Device: { + probo_connect_lite: '프로보 커넥트', + }, + Menus: { + probo_connect_lite: '프로보 커넥트', + }, + }, + en: { + + template: { + connectlite_item_switch: 'Switch', + connectlite_item_infrared: 'Infrared', + connectlite_item_magnetic: 'Magnetic', + connectlite_item_rotation: 'Rotation', + connectlite_item_color: 'Color', + connectlite_item_acceleration: 'Acceleration', + connectlite_item_ultrasonic: 'Ultrasonic', + connectlite_item_heart_rate: 'Heart Rate', + connectlite_item_illuminance: 'Illuminance', + connectlite_item_temperature: 'Temperature', + connectlite_item_sound: 'Sound', + connectlite_item_tilt: 'Tilt', + connectlite_item_pressure: 'Pressure', + connectlite_item_multi_touch: 'Multi Touch', + connectlite_item_compass: 'Compass', + connectlite_item_tri_acceleration: '3Acceleration', + connectlite_item_multi_switch: 'Multi Switch', + connectlite_item_infinite_rotation: 'Infinite Rotation', + connectlite_item_extension_input: 'Extension Input', + connectlite_item_color_red: 'Red', + connectlite_item_color_green: 'Green', + connectlite_item_color_blue: 'Blue', + connectlite_item_color_cyan: 'Cyan', + connectlite_item_color_magenta: 'Magenta', + connectlite_item_color_yellow: 'Yellow', + connectlite_item_color_black: 'Black', + connectlite_item_color_white: 'White', + connectlite_item_value: 'Value', + connectlite_item_angle: 'Angle', + connectlite_item_absolute_angle: 'Absolute Angle', + connectlite_item_number_of_rotations: 'Number of Rotations', + connectlite_item_key_1: 'Key1', + connectlite_item_key_2: 'Key2', + connectlite_item_key_3: 'Key3', + connectlite_item_key_4: 'Key4', + connectlite_item_key_5: 'Key5', + connectlite_item_key_6: 'Key6', + connectlite_item_key_7: 'Key7', + connectlite_item_key_8: 'Key8', + connectlite_item_all: 'All', + connectlite_item_on: 'On', + connectlite_item_off: 'Off', + connectlite_item_note_whole: 'Whole', + connectlite_item_note_half: 'Half', + connectlite_item_note_quarter: 'Quarter', + connectlite_item_note_eighth: 'Eighth', + connectlite_item_note_sixteenth: 'Sixteenth', + connectlite_item_note_thirty_second: 'Thirty-Second', + connectlite_item_pitch_do: 'do', + connectlite_item_pitch_do_sharp: 'xdo', + connectlite_item_pitch_re: 're', + connectlite_item_pitch_re_sharp: 'xre', + connectlite_item_pitch_mi: 'mi', + connectlite_item_pitch_fa: 'fa', + connectlite_item_pitch_fa_sharp: 'xfa', + connectlite_item_pitch_sol: 'sol', + connectlite_item_pitch_sol_sharp: 'xsol', + connectlite_item_pitch_ra: 'ra', + connectlite_item_pitch_ra_sharp: 'xra', + connectlite_item_pitch_si: 'si', + connectlite_item_melody_start: 'Start', + connectlite_item_melody_end: 'End', + connectlite_item_melody_level_up: 'Level up', + connectlite_item_melody_level_down: 'Level down', + + connectlite_item_error: 'error', + connectlite_item_nothing: 'nothing', + + connectlite_when_press_remote_key: '%1 When %2 remote control key pressed', + connectlite_when_input_digital_value: '%1 When %2 digital pin input', + + connectlite_set_sensor_setting: 'Set input port %1 to %2 sensor %3', + + connectlite_is_remote_key: 'Remote control %1', + connectlite_is_digital_value: 'Read digital pin %1', + connectlite_is_extension_digital_input: 'Extension digital input %1 to %2', + connectlite_get_analog_value: 'Read analog pin %1', + connectlite_get_extension_analog_input: 'Extension analog input %1 to %2', + connectlite_get_tri_axis_acceler_x: '3acceleration %1 and X', + connectlite_get_tri_axis_acceler_y: '3acceleration %1 and Y', + connectlite_get_tri_axis_acceler_z: '3acceleration %1 and Z', + connectlite_get_value_mapping: '%1 to value %2 ~ %3 change %4 ~ %5', + connectlite_is_color_value: 'Is color sensor %1 %2 ?', + connectlite_get_color_value: 'Color of color sensor %1', + connectlite_set_infinite_setting: 'Set %1 sensor %2 to %3 value %4', + connectlite_get_infinite_mm_diameter: 'The move distance(in mm) when the %1 sensor %2 is %3 mm in diameter', + connectlite_get_infinite_transform_input: '%1 rotation sensor %2 to %3', + connectlite_is_multi_sensor: 'Multi sensor %1 key %2', + connectlite_is_multi_switch: 'A key number of the multi-switch sensor %1 = %2', + connectlite_set_eeprom_call:'Calling the value of EEPROM %1 address', + connectlite_get_eeprom_address_value: 'Value of EEPROM address', + + connectlite_set_dc_output: 'DC motor %1 velocity %2 %3', + connectlite_set_servo_output: 'Servo motor %1 position %2 %3', + connectlite_set_s_dc_output: 'Servo motor %1 speed %2 %3', + connectlite_set_port_output: 'Set digital pin %1 as %2 %3', + connectlite_play_melody_note_output: 'Play key %1 for %2 note %3', + connectlite_play_melody_sec_output: 'Play key %1 for %2 secs %3', + connectlite_play_melody_output: 'Play key %1 %2', + connectlite_play_value_sec_output: 'Play value %1 for %2 secs %3', + connectlite_play_value_output: 'Play value %1 %2', + connectlite_play_melody_track_output: 'Play sound %1 for %2 secs %3', + connectlite_play_melody_off: 'Stop tone %1', + connectlite_set_rgbled_on_output: 'Turn on RGB LED %1 to %2 %3', + connectlite_set_rgbled_off_output: 'Turn off RGB LED %1 %2', + connectlite_set_rgbled_dimming_output: 'Dimming RGB LED %1 to %2 %3', + connectlite_set_rgbled_flashing_output: 'RGB LED %1 Blinking %2 at %3 second intervals %4', + connectlite_set_fnd_output: 'Set FND to %1 %2', + connectlite_set_fnd_off: 'Turn off FND %1', + connectlite_set_eeprom_write: 'Set EEPROM %1 address to %2 %3', + }, + Device: { + probo_connect_lite: 'Probo Connect', + }, + Menus: { + probo_connect_lite: 'Probo Connect', + }, + }, + }; + } + + // 시작하기 및 정지하기 시 기기상태를 초기화한다. + setZero() { + this.Infinite = { + Buff: { + AA1: 0, + AA2: 0, + AA3: 0, + AA4: 0 + }, + Count: { + AA1: 0, + AA2: 0, + AA3: 0, + AA4: 0 + }, + Start: { + AA1: 0, + AA2: 0, + AA3: 0, + AA4: 0 + } + }; + this.SensorSet = { + AA1: 0, + AA2: 0, + AA3: 0, + AA4: 0 + }; + this.InputData = { + Analog: { + AA1: 0, + AA2: 0, + AA3: 0, + AA4: 0 + }, + Digital: { + A1: 0, + A2: 0, + A3: 0, + A4: 0, + FEA1: 0, + FEA2: 0, + FEA3: 0, + FEA4: 0, + REA1: 0, + REA2: 0, + REA3: 0, + REA4: 0, + BEA1: 0, + BEA2: 0, + BEA3: 0, + BEA4: 0 + }, + Remote: { + R_1: 0, + R_2: 0, + R_3: 0, + R_4: 0, + R_5: 0, + R_6: 0, + R_7: 0, + R_8: 0, + R_L1: 0, + R_L2: 0, + R_R1: 0, + R_R2: 0 + }, + EEPROM: { + EC: 0, + EEPR2: 0, + EEPR1: 0 + }, + Infinite:{ + ROTATION_1: 0, + ROTATION_2: 0, + ROTATION_3: 0, + ROTATION_4: 0 + }, + Acceler:{ + AXIS_X1: 0, + AXIS_X2: 0, + AXIS_X3: 0, + AXIS_X4: 0, + AXIS_Y1: 0, + AXIS_Y2: 0, + AXIS_Y3: 0, + AXIS_Y4: 0, + AXIS_Z1: 0, + AXIS_Z2: 0, + AXIS_Z3: 0, + AXIS_Z4: 0 + } + }; + this.RemoteData = { + B1: 0, + B2: 0, + B3: 0, + B4: 0, + Servo1: 0, + Servo2: 0, + Servo3: 0, + Servo4: 0, + DC1: 0, + DC2: 0, + DC3: 0, + DC4: 0, + MEL2: 0, + MEL1: 0, + FND: 100, + EEPR4: 0, + EEPR3: 0, + EEPR2: 0, + EEPR1: 0, + ASET2: 0, + ASET1: 0 + }; + this.EdgeFlag = { + FEA1: 0, + FEA2: 0, + FEA3: 0, + FEA4: 0, + REA1: 0, + REA2: 0, + REA3: 0, + REA4: 0, + BEA1: 0, + BEA2: 0, + BEA3: 0, + BEA4: 0 + }; + this.EEPROM = { + Buff: 0, + Count: 0 + }; + + if (Entry.hwLite && Entry.hwLite.serial) { + Entry.hwLite.serial.update(); + }; + } + + // 하드웨어 연결 후 초기화한다. + async initialHandshake() { + const modePacket = new Uint8Array(2).fill(0); + modePacket[0] = 0x63; + modePacket[1] = 0x36; + + while(true) { + const response = await Entry.hwLite.serial.sendAsyncWithThrottle(modePacket); + if (response[0] !== CONNECT_INDEX) { + modePacket[0] = 0x24; + modePacket[1] = 0x42; + } else { + this.version = (response.length === 1) + ? 0 + : response[1]; + await Entry.Utils.sleep(1000); + break; + } + await Entry.Utils.sleep(100); + } + + Entry.addEventListener('run', this.handleRemoteEventInterval.bind(this)); + Entry.addEventListener('run', this.handleDigitalEventInterval.bind(this)); + Entry.addEventListener('beforeStop', clearInterval(this.remoteEventIntervalId)); + Entry.addEventListener('beforeStop', clearInterval(this.digitalEventIntervalId)); + + this.setZero(); + + if (this.version === 0) { + const packet = await Entry.hwLite.serial.reader.read(); + this.version = packet.value[0]; + if (this.version !== RELEASE_VERSION) { + const ko = `펌웨어를 업데이트 하세요.\n`; + const en = `(Please, Update your firmware.)\n`; + const version = ` - 현재(now): v.${this.version}\n - 최신(latest): v.${RELEASE_VERSION}`; + alert(`${ko}${en}${version}`); + } + } + + return true; + } + + handleRemoteEventInterval() { + this.remoteEventIntervalId = setInterval(this.remoteEvent.bind(this), EVENT_INTERVAL); + } + + handleDigitalEventInterval() { + this.digitalEventIntervalId = setInterval(this.digitalEvent.bind(this), EVENT_INTERVAL); + } + + // 디바이스에서 값을 읽어온다. + handleLocalData(buffer) { + buffer.forEach(b => this.qEnqueue(b)); + + while(this.qCount() >= this.inputPacket.length) { + if (!this.process) { + while(this.qCount() > 0) { + if (this.inputPacket[0] !== 0xCD) { + this.inputPacket[0] = this.qDequeue(); + } else if (this.inputPacket[1] !== 0xDA) { + this.inputPacket[1] = this.qDequeue(); + } else { + this.inputPacket[2] = this.qDequeue(); + this.pLength = this.inputPacket[2] + 3; + this.process = true; + break; + } + } + } + + if (this.process && (this.qCount() >= this.pLength)) { + for (let i = 3; i < this.pLength; i++) { + this.inputPacket[i] = this.qDequeue(); + } + if (this.checksumHandle(this.inputPacket)) { + this.processInputPacket(this.inputPacket); + } + + this.inputPacket = new Uint8Array(RECEIVED_PACKET_LENGTH).fill(-1); + this.process = false; + this.sendFlag = true; + this.pLength = 0; + } + } + + if (this.sendFlag) { + setTimeout( + () => { + if (Entry.hwLite && Entry.hwLite.serial) { + Entry.hwLite.serial.update(); + this.sendFlag = false; + } + }, + SERIAL_INTERVAL + ); + }; + } + + //디바이스에 값을 쓴다. + requestLocalData() { + if (this.sendFlag) { + return this.generateOutputPacket(this.RemoteData); + } + } + + qEnqueue(data) { + this.qBuffer[this.qRear] = data; + this.qRear = (this.qRear + 1) % this.qSize + } + + qDequeue() { + const data = this.qBuffer[this.qFront]; + this.qBuffer[this.qFront] = -1; + this.qFront = (this.qFront + 1) % this.qSize; + return data; + } + + qCount() { + return (this.qFront <= this.qRear) + ? (this.qRear - this.qFront) + : (this.qSize - this.qFront + this.qRear); + } + + checksumRequest(packet) { + const length = packet[2] + 2; + let checker = 0; + for(let i = 3; i < length; i++) { + checker += packet[i]; + } + return (checker & 0xFF); + + } + + checksumHandle(packet) { + let checker = 0; + const length = packet[2] + 2; + for(let i = 3; i < length ; i++ ) { + checker += packet[i]; + } + return (packet[length] === (checker & 0xFF)) + } + + processInputPacket(packet) { + const digitalByte1 = packet[8]; + const digitalByte2 = packet[9]; + const remoteByte1 = packet[10]; + const remoteByte2 = packet[11]; + const rotationByte = packet[16]; + + this.InputData.Analog.AA1 = packet[4]; + this.InputData.Analog.AA2 = packet[5]; + this.InputData.Analog.AA3 = packet[6]; + this.InputData.Analog.AA4 = packet[7]; + + this.InputData.Digital.A4 = (digitalByte1 >> 7) & 0x01; + this.InputData.Digital.A3 = (digitalByte1 >> 6) & 0x01; + this.InputData.Digital.A2 = (digitalByte1 >> 5) & 0x01; + this.InputData.Digital.A1 = (digitalByte1 >> 4) & 0x01; + this.InputData.Digital.FEA4 = (digitalByte1 >> 3) & 0x01; + this.InputData.Digital.FEA3 = (digitalByte1 >> 2) & 0x01; + this.InputData.Digital.FEA2 = (digitalByte1 >> 1) & 0x01; + this.InputData.Digital.FEA1 = digitalByte1 & 0x01; + this.InputData.Digital.REA4 = (digitalByte2 >> 7) & 0x01; + this.InputData.Digital.REA3 = (digitalByte2 >> 6) & 0x01; + this.InputData.Digital.REA2 = (digitalByte2 >> 5) & 0x01; + this.InputData.Digital.REA1 = (digitalByte2 >> 4) & 0x01; + this.InputData.Digital.BEA4 = (digitalByte2 >> 3) & 0x01; + this.InputData.Digital.BEA3 = (digitalByte2 >> 2) & 0x01; + this.InputData.Digital.BEA2 = (digitalByte2 >> 1) & 0x01; + this.InputData.Digital.BEA1 = digitalByte2 & 0x01; + + this.InputData.Remote.R_3 = (remoteByte1 >> 7) & 0x01; + this.InputData.Remote.R_2 = (remoteByte1 >> 6) & 0x01; + this.InputData.Remote.R_4 = (remoteByte1 >> 5) & 0x01; + this.InputData.Remote.R_1 = (remoteByte1 >> 4) & 0x01; + this.InputData.Remote.R_7 = (remoteByte2 >> 7) & 0x01; + this.InputData.Remote.R_6 = (remoteByte2 >> 6) & 0x01; + this.InputData.Remote.R_8 = (remoteByte2 >> 5) & 0x01; + this.InputData.Remote.R_5 = (remoteByte2 >> 4) & 0x01; + this.InputData.Remote.R_R1 = (remoteByte2 >> 3) & 0x01; + this.InputData.Remote.R_L1 = (remoteByte2 >> 2) & 0x01; + this.InputData.Remote.R_R2 = (remoteByte2 >> 1) & 0x01; + this.InputData.Remote.R_L2 = remoteByte2 & 0x01; + + this.InputData.EEPROM.EC = packet[13]; + this.InputData.EEPROM.EEPR2 = packet[14]; + this.InputData.EEPROM.EEPR1 = packet[15]; + + this.InputData.Infinite.ROTATION_1 = (rotationByte >> 6) & 0x0C; + this.InputData.Infinite.ROTATION_2 = (rotationByte >> 4) & 0x0C; + this.InputData.Infinite.ROTATION_3 = (rotationByte >> 2) & 0x0C; + this.InputData.Infinite.ROTATION_4 = rotationByte & 0x03; + + this.InputData.Acceler.AXIS_X1 = packet[4]; + this.InputData.Acceler.AXIS_X2 = packet[5]; + this.InputData.Acceler.AXIS_X3 = packet[6]; + this.InputData.Acceler.AXIS_X4 = packet[7]; + + this.InputData.Acceler.AXIS_Y1 = packet[17]; + this.InputData.Acceler.AXIS_Y2 = packet[19]; + this.InputData.Acceler.AXIS_Y3 = packet[21]; + this.InputData.Acceler.AXIS_Y4 = packet[23]; + + this.InputData.Acceler.AXIS_Z1 = packet[18]; + this.InputData.Acceler.AXIS_Z2 = packet[20]; + this.InputData.Acceler.AXIS_Z3 = packet[22]; + this.InputData.Acceler.AXIS_Z4 = packet[24]; + } + + generateOutputPacket(remoteData) { + + const outputPacket = new Uint8Array(SEND_PACKET_LENGTH).fill(-1); + + outputPacket[0] = 0xAD; + outputPacket[1] = 0xDA; + outputPacket[2] = outputPacket.length - 3; + + outputPacket[3] = 0xF0 | (remoteData.B4 << 3) | (remoteData.B3 << 2) | (remoteData.B2 << 1) | remoteData.B1; + + outputPacket[4] = remoteData.Servo1; + outputPacket[5] = remoteData.Servo2; + outputPacket[6] = remoteData.Servo3; + outputPacket[7] = remoteData.Servo4; + + outputPacket[8] = remoteData.DC1; + outputPacket[9] = remoteData.DC2; + outputPacket[10] = remoteData.DC3; + outputPacket[11] = remoteData.DC4; + + outputPacket[12] = remoteData.MEL2; + outputPacket[13] = remoteData.MEL1; + + outputPacket[14] = remoteData.FND; + + outputPacket[15] = remoteData.EEPR4; + outputPacket[16] = remoteData.EEPR3; + outputPacket[17] = remoteData.EEPR2; + outputPacket[18] = remoteData.EEPR1; + + outputPacket[19] = remoteData.ASET2; + outputPacket[20] = remoteData.ASET1; + + outputPacket[21] = this.checksumRequest(outputPacket); + + return outputPacket; + } + + getMonitorPort() { + return { ...this.InputData.Analog }; + } + + getRemoteKey(data) { + const num = Number(data); + + if (1 <= num && num <= 8) { + return `R_${num}`; + } else if (9 <= num && num <= 10) { + return `R_L${(num - 8)}`; + } else if (11 <= num && num <= 12) { + return `R_R${(num - 10)}`; + } else { + return data; + } + } + + getDigitalKey(data) { + const num = Number(data); + + if (1 <= num && num <= 4) { + return `A${num}`; + } else if (5 <= num && num <= 8) { + return `FEA${num - 4}`; + } else if (9 <= num && num <= 12) { + return `REA${num - 8}`; + } else if (13 <= num && num <= 16) { + return `BEA${num - 12}`; + } else { + return data; + } + } + + getDigitalStateValue(key) { + let value = false; + switch(key) { + case 'A1': + case 'A2': + case 'A3': + case 'A4': + value = (Entry.ProboConnectLite.InputData.Digital[key] === 1); + break; + default: + if (Entry.ProboConnectLite.InputData.Digital[key] === 1) { + if (Entry.ProboConnectLite.EdgeFlag[key] === 0) { + Entry.ProboConnectLite.EdgeFlag[key] = 1; + value = true; + } + } else { + Entry.ProboConnectLite.EdgeFlag[key] = 0; + } + break; + } + + return value; + } + + getAnalogKey(data) { + const num = Number(data); + + if (1 <= num && num <= 4) { + return `AA${num}`; + } else { + return data; + } + } + + getSettingSensorValue(key) { + switch (key) { + case '1': // 스위치 + case '2': // 적외선 + case '3': // 자석 + case '16': // 분배기 + case Lang.template.connectlite_item_switch: // 스위치 + case Lang.template.connectlite_item_infrared: // 적외선 + case Lang.template.connectlite_item_magnetic: // 자석 + case Lang.template.connectlite_item_multi_switch: // 분배기 + return 1; + case '4': // 회전 + case '7': // 조도 + case '9': // 초음파 + case Lang.template.connectlite_item_rotation: // 회전 + case Lang.template.connectlite_item_illuminance: // 조도 + case Lang.template.connectlite_item_ultrasonic: // 초음파 + return 2; + case '10': // 소리 + case Lang.template.connectlite_item_sound: // 소리 + return 3; + case '11': // 기울기 + case Lang.template.connectlite_item_tilt: // 기울기 + return 4; + case '12': // 압력 + case Lang.template.connectlite_item_pressure: // 압력 + return 5; + case '8': // 심박 + case Lang.template.connectlite_item_heart_rate: // 심박 + return 6; + case '5': // 컬러 + case Lang.template.connectlite_item_color: // 컬러 + return 7; + case '6': // 가속도 + case Lang.template.connectlite_item_acceleration: // 가속도 + return 8; + case '14': // 나침반 + case '15': // 3축 가속도 + case '17': // 확장 입력 + case Lang.template.connectlite_item_compass: + case Lang.template.connectlite_item_tri_acceleration: + case Lang.template.connectlite_item_extension_input: + return 9; + case '13': // 멀티터치(멀티키) + case Lang.template.connectlite_item_multi_touch: // 멀티터치(멀티키) + return 11; + default: + return key; + } + } + + getAxisKey(data, axis) { + switch (data) { + case 'AA1': + case 'AA2': + case 'AA3': + case 'AA4': + data = data.substr(2, 2); + break; + } + + return `AXIS_${axis}${data}`; + } + + getMultiKeyValue(key) { + const num = Number(key); + + if (1 <= num && num <= 8) { + return (num - 1); + } else { + switch (key) { + case Lang.template.connectlite_item_key_1: + return 0; + case Lang.template.connectlite_item_key_2: + return 1; + case Lang.template.connectlite_item_key_3: + return 2; + case Lang.template.connectlite_item_key_4: + return 3; + case Lang.template.connectlite_item_key_5: + return 4; + case Lang.template.connectlite_item_key_6: + return 5; + case Lang.template.connectlite_item_key_7: + return 6; + case Lang.template.connectlite_item_key_8: + return 7; + default: + return key; + } + } + } + + getExtentionDigitalValue(key) { + const num = Number(key); + if (1 <= num && num <= 8) { + return (num - 1); + } else if (9 <= num && num <= 16) { + return (num - 9); + } else { + switch (key) { + case 'EA1': + case 'ET1': + return 0; + case 'EA2': + case 'ET2': + return 1; + case 'EA3': + case 'ET3': + return 2; + case 'EA4': + case 'ET4': + return 3; + case 'EA5': + case 'ET5': + return 4; + case 'EA6': + case 'ET6': + return 5; + case 'EA7': + case 'ET7': + return 6; + case 'EA8': + case 'ET8': + return 7; + default: + return key; + } + } + } + + getExtentionAnalogKey(data) { + switch (data) { + case '1': + case 'EAA1': + return 'Y'; + case '2': + case 'EAA2': + return 'Z'; + default: + return data; + } + } + + getDckey(data) { + const num = Number(data); + + if (1 <= num && num <= 7) { + return `DC${num}`; + } else { + return data; + } + } + + getServoKey(data) { + const num = Number(data); + + if (1 <= num && num <= 4) { + return `Servo${num}`; + } else { + return data; + } + } + + getPortKey(data) { + const num = Number(data); + + if (1 <= num && num <= 4) { + return `B${num}`; + } else { + return data; + } + } + + getPortToggleValue(key) { + switch (key) { + case '1': + case Lang.template.connectlite_item_on: + return 1; + case '0': + case Lang.template.connectlite_item_off: + return 0; + default: + return key; + } + } + + getSensorAngleKey(data) { + switch (data) { + case '1': + case Lang.template.connectlite_item_value: + return 'IS1'; + case '2': + case Lang.template.connectlite_item_angle: + return 'IS2'; + case '3': + case Lang.template.connectlite_item_absolute_angle: + return 'IS3'; + case '4': + case Lang.template.connectlite_item_number_of_rotations: + return 'IS4'; + default: + return data; + } + } + + getPitchValue(pitch) { + // 배열의 인덱스 1번부터 음표 + const index = (pitch % 12) + 1; + + if (36 <= pitch && pitch <= 47) { + return Entry.ProboConnectLite.Melody[index]; + } else if (48 <= pitch && pitch <= 59) { + return Entry.ProboConnectLite.Melody[index] >> 1; + } else if (60 <= pitch && pitch <= 71) { + return Entry.ProboConnectLite.Melody[index] >> 2; + } else if (72 <= pitch && pitch <= 83) { + return Entry.ProboConnectLite.Melody[index] >> 3; + } else { + return Entry.ProboConnectLite.Melody[0]; + } + } + + getNoteKey(data) { + switch (data) { + case '1': + case Lang.template.connectlite_item_note_whole: + return 'n1'; + case '2': + case Lang.template.connectlite_item_note_half: + return 'n2'; + case '4': + case Lang.template.connectlite_item_note_quarter: + return 'n4'; + case '8': + case Lang.template.connectlite_item_note_eighth: + return 'n8'; + case '16': + case Lang.template.connectlite_item_note_sixteenth: + return 'n16'; + case '32': + case Lang.template.connectlite_item_note_thirty_second: + return 'n32'; + default: + return data; + } + } + + getMelodyValue(key) { + switch (key) { + case '1': + case Lang.template.connectlite_item_melody_start: + return 0; + case '2': + case Lang.template.connectlite_item_melody_end: + return 1; + case '3': + case Lang.template.connectlite_item_melody_level_up: + return 2; + case '4': + case Lang.template.connectlite_item_melody_level_down: + return 3; + default: + return key; + } + } + + getColorSensorKey(data) { + switch (data) { + case '1': + case Lang.template.connectlite_item_color_red: + return 'Red'; + case '2': + case Lang.template.connectlite_item_color_green: + return 'Green'; + case '3': + case Lang.template.connectlite_item_color_blue: + return 'Blue'; + case '4': + case Lang.template.connectlite_item_color_yellow: + return 'Yellow'; + case '5': + case Lang.template.connectlite_item_color_black: + return 'Black'; + case '6': + case Lang.template.connectlite_item_color_white: + return 'White'; + default: + return data; + } + } + + getRgbToggleValue(key) { + switch (key) { + case '0': + return this.Rgb.Off; + case '1': + case Lang.template.technicpowerlite_item_color_red: + return this.Rgb.On.Red; + case '2': + case Lang.template.technicpowerlite_item_color_green: + return this.Rgb.On.Green; + case '3': + case Lang.template.technicpowerlite_item_color_blue: + return this.Rgb.On.Blue; + case '4': + case Lang.template.technicpowerlite_item_color_cyan: + return this.Rgb.On.Cyan; + case '5': + case Lang.template.technicpowerlite_item_color_magenta: + return this.Rgb.On.Magenta; + case '6': + case Lang.template.technicpowerlite_item_color_yellow: + return this.Rgb.On.Yellow; + case '7': + case Lang.template.technicpowerlite_item_color_white: + return this.Rgb.On.White; + default: + return key; + } + } + + getRgbTwinkleValue(key, sec) { + let twinkle = 0; + switch (sec) { + case 0.05: + twinkle += 1; + break; + case 0.1: + twinkle += 2; + break; + case 0.2: + twinkle += 3; + break; + case 0.5: + twinkle += 4; + break; + case 1: + twinkle += 5; + break; + } + + return this.getRgbToggleValue(key) + twinkle; + } + + getRgbDimmingValue(key) { + switch (key) { + case '1': + case Lang.template.technicpowerlite_item_color_red: + return this.Rgb.Dimming.Red; + case '2': + case Lang.template.technicpowerlite_item_color_green: + return this.Rgb.Dimming.Green; + case '3': + case Lang.template.technicpowerlite_item_color_blue: + return this.Rgb.Dimming.Blue; + case '4': + case Lang.template.technicpowerlite_item_color_cyan: + return this.Rgb.Dimming.Cyan; + case '5': + case Lang.template.technicpowerlite_item_color_magenta: + return this.Rgb.Dimming.Magenta; + case '6': + case Lang.template.technicpowerlite_item_color_yellow: + return this.Rgb.Dimming.Yellow; + case '7': + case Lang.template.technicpowerlite_item_color_white: + return this.Rgb.Dimming.White; + default: + return key; + } + } + + getBlocks() { + return { + ///======================================================================================== + /// Dropdown block + ///======================================================================================== + connectlite_dropdown_remote_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + ['R_1', '1'], + ['R_2', '2'], + ['R_3', '3'], + ['R_4', '4'], + ['R_5', '5'], + ['R_6', '6'], + ['R_7', '7'], + ['R_8', '8'], + ['R_L1', '9'], + ['R_L2', '10'], + ['R_R1', '11'], + ['R_R2', '12'], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringValue('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + ['R_1', '1'], + ['R_2', '2'], + ['R_3', '3'], + ['R_4', '4'], + ['R_5', '5'], + ['R_6', '6'], + ['R_7', '7'], + ['R_8', '8'], + ['R_L1', '9'], + ['R_L2', '10'], + ['R_R1', '11'], + ['R_R2', '12'], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_remote_key', + }, + ], + }, + }, + connectlite_dropdown_digital_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + ['A1', '1'], + ['A2', '2'], + ['A3', '3'], + ['A4', '4'], + ['FEA1', '5'], + ['FEA2', '6'], + ['FEA3', '7'], + ['FEA4', '8'], + ['REA1', '9'], + ['REA2', '10'], + ['REA3', '11'], + ['REA4', '12'], + ['BEA1', '13'], + ['BEA2', '14'], + ['BEA3', '15'], + ['BEA4', '16'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + ['A1', '1'], + ['A2', '2'], + ['A3', '3'], + ['A4', '4'], + ['FEA1', '5'], + ['FEA2', '6'], + ['FEA3', '7'], + ['FEA4', '8'], + ['REA1', '9'], + ['REA2', '10'], + ['REA3', '11'], + ['REA4', '12'], + ['BEA1', '13'], + ['BEA2', '14'], + ['BEA3', '15'], + ['BEA4', '16'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_digital_key', + }, + ], + } + }, + connectlite_dropdown_analog_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + ['AA1', '1'], + ['AA2', '2'], + ['AA3', '3'], + ['AA4', '4'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + ['AA1', '1'], + ['AA2', '2'], + ['AA3', '3'], + ['AA4', '4'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_analog_key', + }, + ], + }, + }, + connectlite_dropdown_setting_sensor_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_switch, '1'], + [Lang.template.connectlite_item_infrared, '2'], + [Lang.template.connectlite_item_magnetic, '3'], + [Lang.template.connectlite_item_rotation, '4'], + [Lang.template.connectlite_item_color, '5'], + [Lang.template.connectlite_item_acceleration, '6'], + [Lang.template.connectlite_item_ultrasonic, '7'], + [Lang.template.connectlite_item_heart_rate, '8'], + [Lang.template.connectlite_item_illuminance, '9'], + [Lang.template.connectlite_item_sound, '10'], + [Lang.template.connectlite_item_tilt, '11'], + [Lang.template.connectlite_item_pressure, '12'], + [Lang.template.connectlite_item_multi_touch, '13'], + [Lang.template.connectlite_item_compass, '14'], + [Lang.template.connectlite_item_tri_acceleration, '15'], + [Lang.template.connectlite_item_multi_switch, '16'], + [Lang.template.connectlite_item_extension_input, '17'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_switch, '1'], + [Lang.template.connectlite_item_infrared, '2'], + [Lang.template.connectlite_item_magnetic, '3'], + [Lang.template.connectlite_item_rotation, '4'], + [Lang.template.connectlite_item_color, '5'], + [Lang.template.connectlite_item_acceleration, '6'], + [Lang.template.connectlite_item_ultrasonic, '7'], + [Lang.template.connectlite_item_heart_rate, '8'], + [Lang.template.connectlite_item_illuminance, '9'], + [Lang.template.connectlite_item_sound, '10'], + [Lang.template.connectlite_item_tilt, '11'], + [Lang.template.connectlite_item_pressure, '12'], + [Lang.template.connectlite_item_multi_touch, '13'], + [Lang.template.connectlite_item_compass, '14'], + [Lang.template.connectlite_item_tri_acceleration, '15'], + [Lang.template.connectlite_item_multi_switch, '16'], + [Lang.template.connectlite_item_extension_input, '17'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_setting_sensor_key', + }, + ], + }, + }, + connectlite_dropdown_inNcom_sensor_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_infinite_rotation, '1'], + [Lang.template.connectlite_item_compass, '2'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_infinite_rotation, '1'], + [Lang.template.connectlite_item_compass, '2'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_inNcom_sensor_key', + }, + ], + }, + }, + connectlite_dropdown_sensor_color_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_color_red, '1'], + [Lang.template.connectlite_item_color_green, '2'], + [Lang.template.connectlite_item_color_blue, '3'], + [Lang.template.connectlite_item_color_yellow, '4'], + [Lang.template.connectlite_item_color_black, '5'], + [Lang.template.connectlite_item_color_white, '6'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_color_red, '1'], + [Lang.template.connectlite_item_color_green, '2'], + [Lang.template.connectlite_item_color_blue, '3'], + [Lang.template.connectlite_item_color_yellow, '4'], + [Lang.template.connectlite_item_color_black, '5'], + [Lang.template.connectlite_item_color_white, '6'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_sensor_color_key', + }, + ], + }, + }, + connectlite_dropdown_rgb_color_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_color_red, '1'], + [Lang.template.connectlite_item_color_green, '2'], + [Lang.template.connectlite_item_color_blue, '3'], + [Lang.template.connectlite_item_color_cyan, '4'], + [Lang.template.connectlite_item_color_magenta, '5'], + [Lang.template.connectlite_item_color_yellow, '6'], + [Lang.template.connectlite_item_color_white, '7'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_color_red, '1'], + [Lang.template.connectlite_item_color_green, '2'], + [Lang.template.connectlite_item_color_blue, '3'], + [Lang.template.connectlite_item_color_cyan, '4'], + [Lang.template.connectlite_item_color_magenta, '5'], + [Lang.template.connectlite_item_color_yellow, '6'], + [Lang.template.connectlite_item_color_white, '7'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_rgb_color_key', + }, + ], + }, + }, + connectlite_dropdown_sensor_angle_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_value, '1'], + [Lang.template.connectlite_item_angle, '2'], + [Lang.template.connectlite_item_absolute_angle, '3'], + [Lang.template.connectlite_item_number_of_rotations, '4'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_value, '1'], + [Lang.template.connectlite_item_angle, '2'], + [Lang.template.connectlite_item_absolute_angle, '3'], + [Lang.template.connectlite_item_number_of_rotations, '4'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_sensor_angle_key', + }, + ], + }, + }, + connectlite_dropdown_multikey_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_key_1, '1'], + [Lang.template.connectlite_item_key_2, '2'], + [Lang.template.connectlite_item_key_3, '3'], + [Lang.template.connectlite_item_key_4, '4'], + [Lang.template.connectlite_item_key_5, '5'], + [Lang.template.connectlite_item_key_6, '6'], + [Lang.template.connectlite_item_key_7, '7'], + [Lang.template.connectlite_item_key_8, '8'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_key_1, '1'], + [Lang.template.connectlite_item_key_2, '2'], + [Lang.template.connectlite_item_key_3, '3'], + [Lang.template.connectlite_item_key_4, '4'], + [Lang.template.connectlite_item_key_5, '5'], + [Lang.template.connectlite_item_key_6, '6'], + [Lang.template.connectlite_item_key_7, '7'], + [Lang.template.connectlite_item_key_8, '8'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_multikey_key', + }, + ], + }, + }, + connectlite_dropdown_extension_digital_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + ['EA1', '1'], + ['EA2', '2'], + ['EA3', '3'], + ['EA4', '4'], + ['EA5', '5'], + ['EA6', '6'], + ['EA7', '7'], + ['EA8', '8'], + ['ET1', '9'], + ['ET2', '10'], + ['ET3', '11'], + ['ET4', '12'], + ['ET5', '13'], + ['ET6', '14'], + ['ET7', '15'], + ['ET8', '16'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + ['EA1', '1'], + ['EA2', '2'], + ['EA3', '3'], + ['EA4', '4'], + ['EA5', '5'], + ['EA6', '6'], + ['EA7', '7'], + ['EA8', '8'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_extension_digital_key', + }, + ], + }, + }, + connectlite_dropdown_extension_analog_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + ['EAA1', '1'], + ['EAA2', '2'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + ['EAA1', '1'], + ['EAA2', '2'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_extension_analog_key', + }, + ], + }, + }, + connectlite_dropdown_dc_1_all_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['1,2', '5'], + ['3,4', '6'], + [Lang.template.connectlite_item_all, '7'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + null + ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['1,2', '5'], + ['3,4', '6'], + [Lang.template.connectlite_item_all, '7'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_dc_1_all_key', + }, + ], + }, + }, + connectlite_dropdown_velocity_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + ['20', '20'], + ['15', '15'], + ['10', '10'], + ['5', '5'], + ['0', '0'], + ['-5', '-5'], + ['-10', '-10'], + ['-15', '-15'], + ['-20', '-20'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + null + ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + ['20', '20'], + ['15', '15'], + ['10', '10'], + ['5', '5'], + ['0', '0'], + ['-5', '-5'], + ['-10', '-10'], + ['-15', '-15'], + ['-20', '-20'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_velocity_key', + }, + ], + }, + }, + connectlite_dropdown_servo_position_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['20', '20'], + ['40', '40'], + ['60', '60'], + ['80', '80'], + ['100', '100'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + null + ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['20', '20'], + ['40', '40'], + ['60', '60'], + ['80', '80'], + ['100', '100'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_servo_position_key', + }, + ], + }, + }, + connectlite_dropdown_port_1_4_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_port_1_4_key', + }, + ], + }, + }, + connectlite_dropdown_on_off_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_on, '1'], + [Lang.template.connectlite_item_off, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + events: {}, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_on, '1'], + [Lang.template.connectlite_item_off, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_on_off_key', + }, + ], + }, + }, + connectlite_dropdown_note_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_note_whole, '1'], + [Lang.template.connectlite_item_note_half, '2'], + [Lang.template.connectlite_item_note_quarter, '4'], + [Lang.template.connectlite_item_note_eighth, '8'], + [Lang.template.connectlite_item_note_sixteenth, '16'], + [Lang.template.connectlite_item_note_thirty_second, '32'], + ], + value: '4', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_note_whole, '1'], + [Lang.template.connectlite_item_note_half, '2'], + [Lang.template.connectlite_item_note_quarter, '4'], + [Lang.template.connectlite_item_note_eighth, '8'], + [Lang.template.connectlite_item_note_sixteenth, '16'], + [Lang.template.connectlite_item_note_thirty_second, '32'], + ], + value: '4', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_note_key', + }, + ], + }, + }, + connectlite_dropdown_time_1_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + ['0.1', '0.1'], + ['0.3', '0.3'], + ['0.5', '0.5'], + ['0.7', '0.7'], + ['1', '1'], + ['2', '2'], + ], + value: '0.5', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + null + ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + ['0.1', '0.1'], + ['0.3', '0.3'], + ['0.5', '0.5'], + ['0.7', '0.7'], + ['1', '1'], + ['2', '2'], + ], + value: '0.5', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_time_1_key', + }, + ], + }, + }, + connectlite_dropdown_time_2_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + ['0.1', '0.1'], + ['0.3', '0.3'], + ['0.5', '0.5'], + ['0.7', '0.7'], + ['1', '1'], + ['2', '2'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + null + ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + ['0.1', '0.1'], + ['0.3', '0.3'], + ['0.5', '0.5'], + ['0.7', '0.7'], + ['1', '1'], + ['2', '2'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_time_2_key', + }, + ], + }, + }, + connectlite_dropdown_time_3: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + ['0.05', '0.05'], + ['0.1', '0.1'], + ['0.2', '0.2'], + ['0.5', '0.5'], + ['1', '1'], + ], + value: '0.5', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + null + ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + ['0.05', '0.05'], + ['0.1', '0.1'], + ['0.2', '0.2'], + ['0.5', '0.5'], + ['1', '1'], + ], + value: '0.5', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_time_3', + }, + ], + }, + }, + connectlite_dropdown_pitch_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'DropdownExtra', + options: [ + [Lang.template.connectlite_item_pitch_do + ' (36)', '36'], + [Lang.template.connectlite_item_pitch_do_sharp + ' (37)', '37'], + [Lang.template.connectlite_item_pitch_re + ' (38)', '38'], + [Lang.template.connectlite_item_pitch_re_sharp + ' (39)', '39'], + [Lang.template.connectlite_item_pitch_mi + ' (40)', '40'], + [Lang.template.connectlite_item_pitch_fa + ' (41)', '41'], + [Lang.template.connectlite_item_pitch_fa_sharp + ' (42)', '42'], + [Lang.template.connectlite_item_pitch_sol + ' (43)', '43'], + [Lang.template.connectlite_item_pitch_sol_sharp + ' (44)', '44'], + [Lang.template.connectlite_item_pitch_ra + ' (45)', '45'], + [Lang.template.connectlite_item_pitch_ra_sharp + ' (46)', '46'], + [Lang.template.connectlite_item_pitch_si + ' (47)', '47'], + + [Lang.template.connectlite_item_pitch_do + ' (48)', '48'], + [Lang.template.connectlite_item_pitch_do_sharp + ' (49)', '49'], + [Lang.template.connectlite_item_pitch_re + ' (50)', '50'], + [Lang.template.connectlite_item_pitch_re_sharp + ' (51)', '51'], + [Lang.template.connectlite_item_pitch_mi + ' (52)', '52'], + [Lang.template.connectlite_item_pitch_fa + ' (53)', '53'], + [Lang.template.connectlite_item_pitch_fa_sharp + ' (54)', '54'], + [Lang.template.connectlite_item_pitch_sol + ' (55)', '55'], + [Lang.template.connectlite_item_pitch_sol_sharp + ' (56)', '56'], + [Lang.template.connectlite_item_pitch_ra + ' (57)', '57'], + [Lang.template.connectlite_item_pitch_ra_sharp + ' (58)', '58'], + [Lang.template.connectlite_item_pitch_si + ' (59)', '59'], + + [Lang.template.connectlite_item_pitch_do + ' (60)', '60'], + [Lang.template.connectlite_item_pitch_do_sharp + ' (61)', '61'], + [Lang.template.connectlite_item_pitch_re + ' (62)', '62'], + [Lang.template.connectlite_item_pitch_re_sharp + ' (63)', '63'], + [Lang.template.connectlite_item_pitch_mi + ' (64)', '64'], + [Lang.template.connectlite_item_pitch_fa + ' (65)', '65'], + [Lang.template.connectlite_item_pitch_fa_sharp + ' (66)', '66'], + [Lang.template.connectlite_item_pitch_sol + ' (67)', '67'], + [Lang.template.connectlite_item_pitch_sol_sharp + ' (68)', '68'], + [Lang.template.connectlite_item_pitch_ra + ' (69)', '69'], + [Lang.template.connectlite_item_pitch_ra_sharp + ' (70)', '70'], + [Lang.template.connectlite_item_pitch_si + ' (71)', '71'], + + [Lang.template.connectlite_item_pitch_do + ' (72)', '72'], + [Lang.template.connectlite_item_pitch_do_sharp + ' (73)', '73'], + [Lang.template.connectlite_item_pitch_re + ' (74)', '74'], + [Lang.template.connectlite_item_pitch_re_sharp + ' (75)', '75'], + [Lang.template.connectlite_item_pitch_mi + ' (76)', '76'], + [Lang.template.connectlite_item_pitch_fa + ' (77)', '77'], + [Lang.template.connectlite_item_pitch_fa_sharp + ' (78)', '78'], + [Lang.template.connectlite_item_pitch_sol + ' (79)', '79'], + [Lang.template.connectlite_item_pitch_sol_sharp + ' (80)', '80'], + [Lang.template.connectlite_item_pitch_ra + ' (81)', '81'], + [Lang.template.connectlite_item_pitch_ra_sharp + ' (82)', '82'], + [Lang.template.connectlite_item_pitch_si + ' (83)', '83'], + ], + value: '60', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + null + ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + const value = script.getStringField('PARAM0'); + return value; + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_pitch_do + ' (36)', '36'], + [Lang.template.connectlite_item_pitch_do_sharp + ' (37)', '37'], + [Lang.template.connectlite_item_pitch_re + ' (38)', '38'], + [Lang.template.connectlite_item_pitch_re_sharp + ' (39)', '39'], + [Lang.template.connectlite_item_pitch_mi + ' (40)', '40'], + [Lang.template.connectlite_item_pitch_fa + ' (41)', '41'], + [Lang.template.connectlite_item_pitch_fa_sharp + ' (42)', '42'], + [Lang.template.connectlite_item_pitch_sol + ' (43)', '43'], + [Lang.template.connectlite_item_pitch_sol_sharp + ' (44)', '44'], + [Lang.template.connectlite_item_pitch_ra + ' (45)', '45'], + [Lang.template.connectlite_item_pitch_ra_sharp + ' (46)', '46'], + [Lang.template.connectlite_item_pitch_si + ' (47)', '47'], + + [Lang.template.connectlite_item_pitch_do + ' (48)', '48'], + [Lang.template.connectlite_item_pitch_do_sharp + ' (49)', '49'], + [Lang.template.connectlite_item_pitch_re + ' (50)', '50'], + [Lang.template.connectlite_item_pitch_re_sharp + ' (51)', '51'], + [Lang.template.connectlite_item_pitch_mi + ' (52)', '52'], + [Lang.template.connectlite_item_pitch_fa + ' (53)', '53'], + [Lang.template.connectlite_item_pitch_fa_sharp + ' (54)', '54'], + [Lang.template.connectlite_item_pitch_sol + ' (55)', '55'], + [Lang.template.connectlite_item_pitch_sol_sharp + ' (56)', '56'], + [Lang.template.connectlite_item_pitch_ra + ' (57)', '57'], + [Lang.template.connectlite_item_pitch_ra_sharp + ' (58)', '58'], + [Lang.template.connectlite_item_pitch_si + ' (59)', '59'], + + [Lang.template.connectlite_item_pitch_do + ' (60)', '60'], + [Lang.template.connectlite_item_pitch_do_sharp + ' (61)', '61'], + [Lang.template.connectlite_item_pitch_re + ' (62)', '62'], + [Lang.template.connectlite_item_pitch_re_sharp + ' (63)', '63'], + [Lang.template.connectlite_item_pitch_mi + ' (64)', '64'], + [Lang.template.connectlite_item_pitch_fa + ' (65)', '65'], + [Lang.template.connectlite_item_pitch_fa_sharp + ' (66)', '66'], + [Lang.template.connectlite_item_pitch_sol + ' (67)', '67'], + [Lang.template.connectlite_item_pitch_sol_sharp + ' (68)', '68'], + [Lang.template.connectlite_item_pitch_ra + ' (69)', '69'], + [Lang.template.connectlite_item_pitch_ra_sharp + ' (70)', '70'], + [Lang.template.connectlite_item_pitch_si + ' (71)', '71'], + + [Lang.template.connectlite_item_pitch_do + ' (72)', '72'], + [Lang.template.connectlite_item_pitch_do_sharp + ' (73)', '73'], + [Lang.template.connectlite_item_pitch_re + ' (74)', '74'], + [Lang.template.connectlite_item_pitch_re_sharp + ' (75)', '75'], + [Lang.template.connectlite_item_pitch_mi + ' (76)', '76'], + [Lang.template.connectlite_item_pitch_fa + ' (77)', '77'], + [Lang.template.connectlite_item_pitch_fa_sharp + ' (78)', '78'], + [Lang.template.connectlite_item_pitch_sol + ' (79)', '79'], + [Lang.template.connectlite_item_pitch_sol_sharp + ' (80)', '80'], + [Lang.template.connectlite_item_pitch_ra + ' (81)', '81'], + [Lang.template.connectlite_item_pitch_ra_sharp + ' (82)', '82'], + [Lang.template.connectlite_item_pitch_si + ' (83)', '83'], + ], + value: '60', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_pitch_key', + }, + ], + }, + }, + connectlite_dropdown_melody_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_melody_start, '1'], + [Lang.template.connectlite_item_melody_end, '2'], + [Lang.template.connectlite_item_melody_level_up, '3'], + [Lang.template.connectlite_item_melody_level_down, '4'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ null ], + }, + paramsKeyMap: { + PARAM0: 0, + }, + func: function(sprite, script) { + return script.getStringField('PARAM0'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.template.connectlite_item_melody_start, '1'], + [Lang.template.connectlite_item_melody_end, '2'], + [Lang.template.connectlite_item_melody_level_up, '3'], + [Lang.template.connectlite_item_melody_level_down, '4'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'connectlite_dropdown_melody_key', + }, + ], + }, + }, + ///======================================================================================== + /// Event block + ///======================================================================================== + // %1 리모컨 %2 키를 눌렀을 때 + connectlite_when_press_remote_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_event', + statements: [], + params: [ + { + type: 'Indicator', + img: 'block_icon/start_icon_hardwarelite.svg', + size: 14, + position: { + x: 0, + y: -2, + }, + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'connectlite_dropdown_remote_key', + }, + ], + type: 'connectlite_when_press_remote_key', + }, + paramsKeyMap: { + PARAM1: 1, + }, + class: 'connectlite_event', + isNotFor: ['ProboConnectLite'], + event: 'connectlite_event_remote_input', + func(sprite, script) { + const key = Entry.ProboConnectLite.getRemoteKey(script.getStringValue('PARAM1')); + return (Entry.ProboConnectLite.InputData.Remote[key] === 1) + ? script.callReturn() + : this.die(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.when_press_remote_key(%2)', + blockType: 'event', + passTest: true, + textParams: [ + undefined, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // %1 디지털 입력 %2 이(가) 들어왔을 때 + connectlite_when_input_digital_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_event', + statements: [], + params: [ + { + type: 'Indicator', + img: 'block_icon/start_icon_hardwarelite.svg', + size: 14, + position: { + x: 0, + y: -2, + }, + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'connectlite_dropdown_digital_key', + }, + ], + type: 'connectlite_when_input_digital_value', + }, + paramsKeyMap: { + PARAM1: 1, + }, + class: 'connectlite_event', + isNotFor: ['ProboConnectLite'], + event: 'connectlite_event_digital_input', + func(sprite, script) { + const key = Entry.ProboConnectLite.getDigitalKey(script.getStringValue('PARAM1')); + const value = Entry.ProboConnectLite.getDigitalStateValue(key); + return (value) + ? script.callReturn() + : this.die(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.when_input_digital_value(%2)', + blockType: 'event', + passTest: true, + textParams: [ + undefined, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + ///======================================================================================== + /// Setting Block + ///======================================================================================== + // 입력포트 %1 을(를) %2 센서로 설정 %3 + connectlite_set_sensor_setting: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_analog_key', + }, + { + type: 'connectlite_dropdown_setting_sensor_key', + }, + null, + ], + type: 'connectlite_set_sensor_setting', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_setting', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getAnalogKey(script.getStringValue('PARAM0')); + const value = Entry.ProboConnectLite.getSettingSensorValue(script.getStringValue('PARAM1')); + const sensorSet = Entry.ProboConnectLite.SensorSet; + sensorSet[key] = value; + Entry.ProboConnectLite.RemoteData.ASET2 = ((sensorSet.AA1 << 4) | sensorSet.AA2) & 0xFF; + Entry.ProboConnectLite.RemoteData.ASET1 = ((sensorSet.AA3 << 4) | sensorSet.AA4) & 0xFF; + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_sensor_setting(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + ///======================================================================================== + /// Input block + ///======================================================================================== + // 리모컨 입력 %1 + connectlite_is_remote_key: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_remote_key', + }, + ], + type: 'connectlite_is_remote_key', + }, + paramsKeyMap: { + PARAM0: 0, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getRemoteKey(script.getStringValue('PARAM0')); + return (Entry.ProboConnectLite.InputData.Remote[key] === 1); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.is_remote_key(%1)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 디지털 입력 %1 + connectlite_is_digital_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_digital_key', + }, + ], + type: 'connectlite_is_digital_value', + }, + paramsKeyMap: { + PARAM0: 0, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getDigitalKey(script.getStringValue('PARAM0')); + return Entry.ProboConnectLite.getDigitalStateValue(key);; + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.is_digital_value(%1)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 아날로그 입력 %1 + connectlite_get_analog_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_analog_key', + }, + ], + type: 'connectlite_get_analog_value', + }, + paramsKeyMap: { + PARAM0: 0, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getAnalogKey(script.getStringValue('PARAM0')); + return (Entry.ProboConnectLite.SensorSet[key] === 5) // 5: 압력 + ? 255 - Entry.ProboConnectLite.InputData.Analog[key] + : Entry.ProboConnectLite.InputData.Analog[key]; + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.get_analog_value(%1)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 3가속도 %1의 X축 + connectlite_get_tri_axis_acceler_x: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_analog_key', + }, + ], + type: 'connectlite_get_tri_axis_acceler_x', + }, + paramsKeyMap: { + PARAM0: 0, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getAxisKey(script.getStringValue('PARAM0'), "X"); + const value = Entry.ProboConnectLite.InputData.Acceler[key]; + return (value & 0x80) + ? Number((value - 255) / 10).toFixed(1) + : Number(value / 10).toFixed(1); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.get_tri_axis_acceler_x(%1)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 3가속도 %1의 Y축 + connectlite_get_tri_axis_acceler_y: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_analog_key', + }, + ], + type: 'connectlite_get_tri_axis_acceler_y', + }, + paramsKeyMap: { + PARAM0: 0, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getAxisKey(script.getStringValue('PARAM0'),"Y"); + const value = Entry.ProboConnectLite.InputData.Acceler[key]; + return (value & 0x80) + ? Number((value - 255) / 10).toFixed(1) + : Number(value / 10).toFixed(1); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.get_tri_axis_acceler_y(%1)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 3가속도 %1의 Z축 + connectlite_get_tri_axis_acceler_z: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_analog_key', + }, + ], + type: 'connectlite_get_tri_axis_acceler_z', + }, + paramsKeyMap: { + PARAM0: 0, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getAxisKey(script.getStringValue('PARAM0'), "Z"); + const value = Entry.ProboConnectLite.InputData.Acceler[key]; + return (value & 0x80) + ? Number((value - 255) / 10).toFixed(1) + : Number(value / 10).toFixed(1); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.get_tri_axis_acceler_z(%1)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + + // %1 의 %2 ~ %3 값을 %4 ~ %5 (으)로 변환 + connectlite_get_value_mapping: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_analog_key', + }, + { + type: 'number', + params: [ 0 ], + }, + { + type: 'number', + params: [ 255 ], + }, + { + type: 'number', + params: [ 0 ], + }, + { + type: 'number', + params: [ 100 ], + }, + ], + type: 'connectlite_get_value_mapping', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + PARAM2: 2, + PARAM3: 3, + PARAM4: 4, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getAnalogKey(script.getStringValue('PARAM0')); + const inMin = script.getNumberValue('PARAM1'); + const inMax = script.getNumberValue('PARAM2'); + const outMin = script.getNumberValue('PARAM3'); + const outMax = script.getNumberValue('PARAM4'); + const data = (Entry.ProboConnectLite.SensorSet[key] === 5) // 5: 압력 + ? 255 - Entry.ProboConnectLite.InputData.Analog[key] + : Entry.ProboConnectLite.InputData.Analog[key]; + return (data - inMin) * (outMax-outMin) / (inMax - inMin) + outMin; + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.get_value_mapping(%1, %2, %3, %4, %5)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 컬러 센서 %1 이(가) %2 인가? + connectlite_is_color_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_analog_key', + }, + { + type: 'connectlite_dropdown_sensor_color_key', + }, + ], + type: 'connectlite_is_color_value', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key0 = Entry.ProboConnectLite.getAnalogKey(script.getStringValue('PARAM0')); + const key1 = Entry.ProboConnectLite.getColorSensorKey(script.getStringValue('PARAM1')); + const value = Entry.ProboConnectLite.InputData.Analog[key0]; + const color = Entry.ProboConnectLite.Color; + return ((color[key1].Min <= value) && (value <= color[key1].Max)); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.is_color_value(%1, %2)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 컬러 센서 %1 의 색상 + connectlite_get_color_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_analog_key', + }, + ], + type: 'connectlite_get_color_value', + }, + paramsKeyMap: { + PARAM0: 0, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key0 = Entry.ProboConnectLite.getAnalogKey(script.getStringValue('PARAM0')); + const value = Entry.ProboConnectLite.InputData.Analog[key0]; + const color = Entry.ProboConnectLite.Color; + + for (let i = 1; i < 7; i++) { + const key1 = Entry.ProboConnectLite.getColorSensorKey(i.toString()); + if ((color[key1].Min <= value) && (value <= color[key1].Max)) { + switch (i) { + case 1: + return Lang.template.connectlite_item_color_red; + case 2: + return Lang.template.connectlite_item_color_green; + case 3: + return Lang.template.connectlite_item_color_blue; + case 4: + return Lang.template.connectlite_item_color_yellow; + case 5: + return Lang.template.connectlite_item_color_black; + case 6: + return Lang.template.connectlite_item_color_white; + default: + return Lang.template.connectlite_item_error; + } + } + } + + return Lang.template.connectlite_item_nothing; + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.get_color_value(%1)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // %1 센서 %2 을 %3 값으로 정하기 %4 + connectlite_set_infinite_setting: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + } + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_inNcom_sensor_key', + }, + { + type: 'connectlite_dropdown_analog_key', + }, + { + type: 'number', + params: [ 0 ], + }, + null + ], + type: 'connectlite_set_infinite_setting', + }, + paramsKeyMap: { + PARAM1: 1, + PARAM2: 2, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getAnalogKey(script.getStringValue('PARAM1')); + let count = 0; + let value = script.getNumberValue('PARAM2'); + + if (value != 0) { + count = Number(value / 255).toFixed(0); + value = value % 255; + } else { + count = 0; + value = 0; + } + + Entry.ProboConnectLite.Infinite.Buff[key] = Entry.ProboConnectLite.InputData.Analog[key]; + Entry.ProboConnectLite.Infinite.Start[key] = Entry.ProboConnectLite.InputData.Analog[key] - value; + Entry.ProboConnectLite.Infinite.Count[key] = count; + + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_infinite_setting(%1, %2, %3)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // %1 센서 %2 지름 %3 의 mm 값 + connectlite_get_infinite_mm_diameter: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_inNcom_sensor_key', + }, + { + type: 'connectlite_dropdown_analog_key', + }, + { + type: 'number', + params: [ 53.5 ], + }, + ], + type: 'connectlite_get_infinite_mm_diameter', + }, + paramsKeyMap: { + PARAM1: 1, + PARAM2: 2, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getAnalogKey(script.getStringValue('PARAM1')); + const radius = script.getNumberValue('PARAM2') / 2; + const pi = 3.141592; + const infinite = Entry.ProboConnectLite.Infinite; + let value = Entry.ProboConnectLite.InputData.Analog[key]; + + if (value < infinite.Buff[key] - 150) { + infinite.Count[key]++; + } else if (value > infinite.Buff[key] + 150) { + infinite.Count[key]--; + } + infinite.Buff[key] = value; + value = (infinite.Buff[key] - infinite.Start[key]) + (infinite.Count[key] * 255); + + return Number((2 * pi * radius) / 255 * value).toFixed(3); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.get_infinite_mm_diameter(%1, %2, %3)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // %1 센서 %2 의 %3 + connectlite_get_infinite_transform_input: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_inNcom_sensor_key', + }, + { + type: 'connectlite_dropdown_analog_key', + }, + { + type: 'connectlite_dropdown_sensor_angle_key', + }, + ], + type: 'connectlite_get_infinite_transform_input', + }, + paramsKeyMap: { + PARAM1: 1, + PARAM2: 2, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key1 = Entry.ProboConnectLite.getAnalogKey(script.getStringValue('PARAM1')); + const key2 = Entry.ProboConnectLite.getSensorAngleKey(script.getStringValue('PARAM2')); + const anlogValue = Entry.ProboConnectLite.InputData.Analog[key1]; + const infinite = Entry.ProboConnectLite.Infinite; + + if (anlogValue < (infinite.Buff[key1] - 150)) { + infinite.Count[key1]++; + } else if (anlogValue > (infinite.Buff[key1] + 150)) { + infinite.Count[key1]--; + } + infinite.Buff[key1] = anlogValue; + const value = (infinite.Buff[key1] - infinite.Start[key1]) + (infinite.Count[key1] * 255); + + switch (key2) { + case 'IS1': + return value; + case 'IS2': + return (value > 0) + ? Math.floor((value % 255) * 1.41732) + : Math.ceil((value % 255) * 1.41732) + case 'IS3': + return Number((360 / 255) * anlogValue).toFixed(0); + case 'IS4': + return (value > 0) + ? Math.floor(value / 255) + : Math.ceil(value / 255); + default: + return Lang.template.connectlite_item_nothing; + + } + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.get_infinite_transform_input(%1, %2, %3)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 멀티키 센서 %1의 %2 + connectlite_is_multi_sensor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_analog_key', + }, + { + type: 'connectlite_dropdown_multikey_key', + }, + ], + type: 'connectlite_is_multi_sensor', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getAnalogKey(script.getStringValue('PARAM0')); + const value = Entry.ProboConnectLite.getMultiKeyValue(script.getStringValue('PARAM1')); + return (Entry.ProboConnectLite.InputData.Analog[key] >> value) & 0x01; + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.is_multi_sensor(%1, %2)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 분배 스위치 %1의 %2 + connectlite_is_multi_switch: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_analog_key', + }, + { + type: 'connectlite_dropdown_multikey_key', + }, + ], + type: 'connectlite_is_multi_switch', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key0 = Entry.ProboConnectLite.getAnalogKey(script.getStringValue('PARAM0')); + const value = Entry.ProboConnectLite.getMultiKeyValue(script.getStringValue('PARAM1')); + const analog = Entry.ProboConnectLite.InputData.Analog[key0]; + const multySwitch = Entry.ProboConnectLite.MultiSwitch; + + for (let i = 0; i < 8; i++) { + const key = 'Key' + (i + 1).toString(); + if (multySwitch[key].Min <= analog && analog <= multySwitch[key].Max) { + return (value === i); + } + } + + return false; + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.is_multi_switch(%1, %2)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 확장 디지털 입력 %1 의 %2 + connectlite_is_extension_digital_input: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_analog_key', + }, + { + type: 'connectlite_dropdown_extension_digital_key', + }, + ], + type: 'connectlite_is_extension_digital_input', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getAxisKey(script.getStringValue('PARAM0'), 'X'); + const shift = Entry.ProboConnectLite.getExtentionDigitalValue(script.getStringValue('PARAM1')); + const value = Entry.ProboConnectLite.InputData.Acceler[key]; + return ((value >> shift) === 1); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.is_extension_digital_input(%1, %2)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 확장 아날로그 입력 %1 의 %2 + connectlite_get_extension_analog_input: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_analog_key', + }, + { + type: 'connectlite_dropdown_extension_analog_key', + }, + ], + type: 'connectlite_get_extension_analog_input', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getAxisKey( + script.getStringValue('PARAM0'), + Entry.ProboConnectLite.getExtentionAnalogKey(script.getStringValue('PARAM1')) + ); + const value = Entry.ProboConnectLite.InputData.Acceler[key]; + return value; + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.get_extension_analog_input(%1, %2)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // EEPROM %1 주소의 값 호출하기 %2 + connectlite_set_eeprom_call: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'number', + params: ['0'] + }, + null + ], + type: 'connectlite_set_eeprom_call', + }, + paramsKeyMap: { + ADDRESS: 0, + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const address = script.getNumberValue('ADDRESS', script); + if (!script.isStart) { + script.isStart = true; + script.timeFlag = 1; + + const ms = 50; + const fps = Entry.FPS || 60; + + Entry.ProboConnectLite.EEPROM.Count = Entry.ProboConnectLite.InputData.EEPROM.EC; + Entry.ProboConnectLite.RemoteData['EEPR4'] = 0x40; + Entry.ProboConnectLite.RemoteData['EEPR3'] = address; + Entry.TimeWaitManager.add( + script.block.id, + function() { + script.timeFlag = 0; + }, + 60 / fps * ms + ); + + return script; + } else if (script.timeFlag == 1) { + return script; + } else { + Entry.ProboConnectLite.EEPROM.Buff = + (Entry.ProboConnectLite.InputData.EEPROM.EEPR2 << 8) + + Entry.ProboConnectLite.InputData.EEPROM.EEPR1; + Entry.ProboConnectLite.RemoteData['EEPR4'] = 0; + Entry.ProboConnectLite.RemoteData['EEPR3'] = 0; + + delete script.timeFlag; + delete script.isStart; + Entry.engine.isContinue = false; + return script.callReturn(); + } + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_eeprom_call(%1)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // EEPROM 주소의 값 + connectlite_get_eeprom_address_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [], + events: {}, + def: { + type: 'connectlite_get_eeprom_address_value', + }, + class: 'connectlite_input', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const count = Entry.ProboConnectLite.EEPROM.Count; + + return (Entry.ProboConnectLite.InputData.EEPROM.EC != count) + ? Entry.ProboConnectLite.EEPROM.Buff + : 0; + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.get_eeprom_address_value', + blockType: 'param', + textParams: [ null ], + }, + ], + }, + }, + + ///======================================================================================== + /// output block + ///======================================================================================== + // DC 모터 %1 을(를) %2 속도로 회전 %3 + connectlite_set_dc_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_dc_1_all_key', + }, + { + type: 'connectlite_dropdown_velocity_key', + }, + null, + ], + type: 'connectlite_set_dc_output', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getDckey(script.getStringValue('PARAM0')); + const value = script.getNumberValue('PARAM1'); + + switch (key) { + case 'DC5': + Entry.ProboConnectLite.RemoteData['DC1'] = value; + Entry.ProboConnectLite.RemoteData['DC2'] = value; + break; + case 'DC6': + Entry.ProboConnectLite.RemoteData['DC3'] = value; + Entry.ProboConnectLite.RemoteData['DC4'] = value; + break; + case 'DC7': + Entry.ProboConnectLite.RemoteData['DC1'] = value; + Entry.ProboConnectLite.RemoteData['DC2'] = value; + Entry.ProboConnectLite.RemoteData['DC3'] = value; + Entry.ProboConnectLite.RemoteData['DC4'] = value; + break; + default: + Entry.ProboConnectLite.RemoteData[key] = value; + break; + } + + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_dc_output(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 서보 모터 %1 의 위치를 %2 로 이동 %3 + connectlite_set_servo_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_port_1_4_key', + }, + { + type: 'connectlite_dropdown_servo_position_key', + }, + null, + ], + type: 'connectlite_set_servo_output', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getServoKey(script.getStringValue('PARAM0')); + const value = script.getNumberValue('PARAM1'); + Entry.ProboConnectLite.RemoteData[key] = Math.min(Math.max(value, 0), 100); + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_servo_output(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // S 모터 %1 을(를) %2 속도로 회전 %3 + connectlite_set_s_dc_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_port_1_4_key', + }, + { + type: 'connectlite_dropdown_velocity_key', + }, + null, + ], + type: 'connectlite_set_s_dc_output', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getServoKey(script.getStringValue('PARAM0')); + const speed = script.getNumberValue('PARAM1'); + const value = Math.min(Math.max(speed, -20), 20) + 148; + + switch (key) { + case 'Servo5': + Entry.ProboConnectLite.RemoteData['Servo1'] = value; + Entry.ProboConnectLite.RemoteData['Servo2'] = value; + break; + case 'Servo6': + Entry.ProboConnectLite.RemoteData['Servo3'] = value; + Entry.ProboConnectLite.RemoteData['Servo4'] = value; + break; + default: + Entry.ProboConnectLite.RemoteData[key] = value; + break; + } + + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_s_dc_output(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 출력핀 %1 을(를) %2 %3 + connectlite_set_port_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_port_1_4_key', + }, + { + type: 'connectlite_dropdown_on_off_key', + }, + null + ], + type: 'connectlite_set_port_output', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getPortKey(script.getStringValue('PARAM0')); + const value = Entry.ProboConnectLite.getPortToggleValue(script.getStringValue('PARAM1')); + + Entry.ProboConnectLite.RemoteData[key] = value; + + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_port_output(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // %1 을(를) %2 음표로 연주하기 %3 + connectlite_play_melody_note_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_pitch_key', + }, + { + type: 'connectlite_dropdown_note_key', + }, + null + ], + type: 'connectlite_play_melody_note_output', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + if (!script.isStart) { + script.isStart = true; + script.timeFlag = 1; + const pitch = Entry.ProboConnectLite.getPitchValue(script.getNumberValue('PARAM0')); + const note = Entry.ProboConnectLite.getNoteKey(script.getStringValue('PARAM1')); + const ms = Entry.ProboConnectLite.Note[note]; + const fps = Entry.FPS || 60; + + Entry.ProboConnectLite.RemoteData['MEL2'] = pitch >> 8; + Entry.ProboConnectLite.RemoteData['MEL1'] = pitch; + Entry.TimeWaitManager.add( + script.block.id, + function() { + script.timeFlag = 0; + }, + 60 / fps * ms + ); + return script; + } else if (script.timeFlag == 1) { + return script; + } else { + Entry.ProboConnectLite.RemoteData['MEL2'] = 0; + Entry.ProboConnectLite.RemoteData['MEL1'] = 0; + + delete script.timeFlag; + delete script.isStart; + Entry.engine.isContinue = false; + + return script.callReturn(); + } + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.play_melody_note_output(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // %1 을(를) %2 초 동안 연주하기 %3 + connectlite_play_melody_sec_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_pitch_key', + }, + { + type: 'connectlite_dropdown_time_1_key', + }, + null + ], + type: 'connectlite_play_melody_sec_output', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + if (!script.isStart) { + script.isStart = true; + script.timeFlag = 1; + const pitch = Entry.ProboConnectLite.getPitchValue(script.getNumberValue('PARAM0')); + const sec = script.getNumberValue('PARAM1'); + const fps = Entry.FPS || 60; + + Entry.ProboConnectLite.RemoteData['MEL2'] = pitch >> 8; + Entry.ProboConnectLite.RemoteData['MEL1'] = pitch; + Entry.TimeWaitManager.add( + script.block.id, + function() { + script.timeFlag = 0; + }, + 60 / fps * sec * 1000 + ); + + return script; + } else if (script.timeFlag == 1) { + return script; + } else { + Entry.ProboConnectLite.RemoteData['MEL2'] = 0; + Entry.ProboConnectLite.RemoteData['MEL1'] = 0; + + delete script.timeFlag; + delete script.isStart; + Entry.engine.isContinue = false; + + return script.callReturn(); + } + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.play_melody_sec_output(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // %1 을(를) 연주하기 %2 + connectlite_play_melody_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_pitch_key', + }, + null + ], + type: 'connectlite_play_melody_output', + }, + paramsKeyMap: { + PARAM0: 0, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const pitch = Entry.ProboConnectLite.getPitchValue(script.getNumberValue('PARAM0')); + Entry.ProboConnectLite.RemoteData['MEL2'] = pitch >> 8; + Entry.ProboConnectLite.RemoteData['MEL1'] = pitch; + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.play_melody_output(%1)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // %1 값을(를) %2 초 동안 연주하기 %3 + connectlite_play_value_sec_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'number', + params: [ 35391 ], + }, + { + type: 'connectlite_dropdown_time_1_key', + }, + null + ], + type: 'connectlite_play_value_sec_output', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + if (!script.isStart) { + script.isStart = true; + script.timeFlag = 1; + + const melody = script.getNumberValue('PARAM0'); + const sec = script.getNumberValue('PARAM1'); + const fps = Entry.FPS || 60; + + Entry.ProboConnectLite.RemoteData['MEL2'] = (melody >> 8) & 0xff; + Entry.ProboConnectLite.RemoteData['MEL1'] = melody & 0xff; + Entry.TimeWaitManager.add( + script.block.id, + function() { + script.timeFlag = 0; + }, + 60 / fps * sec * 1000 + ); + return script; + } else if (script.timeFlag == 1) { + return script; + } else { + Entry.ProboConnectLite.RemoteData['MEL2'] = 0; + Entry.ProboConnectLite.RemoteData['MEL1'] = 0; + + delete script.timeFlag; + delete script.isStart; + Entry.engine.isContinue = false; + return script.callReturn(); + } + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.play_melody_output(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 1 값을(를) 연주하기 %2 + connectlite_play_value_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'number', + params: [ 35391 ], + }, + null + ], + type: 'connectlite_play_value_output', + }, + paramsKeyMap: { + PARAM0: 0, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const melody = script.getNumberValue('PARAM0'); + Entry.ProboConnectLite.RemoteData['MEL2'] = (melody >> 8) & 0xff; + Entry.ProboConnectLite.RemoteData['MEL1'] = melody & 0xff; + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.play_melody_output(%1)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // %1 을(를) %2초 간격으로 재생하기 %3 + connectlite_play_melody_track_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_melody_key', + }, + { + type: 'connectlite_dropdown_time_2_key', + }, + null + ], + type: 'connectlite_play_melody_track_output', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + function getTrackStep(track,script){ + if(!script.isStart){ + script.isStart = true; + script.trackStep = 0; + } + else { + script.trackStep++; + } + const sec = script.getNumberValue('PARAM1'); + const fps = Entry.FPS || 60; + const melody = Entry.ProboConnectLite.Track[track][script.trackStep]; + + Entry.ProboConnectLite.RemoteData['MEL2'] = (melody >> 8) & 0xff; + Entry.ProboConnectLite.RemoteData['MEL1'] = melody & 0xff; + script.timeFlag = 1; + Entry.TimeWaitManager.add( + script.block.id, + function() { + script.timeFlag = 0; + }, + 60 / fps * sec * 1000 + ); + } + const TR = Entry.ProboConnectLite.getMelodyValue( + script.getStringValue('PARAM0') + ); + if (!script.isStart) { + switch(TR) { + case 0 : + script.maxStep = 6; + break; + case 1 : + script.maxStep = 7; + break; + case 2 : + script.maxStep = 3; + break; + case 3 : + script.maxStep = 3; + break; + } + getTrackStep(TR,script); + return script; + } else if (script.timeFlag == 1) { + return script; + } else if (script.trackStep < script.maxStep){ + getTrackStep(TR,script); + return script; + } else { + Entry.ProboConnectLite.RemoteData['MEL2'] = 0; + Entry.ProboConnectLite.RemoteData['MEL1'] = 0; + + delete script.trackStep; + delete script.maxStep; + delete script.timeFlag; + delete script.isStart; + Entry.engine.isContinue = false; + return script.callReturn(); + } + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.play_melody_track_output(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // 멜로디 중지 %1 + connectlite_play_melody_off: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ null ], + type: 'connectlite_play_melody_off', + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + Entry.ProboConnectLite.RemoteData['MEL2'] = 0; + Entry.ProboConnectLite.RemoteData['MEL1'] = 0; + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.play_melody_track_output', + textParams: [ null ], + }, + ], + }, + }, + // RGB LED %1 을(를) %2 으로 켜기 %3 + connectlite_set_rgbled_on_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_port_1_4_key', + }, + { + type: 'connectlite_dropdown_rgb_color_key', + }, + null + ], + type: 'connectlite_set_rgbled_on_output', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getServoKey(script.getStringValue('PARAM0')); + const value = Entry.ProboConnectLite.getRgbToggleValue(script.getStringValue('PARAM1')); + Entry.ProboConnectLite.RemoteData[key] = value; + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_rgbled_on_output(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // RGB LED %1 을(를) 끄기 %2 + connectlite_set_rgbled_off_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_port_1_4_key', + }, + null + ], + type: 'connectlite_set_rgbled_off_output', + }, + paramsKeyMap: { + PARAM0: 0, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getServoKey(script.getStringValue('PARAM0')); + const value = Entry.ProboConnectLite.getRgbToggleValue('0'); + Entry.ProboConnectLite.RemoteData[key] = value; + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_rgbled_off_output(%1)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // RGB LED %1 %2 으로 %3 초 간격 %4 + connectlite_set_rgbled_flashing_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_port_1_4_key', + }, + { + type: 'connectlite_dropdown_rgb_color_key', + }, + { + type: 'connectlite_dropdown_time_3', + }, + null + ], + type: 'connectlite_set_rgbled_flashing_output', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + PARAM2: 2, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getServoKey(script.getStringValue('PARAM0')); + const value = Entry.ProboConnectLite.getRgbTwinkleValue( + script.getStringValue('PARAM1'), + script.getNumberValue('PARAM2') + ); + Entry.ProboConnectLite.RemoteData[key] = value; + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_rgbled_flashing_output(%1, %2, %3)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // RGB LED %1 을(를) %2 으로 디밍 %3 + connectlite_set_rgbled_dimming_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'connectlite_dropdown_port_1_4_key', + }, + { + type: 'connectlite_dropdown_rgb_color_key', + }, + null + ], + type: 'connectlite_set_rgbled_dimming_output', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const key = Entry.ProboConnectLite.getServoKey(script.getStringValue('PARAM0')); + const color = Entry.ProboConnectLite.getRgbDimmingValue(script.getStringValue('PARAM1')); + Entry.ProboConnectLite.RemoteData[key] = color; + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_rgbled_dimming_output(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // FND를 %1 (으)로 설정 %2 + connectlite_set_fnd_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'number', + params: [ 0 ], + }, + null + ], + type: 'connectlite_set_fnd_output', + }, + paramsKeyMap: { + PARAM0: 0, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const value = script.getNumberValue('PARAM0'); + Entry.ProboConnectLite.RemoteData['FND'] = value; + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_fnd_output(%1)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + // FND 끄기 %1 + connectlite_set_fnd_off: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null + ], + type: 'connectlite_set_fnd_off', + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + Entry.ProboConnectLite.RemoteData['FND'] = 100; + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_fnd_off', + textParams: [ null ], + }, + ], + }, + }, + // EEPROM %1 주소에 %2 값 설정하기 %3 + connectlite_set_eeprom_write: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardwarelite_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'number', + params: [ 0 ] + }, + { + type: 'number', + params: [ 0 ] + }, + null, + ], + type: 'connectlite_set_eeprom_write', + }, + paramsKeyMap: { + PARAM0: 0, + PARAM1: 1, + }, + class: 'connectlite_output', + isNotFor: ['ProboConnectLite'], + func: function(sprite, script) { + const address = script.getNumberValue('PARAM0'); + const value = script.getNumberValue('PARAM1'); + + if (!script.isStart) { + script.isStart = true; + script.timeFlag = 1; + + const ms = 50; + const fps = Entry.FPS || 60; + + Entry.ProboConnectLite.RemoteData['EEPR4'] = 0x80; + Entry.ProboConnectLite.RemoteData['EEPR3'] = address; + Entry.ProboConnectLite.RemoteData['EEPR2'] = (value >> 8) & 0xff; + Entry.ProboConnectLite.RemoteData['EEPR1'] = value & 0xff; + Entry.TimeWaitManager.add( + script.block.id, + function() { + script.timeFlag = 0; + }, + 60 / fps * ms + ); + return script; + } else if (script.timeFlag == 1) { + return script; + } else { + Entry.ProboConnectLite.RemoteData['EEPR4'] = 0x40; + Entry.ProboConnectLite.RemoteData['EEPR3'] = address; + Entry.ProboConnectLite.RemoteData['EEPR2'] = 0; + Entry.ProboConnectLite.RemoteData['EEPR1'] = 0; + + setTimeout(function() { + Entry.ProboConnectLite.RemoteData['EEPR4'] = 0; + Entry.ProboConnectLite.RemoteData['EEPR3'] = 0; + Entry.ProboConnectLite.RemoteData['EEPR2'] = 0; + Entry.ProboConnectLite.RemoteData['EEPR1'] = 0; + }, 100); + + delete script.timeFlag; + delete script.isStart; + Entry.engine.isContinue = false; + return script.callReturn(); + } + }, + syntax: { + js: [], + py: [ + { + syntax: 'ProboConnectLite.set_eeprom_write(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + }; // getBlock() return; + } + })(); +})(); + +module.exports = Entry.ProboConnectLite; \ No newline at end of file diff --git a/src/playground/blocks/hardwareLite/metadata_alux_connect_lite.json b/src/playground/blocks/hardwareLite/metadata_alux_connect_lite.json new file mode 100644 index 0000000000..c3ad4b08a8 --- /dev/null +++ b/src/playground/blocks/hardwareLite/metadata_alux_connect_lite.json @@ -0,0 +1,9 @@ +{ + "name": "ProboConnectLite", + "version": "1.0.0", + "type": "hardware", + "title": "프로보 커넥트", + "description": "에이럭스", + "imageName": "alux_proboconnect_lite.png", + "moduleId": "270101" +}