diff --git a/config/devices - Copy.properties b/config/devices - Copy.properties
new file mode 100644
index 0000000..cc3672f
--- /dev/null
+++ b/config/devices - Copy.properties
@@ -0,0 +1,67 @@
+img=ch.psi.pshell.prosilica.Prosilica|25001 "PacketSize=1522;PixelFormat=Mono8;BinningX=1;BinningY=1;RegionX=300;RegionY=200;Width=1000;Height=1000"|||false
+gripper_cam=ch.psi.pshell.imaging.MjpegSource|http://129.129.110.114/axis-cgi/mjpg/video.cgi||-1000|
+microscan=ch.psi.pshell.serial.TcpDevice|129.129.100.200:2001|||
+microscan_cmd=ch.psi.pshell.serial.TcpDevice|129.129.100.200:2003|||
+ue=LaserUE|COM4|||false
+#robot=RobotTcp|127.0.0.1:1000|||
+#onewire=ch.psi.pshell.serial.TcpDevice|129.129.126.83:5000|||
+puck_detection=ch.psi.mxsc.PuckDetection|tell-raspberrypi:5556|||
+#robot_modbus=ch.psi.pshell.modbus.ModbusTCP|129.129.126.100:502|||
+#jf1=ch.psi.pshell.modbus.AnalogInput|robot_modbus 0||100|
+#jf2=ch.psi.pshell.modbus.AnalogInput|robot_modbus 1||100|
+#jf3=ch.psi.pshell.modbus.AnalogInput|robot_modbus 2||100|
+#jf4=ch.psi.pshell.modbus.AnalogInput|robot_modbus 3||100|
+#jf5=ch.psi.pshell.modbus.AnalogInput|robot_modbus 4||100|
+#jf6=ch.psi.pshell.modbus.AnalogInput|robot_modbus 5||100|
+#robot_sts=ch.psi.pshell.modbus.AnalogInputArray|robot_modbus 6 6||100|
+#robot_cmd=ch.psi.pshell.modbus.AnalogOutput|robot_modbus 12|||
+#robot_args=ch.psi.pshell.modbus.AnalogOutputArray|robot_modbus 47 12|||
+#robot_req=ch.psi.pshell.modbus.AnalogOutput|robot_modbus 13|||
+#robot_ack=ch.psi.pshell.modbus.AnalogInput|robot_modbus 14|||
+#robot_ret=ch.psi.pshell.modbus.AnalogInputArray|robot_modbus 15 12|||
+#wago_back=ch.psi.pshell.modbus.ModbusTCP|SF-TEST-WAGO1:502|||
+wago=ch.psi.pshell.modbus.ModbusTCP|wago-mxsc-1:502|||
+led_ok_1=ch.psi.pshell.modbus.DigitalInput|wago 0||1000|
+led_ok_2=ch.psi.pshell.modbus.DigitalInput|wago 1||1000|
+led_ok_3=ch.psi.pshell.modbus.DigitalInput|wago 2||1000|
+feedback_local_safety=ch.psi.pshell.modbus.DigitalInput|wago 3||1000|
+feedback_psys_safety=ch.psi.pshell.modbus.DigitalInput|wago 4||1000|
+filling_phase_separator=ch.psi.pshell.modbus.DigitalInput|wago 5||1000|
+filling_dewar=ch.psi.pshell.modbus.DigitalInput|wago 6||1000|
+dewar_level_high_alarm=ch.psi.pshell.modbus.DigitalInput|wago 7||1000|
+guiding_tool_park=ch.psi.pshell.modbus.DigitalInput|wago 8||1000|
+air_pressure_ok=ch.psi.pshell.modbus.DigitalInput|wago 9||1000|false
+n2_pressure_ok=ch.psi.pshell.modbus.DigitalInput|wago 10||1000|
+he_chamber_valve_1=ch.psi.pshell.modbus.DigitalInput|wago 15||1000|
+he_chamber_valve_2=ch.psi.pshell.modbus.DigitalInput|wago 16||1000|
+relays=ch.psi.pshell.modbus.DigitalOutputArray|wago 0 16||1000|
+release_local_safety=ch.psi.pshell.modbus.DigitalOutput|wago 0|||
+release_psys_safety=ch.psi.pshell.modbus.DigitalOutput|wago 1|||
+ln2_main_power=ch.psi.pshell.modbus.DigitalOutput|wago 2|||
+rim_heater=ch.psi.pshell.modbus.DigitalOutput|wago 3|||
+phase_separator_ln2=ch.psi.pshell.modbus.DigitalOutput|wago 4|||
+dewar_ln2=ch.psi.pshell.modbus.DigitalOutput|wago 5|||false
+valve_he_chamber=ch.psi.pshell.modbus.DigitalOutput|wago 6|||
+gripper_dryer=ch.psi.pshell.modbus.DigitalOutput|wago 7|||
+valve_1=ch.psi.pshell.modbus.DigitalOutput|wago 8|||
+valve_2=ch.psi.pshell.modbus.DigitalOutput|wago 9|||
+valve_3=ch.psi.pshell.modbus.DigitalOutput|wago 10|||
+valve_4=ch.psi.pshell.modbus.DigitalOutput|wago 11|||
+#spare_do_1=ch.psi.pshell.modbus.DigitalOutput|wago 12|||
+#spare_do_2=ch.psi.pshell.modbus.DigitalOutput|wago 13|||
+#spare_do_3=ch.psi.pshell.modbus.DigitalOutput|wago 14|||
+#spare_do_4=ch.psi.pshell.modbus.DigitalOutput|wago 15|||
+phase_separator_level=ch.psi.pshell.modbus.ReadonlyProcessVariable|wago 0||10000|
+dewar_level=ch.psi.pshell.modbus.ReadonlyProcessVariable|wago 1||10000|
+rim_heater_temp=ch.psi.pshell.modbus.ReadonlyProcessVariable|wago 2||10000|
+air_pressure=ch.psi.pshell.modbus.ReadonlyProcessVariable|wago 3||10000|
+n2_pressure=ch.psi.pshell.modbus.ReadonlyProcessVariable|wago 4||10000|
+#spare_ai_1=ch.psi.pshell.modbus.AnalogInput|wago 5|||
+#spare_ai_2=ch.psi.pshell.modbus.AnalogInput|wago 6|||
+#spare_ai_3=ch.psi.pshell.modbus.AnalogInput|wago 7|||
+led_ctrl_1=ch.psi.pshell.modbus.ProcessVariable|wago 0|||
+led_ctrl_2=ch.psi.pshell.modbus.ProcessVariable|wago 1|||
+led_ctrl_3=ch.psi.pshell.modbus.ProcessVariable|wago 2|||
+#spare_ao_3=ch.psi.pshell.modbus.AnalogOutput|wago 3|||
+#cam=ch.psi.pshell.epics.AreaDetector|MX-SAMCAM|||
+#img_back=ch.psi.pshell.imaging.CameraSource|cam||-100|
diff --git a/config/devices-modbus.properties b/config/devices-modbus.properties
new file mode 100644
index 0000000..3faf1af
--- /dev/null
+++ b/config/devices-modbus.properties
@@ -0,0 +1,42 @@
+wago=ch.psi.pshell.modbus.ModbusTCP|tell6d-wago:502|||
+led_ok_1=ch.psi.pshell.modbus.DigitalInput|wago 0||1000|
+led_ok_2=ch.psi.pshell.modbus.DigitalInput|wago 1||1000|
+led_ok_3=ch.psi.pshell.modbus.DigitalInput|wago 2||1000|
+feedback_local_safety=ch.psi.pshell.modbus.DigitalInput|wago 3||1000|
+feedback_psys_safety=ch.psi.pshell.modbus.DigitalInput|wago 4||1000|
+filling_dewar=ch.psi.pshell.modbus.DigitalInput|wago 5||1000|
+dewar_level_high_alarm=ch.psi.pshell.modbus.DigitalInput|wago 6||1000|
+guiding_tool_park=ch.psi.pshell.modbus.DigitalInput|wago 7||1000|
+air_pressure_ok=ch.psi.pshell.modbus.DigitalInput|wago 8||1000|false
+n2_pressure_ok=ch.psi.pshell.modbus.DigitalInput|wago 9||1000|
+smc_magnet_status=ch.psi.pshell.modbus.DigitalInput|wago 10||1000|
+smc_mounted_1=ch.psi.pshell.modbus.DigitalInput|wago 11||1000|
+smc_mounted_2=ch.psi.pshell.modbus.DigitalInput|wago 12||1000|
+magnet_release=ch.psi.pshell.modbus.DigitalInput|wago 13||500|
+spare_di_2=ch.psi.pshell.modbus.DigitalInput|wago 14||500|
+spare_di_3=ch.psi.pshell.modbus.DigitalInput|wago 15||500|
+spare_di_4=ch.psi.pshell.modbus.DigitalInput|wago 16||500|
+relays=ch.psi.pshell.modbus.DigitalOutputArray|wago 0 16||1000|
+release_local_safety=ch.psi.pshell.modbus.DigitalOutput|wago 0|||
+release_psys_safety=ch.psi.pshell.modbus.DigitalOutput|wago 1|||
+#spare_do_1=ch.psi.pshell.modbus.DigitalOutput|wago 2|||
+#spare_do_2=ch.psi.pshell.modbus.DigitalOutput|wago 3|||
+#spare_do_3=ch.psi.pshell.modbus.DigitalOutput|wago 4|||
+gripper_dryer=ch.psi.pshell.modbus.DigitalOutput|wago 5|||
+smc_sup_det=ch.psi.pshell.modbus.DigitalOutput|wago 6|||
+valve_1=ch.psi.pshell.modbus.DigitalOutput|wago 7|||
+valve_2=ch.psi.pshell.modbus.DigitalOutput|wago 8|||
+valve_3=ch.psi.pshell.modbus.DigitalOutput|wago 9|||
+valve_4=ch.psi.pshell.modbus.DigitalOutput|wago 10|||
+dewar_level=ch.psi.pshell.modbus.ReadonlyProcessVariable|wago 0||10000|
+rim_heater_temp=ch.psi.pshell.modbus.ReadonlyProcessVariable|wago 1||10000|
+#spare_ai_1=ch.psi.pshell.modbus.AnalogInput|wago 2|||false
+#spare_ai_2=ch.psi.pshell.modbus.AnalogInput|wago 3|||
+smc_current_rb=ch.psi.pshell.modbus.ReadonlyProcessVariable|wago 4||1000|
+#spare_ai_3=ch.psi.pshell.modbus.AnalogInput|wago 5|||
+#spare_ai_4=ch.psi.pshell.modbus.AnalogInput|wago 6|||
+#spare_ai_5=ch.psi.pshell.modbus.AnalogInput|wago 7|||
+led_ctrl_1=ch.psi.pshell.modbus.ProcessVariable|wago 0|||
+led_ctrl_2=ch.psi.pshell.modbus.ProcessVariable|wago 1|||
+led_ctrl_3=ch.psi.pshell.modbus.ProcessVariable|wago 2|||
+smc_current=ch.psi.pshell.modbus.ProcessVariable|wago 3|||
diff --git a/config/devices.properties b/config/devices.properties
new file mode 100644
index 0000000..439fff4
--- /dev/null
+++ b/config/devices.properties
@@ -0,0 +1,57 @@
+img=ch.psi.pshell.prosilica.Prosilica|204464 "PacketSize=1504;PixelFormat=Mono8;BinningX=1;BinningY=1;RegionX=290;RegionY=130;Width=1000;Height=1000;MulticastEnable=Off"||-200|false
+#gripper_cam=ch.psi.pshell.imaging.MjpegSource|http://axis-accc8ea5e463.psi.ch/axis-cgi/mjpg/video.cgi?camera=1 reopen||-200|false
+#monitoring_cam=ch.psi.pshell.imaging.MjpegSource|http://axis-accc8ea5e463.psi.ch/axis-cgi/mjpg/video.cgi?camera=2 reopen||-200|
+#top_cam=ch.psi.pshell.imaging.MjpegSource|http://axis-accc8ea5e463.psi.ch/axis-cgi/mjpg/video.cgi?camera=3 true||-200|
+#cam=ch.psi.pshell.epics.AreaDetector|MX-SAMCAM|||
+mscan_pin=ch.psi.pshell.serial.TcpDevice|129.129.110.109:2001|||
+mscan_pin_cmd=ch.psi.pshell.serial.TcpDevice|129.129.110.109:2003|||
+mscan_puck=ch.psi.pshell.serial.TcpDevice|129.129.110.93:2001|||
+mscan_puck_cmd=ch.psi.pshell.serial.TcpDevice|129.129.110.93:2003|||
+ue=LaserUE|COM3 50 35|||true
+puck_detection=ch.psi.mxsc.PuckDetection|tell6d-raspberrypi:5556|||
+wago=ch.psi.pshell.modbus.ModbusTCP|tell6d-wago:502|||
+led_ok_1=ch.psi.pshell.modbus.DigitalInput|wago 0||1000|
+led_ok_2=ch.psi.pshell.modbus.DigitalInput|wago 1||1000|
+led_ok_3=ch.psi.pshell.modbus.DigitalInput|wago 2||1000|
+feedback_local_safety=ch.psi.pshell.modbus.DigitalInput|wago 3||1000|
+feedback_psys_safety=ch.psi.pshell.modbus.DigitalInput|wago 4||1000|
+filling_dewar=ch.psi.pshell.modbus.DigitalInput|wago 5||1000|
+dewar_level_high_alarm=ch.psi.pshell.modbus.DigitalInput|wago 6||1000|
+guiding_tool_park=ch.psi.pshell.modbus.DigitalInput|wago 7||1000|
+air_pressure_ok=ch.psi.pshell.modbus.DigitalInput|wago 8||1000|false
+n2_pressure_ok=ch.psi.pshell.modbus.DigitalInput|wago 9||1000|
+smc_magnet_status=ch.psi.pshell.modbus.DigitalInput|wago 10||1000|
+smc_mounted_1=ch.psi.pshell.modbus.DigitalInput|wago 11||1000|
+smc_mounted_2=ch.psi.pshell.modbus.DigitalInput|wago 12||1000|
+magnet_release=ch.psi.pshell.modbus.DigitalInput|wago 13||500|
+detector_cleared=ch.psi.pshell.modbus.DigitalInput|wago 14||1000|
+spare_di_3=ch.psi.pshell.modbus.DigitalInput|wago 15||1000|
+spare_di_4=ch.psi.pshell.modbus.DigitalInput|wago 16||1000|
+relays=ch.psi.pshell.modbus.DigitalOutputArray|wago 0 16||1000|
+release_local_safety=ch.psi.pshell.modbus.DigitalOutput|wago 0|||
+release_psys_safety=ch.psi.pshell.modbus.DigitalOutput|wago 1|||
+#spare_do_1=ch.psi.pshell.modbus.DigitalOutput|wago 2|||
+#spare_do_2=ch.psi.pshell.modbus.DigitalOutput|wago 3|||
+#spare_do_3=ch.psi.pshell.modbus.DigitalOutput|wago 4|||
+gripper_dryer=ch.psi.pshell.modbus.DigitalOutput|wago 5|||
+smc_sup_det=ch.psi.pshell.modbus.DigitalOutput|wago 6|||
+valve_1=ch.psi.pshell.modbus.DigitalOutput|wago 7||1000|
+valve_2=ch.psi.pshell.modbus.DigitalOutput|wago 10||1000|
+valve_3=ch.psi.pshell.modbus.DigitalOutput|wago 8||1000|
+valve_4=ch.psi.pshell.modbus.DigitalOutput|wago 11||1000|
+valve_5=ch.psi.pshell.modbus.DigitalOutput|wago 9||1000|
+valve_6=ch.psi.pshell.modbus.DigitalOutput|wago 12||1000|
+valve_7=ch.psi.pshell.modbus.DigitalOutput|wago 13||1000|
+valve_8=ch.psi.pshell.modbus.DigitalOutput|wago 14||1000|
+dewar_level=ch.psi.pshell.modbus.ReadonlyProcessVariable|wago 0||10000|
+rim_heater_temp=ch.psi.pshell.modbus.ReadonlyProcessVariable|wago 1||10000|
+#spare_ai_1=ch.psi.pshell.modbus.AnalogInput|wago 2|||false
+#spare_ai_2=ch.psi.pshell.modbus.AnalogInput|wago 3|||
+smc_current_rb=ch.psi.pshell.modbus.ReadonlyProcessVariable|wago 4||1000|
+#spare_ai_3=ch.psi.pshell.modbus.AnalogInput|wago 5|||
+#spare_ai_4=ch.psi.pshell.modbus.AnalogInput|wago 6|||
+#spare_ai_5=ch.psi.pshell.modbus.AnalogInput|wago 7|||
+led_ctrl_1=ch.psi.pshell.modbus.ProcessVariable|wago 0|||
+led_ctrl_2=ch.psi.pshell.modbus.ProcessVariable|wago 1|||
+led_ctrl_3=ch.psi.pshell.modbus.ProcessVariable|wago 2|||
+smc_current=ch.psi.pshell.modbus.ProcessVariable|wago 3|||
diff --git a/config/jcae.properties b/config/jcae.properties
new file mode 100644
index 0000000..2bb0691
--- /dev/null
+++ b/config/jcae.properties
@@ -0,0 +1,11 @@
+#Tue Sep 06 15:10:24 CEST 2016
+ch.psi.jcae.ContextFactory.addressList=
+ch.psi.jcae.ContextFactory.serverPort=
+ch.psi.jcae.ContextFactory.maxArrayBytes=20000000
+ch.psi.jcae.ChannelFactory.retries=1
+ch.psi.jcae.ChannelFactory.timeout=500
+ch.psi.jcae.impl.DefaultChannelService.retries=2
+ch.psi.jcae.impl.DefaultChannelService.timeout=1000
+ch.psi.jcae.ContextFactory.autoAddressList=true
+ch.psi.jcae.ContextFactory.useShellVariables=false
+ch.psi.jcae.ContextFactory.addLocalBroadcastInterfaces=false
diff --git a/config/mail.properties b/config/mail.properties
new file mode 100644
index 0000000..e04b672
--- /dev/null
+++ b/config/mail.properties
@@ -0,0 +1,9 @@
+#Mon Oct 23 10:53:54 CEST 2017
+auth=None
+from=
+host=
+port=0
+pwd=
+smsSuffix=@sms.switch.ch
+to=
+usr=
diff --git a/config/plugins.properties b/config/plugins.properties
new file mode 100644
index 0000000..1522a96
--- /dev/null
+++ b/config/plugins.properties
@@ -0,0 +1,21 @@
+MXSC-1.10.0\ -\ Back.jar=disabled
+Commands.java=disabled
+Recovery.java=disabled
+MXSC-1.10.0.jar=disabled
+WagoPanel.java=enabled
+LaserUEPanel.java=enabled
+BarcodeReaderPanel.java=enabled
+PuckDetectionPanel.java=enabled
+HexiposiPanel.java=enabled
+MjpegSource2.java=enabled
+LN2.java=disabled
+Hexiposi.java=disabled
+RobotPanel.java=enabled
+SmartMagnetConfig.java=disabled
+SmartMagnetPanel.java=enabled
+LaserUE.java=enabled
+TestZMQ.java=disabled
+RobotModbus.java=disabled
+RobotTcp.java=disabled
+Beeper.java=disabled
+gui.java=disabled
diff --git a/config/settings.properties b/config/settings.properties
new file mode 100644
index 0000000..fd12ba9
--- /dev/null
+++ b/config/settings.properties
@@ -0,0 +1,19 @@
+#Tue Sep 08 11:53:06 CEST 2020
+dry_mount_counter=1
+room_temperature_enabled=false
+pin_offset=0.0
+puck_types=true
+pin_cleaner_timer=60
+imaging_enabled=false
+dry_timestamp=1.599556340515E9
+roi_h=1000
+led_level=0.0
+beamline_status_enabled=false
+force_dry_mount_count=15
+roi_y=123
+barcode_reader_scan_pucks=false
+cold_position_timeout=3600
+force_dry_timeout=2700
+roi_w=1000
+roi_x=289
+valve_control=false
diff --git a/config/setup-modbus.properties b/config/setup-modbus.properties
new file mode 100644
index 0000000..eb292c1
--- /dev/null
+++ b/config/setup-modbus.properties
@@ -0,0 +1,18 @@
+#Wed Sep 14 15:16:45 CEST 2016
+configFile={config}/config.properties
+configFileDevices={config}/devices-modbus.properties
+configFilePlugins={config}/plugins.properties
+configFileTasks={config}/tasks.properties
+configPath={home}/config
+contextPath={outp}/context
+dataPath={outp}/data
+devicesPath={home}/devices
+extensionsPath={home}/extensions
+imagesPath={outp}/images
+libraryPath={script}; {script}/Lib
+logPath={outp}/log
+pluginsPath={home}/plugins
+scriptPath={home}/script
+scriptType=py
+sessionsPath={outp}/sessions
+wwwPath={home}/www
diff --git a/config/setup.properties b/config/setup.properties
new file mode 100644
index 0000000..7ad15eb
--- /dev/null
+++ b/config/setup.properties
@@ -0,0 +1,20 @@
+#Tue Sep 17 15:06:05 CEST 2019
+configFile={config}/config.properties
+configFileDevices={config}/devices.properties
+configFilePlugins={config}/plugins.properties
+configFileSettings={config}/settings.properties
+configFileTasks={config}/tasks.properties
+configFileVariables={config}/variables.properties
+configPath={home}/config
+contextPath={outp}/context
+dataPath={outp}/data
+devicesPath={home}/devices
+extensionsPath={home}/extensions
+imagesPath={outp}/images
+libraryPath={script}; {script}/Lib
+logPath={outp}/log
+pluginsPath={home}/plugins
+scriptPath={home}/script
+scriptType=py
+sessionsPath={outp}/sessions
+wwwPath={home}/www
diff --git a/config/tasks.properties b/config/tasks.properties
new file mode 100644
index 0000000..92f138b
--- /dev/null
+++ b/config/tasks.properties
@@ -0,0 +1,2 @@
+tasks/LedMonitoring=120
+tasks/ColdPositionTimeout=300
diff --git a/config/variables.properties b/config/variables.properties
new file mode 100644
index 0000000..d3aee7a
--- /dev/null
+++ b/config/variables.properties
@@ -0,0 +1,2 @@
+#Tue Sep 01 09:11:47 CEST 2020
+FileSequentialNumber=184
diff --git a/devices/20161117_163816.png.properties b/devices/20161117_163816.png.properties
new file mode 100644
index 0000000..be1fd91
--- /dev/null
+++ b/devices/20161117_163816.png.properties
@@ -0,0 +1,20 @@
+#Mon Oct 23 15:10:20 CEST 2017
+flipHorizontally=false
+flipVertically=false
+grayscale=false
+invert=false
+rescaleFactor=1.0
+rescaleOffset=0.0
+roiHeight=-1
+roiWidth=-1
+roiX=0
+roiY=0
+rotation=0.0
+rotationCrop=false
+scale=1.0
+spatialCalOffsetX=NaN
+spatialCalOffsetY=NaN
+spatialCalScaleX=NaN
+spatialCalScaleY=NaN
+spatialCalUnits=mm
+transpose=false
diff --git a/devices/A1.properties b/devices/A1.properties
new file mode 100644
index 0000000..d9b32f1
--- /dev/null
+++ b/devices/A1.properties
@@ -0,0 +1,3 @@
+#Fri Jan 31 16:58:30 CET 2020
+detection=Mechanical
+disabled=false
diff --git a/devices/A2.properties b/devices/A2.properties
new file mode 100644
index 0000000..ce6347e
--- /dev/null
+++ b/devices/A2.properties
@@ -0,0 +1,3 @@
+#Thu Jun 06 15:47:03 CEST 2019
+detection=Mechanical
+disabled=false
diff --git a/devices/A3.properties b/devices/A3.properties
new file mode 100644
index 0000000..d21184c
--- /dev/null
+++ b/devices/A3.properties
@@ -0,0 +1,3 @@
+#Tue Jan 21 09:46:43 CET 2020
+detection=Mechanical
+disabled=false
diff --git a/devices/A4.properties b/devices/A4.properties
new file mode 100644
index 0000000..502a5d0
--- /dev/null
+++ b/devices/A4.properties
@@ -0,0 +1,3 @@
+#Thu Jun 06 15:40:34 CEST 2019
+detection=Mechanical
+disabled=false
diff --git a/devices/A5.properties b/devices/A5.properties
new file mode 100644
index 0000000..adcc5f3
--- /dev/null
+++ b/devices/A5.properties
@@ -0,0 +1,3 @@
+#Tue Jan 21 09:46:49 CET 2020
+detection=Mechanical
+disabled=false
diff --git a/devices/B1.properties b/devices/B1.properties
new file mode 100644
index 0000000..22f2102
--- /dev/null
+++ b/devices/B1.properties
@@ -0,0 +1,3 @@
+#Mon Apr 29 16:18:33 CEST 2019
+detection=Mechanical
+disabled=false
diff --git a/devices/B2.properties b/devices/B2.properties
new file mode 100644
index 0000000..ea802c8
--- /dev/null
+++ b/devices/B2.properties
@@ -0,0 +1,3 @@
+#Mon Apr 29 16:40:00 CEST 2019
+detection=Mechanical
+disabled=false
diff --git a/devices/B3.properties b/devices/B3.properties
new file mode 100644
index 0000000..ad0f99d
--- /dev/null
+++ b/devices/B3.properties
@@ -0,0 +1,3 @@
+#Tue Sep 01 14:03:17 CEST 2020
+detection=Mechanical
+disabled=false
diff --git a/devices/B4.properties b/devices/B4.properties
new file mode 100644
index 0000000..074e71d
--- /dev/null
+++ b/devices/B4.properties
@@ -0,0 +1,3 @@
+#Sat Dec 14 17:27:09 CET 2019
+detection=Mechanical
+disabled=false
diff --git a/devices/B5.properties b/devices/B5.properties
new file mode 100644
index 0000000..f768e0f
--- /dev/null
+++ b/devices/B5.properties
@@ -0,0 +1,3 @@
+#Wed Dec 11 08:55:08 CET 2019
+detection=Mechanical
+disabled=false
diff --git a/devices/BasePlate.properties b/devices/BasePlate.properties
new file mode 100644
index 0000000..1e25f83
--- /dev/null
+++ b/devices/BasePlate.properties
@@ -0,0 +1 @@
+#Fri Feb 10 14:35:38 CET 2017
diff --git a/devices/C1.properties b/devices/C1.properties
new file mode 100644
index 0000000..52198c1
--- /dev/null
+++ b/devices/C1.properties
@@ -0,0 +1,3 @@
+#Tue Sep 01 08:37:42 CEST 2020
+detection=Mechanical
+disabled=false
diff --git a/devices/C2.properties b/devices/C2.properties
new file mode 100644
index 0000000..fbcc31c
--- /dev/null
+++ b/devices/C2.properties
@@ -0,0 +1,3 @@
+#Tue Sep 01 13:18:50 CEST 2020
+detection=Mechanical
+disabled=false
diff --git a/devices/C3.properties b/devices/C3.properties
new file mode 100644
index 0000000..5210a65
--- /dev/null
+++ b/devices/C3.properties
@@ -0,0 +1,3 @@
+#Thu Sep 19 08:23:37 CEST 2019
+detection=Mechanical
+disabled=false
diff --git a/devices/C4.properties b/devices/C4.properties
new file mode 100644
index 0000000..61fba0c
--- /dev/null
+++ b/devices/C4.properties
@@ -0,0 +1,3 @@
+#Wed Dec 11 08:56:26 CET 2019
+detection=Mechanical
+disabled=false
diff --git a/devices/C5.properties b/devices/C5.properties
new file mode 100644
index 0000000..354cfeb
--- /dev/null
+++ b/devices/C5.properties
@@ -0,0 +1,3 @@
+#Thu Sep 19 08:23:43 CEST 2019
+detection=Mechanical
+disabled=false
diff --git a/devices/D1.properties b/devices/D1.properties
new file mode 100644
index 0000000..d83b456
--- /dev/null
+++ b/devices/D1.properties
@@ -0,0 +1,3 @@
+#Thu Sep 19 08:23:48 CEST 2019
+detection=Mechanical
+disabled=false
diff --git a/devices/D2.properties b/devices/D2.properties
new file mode 100644
index 0000000..a5df751
--- /dev/null
+++ b/devices/D2.properties
@@ -0,0 +1,3 @@
+#Tue Sep 08 09:28:59 CEST 2020
+detection=Mechanical
+disabled=false
diff --git a/devices/D3.properties b/devices/D3.properties
new file mode 100644
index 0000000..2e933c9
--- /dev/null
+++ b/devices/D3.properties
@@ -0,0 +1,3 @@
+#Tue Sep 08 09:29:02 CEST 2020
+detection=Mechanical
+disabled=false
diff --git a/devices/D4.properties b/devices/D4.properties
new file mode 100644
index 0000000..1be19b4
--- /dev/null
+++ b/devices/D4.properties
@@ -0,0 +1,3 @@
+#Tue Sep 08 09:29:05 CEST 2020
+detection=Mechanical
+disabled=false
diff --git a/devices/D5.properties b/devices/D5.properties
new file mode 100644
index 0000000..9d34242
--- /dev/null
+++ b/devices/D5.properties
@@ -0,0 +1,3 @@
+#Tue Sep 08 09:29:08 CEST 2020
+detection=Mechanical
+disabled=false
diff --git a/devices/E1.properties b/devices/E1.properties
new file mode 100644
index 0000000..861f9f8
--- /dev/null
+++ b/devices/E1.properties
@@ -0,0 +1,3 @@
+#Fri Aug 14 14:28:32 CEST 2020
+detection=Mechanical
+disabled=true
diff --git a/devices/E2.properties b/devices/E2.properties
new file mode 100644
index 0000000..34dabc7
--- /dev/null
+++ b/devices/E2.properties
@@ -0,0 +1,3 @@
+#Fri Aug 14 10:51:15 CEST 2020
+detection=Mechanical
+disabled=true
diff --git a/devices/E3.properties b/devices/E3.properties
new file mode 100644
index 0000000..a133c30
--- /dev/null
+++ b/devices/E3.properties
@@ -0,0 +1,3 @@
+#Fri Aug 14 10:51:19 CEST 2020
+detection=Mechanical
+disabled=true
diff --git a/devices/E4.properties b/devices/E4.properties
new file mode 100644
index 0000000..818280c
--- /dev/null
+++ b/devices/E4.properties
@@ -0,0 +1,3 @@
+#Fri Aug 14 10:51:24 CEST 2020
+detection=Mechanical
+disabled=true
diff --git a/devices/E5.properties b/devices/E5.properties
new file mode 100644
index 0000000..7fb793f
--- /dev/null
+++ b/devices/E5.properties
@@ -0,0 +1,3 @@
+#Fri Aug 14 10:51:29 CEST 2020
+detection=Mechanical
+disabled=true
diff --git a/devices/F1.properties b/devices/F1.properties
new file mode 100644
index 0000000..b9fd935
--- /dev/null
+++ b/devices/F1.properties
@@ -0,0 +1,3 @@
+#Fri Aug 14 11:31:09 CEST 2020
+detection=Mechanical
+disabled=true
diff --git a/devices/F2.properties b/devices/F2.properties
new file mode 100644
index 0000000..12b665e
--- /dev/null
+++ b/devices/F2.properties
@@ -0,0 +1,3 @@
+#Fri Aug 14 10:51:39 CEST 2020
+detection=Mechanical
+disabled=true
diff --git a/devices/F3.properties b/devices/F3.properties
new file mode 100644
index 0000000..321743f
--- /dev/null
+++ b/devices/F3.properties
@@ -0,0 +1,3 @@
+#Fri Aug 14 10:51:44 CEST 2020
+detection=Mechanical
+disabled=true
diff --git a/devices/F4.properties b/devices/F4.properties
new file mode 100644
index 0000000..a0e68f2
--- /dev/null
+++ b/devices/F4.properties
@@ -0,0 +1,3 @@
+#Fri Aug 14 10:51:47 CEST 2020
+detection=Mechanical
+disabled=true
diff --git a/devices/F5.properties b/devices/F5.properties
new file mode 100644
index 0000000..2c095dc
--- /dev/null
+++ b/devices/F5.properties
@@ -0,0 +1,3 @@
+#Fri Aug 14 10:51:50 CEST 2020
+detection=Mechanical
+disabled=true
diff --git a/devices/R1.properties b/devices/R1.properties
new file mode 100644
index 0000000..fa91122
--- /dev/null
+++ b/devices/R1.properties
@@ -0,0 +1,3 @@
+#Tue Feb 19 12:07:25 CET 2019
+detection=Both
+disabled=false
diff --git a/devices/R2.properties b/devices/R2.properties
new file mode 100644
index 0000000..fa91122
--- /dev/null
+++ b/devices/R2.properties
@@ -0,0 +1,3 @@
+#Tue Feb 19 12:07:25 CET 2019
+detection=Both
+disabled=false
diff --git a/devices/R3.properties b/devices/R3.properties
new file mode 100644
index 0000000..fa91122
--- /dev/null
+++ b/devices/R3.properties
@@ -0,0 +1,3 @@
+#Tue Feb 19 12:07:25 CET 2019
+detection=Both
+disabled=false
diff --git a/devices/R4.properties b/devices/R4.properties
new file mode 100644
index 0000000..fa91122
--- /dev/null
+++ b/devices/R4.properties
@@ -0,0 +1,3 @@
+#Tue Feb 19 12:07:25 CET 2019
+detection=Both
+disabled=false
diff --git a/devices/R5.properties b/devices/R5.properties
new file mode 100644
index 0000000..fa91122
--- /dev/null
+++ b/devices/R5.properties
@@ -0,0 +1,3 @@
+#Tue Feb 19 12:07:25 CET 2019
+detection=Both
+disabled=false
diff --git a/devices/RoomTemperatureBasePlate.properties b/devices/RoomTemperatureBasePlate.properties
new file mode 100644
index 0000000..a8e063a
--- /dev/null
+++ b/devices/RoomTemperatureBasePlate.properties
@@ -0,0 +1 @@
+#Tue Feb 19 12:07:25 CET 2019
diff --git a/devices/Time.properties b/devices/Time.properties
new file mode 100644
index 0000000..33011f0
--- /dev/null
+++ b/devices/Time.properties
@@ -0,0 +1,10 @@
+#Wed Jun 27 10:48:14 CEST 2018
+maxValue=NaN
+minValue=NaN
+offset=0.0
+precision=-1
+resolution=NaN
+rotation=false
+scale=1.0
+sign_bit=0
+unit=null
diff --git a/devices/air_pressure.properties b/devices/air_pressure.properties
new file mode 100644
index 0000000..e476b09
--- /dev/null
+++ b/devices/air_pressure.properties
@@ -0,0 +1,5 @@
+#Thu Mar 01 11:13:34 CET 2018
+offset=0.0
+precision=-1
+scale=1.0
+unit=null
diff --git a/devices/cx.properties b/devices/cx.properties
new file mode 100644
index 0000000..1720045
--- /dev/null
+++ b/devices/cx.properties
@@ -0,0 +1,17 @@
+#Fri Aug 10 15:47:53 CEST 2018
+defaultSpeed=2.0
+estbilizationDelay=0
+hasEnable=false
+homingType=None
+maxSpeed=NaN
+maxValue=0.0
+minSpeed=NaN
+minValue=0.0
+offset=0.0
+precision=3
+resolution=0.001
+rotation=false
+scale=1.0
+sign_bit=0
+startRetries=1
+unit=mm
diff --git a/devices/cz.properties b/devices/cz.properties
new file mode 100644
index 0000000..b8877dd
--- /dev/null
+++ b/devices/cz.properties
@@ -0,0 +1,17 @@
+#Fri Aug 10 15:47:15 CEST 2018
+defaultSpeed=2.0
+estbilizationDelay=0
+hasEnable=false
+homingType=None
+maxSpeed=NaN
+maxValue=0.0
+minSpeed=NaN
+minValue=0.0
+offset=0.0
+precision=3
+resolution=0.001
+rotation=false
+scale=1.0
+sign_bit=0
+startRetries=1
+unit=mm
diff --git a/devices/dewar_level.properties b/devices/dewar_level.properties
new file mode 100644
index 0000000..ac55365
--- /dev/null
+++ b/devices/dewar_level.properties
@@ -0,0 +1,6 @@
+#Tue Jan 22 10:58:09 CET 2019
+offset=0.0
+precision=2
+scale=0.0032
+sign_bit=0
+unit=%
diff --git a/devices/dispatcher.properties b/devices/dispatcher.properties
new file mode 100644
index 0000000..5a3e672
--- /dev/null
+++ b/devices/dispatcher.properties
@@ -0,0 +1,11 @@
+#Thu May 03 11:54:38 CEST 2018
+disableCompression=false
+keepListeningOnStop=false
+mappingIncomplete=null
+parallelHandlerProcessing=true
+sendAwaitFirstMessage=false
+sendBuildChannelConfig=null
+sendStrategy=null
+sendSyncTimeout=0
+socketType=DEFAULT
+validationInconsistency=null
diff --git a/devices/dp1.properties b/devices/dp1.properties
new file mode 100644
index 0000000..c853c11
--- /dev/null
+++ b/devices/dp1.properties
@@ -0,0 +1,11 @@
+#Fri Jul 08 10:53:26 CEST 2016
+motor1=0.0|4.0|8.0|0.0
+motor2=0.0|5.0|3.0|NaN
+motor3=null
+motor4=null
+motor5=null
+motor6=null
+motor7=null
+motor8=null
+positions=Park|Ready|Out|Clear
+precision=-1
diff --git a/devices/fx.properties b/devices/fx.properties
new file mode 100644
index 0000000..44a1a35
--- /dev/null
+++ b/devices/fx.properties
@@ -0,0 +1,17 @@
+#Fri Aug 10 15:47:14 CEST 2018
+defaultSpeed=2.0
+estbilizationDelay=0
+hasEnable=false
+homingType=None
+maxSpeed=NaN
+maxValue=0.0
+minSpeed=NaN
+minValue=0.0
+offset=0.0
+precision=3
+resolution=0.001
+rotation=false
+scale=1.0
+sign_bit=0
+startRetries=1
+unit=mm
diff --git a/devices/fy.properties b/devices/fy.properties
new file mode 100644
index 0000000..44a1a35
--- /dev/null
+++ b/devices/fy.properties
@@ -0,0 +1,17 @@
+#Fri Aug 10 15:47:14 CEST 2018
+defaultSpeed=2.0
+estbilizationDelay=0
+hasEnable=false
+homingType=None
+maxSpeed=NaN
+maxValue=0.0
+minSpeed=NaN
+minValue=0.0
+offset=0.0
+precision=3
+resolution=0.001
+rotation=false
+scale=1.0
+sign_bit=0
+startRetries=1
+unit=mm
diff --git a/devices/gripper_cam.properties b/devices/gripper_cam.properties
new file mode 100644
index 0000000..6fc903f
--- /dev/null
+++ b/devices/gripper_cam.properties
@@ -0,0 +1,20 @@
+#Thu Jun 28 17:46:46 CEST 2018
+flipHorizontally=false
+flipVertically=false
+grayscale=false
+invert=false
+rescaleFactor=1.0
+rescaleOffset=0.0
+roiHeight=-1
+roiWidth=-1
+roiX=0
+roiY=0
+rotation=0.0
+rotationCrop=false
+scale=1.0
+spatialCalOffsetX=NaN
+spatialCalOffsetY=NaN
+spatialCalScaleX=NaN
+spatialCalScaleY=NaN
+spatialCalUnits=mm
+transpose=false
diff --git a/devices/img.properties b/devices/img.properties
new file mode 100644
index 0000000..8ef03e0
--- /dev/null
+++ b/devices/img.properties
@@ -0,0 +1,24 @@
+#Wed Oct 30 16:03:50 CET 2019
+spatialCalOffsetY=-482.0
+invert=false
+colormapMin=6.4
+spatialCalOffsetX=-476.0
+rotation=90.5119714057
+rotationCrop=true
+scale=1.0
+rescaleFactor=1.0
+grayscale=false
+spatialCalUnits=mm
+flipVertically=false
+roiHeight=964
+spatialCalScaleX=0.49344173073372655
+spatialCalScaleY=0.48738915251539194
+flipHorizontally=false
+colormapAutomatic=false
+colormapMax=18.133
+roiY=17
+roiX=25
+rescaleOffset=0.0
+roiWidth=952
+transpose=false
+colormap=Grayscale
diff --git a/devices/led_ctrl.properties b/devices/led_ctrl.properties
new file mode 100644
index 0000000..00dcc48
--- /dev/null
+++ b/devices/led_ctrl.properties
@@ -0,0 +1,8 @@
+#Tue Jun 20 15:07:30 CEST 2017
+maxValue=0.4
+minValue=0.0
+offset=0.0
+precision=2
+resolution=NaN
+scale=3.0E-4
+unit=V
diff --git a/devices/led_ctrl_1.properties b/devices/led_ctrl_1.properties
new file mode 100644
index 0000000..eb9cf02
--- /dev/null
+++ b/devices/led_ctrl_1.properties
@@ -0,0 +1,9 @@
+#Mon Sep 07 09:39:40 CEST 2020
+minValue=0.0
+unit=V
+offset=0.0
+maxValue=1.0
+precision=2
+sign_bit=0
+scale=3.0E-4
+resolution=NaN
diff --git a/devices/led_ctrl_2.properties b/devices/led_ctrl_2.properties
new file mode 100644
index 0000000..eb9cf02
--- /dev/null
+++ b/devices/led_ctrl_2.properties
@@ -0,0 +1,9 @@
+#Mon Sep 07 09:39:40 CEST 2020
+minValue=0.0
+unit=V
+offset=0.0
+maxValue=1.0
+precision=2
+sign_bit=0
+scale=3.0E-4
+resolution=NaN
diff --git a/devices/led_ctrl_3.properties b/devices/led_ctrl_3.properties
new file mode 100644
index 0000000..eb9cf02
--- /dev/null
+++ b/devices/led_ctrl_3.properties
@@ -0,0 +1,9 @@
+#Mon Sep 07 09:39:40 CEST 2020
+minValue=0.0
+unit=V
+offset=0.0
+maxValue=1.0
+precision=2
+sign_bit=0
+scale=3.0E-4
+resolution=NaN
diff --git a/devices/led_level.properties b/devices/led_level.properties
new file mode 100644
index 0000000..52dee03
--- /dev/null
+++ b/devices/led_level.properties
@@ -0,0 +1,9 @@
+#Tue Jun 19 16:41:24 CEST 2018
+maxValue=NaN
+minValue=NaN
+offset=0.0
+precision=-1
+resolution=NaN
+scale=1.0
+sign_bit=0
+unit=null
diff --git a/devices/m1.properties b/devices/m1.properties
new file mode 100644
index 0000000..1cf4553
--- /dev/null
+++ b/devices/m1.properties
@@ -0,0 +1,13 @@
+#Fri Jun 30 09:37:38 CEST 2017
+defaultSpeed=1.0
+estbilizationDelay=0
+maxSpeed=10.0
+maxValue=10.0
+minSpeed=0.1
+minValue=-10.0
+offset=0.0
+precision=2
+resolution=NaN
+rotation=false
+scale=1.0
+unit=mm
diff --git a/devices/m2.properties b/devices/m2.properties
new file mode 100644
index 0000000..1cf4553
--- /dev/null
+++ b/devices/m2.properties
@@ -0,0 +1,13 @@
+#Fri Jun 30 09:37:38 CEST 2017
+defaultSpeed=1.0
+estbilizationDelay=0
+maxSpeed=10.0
+maxValue=10.0
+minSpeed=0.1
+minValue=-10.0
+offset=0.0
+precision=2
+resolution=NaN
+rotation=false
+scale=1.0
+unit=mm
diff --git a/devices/monitoring_cam.properties b/devices/monitoring_cam.properties
new file mode 100644
index 0000000..fa56b35
--- /dev/null
+++ b/devices/monitoring_cam.properties
@@ -0,0 +1,20 @@
+#Thu Aug 09 11:01:09 CEST 2018
+flipHorizontally=false
+flipVertically=false
+grayscale=false
+invert=false
+rescaleFactor=1.0
+rescaleOffset=0.0
+roiHeight=-1
+roiWidth=-1
+roiX=0
+roiY=0
+rotation=0.0
+rotationCrop=false
+scale=1.0
+spatialCalOffsetX=NaN
+spatialCalOffsetY=NaN
+spatialCalScaleX=NaN
+spatialCalScaleY=NaN
+spatialCalUnits=mm
+transpose=false
diff --git a/devices/n2_pressure.properties b/devices/n2_pressure.properties
new file mode 100644
index 0000000..e476b09
--- /dev/null
+++ b/devices/n2_pressure.properties
@@ -0,0 +1,5 @@
+#Thu Mar 01 11:13:34 CET 2018
+offset=0.0
+precision=-1
+scale=1.0
+unit=null
diff --git a/devices/p1.properties b/devices/p1.properties
new file mode 100644
index 0000000..07d9ba5
--- /dev/null
+++ b/devices/p1.properties
@@ -0,0 +1,9 @@
+#Fri Jun 30 09:37:38 CEST 2017
+maxValue=1000.0
+minValue=0.0
+offset=0.0
+precision=-1
+resolution=NaN
+rotation=false
+scale=1.0
+unit=mm
diff --git a/devices/phase_separator.properties b/devices/phase_separator.properties
new file mode 100644
index 0000000..122f8e9
--- /dev/null
+++ b/devices/phase_separator.properties
@@ -0,0 +1,8 @@
+#Wed Feb 28 17:35:59 CET 2018
+maxValue=30000.0
+minValue=0.0
+offset=0.0
+precision=-1
+resolution=NaN
+scale=0.1
+unit=%
diff --git a/devices/phase_separator_level.properties b/devices/phase_separator_level.properties
new file mode 100644
index 0000000..92a5279
--- /dev/null
+++ b/devices/phase_separator_level.properties
@@ -0,0 +1,6 @@
+#Tue Jun 19 16:41:20 CEST 2018
+offset=-25.81632
+precision=2
+scale=0.003888
+sign_bit=0
+unit=%
diff --git a/devices/rim_heater_temp.properties b/devices/rim_heater_temp.properties
new file mode 100644
index 0000000..e1c3b95
--- /dev/null
+++ b/devices/rim_heater_temp.properties
@@ -0,0 +1,6 @@
+#Tue Jun 19 16:41:20 CEST 2018
+offset=-25.81632
+precision=2
+scale=0.003888
+sign_bit=0
+unit=C
diff --git a/devices/robot x.properties b/devices/robot x.properties
new file mode 100644
index 0000000..02ffbf3
--- /dev/null
+++ b/devices/robot x.properties
@@ -0,0 +1,9 @@
+#Tue Sep 12 15:00:38 CEST 2017
+maxValue=NaN
+minValue=NaN
+offset=0.0
+precision=-1
+resolution=NaN
+rotation=false
+scale=1.0
+unit=null
diff --git a/devices/robot.properties b/devices/robot.properties
new file mode 100644
index 0000000..97f6ad6
--- /dev/null
+++ b/devices/robot.properties
@@ -0,0 +1,8 @@
+#Thu Jul 21 08:35:47 CEST 2016
+offsetReadAnalogInput=0
+offsetReadAnalogOutput=0
+offsetReadDigitalInput=0
+offsetReadDigitalOutput=0
+offsetWriteAnalogOutput=0
+offsetWriteDigitalOutput=0
+timeout=1000
diff --git a/devices/robot_j1.properties b/devices/robot_j1.properties
new file mode 100644
index 0000000..bc3a381
--- /dev/null
+++ b/devices/robot_j1.properties
@@ -0,0 +1,10 @@
+#Tue Jun 19 16:41:28 CEST 2018
+maxValue=180.0
+minValue=-180.0
+offset=0.0
+precision=2
+resolution=0.1
+rotation=false
+scale=1.0
+sign_bit=0
+unit=deg
diff --git a/devices/robot_j2.properties b/devices/robot_j2.properties
new file mode 100644
index 0000000..6a892bc
--- /dev/null
+++ b/devices/robot_j2.properties
@@ -0,0 +1,10 @@
+#Tue Jun 19 16:41:28 CEST 2018
+maxValue=127.5
+minValue=-127.5
+offset=0.0
+precision=2
+resolution=0.1
+rotation=false
+scale=1.0
+sign_bit=0
+unit=deg
diff --git a/devices/robot_j3.properties b/devices/robot_j3.properties
new file mode 100644
index 0000000..07bff75
--- /dev/null
+++ b/devices/robot_j3.properties
@@ -0,0 +1,10 @@
+#Tue Jun 19 16:41:28 CEST 2018
+maxValue=152.5
+minValue=-152.5
+offset=0.0
+precision=2
+resolution=0.1
+rotation=false
+scale=1.0
+sign_bit=0
+unit=deg
diff --git a/devices/robot_j4.properties b/devices/robot_j4.properties
new file mode 100644
index 0000000..41d8586
--- /dev/null
+++ b/devices/robot_j4.properties
@@ -0,0 +1,10 @@
+#Tue Jun 19 16:41:28 CEST 2018
+maxValue=270.0
+minValue=-270.0
+offset=0.0
+precision=2
+resolution=0.1
+rotation=false
+scale=1.0
+sign_bit=0
+unit=deg
diff --git a/devices/robot_j5.properties b/devices/robot_j5.properties
new file mode 100644
index 0000000..dab429f
--- /dev/null
+++ b/devices/robot_j5.properties
@@ -0,0 +1,10 @@
+#Tue Jun 19 16:41:28 CEST 2018
+maxValue=132.5
+minValue=-122.5
+offset=0.0
+precision=2
+resolution=0.1
+rotation=false
+scale=1.0
+sign_bit=0
+unit=deg
diff --git a/devices/robot_j6.properties b/devices/robot_j6.properties
new file mode 100644
index 0000000..d688634
--- /dev/null
+++ b/devices/robot_j6.properties
@@ -0,0 +1,10 @@
+#Fri Aug 24 14:56:42 CEST 2018
+maxValue=400.0
+minValue=-400.0
+offset=0.0
+precision=2
+resolution=0.1
+rotation=false
+scale=1.0
+sign_bit=0
+unit=deg
diff --git a/devices/robot_modbus.properties b/devices/robot_modbus.properties
new file mode 100644
index 0000000..31a13be
--- /dev/null
+++ b/devices/robot_modbus.properties
@@ -0,0 +1,8 @@
+#Thu Jul 21 12:02:04 CEST 2016
+offsetReadAnalogInput=0
+offsetReadAnalogOutput=0
+offsetReadDigitalInput=0
+offsetReadDigitalOutput=0
+offsetWriteAnalogOutput=0
+offsetWriteDigitalOutput=0
+timeout=1000
diff --git a/devices/robot_rx.properties b/devices/robot_rx.properties
new file mode 100644
index 0000000..df63f03
--- /dev/null
+++ b/devices/robot_rx.properties
@@ -0,0 +1,10 @@
+#Tue Jun 19 16:41:28 CEST 2018
+maxValue=180.0
+minValue=-180.0
+offset=0.0
+precision=2
+resolution=0.05
+rotation=true
+scale=1.0
+sign_bit=0
+unit=deg
diff --git a/devices/robot_ry.properties b/devices/robot_ry.properties
new file mode 100644
index 0000000..a789ebf
--- /dev/null
+++ b/devices/robot_ry.properties
@@ -0,0 +1,10 @@
+#Tue Jun 19 16:41:28 CEST 2018
+maxValue=180.0
+minValue=-180.0
+offset=0.0
+precision=-2
+resolution=0.05
+rotation=true
+scale=1.0
+sign_bit=0
+unit=deg
diff --git a/devices/robot_rz.properties b/devices/robot_rz.properties
new file mode 100644
index 0000000..2b88035
--- /dev/null
+++ b/devices/robot_rz.properties
@@ -0,0 +1,10 @@
+#Tue Jun 19 16:41:28 CEST 2018
+maxValue=360.0
+minValue=-360.0
+offset=0.0
+precision=2
+resolution=0.1
+rotation=true
+scale=1.0
+sign_bit=0
+unit=deg
diff --git a/devices/robot_x.properties b/devices/robot_x.properties
new file mode 100644
index 0000000..5cdadcc
--- /dev/null
+++ b/devices/robot_x.properties
@@ -0,0 +1,10 @@
+#Tue Jun 19 16:41:28 CEST 2018
+maxValue=1000.0
+minValue=-1000.0
+offset=0.0
+precision=2
+resolution=0.05
+rotation=false
+scale=1.0
+sign_bit=0
+unit=mm
diff --git a/devices/robot_y.properties b/devices/robot_y.properties
new file mode 100644
index 0000000..eb8022e
--- /dev/null
+++ b/devices/robot_y.properties
@@ -0,0 +1,10 @@
+#Tue Jun 19 16:41:28 CEST 2018
+maxValue=1000.0
+minValue=-1000.0
+offset=0.0
+precision=2
+resolution=0.05
+rotation=false
+scale=1.0
+sign_bit=0
+unit=null
diff --git a/devices/robot_z.properties b/devices/robot_z.properties
new file mode 100644
index 0000000..eb8022e
--- /dev/null
+++ b/devices/robot_z.properties
@@ -0,0 +1,10 @@
+#Tue Jun 19 16:41:28 CEST 2018
+maxValue=1000.0
+minValue=-1000.0
+offset=0.0
+precision=2
+resolution=0.05
+rotation=false
+scale=1.0
+sign_bit=0
+unit=null
diff --git a/devices/ry.properties b/devices/ry.properties
new file mode 100644
index 0000000..f43c3d2
--- /dev/null
+++ b/devices/ry.properties
@@ -0,0 +1,17 @@
+#Fri Aug 10 15:47:14 CEST 2018
+defaultSpeed=50.0
+estbilizationDelay=0
+hasEnable=false
+homingType=None
+maxSpeed=NaN
+maxValue=0.0
+minSpeed=NaN
+minValue=0.0
+offset=0.0
+precision=3
+resolution=0.001
+rotation=false
+scale=1.0
+sign_bit=0
+startRetries=1
+unit=deg
diff --git a/devices/smart_magnet.properties b/devices/smart_magnet.properties
new file mode 100644
index 0000000..18a705b
--- /dev/null
+++ b/devices/smart_magnet.properties
@@ -0,0 +1,8 @@
+#Mon Aug 31 09:09:24 CEST 2020
+reverseTime=0.2
+unmountCurrent=20.0
+holdingCurrent=50.0
+restingCurrent=30.0
+reverseCurrent=-10.0
+remanenceCurrent=-10.0
+mountCurrent=30.0
diff --git a/devices/smc_current.properties b/devices/smc_current.properties
new file mode 100644
index 0000000..9d9ba17
--- /dev/null
+++ b/devices/smc_current.properties
@@ -0,0 +1,9 @@
+#Wed Jan 30 11:33:15 CET 2019
+maxValue=70.0
+minValue=-50.0
+offset=0.0
+precision=2
+resolution=NaN
+scale=0.003
+sign_bit=0
+unit=mA
diff --git a/devices/smc_current_rb.properties b/devices/smc_current_rb.properties
new file mode 100644
index 0000000..7709ada
--- /dev/null
+++ b/devices/smc_current_rb.properties
@@ -0,0 +1,6 @@
+#Tue Jun 19 16:45:06 CEST 2018
+offset=0.0
+precision=2
+scale=0.003
+sign_bit=15
+unit=mA
diff --git a/devices/src1.properties b/devices/src1.properties
new file mode 100644
index 0000000..a0b5d6d
--- /dev/null
+++ b/devices/src1.properties
@@ -0,0 +1,24 @@
+#Thu Sep 22 14:45:06 CEST 2016
+colormap=Temperature
+colormapAutomatic=true
+colormapMax=255.0
+colormapMin=0.0
+flipHorizontally=false
+flipVertically=false
+grayscale=false
+invert=false
+rescaleFactor=1.0
+rescaleOffset=0.0
+roiHeight=-1
+roiWidth=-1
+roiX=0
+roiY=0
+rotation=0.0
+rotationCrop=false
+scale=1.0
+spatialCalOffsetX=NaN
+spatialCalOffsetY=NaN
+spatialCalScaleX=NaN
+spatialCalScaleY=NaN
+spatialCalUnits=mm
+transpose=false
diff --git a/devices/src2.properties b/devices/src2.properties
new file mode 100644
index 0000000..2bf8406
--- /dev/null
+++ b/devices/src2.properties
@@ -0,0 +1,24 @@
+#Thu Sep 22 14:45:06 CEST 2016
+colormap=Grayscale
+colormapAutomatic=true
+colormapMax=255.0
+colormapMin=0.0
+flipHorizontally=false
+flipVertically=false
+grayscale=false
+invert=false
+rescaleFactor=1.0
+rescaleOffset=0.0
+roiHeight=-1
+roiWidth=-1
+roiX=0
+roiY=0
+rotation=0.0
+rotationCrop=false
+scale=1.0
+spatialCalOffsetX=NaN
+spatialCalOffsetY=NaN
+spatialCalScaleX=NaN
+spatialCalScaleY=NaN
+spatialCalUnits=mm
+transpose=false
diff --git a/devices/top_cam.properties b/devices/top_cam.properties
new file mode 100644
index 0000000..827552b
--- /dev/null
+++ b/devices/top_cam.properties
@@ -0,0 +1,20 @@
+#Thu Aug 09 11:46:12 CEST 2018
+flipHorizontally=false
+flipVertically=false
+grayscale=false
+invert=false
+rescaleFactor=1.0
+rescaleOffset=0.0
+roiHeight=-1
+roiWidth=-1
+roiX=0
+roiY=0
+rotation=0.0
+rotationCrop=false
+scale=1.0
+spatialCalOffsetX=NaN
+spatialCalOffsetY=NaN
+spatialCalScaleX=NaN
+spatialCalScaleY=NaN
+spatialCalUnits=mm
+transpose=false
diff --git a/devices/ue.properties b/devices/ue.properties
new file mode 100644
index 0000000..f241f62
--- /dev/null
+++ b/devices/ue.properties
@@ -0,0 +1,6 @@
+#Thu Aug 31 16:41:09 CEST 2017
+baudRate=9600
+dataBits=DB_8
+parity=None
+port=null
+stopBits=SB_1
diff --git a/devices/wago.properties b/devices/wago.properties
new file mode 100644
index 0000000..f2650ea
--- /dev/null
+++ b/devices/wago.properties
@@ -0,0 +1,8 @@
+#Wed Feb 28 16:27:51 CET 2018
+offsetReadAnalogInput=0
+offsetReadAnalogOutput=0x200
+offsetReadDigitalInput=0
+offsetReadDigitalOutput=0x200
+offsetWriteAnalogOutput=0
+offsetWriteDigitalOutput=0
+timeout=1000
diff --git a/plugins/BarcodeReaderPanel.form b/plugins/BarcodeReaderPanel.form
new file mode 100644
index 0000000..1d2c4af
--- /dev/null
+++ b/plugins/BarcodeReaderPanel.form
@@ -0,0 +1,114 @@
+
+
+
diff --git a/plugins/BarcodeReaderPanel.java b/plugins/BarcodeReaderPanel.java
new file mode 100644
index 0000000..d6dabed
--- /dev/null
+++ b/plugins/BarcodeReaderPanel.java
@@ -0,0 +1,170 @@
+import ch.psi.pshell.core.Context;
+import ch.psi.pshell.device.Device;
+import ch.psi.pshell.swing.DevicePanel;
+import ch.psi.utils.swing.SwingUtils;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ *
+ */
+public class BarcodeReaderPanel extends DevicePanel {
+
+ volatile boolean enabled;
+ public BarcodeReaderPanel() {
+ initComponents();
+ this.startTimer(100);
+ }
+
+
+ CompletableFuture future;
+
+
+ @Override
+ public void setDevice(Device device){
+ super.setDevice(device);
+ if (device != null){
+ deviceStatePanel1.setDevice(device);
+ deviceValuePanel1.setDevice(device);
+ }
+ }
+
+ @Override
+ public void onTimer(){
+ if ((getDevice()!=null) && enabled){
+ if ((future==null) || (future.isDone())){
+ future = Context.getInstance().evalLineBackgroundAsync(getDevice().getName() + ".get()");
+ }
+ }
+ }
+
+
+ void execute(String statement, boolean showReturn){
+ try {
+ Context.getInstance().evalLineBackgroundAsync(statement).handle((ret, ex) -> {
+ if (BarcodeReaderPanel.this.isShowing()){
+ if (ex != null){
+ showException((Exception)ex);
+ } else if (showReturn){
+ if (ret == null){
+ SwingUtils.showMessage(this, "Return", "No code detected", 20000);
+ } else {
+ SwingUtils.showMessage(this, "Return", "Detected code: " +ret, 20000);
+ }
+ }
+ }
+ return ret;
+ });
+ } catch (Exception ex) {
+ showException(ex);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jPanel3 = new javax.swing.JPanel();
+ buttonEnable = new javax.swing.JButton();
+ buttonDisable = new javax.swing.JButton();
+ buttonRead = new javax.swing.JButton();
+ deviceStatePanel1 = new ch.psi.pshell.swing.DeviceStatePanel();
+ deviceValuePanel1 = new ch.psi.pshell.swing.DeviceValuePanel();
+
+ jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Commands"));
+
+ buttonEnable.setText("Enable");
+ buttonEnable.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonEnableActionPerformed(evt);
+ }
+ });
+
+ buttonDisable.setText("Disable");
+ buttonDisable.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonDisableActionPerformed(evt);
+ }
+ });
+
+ buttonRead.setText("Read");
+ buttonRead.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonReadActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
+ jPanel3.setLayout(jPanel3Layout);
+ jPanel3Layout.setHorizontalGroup(
+ jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(buttonEnable)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(buttonDisable)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(buttonRead)
+ .addContainerGap())
+ );
+
+ jPanel3Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonDisable, buttonEnable, buttonRead});
+
+ jPanel3Layout.setVerticalGroup(
+ jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonEnable)
+ .addComponent(buttonDisable)
+ .addComponent(buttonRead))
+ .addContainerGap())
+ );
+
+ deviceValuePanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Value"));
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(deviceValuePanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(deviceStatePanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(deviceValuePanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(deviceStatePanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0))
+ );
+ }// //GEN-END:initComponents
+
+ private void buttonEnableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonEnableActionPerformed
+ execute(getDevice().getName() + ".enable()", false);
+ enabled = true;
+ }//GEN-LAST:event_buttonEnableActionPerformed
+
+ private void buttonDisableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDisableActionPerformed
+ enabled = false;
+ execute(getDevice().getName() + ".disable()", false);
+ }//GEN-LAST:event_buttonDisableActionPerformed
+
+ private void buttonReadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonReadActionPerformed
+ enabled = false;
+ execute(getDevice().getName() + ".read(5.0) ", true);
+ }//GEN-LAST:event_buttonReadActionPerformed
+
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton buttonDisable;
+ private javax.swing.JButton buttonEnable;
+ private javax.swing.JButton buttonRead;
+ private ch.psi.pshell.swing.DeviceStatePanel deviceStatePanel1;
+ private ch.psi.pshell.swing.DeviceValuePanel deviceValuePanel1;
+ private javax.swing.JPanel jPanel3;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/plugins/Beeper.java b/plugins/Beeper.java
new file mode 100644
index 0000000..c1fea67
--- /dev/null
+++ b/plugins/Beeper.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014 Paul Scherrer Institute. All rights reserved.
+ */
+
+import ch.psi.pshell.device.*;
+import com.sun.jna.Function;
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.win32.StdCallLibrary;
+import com.sun.jna.win32.W32APIFunctionMapper;
+import com.sun.jna.win32.W32APITypeMapper;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ */
+public class Beeper extends DeviceBase {
+
+ public Beeper(String name) {
+ super(name);
+ }
+
+ // JNA Mapping
+ static Map UNICODE_OPTIONS = new HashMap() {
+
+ {
+ put("type-mapper", W32APITypeMapper.UNICODE);
+ put("function-mapper", W32APIFunctionMapper.UNICODE);
+ }
+ };
+
+ interface Kernel32 extends StdCallLibrary {
+
+ public static final String LIBRARY_NAME = "kernel32";
+ Kernel32 INSTANCE = (Kernel32) Native.loadLibrary(LIBRARY_NAME, Kernel32.class, UNICODE_OPTIONS);
+ Kernel32 SYNC_INSTANCE = (Kernel32) Native.synchronizedLibrary(INSTANCE);
+
+ boolean Beep(int FREQUENCY, int DURATION);
+
+ void Sleep(int DURATION);
+
+ int CreateEventW(Pointer securityAttributes, boolean manualReset, boolean initialState, String name);
+
+ int CreateThread(/*Pointer*/int lpThreadAttributes, IntByReference dwStackSize, Function lpStartAddress, Structure lpParameter, int dwCreationFlags, IntByReference lpThreadId);
+ public static final int STILL_ACTIVE = 259;
+
+ int GetExitCodeThread(int hThread, IntByReference lpExitCode);
+
+ int GetLastError();
+
+ boolean CloseHandle(int handle);
+
+ }
+ private final int mEventHandle = Kernel32.INSTANCE.CreateEventW(Pointer.NULL, true, false, null);
+
+
+ //Public interface
+ public int getLastError(){
+ return Kernel32.SYNC_INSTANCE.GetLastError();
+ }
+
+ public void sleep(int duration){
+ Kernel32.SYNC_INSTANCE.Sleep(duration);
+ }
+
+ public void beep(int frequency, int duration){
+ Kernel32.SYNC_INSTANCE.Beep(frequency, duration);
+ }
+
+}
diff --git a/plugins/Commands.form b/plugins/Commands.form
new file mode 100644
index 0000000..26eeaf0
--- /dev/null
+++ b/plugins/Commands.form
@@ -0,0 +1,804 @@
+
+
+
diff --git a/plugins/Commands.java b/plugins/Commands.java
new file mode 100644
index 0000000..fb37d24
--- /dev/null
+++ b/plugins/Commands.java
@@ -0,0 +1,928 @@
+/*
+ * Copyright (c) 2014-2017 Paul Scherrer Institute. All rights reserved.
+ */
+
+import ch.psi.pshell.device.Device;
+import ch.psi.pshell.device.DeviceAdapter;
+import ch.psi.pshell.device.GenericDevice;
+import ch.psi.pshell.ui.Panel;
+import ch.psi.utils.State;
+import ch.psi.utils.swing.SwingUtils;
+import java.awt.Component;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JComponent;
+import javax.swing.JSpinner;
+import javax.swing.JTextField;
+
+/**
+ *
+ */
+public class Commands extends Panel {
+
+ public Commands() {
+ initComponents();
+ ((JSpinner.DefaultEditor)spinnerSegment.getEditor()).getTextField().setHorizontalAlignment(JTextField.CENTER);
+ ((JSpinner.DefaultEditor)spinnerPuck.getEditor()).getTextField().setHorizontalAlignment(JTextField.CENTER);
+ ((JSpinner.DefaultEditor)spinnerSample.getEditor()).getTextField().setHorizontalAlignment(JTextField.CENTER);
+
+
+ try{
+ spinnerDryTime.setValue(getContext().getScriptManager().getVar("DEFAULT_DRY_HEAT_TIME"));
+ spinnerDrySpeed.setValue(getContext().getScriptManager().getVar("DEFAULT_DRY_SPEED"));
+ } catch(Exception ex){
+ this.showException(ex);
+ }
+ }
+
+ //Overridable callbacks
+ @Override
+ public void onInitialize(int runCount) {
+ GenericDevice basePlate = getDevice("BasePlate");
+ if (basePlate != null){
+ basePlate.addListener(new DeviceAdapter() {
+ @Override
+ public void onValueChanged(Device device, Object value, Object former) {
+ if (value!=null){
+ String segment = ((Object[])value)[0].toString();
+ spinnerSegment.setValue(segment);
+ Integer puck = (Integer) ((Object[])value)[1];
+ spinnerPuck.setValue(Integer.valueOf(puck));
+ Integer sample = (Integer) ((Object[])value)[2];
+ if (sample!=null){
+ spinnerSample.setValue(Integer.valueOf(sample));
+ }
+ }
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onStateChange(State state, State former) {
+ boolean enabled = (state == State.Ready);
+ for (Component c: SwingUtils.getComponentsByType(this, JComponent.class)){
+ c.setEnabled(enabled);
+ }
+ spinnerSegment.setEnabled(enabled && !checkAuxiliary.isSelected());
+ spinnerPuck.setEnabled(enabled && !checkAuxiliary.isSelected());
+ buttonScanPuck.setEnabled(enabled && !checkAuxiliary.isSelected());
+ }
+
+ @Override
+ public void onExecutedFile(String fileName, Object result) {
+ }
+
+ //Callback to perform update - in event thread
+ @Override
+ protected void doUpdate() {
+ }
+
+ @Override
+ public boolean isActive() {
+ return true;
+ }
+
+
+ void execute(String statement){
+ execute(statement, false);
+ }
+
+ void execute(String statement, boolean background){
+ execute(statement, background, false);
+ }
+
+ void execute(String statement, boolean background, boolean showReturn){
+ try {
+ evalAsync(statement, background).handle((ret, ex) -> {
+ if (ex != null){
+ if (getContext().getGlobal("recovering") == null) {
+ showException((Exception)ex);
+ }
+ } else if (showReturn){
+ SwingUtils.showMessage(getTopLevel(), "Return", String.valueOf(ret));
+ }
+ return ret;
+ });
+ } catch (Exception ex) {
+ showException(ex);
+ }
+ }
+
+ void execute(String script, Object args){
+ try {
+ runAsync(script, args).handle((ret, ex) -> {
+ if (ex != null){
+ showException((Exception)ex);
+ }
+ return ret;
+ });
+ } catch (Exception ex) {
+ showException(ex);
+ }
+ }
+
+
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jTabbedPane1 = new javax.swing.JTabbedPane();
+ tabCommands = new javax.swing.JPanel();
+ pnDry = new javax.swing.JPanel();
+ jLabel6 = new javax.swing.JLabel();
+ spinnerDryTime = new ch.psi.utils.swing.HorizontalSpinner();
+ buttonDry = new javax.swing.JButton();
+ spinnerDrySpeed = new ch.psi.utils.swing.HorizontalSpinner();
+ jLabel7 = new javax.swing.JLabel();
+ ckeckParkOnDry = new javax.swing.JCheckBox();
+ pnTransfer = new javax.swing.JPanel();
+ buttonMount = new javax.swing.JButton();
+ jPanel5 = new javax.swing.JPanel();
+ jLabel4 = new javax.swing.JLabel();
+ checkForce = new javax.swing.JCheckBox();
+ spinnerSample = new ch.psi.utils.swing.HorizontalSpinner();
+ spinnerPuck = new ch.psi.utils.swing.HorizontalSpinner();
+ jLabel1 = new javax.swing.JLabel();
+ jLabel2 = new javax.swing.JLabel();
+ spinnerSegment = new ch.psi.utils.swing.HorizontalSpinner();
+ jLabel3 = new javax.swing.JLabel();
+ jLabel5 = new javax.swing.JLabel();
+ checkDatamatrix = new javax.swing.JCheckBox();
+ buttonUnmount = new javax.swing.JButton();
+ buttonScanPin = new javax.swing.JButton();
+ buttonScanPuck = new javax.swing.JButton();
+ checkAuxiliary = new javax.swing.JCheckBox();
+ jPanel1 = new javax.swing.JPanel();
+ buttonGripperScan = new javax.swing.JButton();
+ buttonTrash = new javax.swing.JButton();
+ tabAdvanced = new javax.swing.JPanel();
+ pnLowLevel = new javax.swing.JPanel();
+ buttonMovePark = new javax.swing.JButton();
+ buttonMoveCold = new javax.swing.JButton();
+ buttonMoveGonio = new javax.swing.JButton();
+ buttonMoveHeater = new javax.swing.JButton();
+ buttonGetGonio = new javax.swing.JButton();
+ buttonPutGonio = new javax.swing.JButton();
+ buttonMoveDewar = new javax.swing.JButton();
+ buttonMoveHome = new javax.swing.JButton();
+ buttonMoveScanner = new javax.swing.JButton();
+ buttonGetDewar = new javax.swing.JButton();
+ buttonPutDewar = new javax.swing.JButton();
+ buttonMoveAux = new javax.swing.JButton();
+ buttonGetAux = new javax.swing.JButton();
+ buttonPutAux = new javax.swing.JButton();
+ pnDatabase = new javax.swing.JPanel();
+ buttonClearSampleDb = new javax.swing.JButton();
+ buttonResetPuckIds = new javax.swing.JButton();
+ pnMotion = new javax.swing.JPanel();
+ buttonRecover = new javax.swing.JButton();
+ buttonEnableAll = new javax.swing.JButton();
+
+ pnDry.setBorder(javax.swing.BorderFactory.createTitledBorder("Drying"));
+
+ jLabel6.setText("Heat time(s):");
+
+ spinnerDryTime.setModel(new javax.swing.SpinnerNumberModel(35.0d, 1.0d, 50.0d, 1.0d));
+ spinnerDryTime.setRequestFocusEnabled(false);
+
+ buttonDry.setText("Dry");
+ buttonDry.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonDryActionPerformed(evt);
+ }
+ });
+
+ spinnerDrySpeed.setModel(new javax.swing.SpinnerNumberModel(0.4d, 0.1d, 1.0d, 0.1d));
+
+ jLabel7.setText("Speed(%):");
+
+ ckeckParkOnDry.setText("Park on finish");
+
+ javax.swing.GroupLayout pnDryLayout = new javax.swing.GroupLayout(pnDry);
+ pnDry.setLayout(pnDryLayout);
+ pnDryLayout.setHorizontalGroup(
+ pnDryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnDryLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnDryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(buttonDry, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(ckeckParkOnDry))
+ .addGap(18, 25, Short.MAX_VALUE)
+ .addGroup(pnDryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(jLabel6)
+ .addComponent(jLabel7))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnDryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(spinnerDrySpeed, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(spinnerDryTime, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addContainerGap())
+ );
+
+ pnDryLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonDry, spinnerDrySpeed, spinnerDryTime});
+
+ pnDryLayout.setVerticalGroup(
+ pnDryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnDryLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnDryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnDryLayout.createSequentialGroup()
+ .addGroup(pnDryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(buttonDry)
+ .addComponent(spinnerDryTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnDryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(spinnerDrySpeed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(jLabel7)
+ .addComponent(ckeckParkOnDry)))
+ .addComponent(jLabel6))
+ .addContainerGap())
+ );
+
+ pnTransfer.setBorder(javax.swing.BorderFactory.createTitledBorder("Sample Transfer"));
+
+ buttonMount.setText("Mount");
+ buttonMount.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonMountActionPerformed(evt);
+ }
+ });
+
+ jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel4.setText("Force:");
+
+ checkForce.setSelected(true);
+ checkForce.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
+
+ spinnerSample.setModel(new javax.swing.SpinnerNumberModel(1, 1, 16, 1));
+
+ spinnerPuck.setModel(new javax.swing.SpinnerNumberModel(1, 1, 5, 1));
+
+ jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel1.setText("Segment:");
+
+ jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel2.setText("Puck:");
+
+ spinnerSegment.setModel(new javax.swing.SpinnerListModel(new String[] {"A", "B", "C", "D", "E", "F"}));
+
+ jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel3.setText("Sample:");
+
+ jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel5.setText("Read DM:");
+
+ checkDatamatrix.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
+
+ javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
+ jPanel5.setLayout(jPanel5Layout);
+ jPanel5Layout.setHorizontalGroup(
+ jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel5Layout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jLabel3)
+ .addComponent(jLabel2)
+ .addComponent(jLabel1)
+ .addComponent(jLabel4)
+ .addComponent(jLabel5))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(spinnerPuck, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(checkForce)
+ .addComponent(checkDatamatrix)
+ .addComponent(spinnerSample, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(spinnerSegment, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(0, 0, 0))
+ );
+
+ jPanel5Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel1, jLabel2, jLabel3, jLabel4, jLabel5});
+
+ jPanel5Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {spinnerPuck, spinnerSample, spinnerSegment});
+
+ jPanel5Layout.setVerticalGroup(
+ jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel5Layout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel1)
+ .addComponent(spinnerSegment, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel2)
+ .addComponent(spinnerPuck, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel3)
+ .addComponent(spinnerSample, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel4)
+ .addComponent(checkForce))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel5)
+ .addComponent(checkDatamatrix)))
+ );
+
+ buttonUnmount.setText("Unmount");
+ buttonUnmount.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonUnmountActionPerformed(evt);
+ }
+ });
+
+ buttonScanPin.setText("Scan Pin");
+ buttonScanPin.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonScanPinActionPerformed(evt);
+ }
+ });
+
+ buttonScanPuck.setText("Scan Puck");
+ buttonScanPuck.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonScanPuckActionPerformed(evt);
+ }
+ });
+
+ checkAuxiliary.setText("Auxiliary");
+ checkAuxiliary.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ checkAuxiliaryActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout pnTransferLayout = new javax.swing.GroupLayout(pnTransfer);
+ pnTransfer.setLayout(pnTransferLayout);
+ pnTransferLayout.setHorizontalGroup(
+ pnTransferLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnTransferLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnTransferLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(buttonMount, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(buttonUnmount, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(buttonScanPin, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(buttonScanPuck, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(checkAuxiliary))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
+ );
+
+ pnTransferLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonMount, buttonScanPin, buttonUnmount});
+
+ pnTransferLayout.setVerticalGroup(
+ pnTransferLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnTransferLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnTransferLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGroup(pnTransferLayout.createSequentialGroup()
+ .addComponent(buttonMount)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(buttonUnmount)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(buttonScanPin)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(buttonScanPuck)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(checkAuxiliary)))
+ .addContainerGap())
+ );
+
+ jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Gripper"));
+
+ buttonGripperScan.setText("Scan");
+ buttonGripperScan.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonGripperScanActionPerformed(evt);
+ }
+ });
+
+ buttonTrash.setText("Trash");
+ buttonTrash.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonTrashActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+ jPanel1.setLayout(jPanel1Layout);
+ jPanel1Layout.setHorizontalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(buttonGripperScan, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(buttonTrash, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
+ );
+ jPanel1Layout.setVerticalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonGripperScan)
+ .addComponent(buttonTrash))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ javax.swing.GroupLayout tabCommandsLayout = new javax.swing.GroupLayout(tabCommands);
+ tabCommands.setLayout(tabCommandsLayout);
+ tabCommandsLayout.setHorizontalGroup(
+ tabCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(tabCommandsLayout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addGroup(tabCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(pnDry, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(pnTransfer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+ );
+ tabCommandsLayout.setVerticalGroup(
+ tabCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(tabCommandsLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(pnDry, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(pnTransfer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
+ );
+
+ jTabbedPane1.addTab("Commands", tabCommands);
+
+ pnLowLevel.setBorder(javax.swing.BorderFactory.createTitledBorder("Low-level Motion Commands"));
+
+ buttonMovePark.setText("Move Park");
+ buttonMovePark.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonMoveParkActionPerformed(evt);
+ }
+ });
+
+ buttonMoveCold.setText("Move Cold");
+ buttonMoveCold.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonMoveColdActionPerformed(evt);
+ }
+ });
+
+ buttonMoveGonio.setText("Move Gonio");
+ buttonMoveGonio.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonMoveGonioActionPerformed(evt);
+ }
+ });
+
+ buttonMoveHeater.setText("Move Heater");
+ buttonMoveHeater.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonMoveHeaterActionPerformed(evt);
+ }
+ });
+
+ buttonGetGonio.setText("Get Gonio");
+ buttonGetGonio.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonGetGonioActionPerformed(evt);
+ }
+ });
+
+ buttonPutGonio.setText("Put Gonio");
+ buttonPutGonio.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonPutGonioActionPerformed(evt);
+ }
+ });
+
+ buttonMoveDewar.setText("Move Dewar");
+ buttonMoveDewar.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonMoveDewarActionPerformed(evt);
+ }
+ });
+
+ buttonMoveHome.setText("Move Home");
+ buttonMoveHome.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonMoveHomeActionPerformed(evt);
+ }
+ });
+
+ buttonMoveScanner.setText("Move Scanner");
+ buttonMoveScanner.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonMoveScannerActionPerformed(evt);
+ }
+ });
+
+ buttonGetDewar.setText("Get Dewar");
+ buttonGetDewar.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonGetDewarActionPerformed(evt);
+ }
+ });
+
+ buttonPutDewar.setText("Put Dewar");
+ buttonPutDewar.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonPutDewarActionPerformed(evt);
+ }
+ });
+
+ buttonMoveAux.setText("Move Aux");
+ buttonMoveAux.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonMoveAuxActionPerformed(evt);
+ }
+ });
+
+ buttonGetAux.setText("Get Aux");
+ buttonGetAux.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonGetAuxActionPerformed(evt);
+ }
+ });
+
+ buttonPutAux.setText("Put Aux");
+ buttonPutAux.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonPutAuxActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout pnLowLevelLayout = new javax.swing.GroupLayout(pnLowLevel);
+ pnLowLevel.setLayout(pnLowLevelLayout);
+ pnLowLevelLayout.setHorizontalGroup(
+ pnLowLevelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnLowLevelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnLowLevelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(buttonMovePark, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(buttonMoveAux)
+ .addComponent(buttonMoveCold, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(buttonMoveHeater)
+ .addComponent(buttonGetGonio)
+ .addComponent(buttonGetDewar, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(buttonGetAux, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 64, Short.MAX_VALUE)
+ .addGroup(pnLowLevelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(buttonPutDewar, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(buttonPutGonio, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(buttonMoveGonio, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(buttonMoveHome, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(buttonMoveDewar, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(buttonMoveScanner)
+ .addComponent(buttonPutAux, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addContainerGap())
+ );
+
+ pnLowLevelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonGetAux, buttonGetDewar, buttonGetGonio, buttonMoveAux, buttonMoveCold, buttonMoveDewar, buttonMoveGonio, buttonMoveHeater, buttonMoveHome, buttonMovePark, buttonMoveScanner, buttonPutAux, buttonPutDewar, buttonPutGonio});
+
+ pnLowLevelLayout.setVerticalGroup(
+ pnLowLevelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnLowLevelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnLowLevelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonGetDewar)
+ .addComponent(buttonPutDewar))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnLowLevelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonGetAux)
+ .addComponent(buttonPutAux))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnLowLevelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonGetGonio)
+ .addComponent(buttonPutGonio))
+ .addGap(18, 18, 18)
+ .addGroup(pnLowLevelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonMoveGonio)
+ .addComponent(buttonMoveAux))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnLowLevelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonMovePark)
+ .addComponent(buttonMoveHome))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnLowLevelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonMoveDewar)
+ .addComponent(buttonMoveCold))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pnLowLevelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonMoveHeater)
+ .addComponent(buttonMoveScanner))
+ .addContainerGap())
+ );
+
+ pnDatabase.setBorder(javax.swing.BorderFactory.createTitledBorder("Database"));
+
+ buttonClearSampleDb.setText("Clear Sample Db");
+ buttonClearSampleDb.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonClearSampleDbActionPerformed(evt);
+ }
+ });
+
+ buttonResetPuckIds.setText("Reset Puck IDs");
+ buttonResetPuckIds.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonResetPuckIdsActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout pnDatabaseLayout = new javax.swing.GroupLayout(pnDatabase);
+ pnDatabase.setLayout(pnDatabaseLayout);
+ pnDatabaseLayout.setHorizontalGroup(
+ pnDatabaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnDatabaseLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(buttonClearSampleDb)
+ .addGap(18, 18, Short.MAX_VALUE)
+ .addComponent(buttonResetPuckIds)
+ .addContainerGap())
+ );
+
+ pnDatabaseLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonClearSampleDb, buttonResetPuckIds});
+
+ pnDatabaseLayout.setVerticalGroup(
+ pnDatabaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnDatabaseLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnDatabaseLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonClearSampleDb)
+ .addComponent(buttonResetPuckIds))
+ .addContainerGap())
+ );
+
+ pnMotion.setBorder(javax.swing.BorderFactory.createTitledBorder("Motion"));
+
+ buttonRecover.setText("Dewar Recovery");
+ buttonRecover.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonRecoverActionPerformed(evt);
+ }
+ });
+
+ buttonEnableAll.setText("Enable Motion");
+ buttonEnableAll.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonEnableAllActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout pnMotionLayout = new javax.swing.GroupLayout(pnMotion);
+ pnMotion.setLayout(pnMotionLayout);
+ pnMotionLayout.setHorizontalGroup(
+ pnMotionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnMotionLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(buttonRecover)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(buttonEnableAll)
+ .addContainerGap())
+ );
+
+ pnMotionLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonEnableAll, buttonRecover});
+
+ pnMotionLayout.setVerticalGroup(
+ pnMotionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(pnMotionLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(pnMotionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonRecover)
+ .addComponent(buttonEnableAll))
+ .addContainerGap())
+ );
+
+ javax.swing.GroupLayout tabAdvancedLayout = new javax.swing.GroupLayout(tabAdvanced);
+ tabAdvanced.setLayout(tabAdvancedLayout);
+ tabAdvancedLayout.setHorizontalGroup(
+ tabAdvancedLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(tabAdvancedLayout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addGroup(tabAdvancedLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(pnMotion, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(pnDatabase, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(pnLowLevel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGap(0, 0, 0))
+ );
+ tabAdvancedLayout.setVerticalGroup(
+ tabAdvancedLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(tabAdvancedLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(pnLowLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(pnDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(pnMotion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
+ );
+
+ jTabbedPane1.addTab("Advanced", tabAdvanced);
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.TRAILING)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ );
+ }// //GEN-END:initComponents
+
+ private void buttonEnableAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonEnableAllActionPerformed
+ execute("enable_motion()", true);
+ }//GEN-LAST:event_buttonEnableAllActionPerformed
+
+ private void buttonMountActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMountActionPerformed
+ String segment = checkAuxiliary.isSelected() ? "X" : (String) spinnerSegment.getValue();
+ int puck = checkAuxiliary.isSelected() ? 1 :(Integer) spinnerPuck.getValue();
+ int sample = (Integer) spinnerSample.getValue();
+ String force = checkForce.isSelected() ? "True" : "False";
+ String readDatamatrix = checkDatamatrix.isSelected() ? "True" : "False";
+ execute("mount('" + segment + "'," + puck + "," + sample + ", force=" + force + ", read_dm=" + readDatamatrix + ")");
+
+ }//GEN-LAST:event_buttonMountActionPerformed
+
+ private void buttonMoveAuxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveAuxActionPerformed
+ execute("move_aux()");
+ }//GEN-LAST:event_buttonMoveAuxActionPerformed
+
+ private void buttonUnmountActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonUnmountActionPerformed
+ String segment = checkAuxiliary.isSelected() ? "X" : (String) spinnerSegment.getValue();
+ int puck = checkAuxiliary.isSelected() ? 1 :(Integer) spinnerPuck.getValue();
+ int sample = (Integer) spinnerSample.getValue();
+ String force = checkForce.isSelected() ? "True" : "False";
+ execute("unmount('" + segment + "'," + puck + "," + sample + ", force=" + force + ")");
+ }//GEN-LAST:event_buttonUnmountActionPerformed
+
+ private void buttonGetDewarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonGetDewarActionPerformed
+ String segment = (String) spinnerSegment.getValue();
+ int puck = (Integer) spinnerPuck.getValue();
+ int sample = (Integer) spinnerSample.getValue();
+ String force = checkForce.isSelected() ? "True" : "False";
+ execute("get_dewar('" + segment + "'," + puck + "," + sample + ", force=" + force + ")");
+ }//GEN-LAST:event_buttonGetDewarActionPerformed
+
+ private void buttonPutDewarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPutDewarActionPerformed
+ String segment = (String) spinnerSegment.getValue();
+ int puck = (Integer) spinnerPuck.getValue();
+ int sample = (Integer) spinnerSample.getValue();
+ String force = checkForce.isSelected() ? "True" : "False";
+ execute("put_dewar('" + segment + "'," + puck + "," + sample + ", force=" + force + ")");
+ }//GEN-LAST:event_buttonPutDewarActionPerformed
+
+ private void buttonGetGonioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonGetGonioActionPerformed
+ String force = checkForce.isSelected() ? "True" : "False";
+ execute("get_gonio(force=" + force + ")");
+ }//GEN-LAST:event_buttonGetGonioActionPerformed
+
+ private void buttonPutGonioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPutGonioActionPerformed
+ String force = checkForce.isSelected() ? "True" : "False";
+ execute("put_gonio(force=" + force + ")");
+ }//GEN-LAST:event_buttonPutGonioActionPerformed
+
+ private void buttonMoveParkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveParkActionPerformed
+ execute("move_park()");
+ }//GEN-LAST:event_buttonMoveParkActionPerformed
+
+ private void buttonMoveHomeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveHomeActionPerformed
+ execute("move_home()");
+ }//GEN-LAST:event_buttonMoveHomeActionPerformed
+
+ private void buttonMoveGonioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveGonioActionPerformed
+ execute("move_gonio()");
+ }//GEN-LAST:event_buttonMoveGonioActionPerformed
+
+ private void buttonMoveDewarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveDewarActionPerformed
+ execute("move_dewar()");
+ }//GEN-LAST:event_buttonMoveDewarActionPerformed
+
+ private void buttonMoveScannerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveScannerActionPerformed
+ execute("move_scanner()");
+ }//GEN-LAST:event_buttonMoveScannerActionPerformed
+
+ private void buttonMoveHeaterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveHeaterActionPerformed
+ execute("move_heater()");
+ }//GEN-LAST:event_buttonMoveHeaterActionPerformed
+
+ private void buttonDryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDryActionPerformed
+ double dryTime = (Double) spinnerDryTime.getValue();
+ double streamTime = (Double) spinnerDrySpeed.getValue();
+ boolean park = ckeckParkOnDry.isSelected();
+
+ execute("dry(" + dryTime + ", " + streamTime + (park ? ", wait_cold=-1": "") + ")");
+ }//GEN-LAST:event_buttonDryActionPerformed
+
+ private void buttonRecoverActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonRecoverActionPerformed
+ execute("robot_recover()");
+ }//GEN-LAST:event_buttonRecoverActionPerformed
+
+ private void buttonMoveColdActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveColdActionPerformed
+ execute("move_cold()");
+ }//GEN-LAST:event_buttonMoveColdActionPerformed
+
+ private void buttonClearSampleDbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonClearSampleDbActionPerformed
+ execute("clear_samples_info()", true);
+ }//GEN-LAST:event_buttonClearSampleDbActionPerformed
+
+ private void buttonResetPuckIdsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonResetPuckIdsActionPerformed
+ execute("reset_puck_datamatrix()", true);
+ }//GEN-LAST:event_buttonResetPuckIdsActionPerformed
+
+ private void buttonScanPinActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonScanPinActionPerformed
+ String segment = checkAuxiliary.isSelected() ? "X" : (String) spinnerSegment.getValue();
+ int puck = checkAuxiliary.isSelected() ? 1 :(Integer) spinnerPuck.getValue();
+ int sample = (Integer) spinnerSample.getValue();
+ String force = checkForce.isSelected() ? "True" : "False";
+ execute("scan_pin('" + segment + "'," + puck + "," + sample + ", force=" + force + ")", false, true);
+ }//GEN-LAST:event_buttonScanPinActionPerformed
+
+ private void buttonScanPuckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonScanPuckActionPerformed
+ String segment = checkAuxiliary.isSelected() ? "X" : (String) spinnerSegment.getValue();
+ int puck = checkAuxiliary.isSelected() ? 1 :(Integer) spinnerPuck.getValue();
+ String force = checkForce.isSelected() ? "True" : "False";
+ execute("scan_puck('" + segment + "'," + puck + ", force=" + force + ")", false, true);
+ }//GEN-LAST:event_buttonScanPuckActionPerformed
+
+ private void buttonGetAuxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonGetAuxActionPerformed
+ int sample = (Integer) spinnerSample.getValue();
+ execute("get_aux('" + sample + "')");
+ }//GEN-LAST:event_buttonGetAuxActionPerformed
+
+ private void buttonPutAuxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPutAuxActionPerformed
+ int sample = (Integer) spinnerSample.getValue();
+ execute("put_aux('" + sample + "')");
+ }//GEN-LAST:event_buttonPutAuxActionPerformed
+
+ private void checkAuxiliaryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkAuxiliaryActionPerformed
+ onStateChange(getState(), null);
+ }//GEN-LAST:event_checkAuxiliaryActionPerformed
+
+ private void buttonGripperScanActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonGripperScanActionPerformed
+ execute("scan_gripper()");
+ }//GEN-LAST:event_buttonGripperScanActionPerformed
+
+ private void buttonTrashActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonTrashActionPerformed
+ execute("trash()");
+ }//GEN-LAST:event_buttonTrashActionPerformed
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton buttonClearSampleDb;
+ private javax.swing.JButton buttonDry;
+ private javax.swing.JButton buttonEnableAll;
+ private javax.swing.JButton buttonGetAux;
+ private javax.swing.JButton buttonGetDewar;
+ private javax.swing.JButton buttonGetGonio;
+ private javax.swing.JButton buttonGripperScan;
+ private javax.swing.JButton buttonMount;
+ private javax.swing.JButton buttonMoveAux;
+ private javax.swing.JButton buttonMoveCold;
+ private javax.swing.JButton buttonMoveDewar;
+ private javax.swing.JButton buttonMoveGonio;
+ private javax.swing.JButton buttonMoveHeater;
+ private javax.swing.JButton buttonMoveHome;
+ private javax.swing.JButton buttonMovePark;
+ private javax.swing.JButton buttonMoveScanner;
+ private javax.swing.JButton buttonPutAux;
+ private javax.swing.JButton buttonPutDewar;
+ private javax.swing.JButton buttonPutGonio;
+ private javax.swing.JButton buttonRecover;
+ private javax.swing.JButton buttonResetPuckIds;
+ private javax.swing.JButton buttonScanPin;
+ private javax.swing.JButton buttonScanPuck;
+ private javax.swing.JButton buttonTrash;
+ private javax.swing.JButton buttonUnmount;
+ private javax.swing.JCheckBox checkAuxiliary;
+ private javax.swing.JCheckBox checkDatamatrix;
+ private javax.swing.JCheckBox checkForce;
+ private javax.swing.JCheckBox ckeckParkOnDry;
+ private javax.swing.JLabel jLabel1;
+ private javax.swing.JLabel jLabel2;
+ private javax.swing.JLabel jLabel3;
+ private javax.swing.JLabel jLabel4;
+ private javax.swing.JLabel jLabel5;
+ private javax.swing.JLabel jLabel6;
+ private javax.swing.JLabel jLabel7;
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel5;
+ private javax.swing.JTabbedPane jTabbedPane1;
+ private javax.swing.JPanel pnDatabase;
+ private javax.swing.JPanel pnDry;
+ private javax.swing.JPanel pnLowLevel;
+ private javax.swing.JPanel pnMotion;
+ private javax.swing.JPanel pnTransfer;
+ private javax.swing.JSpinner spinnerDrySpeed;
+ private javax.swing.JSpinner spinnerDryTime;
+ private javax.swing.JSpinner spinnerPuck;
+ private javax.swing.JSpinner spinnerSample;
+ private javax.swing.JSpinner spinnerSegment;
+ private javax.swing.JPanel tabAdvanced;
+ private javax.swing.JPanel tabCommands;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/plugins/Hexiposi.form b/plugins/Hexiposi.form
new file mode 100644
index 0000000..4687d34
--- /dev/null
+++ b/plugins/Hexiposi.form
@@ -0,0 +1,34 @@
+
+
+
diff --git a/plugins/Hexiposi.java b/plugins/Hexiposi.java
new file mode 100644
index 0000000..2c55c2c
--- /dev/null
+++ b/plugins/Hexiposi.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014-2018 Paul Scherrer Institute. All rights reserved.
+ */
+
+import ch.psi.pshell.core.Context;
+import ch.psi.pshell.ui.StripChart;
+import ch.psi.pshell.ui.App;
+import ch.psi.pshell.ui.Panel;
+import ch.psi.utils.State;
+import java.io.File;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ */
+public class Hexiposi extends Panel {
+ final StripChart stripChart;
+ public Hexiposi() {
+ initComponents();
+ stripChart = new StripChart(this.getTopLevel(), false, App.getStripChartFolderArg());
+ panel.add(stripChart.getPlotPanel());
+
+ try {
+ stripChart.open(new File(Context.getInstance().getSetup().expandPath("{home}/stripchart/hexiposi_positon.scd")));
+ stripChart.start();
+ } catch (Exception ex) {
+ showException(ex);
+ Logger.getLogger(Hexiposi.class.getName()).log(Level.WARNING, null, ex);
+ }
+
+ }
+
+ //Overridable callbacks
+ @Override
+ public void onInitialize(int runCount) {
+
+ }
+
+ @Override
+ public void onStateChange(State state, State former) {
+
+ }
+
+ @Override
+ public void onExecutedFile(String fileName, Object result) {
+ }
+
+
+ //Callback to perform update - in event thread
+ @Override
+ protected void doUpdate() {
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ panel = new javax.swing.JPanel();
+
+ panel.setLayout(new java.awt.BorderLayout());
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ );
+ }// //GEN-END:initComponents
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel panel;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/plugins/HexiposiPanel.form b/plugins/HexiposiPanel.form
new file mode 100644
index 0000000..65d0c18
--- /dev/null
+++ b/plugins/HexiposiPanel.form
@@ -0,0 +1,81 @@
+
+
+
diff --git a/plugins/HexiposiPanel.java b/plugins/HexiposiPanel.java
new file mode 100644
index 0000000..b29a526
--- /dev/null
+++ b/plugins/HexiposiPanel.java
@@ -0,0 +1,110 @@
+
+
+import ch.psi.pshell.core.Context;
+import ch.psi.pshell.device.Device;
+import ch.psi.pshell.swing.DevicePanel;
+
+/**
+ *
+ */
+public class HexiposiPanel extends DevicePanel {
+
+ /**
+ * Creates new form HexiposiPositionPanel
+ */
+ public HexiposiPanel() {
+ initComponents();
+ }
+
+ @Override
+ public void setDevice(Device device){
+ super.setDevice(device);
+ discretePositionerPanel.setDevice(device);
+ }
+
+ @Override
+ public void setEnabled(boolean enabled){
+ super.setEnabled(enabled);
+ discretePositionerPanel.setEnabled(enabled);
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ discretePositionerPanel = new ch.psi.pshell.swing.DiscretePositionerPanel();
+ jPanel1 = new javax.swing.JPanel();
+ buttonHoming = new javax.swing.JButton();
+
+ jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Initialize"));
+
+ buttonHoming.setText("Homing");
+ buttonHoming.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonHomingActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+ jPanel1.setLayout(jPanel1Layout);
+ jPanel1Layout.setHorizontalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(buttonHoming)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ jPanel1Layout.setVerticalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addComponent(buttonHoming)
+ .addContainerGap())
+ );
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+ .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(discretePositionerPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGap(0, 0, Short.MAX_VALUE))
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(discretePositionerPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ );
+ }// //GEN-END:initComponents
+
+ private void buttonHomingActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonHomingActionPerformed
+ try {
+ //Context.getInstance().evalLineAsync("hexiposi.move_home()").handle((ret, ex) -> {
+ Context.getInstance().evalLineAsync("homing_hexiposi()").handle((ret, ex) -> {
+ if (ex != null){
+ showException((Exception)ex);
+ }
+ return ret;
+ });
+ } catch (Exception ex) {
+ showException(ex);
+ }
+
+ }//GEN-LAST:event_buttonHomingActionPerformed
+
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton buttonHoming;
+ private ch.psi.pshell.swing.DiscretePositionerPanel discretePositionerPanel;
+ private javax.swing.JPanel jPanel1;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/plugins/LN2.form b/plugins/LN2.form
new file mode 100644
index 0000000..4687d34
--- /dev/null
+++ b/plugins/LN2.form
@@ -0,0 +1,34 @@
+
+
+
diff --git a/plugins/LN2.java b/plugins/LN2.java
new file mode 100644
index 0000000..2300e49
--- /dev/null
+++ b/plugins/LN2.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014-2018 Paul Scherrer Institute. All rights reserved.
+ */
+
+import ch.psi.pshell.core.Context;
+import ch.psi.pshell.plot.TimePlotBase;
+import ch.psi.pshell.ui.StripChart;
+import ch.psi.pshell.ui.App;
+import ch.psi.pshell.ui.Panel;
+import ch.psi.utils.State;
+import ch.psi.utils.swing.SwingUtils;
+import java.awt.Dimension;
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ */
+public class LN2 extends Panel {
+ final StripChart stripChart;
+ TimePlotBase plot;
+ public LN2() {
+ initComponents();
+ stripChart = new StripChart(this.getTopLevel(), false, App.getStripChartFolderArg());
+ panel.add(stripChart.getPlotPanel());
+
+ try {
+ stripChart.open(new File(Context.getInstance().getSetup().expandPath("{home}/stripchart/LN2_Monitoring.scd")));
+ stripChart.start();
+ } catch (Exception ex) {
+ showException(ex);
+ Logger.getLogger(LN2.class.getName()).log(Level.WARNING, null, ex);
+ }
+
+ plot = (TimePlotBase) SwingUtils.getComponentsByType(stripChart.getPlotPanel(),TimePlotBase.class)[0];
+ }
+
+ //Overridable callbacks
+ @Override
+ public void onInitialize(int runCount) {
+ }
+
+
+ @Override
+ public void onStop() {
+ //saveImage();
+ super.onStop();
+ }
+
+ @Override
+ public void onStateChange(State state, State former) {
+ if ( (state == State.Closing) ||
+ ((state == State.Initializing) && (former != State.Invalid))
+ ){
+ saveImage();
+ }
+
+ }
+
+ @Override
+ public void onExecutedFile(String fileName, Object result) {
+ }
+
+ public void saveImage(){
+ getLogger().severe("Saving image");
+ try {
+ String fileName = new File(getContext().getSetup().expandPath("{images}/ln2/{date}_{time}.png")).getCanonicalPath();
+ getLogger().severe("File: " + fileName);
+ plot.saveSnapshot(fileName, "png", new Dimension(1200,800));
+ } catch (Exception ex) {
+ getLogger().log(Level.SEVERE, null, ex);
+ }
+ getLogger().severe("Done");
+ }
+
+ //Callback to perform update - in event thread
+ @Override
+ protected void doUpdate() {
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ panel = new javax.swing.JPanel();
+
+ panel.setLayout(new java.awt.BorderLayout());
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ );
+ }// //GEN-END:initComponents
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel panel;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/plugins/LaserUE.java b/plugins/LaserUE.java
new file mode 100644
index 0000000..cb79550
--- /dev/null
+++ b/plugins/LaserUE.java
@@ -0,0 +1,90 @@
+import ch.psi.pshell.device.Readable;
+import ch.psi.pshell.serial.SerialPortDevice;
+import ch.psi.pshell.serial.SerialPortDeviceConfig;
+import static ch.psi.utils.BitMask.*;
+import ch.psi.utils.Convert;
+import ch.psi.utils.State;
+import java.io.IOException;
+
+/*
+ *
+ */
+public class LaserUE extends SerialPortDevice {
+
+ final Readable readable;
+ final double range;
+ final double offset;
+
+ public LaserUE(String name, String port, double range, double offset) {
+ super(name, port, 921600, SerialPortDeviceConfig.DataBits.DB_8, SerialPortDeviceConfig.StopBits.SB_1, SerialPortDeviceConfig.Parity.None);
+ this.range = range;
+ this.offset = offset;
+ this.setMode(Mode.FullDuplex);
+ readable = new Readable() {
+ @Override
+ public Object read() throws IOException, InterruptedException {
+ return take();
+ }
+
+ @Override
+ public String getName() {
+ return LaserUE.this.getName() + "_readout";
+ }
+ };
+ }
+
+ @Override
+ protected void doInitialize() throws IOException, InterruptedException {
+ super.doInitialize();
+ //TODO: Start DAQ in ILD1320: http://www.micro-epsilon.com/download/manuals/man--optoNCDT-1320--en.pdf
+ setState(State.Ready);
+ write("OUTPUT RS422\n\r");
+ }
+
+ public Readable getReadable() {
+ return readable;
+ }
+
+ int value = 0;
+ int count = 0;
+
+ @Override
+ protected void onByte(int rx) {
+ int index = ((rx & BIT7) > 0) ? 2 : (((rx & BIT6) > 0) ? 1 : 0);
+ if (count == index) {
+ if (index == 0) {
+ value = rx & 0x3F;
+ count = 1;
+ } else if (index == 1) {
+ value = ((rx & 0x3F) << 6) + value;
+ count = 2;
+ } else if (index == 2) {
+ value = ((rx & 0x0F) << 12) + value;
+ //double val = ((double)value)/1000;
+ double val = (0.01) * (102.0 * value / 65520.0 - 1) * range;
+ if ((val <= 0.0) || (val > range)) {
+ val = Double.NaN;
+ } else {
+ val+=offset;
+ val = Convert.roundDouble(val, 3);
+ }
+ setCache(val);
+ count = 0;
+ } else {
+ count = 0;
+ }
+ } else {
+ count = 0;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ LaserUE l = new LaserUE("UE", "COM3", 50.0, 35.0);
+ l.setMonitored(true);
+ l.initialize();
+
+ Thread.sleep(10000);
+ l.close();
+ }
+}
+
diff --git a/plugins/LaserUEPanel.form b/plugins/LaserUEPanel.form
new file mode 100644
index 0000000..c9c5f8d
--- /dev/null
+++ b/plugins/LaserUEPanel.form
@@ -0,0 +1,59 @@
+
+
+
diff --git a/plugins/LaserUEPanel.java b/plugins/LaserUEPanel.java
new file mode 100644
index 0000000..017fb77
--- /dev/null
+++ b/plugins/LaserUEPanel.java
@@ -0,0 +1,98 @@
+import ch.psi.pshell.core.Context;
+import ch.psi.pshell.device.Device;
+import ch.psi.pshell.swing.DevicePanel;
+import ch.psi.utils.swing.SwingUtils;
+
+/**
+ *
+ */
+public class LaserUEPanel extends DevicePanel {
+
+ public LaserUEPanel() {
+ initComponents();
+ }
+
+ @Override
+ public void setDevice(Device device){
+ super.setDevice(device);
+ if (device!=null){
+ historyChart.addDevice("Laser Distance", device);
+ } else {
+ for (Device d: historyChart.getDevices()){
+ historyChart.removeDevice(device);
+ }
+ }
+ }
+
+
+ void execute(String statement, boolean showReturn){
+ try {
+ Context.getInstance().evalLineBackgroundAsync(statement).handle((ret, ex) -> {
+ if (LaserUEPanel.this.isShowing()){
+ if (ex != null){
+ showException((Exception)ex);
+ } else if (showReturn){
+ if (ret == null){
+ SwingUtils.showMessage(this, "Return", "No code detected", 20000);
+ } else {
+ SwingUtils.showMessage(this, "Return", "Detected code: " +ret, 20000);
+ }
+ }
+ }
+ return ret;
+ });
+ } catch (Exception ex) {
+ showException(ex);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ deviceStatePanel2 = new ch.psi.pshell.swing.DeviceStatePanel();
+ try {
+ historyChart = new ch.psi.pshell.swing.HistoryChart();
+ } catch (java.lang.ClassNotFoundException e1) {
+ e1.printStackTrace();
+ } catch (java.lang.InstantiationException e2) {
+ e2.printStackTrace();
+ } catch (java.lang.IllegalAccessException e3) {
+ e3.printStackTrace();
+ }
+ deviceValuePanel1 = new ch.psi.pshell.swing.DeviceValuePanel();
+
+ deviceStatePanel2.setDeviceName("ue");
+
+ deviceValuePanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Value"));
+ deviceValuePanel1.setDeviceName("ue");
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(historyChart, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(deviceStatePanel2, javax.swing.GroupLayout.DEFAULT_SIZE, 297, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(deviceValuePanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 297, Short.MAX_VALUE))
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(historyChart, javax.swing.GroupLayout.DEFAULT_SIZE, 307, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(deviceStatePanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(deviceValuePanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ );
+ }// //GEN-END:initComponents
+
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private ch.psi.pshell.swing.DeviceStatePanel deviceStatePanel2;
+ private ch.psi.pshell.swing.DeviceValuePanel deviceValuePanel1;
+ private ch.psi.pshell.swing.HistoryChart historyChart;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/plugins/MXSC-1.14.0.jar b/plugins/MXSC-1.14.0.jar
new file mode 100644
index 0000000..c935b06
Binary files /dev/null and b/plugins/MXSC-1.14.0.jar differ
diff --git a/plugins/MjpegSource2.java b/plugins/MjpegSource2.java
new file mode 100644
index 0000000..89ab9ef
--- /dev/null
+++ b/plugins/MjpegSource2.java
@@ -0,0 +1,149 @@
+
+import ch.psi.pshell.imaging.SourceBase;
+import ch.psi.pshell.imaging.SourceConfig;
+import ch.psi.pshell.imaging.Utils;
+import java.awt.image.BufferedImage;
+import java.io.BufferedInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.logging.Level;
+
+/**
+ * Image source receive frames from a mjpeg server.
+ */
+public class MjpegSource2 extends SourceBase {
+
+ final String url;
+ final boolean flushOnUpdate;
+
+ public MjpegSource2(String name, String url) {
+ this(name, url, false);
+ }
+
+ public MjpegSource2(String name, String url, boolean flushOnUpdate) {
+ super(name, new SourceConfig());
+ this.url = url;
+ this.flushOnUpdate = flushOnUpdate;
+ }
+
+ InputStream stream;
+
+ @Override
+ protected void doInitialize() throws IOException, InterruptedException {
+ super.doInitialize();
+ URL aux = new URL(url);
+ stream = aux.openStream();
+ if (!stream.markSupported()) {
+ stream = new BufferedInputStream(stream);
+ }
+ }
+
+ Thread monitoredThread;
+
+ @Override
+ protected void doSetMonitored(boolean value) {
+ if (value && (monitoredThread == null)) {
+ monitoredThread = new Thread(() -> {
+ try {
+ while (true) {
+ try {
+ doUpdate();
+ Thread.sleep(1);
+ } catch (IOException ex) {
+ getLogger().log(Level.FINE, null, ex);
+ }
+ }
+ } catch (InterruptedException ex) {
+ return;
+ }
+ });
+ monitoredThread.setDaemon(true);
+ monitoredThread.start();
+ } else if (!value && (monitoredThread != null)) {
+ monitoredThread.interrupt();
+ monitoredThread = null;
+ }
+ }
+
+ final byte[] START_OF_FRAME = {(byte) 0xFF, (byte) 0xD8};
+ final byte[] END_OF_FRAME = {(byte) 0xFF, (byte) 0xD9};
+ final int MAX_FRAME_SIZE = 512 * 1024;
+
+ @Override
+ protected void doUpdate() throws IOException, InterruptedException {
+ byte[] data = null;
+ if (stream != null) {
+ if (flushOnUpdate) {
+ flush();
+ }
+ try {
+ data = readData();
+ } catch (EOFException ex) {
+ //Try to reopen stream
+ doInitialize();
+ data = readData();
+ }
+ }
+ if (data == null) {
+ pushImage(null);
+ } else {
+ BufferedImage img = Utils.newImage(data);
+ pushImage(img);
+ }
+ }
+ byte[] readData() throws IOException {
+ if (stream != null) {
+ stream.mark(MAX_FRAME_SIZE);
+ int startOfFrame = waitBytes(START_OF_FRAME) - START_OF_FRAME.length;
+ if (startOfFrame >= 0) {
+ int endOfFrame = waitBytes(END_OF_FRAME);
+ if (endOfFrame >= 0) {
+ stream.reset();
+ stream.skip(startOfFrame);
+ int length = endOfFrame ;//- END_OF_FRAME.length ;
+ byte[] data = new byte[length];
+ stream.read(data, 0, length);
+ return data;
+ }
+ }
+ }
+ return null;
+ }
+
+ int waitBytes(byte[] data) throws IOException {
+ int index = 0;
+ int dataPos = 0;
+ while (true) {
+ int ret = stream.read();
+ if (ret < 0) {
+ throw new EOFException();
+ }
+ byte value = (byte) ret;
+ if (value == data[dataPos]) {
+ dataPos++;
+ if (dataPos == data.length) {
+ return (index + 1);
+ }
+ } else {
+ dataPos = 0;
+ }
+ index++;
+ if (index >= MAX_FRAME_SIZE) {
+ return -1;
+ }
+ }
+ }
+
+ public void flush() throws IOException {
+ //stream.skip(stream.available());
+ //TODO: Skipping won't make the current image to be displayed
+ stream.close();
+ stream = new URL(url).openStream();
+ if (!stream.markSupported()) {
+ stream = new BufferedInputStream(stream);
+ }
+ }
+
+}
diff --git a/plugins/PuckDetectionPanel.form b/plugins/PuckDetectionPanel.form
new file mode 100644
index 0000000..8045142
--- /dev/null
+++ b/plugins/PuckDetectionPanel.form
@@ -0,0 +1,201 @@
+
+
+
diff --git a/plugins/PuckDetectionPanel.java b/plugins/PuckDetectionPanel.java
new file mode 100644
index 0000000..e07dde6
--- /dev/null
+++ b/plugins/PuckDetectionPanel.java
@@ -0,0 +1,281 @@
+import ch.psi.mxsc.Puck;
+import ch.psi.mxsc.PuckDetection;
+import ch.psi.mxsc.PuckState;
+import ch.psi.mxsc.PuckState.SwitchState;
+import ch.psi.pshell.core.Context;
+import ch.psi.pshell.swing.DevicePanel;
+import ch.psi.utils.swing.SwingUtils;
+
+/**
+ *
+ */
+public class PuckDetectionPanel extends DevicePanel {
+
+ public PuckDetectionPanel() {
+ initComponents();
+ int row = 0;
+ for (String segment : new String[]{"A", "B", "C", "D", "E", "F"}){
+ for (int puck=1; puck<=5; puck++){
+ table.getModel().setValueAt(segment+puck, row++, 0);
+ }
+ }
+ }
+
+ @Override
+ public PuckDetection getDevice(){
+ return (PuckDetection) super.getDevice();
+ }
+
+
+ @Override
+ protected void onDeviceCacheChanged(Object value, Object former, long timestamp, boolean arg3) {
+ for (int row=0; row< 30; row++){
+ String name = table.getModel().getValueAt(row, 0).toString();
+ //int id = row+1;
+ try {
+ Puck puck = getDevice().getPuck(name);
+ int id = puck.getIndex() + 1;
+ PuckState state = getDevice().getPuckState(id);
+ table.getModel().setValueAt(state.online, row, 1);
+ table.getModel().setValueAt((SwitchState.Off == state.mecSwitch) ? "" : String.valueOf(state.mecSwitch), row, 2);
+ table.getModel().setValueAt((SwitchState.Off == state.indSwitch) ? "" : String.valueOf(state.indSwitch), row, 3);
+ table.getModel().setValueAt(puck.getDetection() == null ? "" : puck.getDetection(), row, 4);
+ table.getModel().setValueAt(puck.getPuckType() == null ? "" : puck.getPuckType(), row, 5);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ table.getModel().setValueAt(false, row, 1);
+ table.getModel().setValueAt(false, row, 2);
+ table.getModel().setValueAt(false, row, 3);
+ table.getModel().setValueAt("", row, 4);
+ table.getModel().setValueAt("", row, 5);
+ }
+ }
+ }
+
+ void execute(String statement, boolean showReturn){
+ try {
+ Context.getInstance().evalLineBackgroundAsync(statement).handle((ret, ex) -> {
+ if (ex != null){
+ showException((Exception)ex);
+ } else if (showReturn){
+ SwingUtils.showMessage(this, "Return", String.valueOf(ret));
+ }
+ return ret;
+ });
+ } catch (Exception ex) {
+ showException(ex);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jPanel3 = new javax.swing.JPanel();
+ buttonPuckDetCheck = new javax.swing.JButton();
+ buttonPuckDetStop = new javax.swing.JButton();
+ buttonPuckDetStart = new javax.swing.JButton();
+ jPanel1 = new javax.swing.JPanel();
+ jScrollPane1 = new javax.swing.JScrollPane();
+ table = new javax.swing.JTable();
+ buttonConfigure = new javax.swing.JButton();
+ deviceStatePanel1 = new ch.psi.pshell.swing.DeviceStatePanel();
+
+ jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Raspberry Pi "));
+
+ buttonPuckDetCheck.setText("Check");
+ buttonPuckDetCheck.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonPuckDetCheckActionPerformed(evt);
+ }
+ });
+
+ buttonPuckDetStop.setText("Stop");
+ buttonPuckDetStop.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonPuckDetStopActionPerformed(evt);
+ }
+ });
+
+ buttonPuckDetStart.setText("Start");
+ buttonPuckDetStart.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonPuckDetStartActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
+ jPanel3.setLayout(jPanel3Layout);
+ jPanel3Layout.setHorizontalGroup(
+ jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(buttonPuckDetCheck)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 107, Short.MAX_VALUE)
+ .addComponent(buttonPuckDetStop)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 108, Short.MAX_VALUE)
+ .addComponent(buttonPuckDetStart)
+ .addContainerGap())
+ );
+
+ jPanel3Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonPuckDetCheck, buttonPuckDetStart, buttonPuckDetStop});
+
+ jPanel3Layout.setVerticalGroup(
+ jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonPuckDetCheck)
+ .addComponent(buttonPuckDetStop)
+ .addComponent(buttonPuckDetStart))
+ .addContainerGap())
+ );
+
+ jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Detection"));
+
+ table.setModel(new javax.swing.table.DefaultTableModel(
+ new Object [][] {
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null},
+ {null, null, null, null, null, null}
+ },
+ new String [] {
+ "Puck", "Online", "Mechanical", "Inductive", "Detection", "Image"
+ }
+ ) {
+ Class[] types = new Class [] {
+ java.lang.String.class, java.lang.Boolean.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
+ };
+ boolean[] canEdit = new boolean [] {
+ false, false, false, false, false, false
+ };
+
+ public Class getColumnClass(int columnIndex) {
+ return types [columnIndex];
+ }
+
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return canEdit [columnIndex];
+ }
+ });
+ jScrollPane1.setViewportView(table);
+
+ buttonConfigure.setText("Configure");
+ buttonConfigure.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonConfigureActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+ jPanel1.setLayout(jPanel1Layout);
+ jPanel1Layout.setHorizontalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addGap(0, 0, Short.MAX_VALUE)
+ .addComponent(buttonConfigure)
+ .addGap(0, 0, Short.MAX_VALUE)))
+ .addContainerGap())
+ );
+ jPanel1Layout.setVerticalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 282, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(buttonConfigure)
+ .addContainerGap())
+ );
+
+ deviceStatePanel1.setDeviceName("puck_detection");
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(deviceStatePanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGap(0, 0, 0)
+ .addComponent(deviceStatePanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0))
+ );
+ }// //GEN-END:initComponents
+
+ private void buttonPuckDetCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPuckDetCheckActionPerformed
+ execute("check_puck_detection()", true);
+ }//GEN-LAST:event_buttonPuckDetCheckActionPerformed
+
+ private void buttonPuckDetStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPuckDetStopActionPerformed
+ execute("stop_puck_detection()", false);
+ }//GEN-LAST:event_buttonPuckDetStopActionPerformed
+
+ private void buttonPuckDetStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPuckDetStartActionPerformed
+ execute("start_puck_detection()", false);
+ }//GEN-LAST:event_buttonPuckDetStartActionPerformed
+
+ private void buttonConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonConfigureActionPerformed
+ try {
+ if (table.getSelectedRow()<0){
+ throw new Exception("Select a puck");
+ }
+ String name = table.getModel().getValueAt(table.getSelectedRow(), 0).toString();
+ Puck puck = getDevice().getPuck(name);
+ DevicePanel.showConfigEditor(this, puck, true, false);
+ } catch (Exception ex) {
+ showException(ex);
+ }
+
+ }//GEN-LAST:event_buttonConfigureActionPerformed
+
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton buttonConfigure;
+ private javax.swing.JButton buttonPuckDetCheck;
+ private javax.swing.JButton buttonPuckDetStart;
+ private javax.swing.JButton buttonPuckDetStop;
+ private ch.psi.pshell.swing.DeviceStatePanel deviceStatePanel1;
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel3;
+ private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JTable table;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/plugins/Recovery.form b/plugins/Recovery.form
new file mode 100644
index 0000000..fa22373
--- /dev/null
+++ b/plugins/Recovery.form
@@ -0,0 +1,140 @@
+
+
+
diff --git a/plugins/Recovery.java b/plugins/Recovery.java
new file mode 100644
index 0000000..ee1e216
--- /dev/null
+++ b/plugins/Recovery.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2014-2017 Paul Scherrer Institute. All rights reserved.
+ */
+
+import ch.psi.pshell.device.Device;
+import ch.psi.pshell.ui.Panel;
+import ch.psi.utils.State;
+import ch.psi.utils.swing.SwingUtils;
+import java.awt.Color;
+import java.io.IOException;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.SwingUtilities;
+
+/**
+ *
+ */
+public class Recovery extends Panel {
+
+ public Recovery() {
+ initComponents();
+ startTimer(2500, 200);
+ }
+
+ //Overridable callbacks
+ @Override
+ public void onInitialize(int runCount) {
+ getContext().setGlobal("recovering", null);
+ }
+
+ @Override
+ public void onStateChange(State state, State former) {
+ if (state==State.Ready){
+ SwingUtilities.invokeLater(()->{onTimer();});
+ }
+ textSegment.setEnabled(state == State.Ready);
+ textDistance.setEnabled(state == State.Ready);
+ textPosition.setEnabled(state == State.Ready);
+ updateButton();
+ }
+
+ void updateButton(){
+ buttonRecover.setEnabled((getContext().getState().isNormal()) &&
+ (textPosition.getText().trim().isEmpty()) &&
+ (!textSegment.getText().trim().isEmpty()) &&
+ !isRecovering()
+ );
+
+ }
+
+ boolean isRecovering(){
+ return "true".equals(getContext().getGlobal("recovering"));
+ }
+
+ @Override
+ public void onExecutedFile(String fileName, Object result) {
+ }
+
+
+
+ @Override
+ protected void onTimer() {
+ System.out.println(".");
+ Device robot = getContext().getDevicePool().getByName("robot", Device.class);
+ if ((robot==null) || (!robot.getState().isNormal())){
+ System.out.println("*");
+ ledValidSegment.setColor(Color.BLACK);
+ textSegment.setText("");
+ ledKnownPosition.setColor(Color.BLACK);
+ textPosition.setText("");
+ } else {
+ if (getState().isNormal()){
+ String point = null;
+ try{
+ point = (String) eval("robot.get_current_point()", true);
+ ledKnownPosition.setColor((point == null) ? Color.RED : Color.GREEN);
+ textPosition.setText((point == null) ? "": point);
+ } catch (Exception ex) {
+ System.out.println(ex);
+ ledKnownPosition.setColor(Color.BLACK);
+ textPosition.setText("");
+ }
+ List segment = null;
+ try{
+ segment = (List) eval("get_current_segment()", true);
+ ledValidSegment.setColor((segment == null) ? Color.RED : Color.GREEN);
+ textSegment.setText((segment == null) ? "": segment.get(0) + "->" + segment.get(1) + " [" + segment.get(2) + "mm]");
+ if ((segment == null)||(point!=null)){
+ textDistance.setText("");
+ } else {
+ try{
+ Object distance = eval("get_current_distance()", true);
+ textDistance.setText((distance == null) ? "" : String.format("%1.2f",((Number)distance).doubleValue()));
+ } catch (Exception ex) {
+ textDistance.setText("");
+ }
+ }
+ } catch (Exception ex) {
+ System.out.println(ex);
+ ledValidSegment.setColor(Color.BLACK);
+ textSegment.setText("");
+ textDistance.setText("");
+ }
+ try{
+ Boolean is_in_dewar = (Boolean) eval("is_in_dewar()", true);
+ if ((segment==null) && is_in_dewar){
+ ledValidSegment.setColor(Color.GREEN);
+ textSegment.setText("Inside Dewar");
+ }
+ } catch (Exception ex) {
+ System.out.println(ex);
+ }
+ }
+ }
+ updateButton();
+ }
+
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ ledKnownPosition = new ch.psi.pshell.swing.Led();
+ jLabel6 = new javax.swing.JLabel();
+ ledValidSegment = new ch.psi.pshell.swing.Led();
+ jLabel7 = new javax.swing.JLabel();
+ buttonRecover = new javax.swing.JButton();
+ buttonAbort = new javax.swing.JButton();
+ textPosition = new javax.swing.JTextField();
+ textSegment = new javax.swing.JTextField();
+ textDistance = new javax.swing.JTextField();
+ jLabel8 = new javax.swing.JLabel();
+
+ jLabel6.setText("Known position");
+
+ jLabel7.setText("Valid segment");
+
+ buttonRecover.setText("Recover");
+ buttonRecover.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonRecoverActionPerformed(evt);
+ }
+ });
+
+ buttonAbort.setText("Abort");
+ buttonAbort.setEnabled(false);
+ buttonAbort.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonAbortActionPerformed(evt);
+ }
+ });
+
+ textPosition.setEditable(false);
+
+ textSegment.setEditable(false);
+
+ textDistance.setEditable(false);
+ textDistance.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
+
+ jLabel8.setText("Distance:");
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(ledKnownPosition, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(jLabel6)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(textPosition))
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(ledValidSegment, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(jLabel7)
+ .addGap(16, 16, 16)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(0, 103, Short.MAX_VALUE)
+ .addComponent(jLabel8)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(textDistance, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(textSegment))))
+ .addGap(8, 8, 8))
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(buttonRecover, javax.swing.GroupLayout.DEFAULT_SIZE, 179, Short.MAX_VALUE)
+ .addComponent(buttonAbort, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(ledKnownPosition, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(jLabel6)
+ .addComponent(textPosition, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(ledValidSegment, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(jLabel7)
+ .addComponent(textSegment, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(jLabel8)
+ .addComponent(textDistance, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 61, Short.MAX_VALUE)
+ .addComponent(buttonRecover)
+ .addGap(18, 18, 18)
+ .addComponent(buttonAbort)
+ .addGap(24, 24, 24))
+ );
+ }// //GEN-END:initComponents
+
+ private void buttonRecoverActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonRecoverActionPerformed
+ try{
+ if (isRecovering()){
+ getLogger().warning("Ongoing recovery ");
+ return;
+ }
+ buttonAbort.setEnabled(true);
+ getContext().setGlobal("recovering", "true");
+ Device robot = getContext().getDevicePool().getByName("robot", Device.class);
+ abort();
+ getContext().waitState(State.Ready, 5000);
+ eval("robot.stop_task()", false);
+ robot.waitReady(5000);
+ evalAsync("recover()", false).handle((ret, ex) -> {
+ if (ex != null){
+ if (!getContext().isAborted()){
+ showException((Exception)ex);
+ }
+ } else {
+ SwingUtils.showMessage(getTopLevel(), "Return", String.valueOf(ret));
+ }
+ getContext().setGlobal("recovering", null);
+ buttonAbort.setEnabled(false);
+ return ret;
+ });
+ } catch (Exception ex) {
+ showException(ex);
+ getContext().setGlobal("recovering", null);
+ buttonAbort.setEnabled(false);
+ }
+ }//GEN-LAST:event_buttonRecoverActionPerformed
+
+ private void buttonAbortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonAbortActionPerformed
+ try {
+ abort();
+ try{
+ eval("robot.disable()", true);
+ } catch (Exception ex){
+ this.showException(ex);
+ }
+ try{
+ eval("robot.stop_task()", true);
+ } catch (Exception ex){
+ this.showException(ex);
+ }
+ try{
+ eval("robot.reset_motion()", true);
+ } catch (Exception ex){
+ this.showException(ex);
+ }
+ } catch (InterruptedException ex) {
+ //showException(ex);
+ }
+ }//GEN-LAST:event_buttonAbortActionPerformed
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton buttonAbort;
+ private javax.swing.JButton buttonRecover;
+ private javax.swing.JLabel jLabel6;
+ private javax.swing.JLabel jLabel7;
+ private javax.swing.JLabel jLabel8;
+ private ch.psi.pshell.swing.Led ledKnownPosition;
+ private ch.psi.pshell.swing.Led ledValidSegment;
+ private javax.swing.JTextField textDistance;
+ private javax.swing.JTextField textPosition;
+ private javax.swing.JTextField textSegment;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/plugins/RobotModbus.java b/plugins/RobotModbus.java
new file mode 100644
index 0000000..ca2e149
--- /dev/null
+++ b/plugins/RobotModbus.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2014 Paul Scherrer Institute. All rights reserved.
+ */
+
+import ch.psi.pshell.device.*;
+import ch.psi.pshell.modbus.*;
+
+/**
+ */
+public class RobotModbus extends ModbusTCP {
+
+ public RobotModbus(String name, String server) {
+ super(name, server);
+ }
+
+ public Object run() throws Exception{
+ Thread.sleep(1000);
+ return ("Done run");
+ }
+
+}
diff --git a/plugins/RobotPanel.form b/plugins/RobotPanel.form
new file mode 100644
index 0000000..bf9c0d6
--- /dev/null
+++ b/plugins/RobotPanel.form
@@ -0,0 +1,587 @@
+
+
+
diff --git a/plugins/RobotPanel.java b/plugins/RobotPanel.java
new file mode 100644
index 0000000..e841f57
--- /dev/null
+++ b/plugins/RobotPanel.java
@@ -0,0 +1,685 @@
+
+import ch.psi.pshell.device.Device;
+import ch.psi.pshell.ui.App;
+import ch.psi.pshell.swing.DevicePanel;
+import ch.psi.pshell.core.Context;
+import ch.psi.utils.State;
+import java.awt.Color;
+import java.util.Map;
+import javax.swing.JSpinner;
+import javax.swing.JTextField;
+
+/**
+ *
+ */
+public class RobotPanel extends DevicePanel {
+
+ /**
+ * Creates new form RobotPanel
+ */
+ public RobotPanel() {
+ initComponents();
+ ((JSpinner.DefaultEditor)spinnerSpeed.getEditor()).getTextField().setHorizontalAlignment(JTextField.CENTER);
+ }
+
+ @Override
+ public void setDevice(Device device) {
+ super.setDevice(device);
+ if (device == null) {
+
+ }
+ panelState.setDevice(device);
+ }
+
+ @Override
+ protected void onDeviceStateChanged(State state, State former) {
+ boolean enabled = state.isNormal();
+ spinnerSpeed.setEnabled(enabled);
+ buttonAbort.setEnabled(enabled);
+ if (!enabled){
+ buttonEnable.setEnabled(enabled);
+ buttonDisable.setEnabled(enabled);
+ butonStop.setEnabled(enabled);
+ buttonPause.setEnabled(enabled);
+ buttonResume.setEnabled(enabled);
+ }
+ }
+
+ boolean updating;
+ @Override
+ protected void onDeviceCacheChanged(Object value, Object former, long timestamp, boolean valueChange) {
+ updating = true;
+ try{
+ Boolean powered = null;
+ Boolean empty = null;
+ Boolean settled = null;
+ Boolean moving = null;
+ Boolean open = null;
+ Integer speed = null;
+ String task = null;
+ String mode = null;
+ String position = null;
+
+ if ((value != null) && (value instanceof Map)) {
+ Map status = (Map) value;
+ try {
+ powered = (Boolean) status.get("powered");
+ } catch (Exception ex) {
+ }
+ try {
+ empty = (Boolean) status.get("empty");
+ } catch (Exception ex) {
+ }
+ try {
+ settled = (Boolean) status.get("settled");
+ } catch (Exception ex) {
+ }
+ try {
+ open = (Boolean) status.get("open");
+ } catch (Exception ex) {
+ }
+ try {
+ speed = (Integer) status.get("speed");
+ } catch (Exception ex) {
+ }
+ try {
+ position = (String) status.get("pos");
+ if (position==null){
+ position = "";
+ }
+ } catch (Exception ex) {
+ }
+ try {
+ task = ((status.containsKey("task")) && (status.get("task") == null)) ? "" : ((String) status.get("task")).trim();
+ } catch (Exception ex) {
+ System.out.println(ex);
+ ex.printStackTrace();
+ }
+ try {
+ mode = ((String) status.get("mode")).trim();
+ //mode = (String) Context.getInstance().evalLineBackground(getDevice().getName() + ".working_mode");
+ } catch (Exception ex) {
+ }
+ try {
+ //if (status.get("status").equals("hold")){
+ // moving = false;
+ //} else if (status.get("status").equals("move")){
+ // moving = true;
+ //}
+ moving = Boolean.FALSE.equals(settled) || Boolean.FALSE.equals(empty);
+ } catch (Exception ex) {
+ }
+ }
+
+ boolean remote = mode.equals("remote");
+ boolean enabled = Boolean.TRUE.equals(powered);
+ buttonEnable.setEnabled((powered != null) && (powered == false));
+ buttonDisable.setEnabled(enabled);
+
+ butonStop.setEnabled(remote && Boolean.TRUE.equals(moving));
+ buttonPause.setEnabled(remote && enabled && Boolean.TRUE.equals(moving) && Boolean.FALSE.equals(settled));
+ buttonResume.setEnabled(remote && enabled && Boolean.TRUE.equals(moving) && Boolean.TRUE.equals(settled));
+
+
+ ledPowered.setColor((powered == null) ? Color.GRAY : (powered ? Color.YELLOW : Color.DARK_GRAY));
+ ledEmpty.setColor((empty == null) ? Color.GRAY : (empty ? Color.GREEN : Color.YELLOW));
+ ledSettled.setColor((settled == null) ? Color.GRAY : (settled ? Color.GREEN : Color.YELLOW));
+ ledOpen.setColor((open == null) ? Color.GRAY : (open ? Color.GREEN : Color.DARK_GRAY));
+ ledMoving.setColor((moving == null) ? Color.GRAY : (moving ? Color.YELLOW : Color.DARK_GRAY));
+ textTask.setText((task == null) ? "" : task);
+ ledTask.setColor((task == null) ? Color.GRAY : (task.isEmpty() ? Color.DARK_GRAY : Color.YELLOW));
+ textPosition.setText((position == null) ? "" : position);
+ ledPosition.setColor((position == null) ? Color.GRAY : (position.isEmpty() ? Color.DARK_GRAY : Color.GREEN));
+ //buttonAbort.setEnabled(!textTask.getText().isEmpty());
+ spinnerSpeed.setEnabled(speed != null);
+ if (speed == null) {
+ spinnerSpeed.setValue(0);
+ } else {
+ spinnerSpeed.setValue(speed);
+ }
+ ledMode.setColor((mode == null) ? Color.BLACK : (remote ? Color.GREEN : Color.YELLOW));
+ textMode.setText((mode == null) ? "" : mode);
+
+ } finally{
+ updating = false;
+ }
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jPanel1 = new javax.swing.JPanel();
+ ledPowered = new ch.psi.pshell.swing.Led();
+ jLabel1 = new javax.swing.JLabel();
+ panelPowerCtr = new javax.swing.JPanel();
+ buttonDisable = new javax.swing.JButton();
+ buttonEnable = new javax.swing.JButton();
+ jPanel2 = new javax.swing.JPanel();
+ jLabel2 = new javax.swing.JLabel();
+ spinnerSpeed = new ch.psi.utils.swing.HorizontalSpinner();
+ jLabel7 = new javax.swing.JLabel();
+ ledMoving = new ch.psi.pshell.swing.Led();
+ panelMotionCtr = new javax.swing.JPanel();
+ butonStop = new javax.swing.JButton();
+ buttonResume = new javax.swing.JButton();
+ buttonPause = new javax.swing.JButton();
+ jPanel3 = new javax.swing.JPanel();
+ jLabel3 = new javax.swing.JLabel();
+ ledSettled = new ch.psi.pshell.swing.Led();
+ jLabel4 = new javax.swing.JLabel();
+ ledEmpty = new ch.psi.pshell.swing.Led();
+ textTask = new javax.swing.JTextField();
+ jLabel6 = new javax.swing.JLabel();
+ textMode = new javax.swing.JTextField();
+ buttonAbort = new javax.swing.JButton();
+ jLabel8 = new javax.swing.JLabel();
+ ledTask = new ch.psi.pshell.swing.Led();
+ ledMode = new ch.psi.pshell.swing.Led();
+ textPosition = new javax.swing.JTextField();
+ ledPosition = new ch.psi.pshell.swing.Led();
+ jLabel9 = new javax.swing.JLabel();
+ panelState = new ch.psi.pshell.swing.DeviceStatePanel();
+ jPanel4 = new javax.swing.JPanel();
+ ledOpen = new ch.psi.pshell.swing.Led();
+ jLabel5 = new javax.swing.JLabel();
+ panelPowerCtr1 = new javax.swing.JPanel();
+ buttonClose = new javax.swing.JButton();
+ buttonOpen = new javax.swing.JButton();
+
+ jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Power"));
+
+ ledPowered.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
+
+ jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel1.setText("Powered:");
+
+ buttonDisable.setText("Disable");
+ buttonDisable.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonDisableActionPerformed(evt);
+ }
+ });
+
+ buttonEnable.setText("Enable");
+ buttonEnable.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonEnableActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout panelPowerCtrLayout = new javax.swing.GroupLayout(panelPowerCtr);
+ panelPowerCtr.setLayout(panelPowerCtrLayout);
+ panelPowerCtrLayout.setHorizontalGroup(
+ panelPowerCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelPowerCtrLayout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addComponent(buttonEnable)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE)
+ .addComponent(buttonDisable))
+ );
+ panelPowerCtrLayout.setVerticalGroup(
+ panelPowerCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelPowerCtrLayout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addGroup(panelPowerCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+ .addComponent(buttonDisable, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(buttonEnable))
+ .addGap(0, 0, 0))
+ );
+
+ javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+ jPanel1.setLayout(jPanel1Layout);
+ jPanel1Layout.setHorizontalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(ledPowered, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(panelPowerCtr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ jPanel1Layout.setVerticalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addGap(4, 4, 4)
+ .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel1)
+ .addComponent(ledPowered, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(panelPowerCtr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(2, 2, 2))
+ );
+
+ jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Motion"));
+
+ jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel2.setText("Speed:");
+
+ spinnerSpeed.setModel(new javax.swing.SpinnerNumberModel(10, null, 100, 1));
+ spinnerSpeed.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ spinnerSpeedStateChanged(evt);
+ }
+ });
+
+ jLabel7.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel7.setText("Moving:");
+
+ ledMoving.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
+
+ butonStop.setIcon(new javax.swing.ImageIcon(App.class.getResource("/ch/psi/pshell/ui/Stop.png")));
+ butonStop.setText(" ");
+ butonStop.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ butonStop.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ butonStopActionPerformed(evt);
+ }
+ });
+
+ buttonResume.setIcon(new javax.swing.ImageIcon(App.class.getResource("/ch/psi/pshell/ui/Play.png")));
+ buttonResume.setText(" ");
+ buttonResume.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ buttonResume.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonResumeActionPerformed(evt);
+ }
+ });
+
+ buttonPause.setIcon(new javax.swing.ImageIcon(App.class.getResource("/ch/psi/pshell/ui/Pause.png")));
+ buttonPause.setText(" ");
+ buttonPause.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ buttonPause.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonPauseActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout panelMotionCtrLayout = new javax.swing.GroupLayout(panelMotionCtr);
+ panelMotionCtr.setLayout(panelMotionCtrLayout);
+ panelMotionCtrLayout.setHorizontalGroup(
+ panelMotionCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelMotionCtrLayout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addComponent(butonStop, javax.swing.GroupLayout.DEFAULT_SIZE, 45, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(buttonPause, javax.swing.GroupLayout.DEFAULT_SIZE, 46, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(buttonResume, javax.swing.GroupLayout.DEFAULT_SIZE, 47, Short.MAX_VALUE)
+ .addGap(0, 0, 0))
+ );
+ panelMotionCtrLayout.setVerticalGroup(
+ panelMotionCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelMotionCtrLayout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addGroup(panelMotionCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(butonStop, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(buttonPause, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(buttonResume, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGap(0, 0, 0))
+ );
+
+ javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
+ jPanel2.setLayout(jPanel2Layout);
+ jPanel2Layout.setHorizontalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel2Layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel2Layout.createSequentialGroup()
+ .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(ledMoving, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(14, 14, 14)
+ .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(panelMotionCtr, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(spinnerSpeed))
+ .addContainerGap())
+ );
+ jPanel2Layout.setVerticalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel2Layout.createSequentialGroup()
+ .addGap(4, 4, 4)
+ .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel7)
+ .addComponent(ledMoving, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(panelMotionCtr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(jLabel2)
+ .addComponent(spinnerSpeed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(2, 2, 2))
+ );
+
+ jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Status"));
+
+ jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel3.setText("Settled:");
+
+ ledSettled.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
+
+ jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel4.setText("Empty:");
+
+ ledEmpty.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
+
+ textTask.setEditable(false);
+ textTask.setHorizontalAlignment(javax.swing.JTextField.CENTER);
+
+ jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel6.setText("Mode:");
+
+ textMode.setEditable(false);
+ textMode.setHorizontalAlignment(javax.swing.JTextField.CENTER);
+
+ buttonAbort.setText("Abort");
+ buttonAbort.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonAbortActionPerformed(evt);
+ }
+ });
+
+ jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel8.setText("Task:");
+
+ ledTask.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
+
+ ledMode.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
+
+ textPosition.setEditable(false);
+ textPosition.setHorizontalAlignment(javax.swing.JTextField.CENTER);
+
+ ledPosition.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
+
+ jLabel9.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel9.setText("Position:");
+
+ javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
+ jPanel3.setLayout(jPanel3Layout);
+ jPanel3Layout.setHorizontalGroup(
+ jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(ledTask, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(ledEmpty, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(ledSettled, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(ledPosition, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(textTask)
+ .addComponent(textPosition)))
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(ledMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(textMode)))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(buttonAbort)
+ .addContainerGap())
+ );
+
+ jPanel3Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel3, jLabel4, jLabel6, jLabel8, jLabel9});
+
+ jPanel3Layout.setVerticalGroup(
+ jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
+ .addGap(4, 4, 4)
+ .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel3)
+ .addComponent(ledSettled, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(2, 2, 2)
+ .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel4)
+ .addComponent(ledEmpty, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(2, 2, 2)
+ .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(textMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(ledMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(jLabel6))
+ .addGap(2, 2, 2)
+ .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(buttonAbort)
+ .addComponent(jLabel8)
+ .addComponent(ledTask, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(textTask, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(2, 2, 2)
+ .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel9)
+ .addComponent(ledPosition, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(textPosition, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(2, 2, 2))
+ );
+
+ jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Tool"));
+
+ ledOpen.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
+
+ jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel5.setText("Open:");
+
+ buttonClose.setText(" Close ");
+ buttonClose.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonCloseActionPerformed(evt);
+ }
+ });
+
+ buttonOpen.setText(" Open ");
+ buttonOpen.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonOpenActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout panelPowerCtr1Layout = new javax.swing.GroupLayout(panelPowerCtr1);
+ panelPowerCtr1.setLayout(panelPowerCtr1Layout);
+ panelPowerCtr1Layout.setHorizontalGroup(
+ panelPowerCtr1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelPowerCtr1Layout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addComponent(buttonOpen)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE)
+ .addComponent(buttonClose))
+ );
+
+ panelPowerCtr1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonClose, buttonOpen});
+
+ panelPowerCtr1Layout.setVerticalGroup(
+ panelPowerCtr1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelPowerCtr1Layout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addGroup(panelPowerCtr1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+ .addComponent(buttonClose, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(buttonOpen))
+ .addGap(0, 0, 0))
+ );
+
+ javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
+ jPanel4.setLayout(jPanel4Layout);
+ jPanel4Layout.setHorizontalGroup(
+ jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel4Layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(ledOpen, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(panelPowerCtr1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ jPanel4Layout.setVerticalGroup(
+ jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel4Layout.createSequentialGroup()
+ .addGap(4, 4, 4)
+ .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel5)
+ .addComponent(ledOpen, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(panelPowerCtr1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(2, 2, 2))
+ );
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(panelState, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(panelState, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ );
+ }// //GEN-END:initComponents
+
+ private void buttonEnableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonEnableActionPerformed
+ try{
+ Context.getInstance().evalLineBackground(getDevice().getName() + ".enable()");
+ } catch (Exception ex){
+ this.showException(ex);
+ }
+ }//GEN-LAST:event_buttonEnableActionPerformed
+
+ private void buttonDisableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDisableActionPerformed
+ try{
+ Context.getInstance().evalLineBackground(getDevice().getName() + ".disable()");
+ } catch (Exception ex){
+ this.showException(ex);
+ }
+ }//GEN-LAST:event_buttonDisableActionPerformed
+
+ private void spinnerSpeedStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerSpeedStateChanged
+ try{
+ if (!updating){
+ Context.getInstance().evalLineBackground(getDevice().getName() + ".set_monitor_speed(" + spinnerSpeed.getValue() + ")");
+ }
+ } catch (Exception ex){
+ this.showException(ex);
+ }
+ }//GEN-LAST:event_spinnerSpeedStateChanged
+
+ private void butonStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_butonStopActionPerformed
+ try{
+ Context.getInstance().evalLineBackground(getDevice().getName() + ".reset_motion()");
+ } catch (Exception ex){
+ this.showException(ex);
+ }
+ }//GEN-LAST:event_butonStopActionPerformed
+
+ private void buttonPauseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPauseActionPerformed
+ try{
+ Context.getInstance().evalLineBackground(getDevice().getName() + ".stop()");
+ } catch (Exception ex){
+ this.showException(ex);
+ }
+ }//GEN-LAST:event_buttonPauseActionPerformed
+
+ private void buttonResumeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonResumeActionPerformed
+ try{
+ Context.getInstance().evalLineBackground(getDevice().getName() + ".resume()");
+ } catch (Exception ex){
+ this.showException(ex);
+ }
+ }//GEN-LAST:event_buttonResumeActionPerformed
+
+ private void buttonAbortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonAbortActionPerformed
+ try{
+ Context.getInstance().evalLineBackground(getDevice().getName() + ".stop_task()");
+ //Context.getInstance().evalLineBackground(getDevice().getName() + ".task_kill('" + textTask.getText() + "')");
+ } catch (Exception ex){
+ this.showException(ex);
+ }
+ }//GEN-LAST:event_buttonAbortActionPerformed
+
+ private void buttonCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonCloseActionPerformed
+ try{
+ Context.getInstance().evalLineBackground(getDevice().getName() + ".close_tool()");
+ } catch (Exception ex){
+ this.showException(ex);
+ }
+ }//GEN-LAST:event_buttonCloseActionPerformed
+
+ private void buttonOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonOpenActionPerformed
+ try{
+ Context.getInstance().evalLineBackground(getDevice().getName() + ".open_tool()");
+ } catch (Exception ex){
+ this.showException(ex);
+ }
+ }//GEN-LAST:event_buttonOpenActionPerformed
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton butonStop;
+ private javax.swing.JButton buttonAbort;
+ private javax.swing.JButton buttonClose;
+ private javax.swing.JButton buttonDisable;
+ private javax.swing.JButton buttonEnable;
+ private javax.swing.JButton buttonOpen;
+ private javax.swing.JButton buttonPause;
+ private javax.swing.JButton buttonResume;
+ private javax.swing.JLabel jLabel1;
+ private javax.swing.JLabel jLabel2;
+ private javax.swing.JLabel jLabel3;
+ private javax.swing.JLabel jLabel4;
+ private javax.swing.JLabel jLabel5;
+ private javax.swing.JLabel jLabel6;
+ private javax.swing.JLabel jLabel7;
+ private javax.swing.JLabel jLabel8;
+ private javax.swing.JLabel jLabel9;
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel2;
+ private javax.swing.JPanel jPanel3;
+ private javax.swing.JPanel jPanel4;
+ private ch.psi.pshell.swing.Led ledEmpty;
+ private ch.psi.pshell.swing.Led ledMode;
+ private ch.psi.pshell.swing.Led ledMoving;
+ private ch.psi.pshell.swing.Led ledOpen;
+ private ch.psi.pshell.swing.Led ledPosition;
+ private ch.psi.pshell.swing.Led ledPowered;
+ private ch.psi.pshell.swing.Led ledSettled;
+ private ch.psi.pshell.swing.Led ledTask;
+ private javax.swing.JPanel panelMotionCtr;
+ private javax.swing.JPanel panelPowerCtr;
+ private javax.swing.JPanel panelPowerCtr1;
+ private ch.psi.pshell.swing.DeviceStatePanel panelState;
+ private javax.swing.JSpinner spinnerSpeed;
+ private javax.swing.JTextField textMode;
+ private javax.swing.JTextField textPosition;
+ private javax.swing.JTextField textTask;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/plugins/RobotTcp.java b/plugins/RobotTcp.java
new file mode 100644
index 0000000..d3f4c33
--- /dev/null
+++ b/plugins/RobotTcp.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2014 Paul Scherrer Institute. All rights reserved.
+ */
+
+import ch.psi.pshell.device.*;
+import ch.psi.pshell.serial.*;
+
+/**
+ */
+public class RobotTcp extends TcpDevice {
+
+ public RobotTcp(String name, String server) {
+ super(name, server);
+ }
+
+ public Object run() throws Exception{
+ Thread.sleep(1000);
+ return ("Done");
+ }
+
+}
diff --git a/plugins/SmartMagnetConfig.java b/plugins/SmartMagnetConfig.java
new file mode 100644
index 0000000..2c6213c
--- /dev/null
+++ b/plugins/SmartMagnetConfig.java
@@ -0,0 +1,14 @@
+
+import ch.psi.pshell.device.DeviceConfig;
+
+/**
+ *
+ */
+public class SmartMagnetConfig extends DeviceConfig{
+ public double holdingCurrent;
+ public double restingCurrent;
+ public double mountCurrent;
+ public double unmountCurrent;
+ public double remanenceCurrent;
+
+}
diff --git a/plugins/SmartMagnetPanel.form b/plugins/SmartMagnetPanel.form
new file mode 100644
index 0000000..432e7bd
--- /dev/null
+++ b/plugins/SmartMagnetPanel.form
@@ -0,0 +1,284 @@
+
+
+
diff --git a/plugins/SmartMagnetPanel.java b/plugins/SmartMagnetPanel.java
new file mode 100644
index 0000000..589fb82
--- /dev/null
+++ b/plugins/SmartMagnetPanel.java
@@ -0,0 +1,320 @@
+
+import ch.psi.pshell.device.Device;
+import ch.psi.pshell.ui.App;
+import ch.psi.pshell.swing.DevicePanel;
+import ch.psi.pshell.core.Context;
+import ch.psi.utils.State;
+import java.awt.Color;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.script.ScriptException;
+
+/**
+ *
+ */
+public class SmartMagnetPanel extends DevicePanel {
+
+ /**
+ * Creates new form RobotPanel
+ */
+ public SmartMagnetPanel() {
+ initComponents();
+ }
+
+ @Override
+ public void setDevice(Device device) {
+ super.setDevice(device);
+ if (device == null) {
+
+ }
+ panelState.setDevice(device);
+ this.startTimer(1000, 100);
+ }
+
+ @Override
+ protected void onDeviceStateChanged(State state, State former) {
+ switch(state){
+ case Paused:
+ ledSupressed.setColor(Color.ORANGE);
+ ledStatus.setColor(Color.GREEN);
+ ledMounted.setColor(Color.RED);
+ break;
+ case Ready:
+ ledSupressed.setColor(Color.BLACK);
+ ledStatus.setColor(Color.GREEN);
+ ledMounted.setColor(Color.GREEN);
+ break;
+ case Busy:
+ ledSupressed.setColor(Color.BLACK);
+ ledStatus.setColor(Color.GREEN);
+ ledMounted.setColor(Color.ORANGE);
+ break;
+ case Fault:
+ ledSupressed.setColor(Color.RED);
+ ledStatus.setColor(Color.RED);
+ ledMounted.setColor(Color.RED);
+ break;
+ default:
+ ledSupressed.setColor(Color.BLACK);
+ ledStatus.setColor(Color.BLACK);
+ ledMounted.setColor(Color.BLACK);
+ break;
+ }
+ buttonSupressOn.setEnabled((state==State.Ready) || (state == State.Busy));
+ buttonSupressOff.setEnabled(state == State.Paused);
+ }
+
+ @Override
+ protected void onDeviceCacheChanged(Object value, Object former, long timestamp, boolean valueChange) {
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jPanel1 = new javax.swing.JPanel();
+ ledStatus = new ch.psi.pshell.swing.Led();
+ jLabel1 = new javax.swing.JLabel();
+ panelPowerCtr = new javax.swing.JPanel();
+ jLabel5 = new javax.swing.JLabel();
+ ledMounted = new ch.psi.pshell.swing.Led();
+ jLabel10 = new javax.swing.JLabel();
+ panelCurrentRb = new ch.psi.pshell.swing.DeviceValuePanel();
+ panelState = new ch.psi.pshell.swing.DeviceStatePanel();
+ panelCurrent = new ch.psi.pshell.swing.ProcessVariablePanel();
+ jPanel2 = new javax.swing.JPanel();
+ jLabel2 = new javax.swing.JLabel();
+ ledSupressed = new ch.psi.pshell.swing.Led();
+ buttonSupressOn = new javax.swing.JButton();
+ buttonSupressOff = new javax.swing.JButton();
+ jPanel3 = new javax.swing.JPanel();
+ buttonConfiguration = new javax.swing.JButton();
+
+ jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Status"));
+
+ ledStatus.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
+
+ jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel1.setText("Status:");
+
+ javax.swing.GroupLayout panelPowerCtrLayout = new javax.swing.GroupLayout(panelPowerCtr);
+ panelPowerCtr.setLayout(panelPowerCtrLayout);
+ panelPowerCtrLayout.setHorizontalGroup(
+ panelPowerCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 150, Short.MAX_VALUE)
+ );
+ panelPowerCtrLayout.setVerticalGroup(
+ panelPowerCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 23, Short.MAX_VALUE)
+ );
+
+ jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel5.setText("Mounted:");
+
+ ledMounted.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
+
+ jLabel10.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel10.setText("Current:");
+
+ panelCurrentRb.setDeviceName("smc_current_rb");
+
+ javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+ jPanel1.setLayout(jPanel1Layout);
+ jPanel1Layout.setHorizontalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(ledStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(panelPowerCtr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(ledMounted, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(panelCurrentRb, javax.swing.GroupLayout.PREFERRED_SIZE, 173, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ jPanel1Layout.setVerticalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addGap(4, 4, 4)
+ .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel1)
+ .addComponent(ledStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(panelPowerCtr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel5)
+ .addComponent(ledMounted, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jLabel10)
+ .addComponent(panelCurrentRb, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addContainerGap())
+ );
+
+ panelCurrent.setBorder(javax.swing.BorderFactory.createTitledBorder("Current"));
+ panelCurrent.setDeviceName("smc_current");
+
+ jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Supress"));
+
+ jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
+ jLabel2.setText("Supressed:");
+
+ ledSupressed.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N
+
+ buttonSupressOn.setText("On");
+ buttonSupressOn.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonSupressOnActionPerformed(evt);
+ }
+ });
+
+ buttonSupressOff.setText("Off");
+ buttonSupressOff.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonSupressOffActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
+ jPanel2.setLayout(jPanel2Layout);
+ jPanel2Layout.setHorizontalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel2Layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(jLabel2)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(ledSupressed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(buttonSupressOn)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(buttonSupressOff)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonSupressOff, buttonSupressOn});
+
+ jPanel2Layout.setVerticalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
+ .addComponent(jLabel2)
+ .addComponent(ledSupressed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(buttonSupressOn)
+ .addComponent(buttonSupressOff))
+ .addContainerGap())
+ );
+
+ jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Configuration"));
+
+ buttonConfiguration.setText("Configuration");
+ buttonConfiguration.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonConfigurationActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
+ jPanel3.setLayout(jPanel3Layout);
+ jPanel3Layout.setHorizontalGroup(
+ jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(buttonConfiguration)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ jPanel3Layout.setVerticalGroup(
+ jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(buttonConfiguration)
+ .addContainerGap())
+ );
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(panelState, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(panelCurrent, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(panelCurrent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(panelState, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ );
+ }// //GEN-END:initComponents
+
+ private void buttonSupressOnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSupressOnActionPerformed
+ try {
+ Context.getInstance().evalLineBackground("smart_magnet.set_supress(True)");
+ } catch (Exception ex) {
+ Logger.getLogger(SmartMagnetPanel.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }//GEN-LAST:event_buttonSupressOnActionPerformed
+
+ private void buttonSupressOffActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonSupressOffActionPerformed
+ try {
+ Context.getInstance().evalLineBackground("smart_magnet.set_supress(False)");
+ } catch (Exception ex) {
+ Logger.getLogger(SmartMagnetPanel.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }//GEN-LAST:event_buttonSupressOffActionPerformed
+
+ private void buttonConfigurationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonConfigurationActionPerformed
+ try {
+ this.showConfigEditor(true, false);
+ } catch (Exception ex) {
+ Logger.getLogger(SmartMagnetPanel.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }//GEN-LAST:event_buttonConfigurationActionPerformed
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton buttonConfiguration;
+ private javax.swing.JButton buttonSupressOff;
+ private javax.swing.JButton buttonSupressOn;
+ private javax.swing.JLabel jLabel1;
+ private javax.swing.JLabel jLabel10;
+ private javax.swing.JLabel jLabel2;
+ private javax.swing.JLabel jLabel5;
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel2;
+ private javax.swing.JPanel jPanel3;
+ private ch.psi.pshell.swing.Led ledMounted;
+ private ch.psi.pshell.swing.Led ledStatus;
+ private ch.psi.pshell.swing.Led ledSupressed;
+ private ch.psi.pshell.swing.ProcessVariablePanel panelCurrent;
+ private ch.psi.pshell.swing.DeviceValuePanel panelCurrentRb;
+ private javax.swing.JPanel panelPowerCtr;
+ private ch.psi.pshell.swing.DeviceStatePanel panelState;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/plugins/TestZMQ.java b/plugins/TestZMQ.java
new file mode 100644
index 0000000..cec2c40
--- /dev/null
+++ b/plugins/TestZMQ.java
@@ -0,0 +1,26 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/**
+ *
+ * @author gac-S_Changer
+ */
+public class TestZMQ {
+ public static void main(String[] args) {
+ String server = "raspberrypi:5556";
+ org.zeromq.ZMQ.Context context = org.zeromq.ZMQ.context(1);
+ org.zeromq.ZMQ.Socket subscriber = context.socket(org.zeromq.ZMQ.SUB);
+ subscriber.connect("tcp://" + server);
+ subscriber.subscribe("Status".getBytes());
+ while (!Thread.currentThread().isInterrupted()) {
+ String type = subscriber.recvStr();
+ String contents = subscriber.recvStr();
+ System.out.println(type + " : " + contents);
+ }
+ subscriber.close();
+ context.term();
+ }
+}
diff --git a/plugins/WagoPanel.form b/plugins/WagoPanel.form
new file mode 100644
index 0000000..9864ffa
--- /dev/null
+++ b/plugins/WagoPanel.form
@@ -0,0 +1,167 @@
+
+
+
diff --git a/plugins/WagoPanel.java b/plugins/WagoPanel.java
new file mode 100644
index 0000000..cacadcd
--- /dev/null
+++ b/plugins/WagoPanel.java
@@ -0,0 +1,207 @@
+import ch.psi.mxsc.Controller;
+import ch.psi.pshell.core.Context;
+import ch.psi.pshell.swing.DevicePanel;
+import java.util.concurrent.CompletableFuture;
+import javax.swing.border.TitledBorder;
+
+/**
+ *
+ */
+public class WagoPanel extends DevicePanel {
+
+ public WagoPanel() {
+ initComponents();
+ this.startTimer(10000);
+ }
+
+
+ CompletableFuture future;
+
+ @Override
+ public void onTimer(){
+ if ((getDevice()!=null)){
+ updateTitle();
+ }
+ }
+
+ void updateTitle(){
+ Boolean roomTemp = (Controller.getInstance().isLedRoomTemp());
+ if (roomTemp==null){
+ ((TitledBorder)panelDewar.getBorder()).setTitle("Dewar Light");
+ } else if (roomTemp==true){
+ ((TitledBorder)panelDewar.getBorder()).setTitle("Dewar Light (room temperature)");
+ } else {
+ ((TitledBorder)panelDewar.getBorder()).setTitle("Dewar Light (LN2)");
+ }
+ }
+
+
+ void execute(String statement){
+ try {
+ Context.getInstance().evalLineBackgroundAsync(statement).handle((ret, ex) -> {
+ if (WagoPanel.this.isShowing()){
+ if (ex != null){
+ showException((Exception)ex);
+ }
+ }
+ return ret;
+ });
+ } catch (Exception ex) {
+ showException(ex);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ deviceStatePanel1 = new ch.psi.pshell.swing.DeviceStatePanel();
+ panelSafety = new javax.swing.JPanel();
+ buttonReleasePsys = new javax.swing.JButton();
+ buttonReleaseLocal = new javax.swing.JButton();
+ panelRobot1 = new javax.swing.JPanel();
+ buttonHeater = new javax.swing.JToggleButton();
+ buttonStream = new javax.swing.JToggleButton();
+ panelDewar = new ch.psi.pshell.swing.ProcessVariablePanel();
+
+ deviceStatePanel1.setDeviceName("wago");
+
+ panelSafety.setBorder(javax.swing.BorderFactory.createTitledBorder("Safety"));
+
+ buttonReleasePsys.setText("Release PSYS");
+ buttonReleasePsys.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonReleasePsysActionPerformed(evt);
+ }
+ });
+
+ buttonReleaseLocal.setText("Release Local");
+ buttonReleaseLocal.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonReleaseLocalActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout panelSafetyLayout = new javax.swing.GroupLayout(panelSafety);
+ panelSafety.setLayout(panelSafetyLayout);
+ panelSafetyLayout.setHorizontalGroup(
+ panelSafetyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelSafetyLayout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(buttonReleasePsys)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(buttonReleaseLocal)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ panelSafetyLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonReleaseLocal, buttonReleasePsys});
+
+ panelSafetyLayout.setVerticalGroup(
+ panelSafetyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelSafetyLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(panelSafetyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonReleaseLocal)
+ .addComponent(buttonReleasePsys))
+ .addContainerGap())
+ );
+
+ panelRobot1.setBorder(javax.swing.BorderFactory.createTitledBorder("Dryer"));
+
+ buttonHeater.setText("Heater");
+ buttonHeater.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonHeaterActionPerformed(evt);
+ }
+ });
+
+ buttonStream.setText("Air Stream");
+ buttonStream.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ buttonStreamActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout panelRobot1Layout = new javax.swing.GroupLayout(panelRobot1);
+ panelRobot1.setLayout(panelRobot1Layout);
+ panelRobot1Layout.setHorizontalGroup(
+ panelRobot1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelRobot1Layout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(buttonHeater)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(buttonStream)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ panelRobot1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonHeater, buttonStream});
+
+ panelRobot1Layout.setVerticalGroup(
+ panelRobot1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelRobot1Layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(panelRobot1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(buttonHeater)
+ .addComponent(buttonStream))
+ .addContainerGap())
+ );
+
+ panelDewar.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Dewar Light", javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.DEFAULT_POSITION));
+ panelDewar.setDeviceName("led_level");
+ panelDewar.setShowAdvanced(false);
+ panelDewar.setShowButtons(false);
+ panelDewar.setShowLimitButtons(false);
+ panelDewar.setShowSlider(true);
+ panelDewar.setShowStop(false);
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(deviceStatePanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(panelSafety, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(panelRobot1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(panelDewar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(panelSafety, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(panelDewar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(panelRobot1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, 0)
+ .addComponent(deviceStatePanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ );
+ }// //GEN-END:initComponents
+
+ private void buttonReleasePsysActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonReleasePsysActionPerformed
+ execute("release_psys()");
+ }//GEN-LAST:event_buttonReleasePsysActionPerformed
+
+ private void buttonReleaseLocalActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonReleaseLocalActionPerformed
+ execute("release_local()");
+ }//GEN-LAST:event_buttonReleaseLocalActionPerformed
+
+ private void buttonHeaterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonHeaterActionPerformed
+ execute("set_heater(" + (buttonHeater.isSelected() ? "True": "False") + ")");
+ }//GEN-LAST:event_buttonHeaterActionPerformed
+
+ private void buttonStreamActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonStreamActionPerformed
+ execute("set_air_stream(" + (buttonStream.isSelected()? "True": "False")+ ")");
+ }//GEN-LAST:event_buttonStreamActionPerformed
+
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JToggleButton buttonHeater;
+ private javax.swing.JButton buttonReleaseLocal;
+ private javax.swing.JButton buttonReleasePsys;
+ private javax.swing.JToggleButton buttonStream;
+ private ch.psi.pshell.swing.DeviceStatePanel deviceStatePanel1;
+ private ch.psi.pshell.swing.ProcessVariablePanel panelDewar;
+ private javax.swing.JPanel panelRobot1;
+ private javax.swing.JPanel panelSafety;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/plugins/gui.form b/plugins/gui.form
new file mode 100644
index 0000000..5775937
--- /dev/null
+++ b/plugins/gui.form
@@ -0,0 +1,62 @@
+
+
+
diff --git a/plugins/gui.java b/plugins/gui.java
new file mode 100644
index 0000000..abeb59b
--- /dev/null
+++ b/plugins/gui.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 Paul Scherrer Institute. All rights reserved.
+ */
+
+import ch.psi.pshell.ui.Panel;
+import ch.psi.utils.State;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ */
+public class gui extends Panel {
+
+ public gui() {
+ initComponents();
+ }
+
+ //Overridable callbacks
+ @Override
+ public void onInitialize(int runCount) {
+
+ }
+
+ @Override
+ public void onStateChange(State state, State former) {
+
+ }
+
+ @Override
+ public void onExecutedFile(String fileName, Object result) {
+ }
+
+
+ //Callback to perform update - in event thread
+ @Override
+ protected void doUpdate() {
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jButton1 = new javax.swing.JButton();
+ renderer1 = new ch.psi.pshell.imaging.Renderer();
+ linePlotJFree1 = new ch.psi.pshell.plot.LinePlotJFree();
+
+ jButton1.setText("Abort");
+ jButton1.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ jButton1ActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(renderer1, javax.swing.GroupLayout.PREFERRED_SIZE, 154, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(82, 82, 82))
+ .addGroup(layout.createSequentialGroup()
+ .addGap(51, 51, 51)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jButton1)
+ .addComponent(linePlotJFree1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addContainerGap(250, Short.MAX_VALUE))
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(24, 24, 24)
+ .addComponent(jButton1)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(renderer1, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 20, Short.MAX_VALUE)
+ .addComponent(linePlotJFree1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
+ );
+ }// //GEN-END:initComponents
+
+ private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
+ try {
+ abort();
+ } catch (InterruptedException ex) {
+ Logger.getLogger(gui.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }//GEN-LAST:event_jButton1ActionPerformed
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton jButton1;
+ private ch.psi.pshell.plot.LinePlotJFree linePlotJFree1;
+ private ch.psi.pshell.imaging.Renderer renderer1;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/script/LN2_Monitoring.scd b/script/LN2_Monitoring.scd
new file mode 100644
index 0000000..d2ab014
--- /dev/null
+++ b/script/LN2_Monitoring.scd
@@ -0,0 +1,15 @@
+[
+ [ [ true, "phase_separator_level", "Device", 1, 1, "102,204,255" ],
+ [ true, "filling_phase_separator", "Device", 1, 1, "51,255,255" ],
+ [ true, "filling_dewar", "Device", 1, 1, "0,0,102" ],
+ [ true, "dewar_level", "Device", 1, 1, "0,51,153" ],
+ [ true, "rim_heater_temp", "Device", 1, 1, "255,0,51" ] ],
+ [ [ "1", 0.0, 100.0, null, null, 1000000.0, false, null ],
+ [ "2", null, null, null, null, null, null, null ],
+ [ "3", null, null, null, null, null, null, null ],
+ [ "4", null, null, null, null, null, null, null ],
+ [ "5", null, null, null, null, null, null, null ] ],
+ [ [ ] ],
+ [ [ "", 20000, 100 ],
+ [ "", "" ] ]
+]
\ No newline at end of file
diff --git a/script/LevelMonitoring.scd b/script/LevelMonitoring.scd
new file mode 100644
index 0000000..ae328cc
--- /dev/null
+++ b/script/LevelMonitoring.scd
@@ -0,0 +1,12 @@
+[
+ [ [ true, "phase_separator_level", "Device", 1, 1, "255,0,0" ],
+ [ true, "dewar_level", "Device", 1, 1, "0,0,255" ] ],
+ [ [ "1", 0.0, 100.0, null, null, 100000.0, false, null ],
+ [ "2", null, null, null, null, null, null, null ],
+ [ "3", null, null, null, null, null, null, null ],
+ [ "4", null, null, null, null, null, null, null ],
+ [ "5", null, null, null, null, null, null, null ] ],
+ [ [ ] ],
+ [ [ "", 20000, 100 ],
+ [ "", "" ] ]
+]
\ No newline at end of file
diff --git a/script/calibration/BinarySearchYZ.py b/script/calibration/BinarySearchYZ.py
new file mode 100644
index 0000000..42db379
--- /dev/null
+++ b/script/calibration/BinarySearchYZ.py
@@ -0,0 +1,29 @@
+import plotutils
+import math
+
+
+#STRATEGY = "Normal"
+#STRATEGY = "Boundary"
+#STRATEGY = "FullNeighborhood"
+RANGE = [-5.0, 5.0]
+STEP_SIZE = 0.1
+LATENCY = 0.05
+
+
+robot.enable()
+move_to_laser()
+
+
+robot.set_motors_enabled(True)
+current_y = robot_y.getPosition()
+current_z = robot_z.getPosition()
+
+
+r = bsearch([robot_y, robot_z], laser_distance,[RANGE[0], RANGE[0]], [RANGE[1], RANGE[1]], [STEP_SIZE,STEP_SIZE], relative = True, maximum=True, strategy = STRATEGY, latency = LATENCY, title = "Binary Search YZ")
+
+
+print r.print()
+opt_y, opt_z= r.getOptimalPosition()
+offset_y, offset_z = opt_y - current_y, opt_z - current_z
+
+print "offset_y: ", offset_y, " offset_z: ", offset_z
\ No newline at end of file
diff --git a/script/calibration/HillClimbingXZ.py b/script/calibration/HillClimbingXZ.py
new file mode 100644
index 0000000..2fcab26
--- /dev/null
+++ b/script/calibration/HillClimbingXZ.py
@@ -0,0 +1,45 @@
+import plotutils
+import math
+
+
+#STRATEGY = "Normal"
+STRATEGY = "Boundary"
+#STRATEGY = "FullNeighborhood"
+RANGE = [-5.0, 5.0]
+INITIAL_STEP = 1.0
+STEP_SIZE = 0.05
+LATENCY = 0.05
+NOISE_FILTER = 1
+
+
+robot.enable()
+move_to_laser()
+
+
+robot.set_motors_enabled(True)
+
+current_x = robot_x.getPosition()
+current_z = robot_z.getPosition()
+
+
+
+
+class Distance(Readable):
+ def read(self):
+ ret = ue.readable.read()
+ ret = 0.0 if math.isnan(ret) else ret
+ return ret
+
+laser_distance=Distance()
+start = time.time()
+r = hsearch([robot_x, robot_z],laser_distance, [RANGE[0], RANGE[0]], [RANGE[1], RANGE[1]], [INITIAL_STEP,INITIAL_STEP], [STEP_SIZE,STEP_SIZE], NOISE_FILTER, relative = True, maximum=True, latency = LATENCY, title = "Hill Climbing XZ")
+
+
+
+print r.print()
+opt_x, opt_z= r.getOptimalPosition()
+offset_x, offset_z = opt_x - current_x, opt_z - current_z
+
+print "offset_x: ", offset_x, " offset_z: ", offset_z
+
+
diff --git a/script/calibration/ScanRZ.py b/script/calibration/ScanRZ.py
new file mode 100644
index 0000000..55d3bba
--- /dev/null
+++ b/script/calibration/ScanRZ.py
@@ -0,0 +1,31 @@
+#Imports
+import plotutils
+from mathutils import fit_gaussian, Gaussian
+
+#Parameters
+RANGE = [-120.0,120.0]
+STEP = 5.0
+LATENCY = 0.005
+RELATIVE = False
+
+#Enabling and checking
+#enable_motion()
+#system_check()
+robot.enable()
+
+
+#Body
+robot.set_tool(TOOL_DEFAULT)
+move_to_laser()
+#robot.set_joint_motors_enabled(True)
+robot.set_motors_enabled(True)
+robot_rz.move(0.0)
+robot.set_motors_enabled(True)
+ret = lscan(robot_rz, ue.readable, RANGE[0], RANGE[1], STEP, latency = LATENCY, relative = RELATIVE, range = "auto", title = "Scan2")
+
+
+#Cleanup
+
+
+
+
diff --git a/script/calibration/ScanX.py b/script/calibration/ScanX.py
new file mode 100644
index 0000000..d10c505
--- /dev/null
+++ b/script/calibration/ScanX.py
@@ -0,0 +1,101 @@
+import plotutils
+from mathutils import fit_gaussian, Gaussian
+
+FIT = True
+
+d = robot.get_distance_to_pnt("pLaser")
+if d<0:
+ raise Exception ("Error calculating distance to laser: " + str(d))
+
+if d>20:
+ raise Exception ("Should be near the laser position to perform the scan")
+
+RANGE = [-5.0, 4.0] #[-1.5, 1.5]
+STEP = 0.02
+Z_OFFSET = 0 #-1.0
+LATENCY = 0.025
+BORDER_SIZE = 0.15
+
+robot.enable()
+robot.set_motors_enabled(True)
+current_positon = robot_x.getPosition()
+robot_z.moveRel(Z_OFFSET)
+
+print "Moving to scan start position: " , RANGE[0]
+robot.set_motors_enabled(True)
+robot_x.moveRel( RANGE[0])
+robot.set_motors_enabled(True)
+print "Starting scan X"
+
+RANGE = [0, (RANGE[1] - RANGE[0] )]
+
+robot.setPolling(25)
+
+try:
+ ret = lscan(robot_x, ue.readable, RANGE[0], RANGE[1], STEP, latency = LATENCY, relative = True)
+finally:
+ robot.setPolling(DEFAULT_ROBOT_POLLING)
+
+d = ret.getReadable(0)
+
+first_index = -1
+last_index = -1
+for i in range(len(d)):
+ if not math.isnan(d[i]):
+ if first_index<0:
+ first_index = i
+ last_index = i
+
+if first_index == -1 or last_index < first_index:
+ raise Exception("Invalid range")
+
+
+remove = int(max(BORDER_SIZE, STEP) / STEP)
+
+_range = [first_index+remove, last_index-remove]
+if _range[1] <= _range[0]:
+ raise Exception("Invalid range: " + str(_range))
+
+
+center_index = int((_range[0] + _range[1])/2)
+center_positon = ret.getPositions(0)[center_index]
+
+
+
+
+y = ret.getReadable(0)[_range[0] : _range[1]]
+x = ret.getPositions(0)[_range[0]: _range[1]]
+
+#Clear NaNs
+first_value=ret.getReadable(0)[first_index]
+y = [(first_value if math.isnan(v) else v) for v in y]
+
+
+
+if FIT:
+ x = enforce_monotonic(x)
+ offset=100
+ (normalization, mean_val, sigma) = fit_gaussian([offset-v for v in y], x)
+ closest_x = mean_val
+ closest_y = 100 -normalization
+else:
+ closest_x = x[y.index(min(y))]
+ closest_y = y[y.index(min(y))]
+
+
+
+if closest_x is None or closest_x <= ret.getPositions(0)[first_index] or closest_x >= ret.getPositions(0)[last_index]:
+ raise Exception("Invalid Fit")
+
+
+
+center_offset = center_positon-closest_y
+#center_offset = current_positon-closest_y
+
+
+
+p=get_plots()[0]
+p.addMarker(closest_x, p.AxisId.X, str(closest_x), Color.GREEN)
+
+robot.set_motors_enabled(True)
+robot_x.move(closest_x)
diff --git a/script/calibration/ScanY.py b/script/calibration/ScanY.py
new file mode 100644
index 0000000..cf93b9a
--- /dev/null
+++ b/script/calibration/ScanY.py
@@ -0,0 +1,99 @@
+import plotutils
+from mathutils import fit_gaussian, Gaussian
+
+FIT = True
+
+d = robot.get_distance_to_pnt("pLaser")
+if d<0:
+ raise Exception ("Error calculating distance to laser: " + str(d))
+
+if d>20:
+ raise Exception ("Should be near the laser position to perform the scan")
+
+RANGE = [-7.0, 4.0] #[-1.5, 1.5]
+STEP = 0.02
+Z_OFFSET = 0 #-1.0
+LATENCY = 0.025
+BORDER_SIZE = 0.15
+
+robot.enable()
+robot.set_motors_enabled(True)
+current_positon = robot_y.getPosition()
+robot_z.moveRel(Z_OFFSET)
+
+
+print "Moving to scan start position: " , RANGE[0]
+robot.set_motors_enabled(True)
+robot_y.moveRel( RANGE[0])
+robot.set_motors_enabled(True)
+print "Starting scan Y"
+
+RANGE = [0, (RANGE[1] - RANGE[0] )]
+
+robot.setPolling(25)
+try:
+ ret = lscan(robot_y, ue.readable, RANGE[0], RANGE[1], STEP, latency = LATENCY, relative = True)
+finally:
+ robot.setPolling(DEFAULT_ROBOT_POLLING)
+
+d = ret.getReadable(0)
+
+first_index = -1
+last_index = -1
+for i in range(len(d)):
+ if not math.isnan(d[i]):
+ if first_index<0:
+ first_index = i
+ last_index = i
+
+if first_index == -1 or last_index < first_index:
+ raise Exception("Invalid range")
+
+
+remove = int(max(BORDER_SIZE, STEP) / STEP)
+
+_range = [first_index+remove, last_index-remove]
+if _range[1] <= _range[0]:
+ raise Exception("Invalid range: " + str(_range))
+
+
+center_index = int((_range[0] + _range[1])/2)
+center_positon = ret.getPositions(0)[center_index]
+
+
+
+
+y = ret.getReadable(0)[_range[0] : _range[1]]
+x = ret.getPositions(0)[_range[0]: _range[1]]
+
+#Clear NaNs
+first_value=ret.getReadable(0)[first_index]
+y = [(first_value if math.isnan(v) else v) for v in y]
+
+
+if FIT:
+ x = enforce_monotonic(x)
+ offset=100
+ (normalization, mean_val, sigma) = fit_gaussian([offset-v for v in y], x)
+ closest_y = mean_val
+ closest_x = 100 -normalization
+else:
+ closest_y = x[y.index(min(y))]
+ closest_x = y[y.index(min(y))]
+
+
+if closest_y is None or closest_y <= ret.getPositions(0)[first_index] or closest_y >= ret.getPositions(0)[last_index]:
+ raise Exception("Invalid Fit")
+
+
+
+center_offset = center_positon-closest_y
+#center_offset = current_positon-closest_y
+
+
+
+p=get_plots()[0]
+p.addMarker(closest_y, p.AxisId.X, str(closest_y), Color.GREEN)
+
+robot.set_motors_enabled(True)
+robot_y.move(closest_y)
diff --git a/script/calibration/ScanYZ.py b/script/calibration/ScanYZ.py
new file mode 100644
index 0000000..bee63e6
--- /dev/null
+++ b/script/calibration/ScanYZ.py
@@ -0,0 +1,93 @@
+import plotutils
+from mathutils import fit_gaussian, Gaussian
+
+SINGLE_PASS = False
+if SINGLE_PASS:
+ STEP_SIZE = 0.2
+else:
+ STEP_SIZE = 1.0
+STEP_Z_FINAL = 0.1
+
+RANGE = [-5.0, 5.0]
+LATENCY = 0.05
+
+Z_FINAL_OFFSET = 0.0
+
+
+SINGLE_PASS = True
+STEP_SIZE = 0.1
+
+
+robot.enable()
+move_to_laser()
+
+step_y = STEP_SIZE
+step_z = STEP_SIZE
+range_y = [RANGE[0], RANGE[1]]
+range_z = [RANGE[0], RANGE[1]]
+
+robot.set_motors_enabled(True)
+current_y = robot_y.getPosition()
+current_z = robot_z.getPosition()
+
+print "Current pos y,z" , current_y, ",", current_z
+ret = ascan([robot_y, robot_z], ue.readable, [range_y[0], range_z[0]], [range_y[1], range_z[1]], [step_y,step_z], latency = LATENCY, relative = True , zigzag=False, title = "Scan XY")
+data = ret.getData(0)[0]
+#plot(Convert.transpose(data), title="Data")
+
+integ = []
+for x in data: integ.append(sum( [ (0.0 if (math.isnan(y)) else y) for y in x]))
+
+xdata= frange(range_y[0], range_y[1], step_y , False, True)
+p = plot(integ, title = "Fit", xdata=xdata)[0]
+
+
+max_x_index = integ.index(max(integ))
+max_x = xdata[max_x_index]
+try:
+ (normalization, mean_val, sigma) = fit_gaussian(integ, xdata)
+except:
+ raise Exception("Invalid Fit")
+gaussian = Gaussian(normalization, mean_val, sigma)
+xdata= frange(range_y[0], range_y[1], step_y/100.0 , False, True)
+plot_function(p, gaussian, "Fit", xdata, show_points = False, show_lines = True, color = Color.BLUE)
+
+#So
+if abs(mean_val - max_x) > 1.0:
+ raise Exception("Invalid Y detection")
+y_offset = mean_val
+center_y = current_y + y_offset
+
+print "Y offset = ", y_offset
+
+robot_y.move(center_y)
+if SINGLE_PASS:
+ z_scan_data = data[max_x_index]
+else:
+ step_z = STEP_Z_FINAL
+ ret2 = lscan(robot_z, ue.readable, range_z[0], range_z[1], step_z, latency = LATENCY, relative = True , zigzag=False)
+ z_scan_data = ret2.getData(0)[0]
+
+max_z_index= z_scan_data.index(max(z_scan_data))
+last_z_index = 0
+for i in range(len(z_scan_data)):
+ if not math.isnan(z_scan_data[i]):
+ last_z_index = i
+#Shape is cone: z is inceraseing. For proper detection last Z must be furthest
+if abs(max_z_index - last_z_index) * step_z > 1.0:
+ raise Exception("Invalid Z detection")
+
+if SINGLE_PASS:
+ max_z = ret.getPositions(1)[len(data[0]) * max_x_index + last_z_index]
+else:
+ max_z = ret2.getPositions(0)[last_z_index]
+
+z_offset = max_z - current_z + Z_FINAL_OFFSET
+
+robot_z.move(max_z + Z_FINAL_OFFSET)
+
+print "Z offset = ", z_offset
+
+
+#Updating tool:
+#update_tool(None, x_offset=x_offset, z_offset=z_offset)
diff --git a/script/calibration/ToolCalibration.py b/script/calibration/ToolCalibration.py
new file mode 100644
index 0000000..602403b
--- /dev/null
+++ b/script/calibration/ToolCalibration.py
@@ -0,0 +1,60 @@
+import plotutils
+from mathutils import fit_gaussian, Gaussian
+
+
+robot.assert_tool(TOOL_CALIBRATION)
+robot.set_motors_enabled(True)
+robot.set_joint_motors_enabled(True)
+
+
+initial_pos = robot.get_cartesian_pos()
+
+robot.enable()
+move_to_laser()
+
+robot.align()
+
+
+run("calibration/ScanYZ")
+
+robot.set_motors_enabled(True)
+
+
+first_y = robot_y.take()
+first_z = robot_z.take()
+first_y = ue.take()
+first_j6 = robot_j6.take()
+if first_y is None:
+ raise Exception("Invalid YZ scan values in first scan")
+
+
+robot.set_joint_motors_enabled(True)
+if first_j6>0:
+ robot_j6.moveRel(-180.0, -1)
+else:
+ robot_j6.moveRel(180.0, -1)
+
+
+robot.set_motors_enabled(True)
+run("calibration/ScanYZ")
+
+robot.set_motors_enabled(True)
+
+second_y = robot_y.take()
+second_z = robot_z.take()
+second_y = ue.take()
+second_j6 = robot_j6.take()
+if second_y is None:
+ raise Exception("Invalid XZ scan values in first scan")
+
+
+#Updates the tool
+xoff = (first_x - second_x)/2
+yoff = (first_y - second_y)/2
+t=robot.get_tool_trsf(TOOL_DEFAULT)
+t[0]=xoff
+t[1]=-yoff
+robot.set_tool_trsf(t, TOOL_DEFAULT)
+
+
+
diff --git a/script/calibration/ToolCalibration2.py b/script/calibration/ToolCalibration2.py
new file mode 100644
index 0000000..e9b71ae
--- /dev/null
+++ b/script/calibration/ToolCalibration2.py
@@ -0,0 +1,86 @@
+import plotutils
+from mathutils import fit_gaussian, Gaussian
+
+
+#robot.assert_tool(TOOL_CALIBRATION)
+#cal_tool = TOOL_DEFAULT
+cal_tool = TOOL_CALIBRATION
+
+robot.set_tool(cal_tool)
+robot.enable()
+move_to_laser()
+
+
+robot.set_motors_enabled(True)
+robot.set_joint_motors_enabled(True)
+initial_pos = robot.get_cartesian_pos()
+
+robot.enable()
+move_to_laser()
+
+#robot.align()
+
+
+run("calibration/ScanY")
+
+pos1 = robot.get_cartesian_pos()
+x1, y1 = closest_x, closest_y
+
+print "Closest 1: ", [x1, y1]
+print "Position 1: ", pos1
+
+
+pj6 = robot_j6.position
+if pj6>0:
+ robot_j6.move(pj6 - 180.0)
+else:
+ robot_j6.move(pj6 + 180.0)
+
+
+run("calibration/ScanY")
+
+
+x2, y2 = closest_x, closest_y
+
+print "Closest 2: ", [x2, y2]
+
+
+
+off_x = x1 - x2
+
+#robot.set_motors_enabled(True)
+#robot_x.moveRel(off_x, -1)
+
+#For composing cannot use tcp_p, need another auxiliary point. tcp_t is also destroyed.
+robot.set_pnt(robot.get_cartesian_pos(), "pTemp")
+robot.set_trsf([off_x, 0,0,0,0,0])
+c=robot.compose("pTemp", FRAME_TABLE, "tcp_t" )
+robot.set_pnt(c, "pTemp")
+robot.movel("pTemp", cal_tool, DESC_SCAN, sync=True)
+
+
+pos2 = robot.get_cartesian_pos()
+print pos2
+
+print "Position 2: ", pos2
+
+
+
+#Updates the tool
+xoff = (pos2[0]-pos1[0])/2
+yoff = (pos2[1]-pos1[1])/2
+
+#print "Offset: ", [xoff, yoff]
+
+t=robot.get_tool_trsf(TOOL_DEFAULT)
+t[0]=xoff
+t[1]=-yoff
+print "Offset: ", [t[0], t[1]]
+robot.set_tool_trsf(t, TOOL_DEFAULT)
+
+robot.set_tool(TOOL_DEFAULT)
+d = robot.get_distance_to_pnt("pLaser")
+if d0:
+ robot_j6.move(pj6 - 180.0)
+else:
+ robot_j6.move(pj6 + 180.0)
+
+
+try:
+ robot.set_frame(FRAME_TABLE)
+ run("calibration/ScanX")
+finally:
+ robot.set_default_frame()
+
+pos2 =robot.get_cartesian_pos()
+x2, l2 = closest_x, closest_y
+
+print "Scan 2 result: ", [x2, l2]
+print "Position 2: ", pos1
+
+off_l = l2 - l1
+print "Offset l: ", off_l
+
+#For composing cannot use tcp_p, need another auxiliary point. tcp_t is also destroyed.
+robot.set_pnt(robot.get_cartesian_pos(), "pTemp")
+robot.set_trsf([0, -off_l, 0, 0, 0, 0])
+c=robot.compose("pTemp", FRAME_TABLE, "tcp_t" )
+robot.set_pnt(c, "pTemp")
+robot.movel("pTemp", cal_tool, DESC_SCAN, sync=True)
+
+
+pos3 = robot.get_cartesian_pos()
+print "Position 3: ", pos3
+
+
+#Updates the tool
+t=robot.get_tool_trsf(TOOL_DEFAULT)
+print "Former tool: " + str(t)
+
+xoff = (pos3[0]-pos1[0])/2
+yoff = (pos3[1]-pos1[1])/2
+xrot = math.degrees(math.atan(yoff/t[2]))
+yrot = math.degrees(math.atan(xoff/t[2]))
+t[0]=xoff
+t[1]=-yoff
+print "Calibrated tool: " + str(t)
+robot.set_tool_trsf(t, TOOL_DEFAULT)
+
+robot.set_tool(TOOL_DEFAULT)
+d = robot.get_distance_to_pnt("pLaser")
+if d0:
+ robot_j6.move(pj6 - 180.0)
+else:
+ robot_j6.move(pj6 + 180.0)
+
+
+run("calibration/ScanX")
+
+
+pos2 =robot.get_cartesian_pos()
+x2, l2 = closest_x, closest_y
+
+print "Scan 2 result: ", [x2, l2]
+print "Position 2: ", pos1
+
+off_l = l2 - l1
+print "Offset l: ", off_l
+
+
+#For composing cannot use tcp_p, need another auxiliary point. tcp_t is also destroyed.
+robot.set_pnt(robot.get_cartesian_pos(), "pTemp")
+robot.set_trsf([0, -off_l, 0, 0, 0, 0])
+c=robot.compose("pTemp", FRAME_DEFAULT, "tcp_t" )
+robot.set_pnt(c, "pTemp")
+robot.movel("pTemp", cal_tool, DESC_SCAN, sync=True)
+
+pos3 = robot.get_cartesian_pos()
+print "Position 3: ", pos3
+
+
+#Updates the tool
+t=robot.get_tool_trsf(TOOL_DEFAULT)
+print "Former tool: " + str(t)
+
+xoff = (pos3[0]-pos1[0])/2
+yoff = (pos3[1]-pos1[1])/2
+xrot = math.degrees(math.atan(yoff/t[2]))
+yrot = math.degrees(math.atan(xoff/t[2]))
+t[0]=xoff
+t[1]=-yoff
+print "Calibrated tool: " + str(t)
+robot.set_tool_trsf(t, TOOL_DEFAULT)
+
+robot.set_tool(TOOL_DEFAULT)
+d = robot.get_distance_to_pnt("pLaser")
+if d0:
+ robot_j6.move(pj6 - 180.0)
+else:
+ robot_j6.move(pj6 + 180.0)
+
+run("calibration/ScanY")
+
+pos2 =robot.get_cartesian_pos()
+l2, y2 = closest_x, closest_y
+
+print "Scan 2 result: ", [l2, y2]
+print "Position 2: ", pos1
+
+off_l = l2 - l1
+print "Offset l: ", off_l
+
+#For composing cannot use tcp_p, need another auxiliary point. tcp_t is also destroyed.
+robot.set_pnt(robot.get_cartesian_pos(), "pTemp")
+robot.set_trsf([-off_l, 0, 0, 0, 0, 0])
+c=robot.compose("pTemp", FRAME_DEFAULT, "tcp_t" )
+robot.set_pnt(c, "pTemp")
+robot.movel("pTemp", cal_tool, DESC_SCAN, sync=True)
+
+
+pos3 = robot.get_cartesian_pos()
+print "Position 3: ", pos3
+
+
+#Updates the tool
+t=robot.get_tool_trsf(TOOL_DEFAULT)
+print "Former tool: " + str(t)
+
+xoff = (pos3[0]-pos1[0])/2
+yoff = (pos3[1]-pos1[1])/2
+xrot = math.degrees(math.atan(yoff/t[2]))
+yrot = math.degrees(math.atan(xoff/t[2]))
+t[0]=xoff #X
+t[1]=-yoff #Y
+#t[3]= xropt #RX
+#t[4]= yropt #RY
+
+print "Calibrated tool: " + str(t)
+
+
+robot.set_tool_trsf(t, TOOL_DEFAULT)
+
+robot.set_tool(TOOL_DEFAULT)
+d = robot.get_distance_to_pnt("pLaser")
+if d" for builtin functions
+ - "devices" for device names
+ - builtin function name for function help
+ - else contains entry for auto-completion
+
+ Returns:
+ List
+
+ """
+ return self._get_response(requests.get(url=self.url+"/autocompletion/" + input))
+
+ def get_contents(self, path=None):
+ """Returns contents of data path.
+
+ Args:
+ path(optional, str): Path to data relative to data home path.
+ - Folder
+ - File
+ - File (data root) | internal path
+ - internal path (on currently open data root)
+
+ Returns:
+ List of contents
+
+ """
+ return self._get_response(requests.get(url=self.url+ "/contents" + ("" if path is None else ( "/"+path))), False)
+
+ def get_data(self, path, type="txt"):
+ """Returns data on a given path.
+
+ Args:
+ path(str): Path to data relative to data home path.
+ - File (data root) | internal path
+ - internal path (on currently open data root)
+ type(optional, str): txt, "json", "bin", "bs"
+
+ Returns:
+ Data accordind to selected format/.
+
+ """
+ if type == "json":
+ return self._get_response(requests.get(url=self.url+ "/data-json/"+path), True)
+ elif type == "bin":
+ return self._get_binary_response(requests.get(url=self.url+"/data-bin/"+path, stream=True))
+ elif type == "bs":
+ from collections import OrderedDict
+ bs = self._get_binary_response(requests.get(url=self.url+"/data-bs/"+path, stream=True))
+ index=0
+ msg = []
+ for i in range(4):
+ size =int.from_bytes(bs[index:index+4], byteorder='big', signed=False)
+ index=index+4
+ msg.append(bs[index:index+size])
+ index=index+size
+ [main_header, data_header, data, timestamp] = msg
+ main_header = json.loads(main_header, object_pairs_hook=OrderedDict)
+ data_header = json.loads(data_header, object_pairs_hook=OrderedDict)
+ channel = data_header["channels"][0]
+ channel["encoding"] = "<" if channel.get("encoding", "little") else ">"
+ from bsread.data.helpers import get_channel_reader
+ channel_value_reader = get_channel_reader(channel)
+ return channel_value_reader(data)
+
+ return self._get_response(requests.get(url=self.url+ "/data" + ("" if path is None else ( "/"+path))), False)
+
+ def print_logs(self):
+ for l in self.get_logs():
+ print ("%s %s %-20s %-8s %s" % tuple(l))
+
+ def print_devices(self):
+ for l in self.get_devices():
+ print ("%-16s %-32s %-10s %-32s %s" % tuple(l))
+
+ def print_help(self, input = ""):
+ for l in self.help(input):
+ print (l)
+
+ #Events
+ def _sse_event_loop_task(self):
+ try:
+ while True:
+ try:
+ messages = SSEClient(self.url+"/events")
+ for msg in messages:
+ if (self.subscribed_events is None) or (msg.event in self.subscribed_events):
+ try:
+ value = json.loads(msg.data)
+ except:
+ value = str(msg.data)
+ self.event_callback(msg.event, value)
+ except IOError as e:
+ #print(e)
+ pass
+ except:
+ print("Error:", sys.exc_info()[1])
+ #raise
+ finally:
+ print ("Exit SSE loop task")
+ self.sse_event_loop_thread = None
+
+
+ def start_sse_event_loop_task(self, subscribed_events = None, event_callback = None):
+ """
+ Initializes server event loop task.
+ Args:
+ subscribed_events: list of event names to substribe to. If None subscribes to all.
+ event_callback: callback function. If None, self.on_event is called instead.
+
+ Usage example:
+ def on_event(name, value):
+ if name == "state":
+ print ("State changed: ", value)
+ elif name == "record":
+ print ("Received scan record: ", value)
+
+ pc.start_sse_event_loop_task(["state", "record"], on_event)
+
+ """
+ self.event_callback = event_callback if event_callback is not None else self.on_event
+ self.subscribed_events = subscribed_events
+ if SSEClient is not None:
+ if self.sse_event_loop_thread is None:
+ self.sse_event_loop_thread = threading.Thread(target=self._sse_event_loop_task, \
+ args = (), \
+ kwargs={}, \
+ daemon=True)
+ self.sse_event_loop_thread.start()
+ else:
+ raise Exception ("sseclient library is not instlled: server events are not available")
+
+ def on_event(self, name, value):
+ pass
+
\ No newline at end of file
diff --git a/script/client/TellClient.py b/script/client/TellClient.py
new file mode 100644
index 0000000..256dbdd
--- /dev/null
+++ b/script/client/TellClient.py
@@ -0,0 +1,184 @@
+from PShellClient import PShellClient
+import json
+import time
+import sys
+
+
+
+class TellClient(PShellClient):
+ def __init__(self, url):
+ PShellClient.__init__(self, url)
+ self.start_sse_event_loop_task(["state", "shell"])
+ self.state = self.get_state()
+ self.debug=False
+
+ def on_event(self, name, value):
+ if name == "state":
+ self.state = value
+ print ("State: ", value)
+ elif name == "shell":
+ if self.debug:
+ print ("> ", value)
+
+ def get_state(self):
+ self.state = PShellClient.get_state(self)
+ return self.state
+
+ def wait_ready(self):
+ count = 0
+ #Monitors event but polls every second just n case an event is missed
+ while (True):
+ if self.state != "Busy":
+ break
+ time.sleep(0.01)
+ count = count + 1
+ if count>=100:
+ count=0
+ self.get_state()
+ if self.state != "Ready":
+ raise Exception("Invalid state: " + str(self.state))
+
+ def set_in_mount_position(self, value):
+ self.eval("in_mount_position = " + str(value) +"&")
+
+ def is_in_mount_position(self):
+ return self.eval("in_mount_position&").lower()=="true"
+
+ def get_samples_info(self):
+ return json.loads(self.eval("get_samples_info()&"))
+
+ def set_samples_info(self, info):
+ #c.run("data/set_samples_info", pars= [info,], background=True)
+ self.eval("set_samples_info(" + json.dumps(info) + ")&")
+
+ def start_cmd(self, cmd, *argv):
+ cmd = cmd + "("
+ for a in argv:
+ cmd = cmd + (("'" + a + "'") if type(a) is str else str(a) ) + ", "
+ cmd = cmd + ")"
+ ret = self.start_eval(cmd)
+ self.get_state()
+ return ret
+
+ def wait_cmd(self, cmd):
+ self.wait_ready()
+ result = self.get_result(cmd)
+ #print (result)
+ if result["exception"] is not None:
+ raise Exception(result["exception"] )
+ return result["return"]
+
+ def mount(self, segment, puck, sample, force=False, read_dm=False, auto_unmount=False):
+ #return self.run("motion/mount", pars= [segment,puck, sample, force, read_dm], background=True)
+ return self.start_cmd("mount", segment, puck, sample, force, read_dm, auto_unmount)
+
+ def unmount(self, segment = None, puck = None, sample = None, force=False):
+ return self.start_cmd("unmount", segment, puck, sample, force)
+
+ def scan_pin(self, segment, puck, sample, force=False):
+ return self.start_cmd("scan_pin", segment, puck, sample, force)
+
+ def scan_puck(self, segment, puck, force=False):
+ return self.start_cmd("scan_puck", segment, puck, force)
+
+ def dry(self, heat_time=30.0, speed=0.5, wait_cold = 30.0):
+ return self.start_cmd("dry", heat_time, speed, wait_cold)
+
+ def move_cold(self):
+ return self.start_cmd("move_cold")
+
+ def trash(self):
+ return self.start_cmd("trash")
+
+ def abort_cmd(self):
+ self.abort()
+ self.eval("robot.stop_task()&")
+
+ def set_gonio_mount_position(homing = False):
+ if homing:
+ self.eval("home_fast_table()")
+ self.eval("set_mount_position()")
+
+ def get_mounted_sample(self):
+ ret = self.eval("get_setting('mounted_sample_position')&").strip()
+ return None if len(ret)==0 else ret
+
+ def get_system_check(self):
+ try:
+ ret = self.eval("system_check()&")
+ except Exception as ex:
+ return ex
+ return "Ok"
+
+ def get_robot_state(self):
+ return self.eval("robot.state&")
+
+
+ def get_robot_status(self):
+ status = self.eval("robot.take()&")
+ return status
+
+ def get_detected_pucks(self):
+ return self.eval("get_detected_pucks()&")
+
+ def set_pin_offset(self, value):
+ self.eval("set_pin_offset(" + str(value)+ ")&")
+
+ def get_pin_offset(self):
+ return self.eval("get_pin_offset()&")
+
+ def print_info(self):
+ print ("State: " + str(self.get_state()))
+ print ("Mounted sample: " + str(self.get_mounted_sample()))
+ print ("System check: " + str(self.get_system_check()))
+ print ("Robot state: " + str(self.get_robot_state()))
+ print ("Robot status: " + str(self.get_robot_status()))
+ print ("Detected pucks: " + str(self.get_detected_pucks()))
+ print ("Pin offset: " + str(self.get_pin_offset()))
+ print ("Mount position: " + str(self.is_in_mount_position()))
+ print ("")
+
+if __name__ == "__main__":
+ tell = TellClient("http://Alexandres-MBP.psi.ch:8080")
+ tell.print_info()
+
+ info = [
+ {
+ "userName": "User",
+ "dewarName": "Dewar",
+ "puckName": "Puck",
+ "puckBarcode": "XXX0001",
+ "puckType": "Minispine",
+ "puckAddress": "",
+ "sampleName": "Sample",
+ "sampleBarcode": "YYY0001",
+ "samplePosition": "1",
+ "sampleStatus": "Present",
+ "sampleMountCount": "0" ,
+ },
+ ]
+ print (tell.get_samples_info())
+ tell.set_samples_info(info)
+ print (tell.get_samples_info())
+
+ tell.abort_cmd()
+
+ cmd = tell.move_cold()
+ print (tell.wait_cmd(cmd))
+
+ cmd = tell.trash()
+ print (tell.wait_cmd(cmd))
+
+ cmd = tell.scan_pin("A", 1, 1)
+ print (tell.wait_cmd(cmd))
+
+ cmd = tell.scan_puck("A", 1, 1)
+ print (tell.wait_cmd(cmd))
+
+ cmd = tell.mount("A", 1, 1)
+ print (tell.wait_cmd(cmd))
+
+ print ("Mounted sample: " + str(tell.get_mounted_sample()))
+ cmd = tell.unmount()
+ print (tell.wait_cmd(cmd))
+ print ("Mounted sample: " + str(tell.get_mounted_sample()))
diff --git a/script/client/sseclient.py b/script/client/sseclient.py
new file mode 100644
index 0000000..3c42858
--- /dev/null
+++ b/script/client/sseclient.py
@@ -0,0 +1,163 @@
+import codecs
+import re
+import time
+import warnings
+
+import six
+
+import requests
+
+
+# Technically, we should support streams that mix line endings. This regex,
+# however, assumes that a system will provide consistent line endings.
+end_of_field = re.compile(r'\r\n\r\n|\r\r|\n\n')
+
+class SSEClient(object):
+ def __init__(self, url, last_id=None, retry=3000, session=None, chunk_size=1024, **kwargs):
+ self.url = url
+ self.last_id = last_id
+ self.retry = retry
+ self.chunk_size = chunk_size
+
+ # Optional support for passing in a requests.Session()
+ self.session = session
+
+ # Any extra kwargs will be fed into the requests.get call later.
+ self.requests_kwargs = kwargs
+
+ # The SSE spec requires making requests with Cache-Control: nocache
+ if 'headers' not in self.requests_kwargs:
+ self.requests_kwargs['headers'] = {}
+ self.requests_kwargs['headers']['Cache-Control'] = 'no-cache'
+
+ # The 'Accept' header is not required, but explicit > implicit
+ self.requests_kwargs['headers']['Accept'] = 'text/event-stream'
+
+ # Keep data here as it streams in
+ self.buf = u''
+
+ self._connect()
+
+ def _connect(self):
+ if self.last_id:
+ self.requests_kwargs['headers']['Last-Event-ID'] = self.last_id
+
+ # Use session if set. Otherwise fall back to requests module.
+ requester = self.session or requests
+ self.resp = requester.get(self.url, stream=True, **self.requests_kwargs)
+ self.resp_iterator = self.resp.iter_content(chunk_size=self.chunk_size)
+
+ # TODO: Ensure we're handling redirects. Might also stick the 'origin'
+ # attribute on Events like the Javascript spec requires.
+ self.resp.raise_for_status()
+
+ def _event_complete(self):
+ return re.search(end_of_field, self.buf) is not None
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ decoder = codecs.getincrementaldecoder(
+ self.resp.encoding)(errors='replace')
+ while not self._event_complete():
+ try:
+ next_chunk = next(self.resp_iterator)
+ if not next_chunk:
+ raise EOFError()
+ self.buf += decoder.decode(next_chunk)
+
+ except (StopIteration, requests.RequestException, EOFError) as e:
+ time.sleep(self.retry / 1000.0)
+ self._connect()
+
+ # The SSE spec only supports resuming from a whole message, so
+ # if we have half a message we should throw it out.
+ head, sep, tail = self.buf.rpartition('\n')
+ self.buf = head + sep
+ continue
+
+ # Split the complete event (up to the end_of_field) into event_string,
+ # and retain anything after the current complete event in self.buf
+ # for next time.
+ (event_string, self.buf) = re.split(end_of_field, self.buf, maxsplit=1)
+ msg = Event.parse(event_string)
+
+ # If the server requests a specific retry delay, we need to honor it.
+ if msg.retry:
+ self.retry = msg.retry
+
+ # last_id should only be set if included in the message. It's not
+ # forgotten if a message omits it.
+ if msg.id:
+ self.last_id = msg.id
+
+ return msg
+
+ if six.PY2:
+ next = __next__
+
+
+class Event(object):
+
+ sse_line_pattern = re.compile('(?P[^:]*):?( ?(?P.*))?')
+
+ def __init__(self, data='', event='message', id=None, retry=None):
+ self.data = data
+ self.event = event
+ self.id = id
+ self.retry = retry
+
+ def dump(self):
+ lines = []
+ if self.id:
+ lines.append('id: %s' % self.id)
+
+ # Only include an event line if it's not the default already.
+ if self.event != 'message':
+ lines.append('event: %s' % self.event)
+
+ if self.retry:
+ lines.append('retry: %s' % self.retry)
+
+ lines.extend('data: %s' % d for d in self.data.split('\n'))
+ return '\n'.join(lines) + '\n\n'
+
+ @classmethod
+ def parse(cls, raw):
+ """
+ Given a possibly-multiline string representing an SSE message, parse it
+ and return a Event object.
+ """
+ msg = cls()
+ for line in raw.splitlines():
+ m = cls.sse_line_pattern.match(line)
+ if m is None:
+ # Malformed line. Discard but warn.
+ warnings.warn('Invalid SSE line: "%s"' % line, SyntaxWarning)
+ continue
+
+ name = m.group('name')
+ if name == '':
+ # line began with a ":", so is a comment. Ignore
+ continue
+ value = m.group('value')
+
+ if name == 'data':
+ # If we already have some data, then join to it with a newline.
+ # Else this is it.
+ if msg.data:
+ msg.data = '%s\n%s' % (msg.data, value)
+ else:
+ msg.data = value
+ elif name == 'event':
+ msg.event = value
+ elif name == 'id':
+ msg.id = value
+ elif name == 'retry':
+ msg.retry = int(value)
+
+ return msg
+
+ def __str__(self):
+ return self.data
diff --git a/script/client/tell.py b/script/client/tell.py
new file mode 100644
index 0000000..56c70b4
--- /dev/null
+++ b/script/client/tell.py
@@ -0,0 +1,79 @@
+import sys
+import os
+import code
+import readline
+import rlcompleter
+import atexit
+
+from TellClient import TellClient
+
+tell = TellClient("http://PC12288:8080")
+
+def info():
+ tell.print_info()
+
+def help():
+ print ("Commands: \n\thelp()\n\tinfo()\n\tmount(segment, puck, sample)\n\tunmount() \n\tdry() " \
+ "\n\tscan(segment, puck, sample=None) \n\tmove_cold() \n\ttrash() \n\tabort() " \
+ "\n\tset_pin_offset(value)")
+
+def assert_transfer_allowed():
+ if not tell.is_in_mount_position():
+ raise Exception("Gonio is not in mount position")
+
+def mount(segment, puck, sample):
+ assert_transfer_allowed()
+ cmd = tell.mount(segment, puck, sample, True, True, True)
+ print (tell.wait_cmd(cmd))
+
+def unmount():
+ assert_transfer_allowed()
+ cmd=tell.unmount(force=True)
+ print (tell.wait_cmd(cmd))
+
+def move_cold():
+ cmd=tell.move_cold()
+ print (tell.wait_cmd(cmd))
+
+def trash():
+ cmd=tell.trash()
+ print (tell.wait_cmd(cmd))
+
+def dry():
+ cmd=tell.dry()
+ print (tell.wait_cmd(cmd))
+
+def scan(segment, puck, sample=None):
+ if sample is None:
+ cmd=tell.scan_puck(segment, puck, True)
+ else:
+ cmd=tell.scan_pin(segment, puck, sample, True)
+ print (tell.wait_cmd(cmd))
+
+def abort():
+ tell.abort_cmd()
+
+def set_pin_offset(value):
+ tell.set_pin_offset(value)
+
+info()
+help()
+
+#for line in sys.stdin:
+# tell.print_info()
+#print ("", end='\r> ')
+
+historyPath = os.path.expanduser("./.history")
+def save_history(historyPath=historyPath):
+ readline.write_history_file(historyPath)
+if os.path.exists(historyPath):
+ readline.read_history_file(historyPath)
+atexit.register(save_history)
+
+#vars = globals(); vars.update(locals())
+vars =locals()
+readline.set_completer(rlcompleter.Completer(vars).complete)
+readline.parse_and_bind("tab: complete")
+
+code.interact(banner = "", local=vars)
+
diff --git a/script/data/get_samples_info.py b/script/data/get_samples_info.py
new file mode 100644
index 0000000..00a5bc3
--- /dev/null
+++ b/script/data/get_samples_info.py
@@ -0,0 +1,4 @@
+
+
+
+set_return(get_samples_info(as_json=False))
\ No newline at end of file
diff --git a/script/data/pucks.py b/script/data/pucks.py
new file mode 100644
index 0000000..3228c34
--- /dev/null
+++ b/script/data/pucks.py
@@ -0,0 +1,51 @@
+def get_puck_names():
+ return [str(a)+str(b) for a in BLOCKS for b in range(1,6)]
+
+
+def get_puck_info():
+ ret = []
+ #for puck in get_puck_names():
+ for puck in BasePlate.pucks:
+ ret.append({"address" : str(puck.name), "status": str(puck.status), "barcode" : str(puck.id)})
+ return ret
+
+
+def get_puck_obj(address):
+ return BasePlate.getChild(address)
+
+
+def get_puck_obj_by_id(puck_id):
+ for puck in BasePlate.pucks:
+ if puck.id == puck_id:
+ return puck
+ return None
+
+
+def set_puck_info(puck_info):
+ #print puck_info
+ for i in puck_info:
+ p=get_puck_obj(i["address"])
+ if p is not None:
+ if (p.status == 'Present') and ( i["status"] =='Present'):
+ if i['barcode'] and (i['barcode'] != str(None)):
+ #print "Setting ", p, " to ", i['barcode']
+ p.id = i['barcode']
+
+def clear_puck_info():
+ save_puck_info([])
+
+def save_puck_info():
+ data = get_puck_info()
+ output_file = open( get_context().setup.expandPath("{context}/pucks_info.json") , "w")
+ output_file.write(json.dumps(data))
+ output_file.close()
+
+def restore_puck_info():
+ try:
+ inputfile = open(get_context().setup.expandPath("{context}/pucks_info.json"), "r")
+ info = json.loads(inputfile.read())
+ except:
+ print >> sys.stderr, "Error reading pucks info file: " + str(sys.exc_info()[1])
+ info = []
+ set_puck_info(info)
+
\ No newline at end of file
diff --git a/script/data/reports.py b/script/data/reports.py
new file mode 100644
index 0000000..629b414
--- /dev/null
+++ b/script/data/reports.py
@@ -0,0 +1,39 @@
+from statsutils import *
+
+
+def report(start, end):
+ """
+ Data format for start and end: "dd/mm/yy" or "dd/mm/yy hh:mm:ss.mmm"
+
+ """
+ cmds = ["mount%", "unmount%", "dry%", "recover%", "trash%", "robot_recover%", "scan%", "homing%"]
+
+ conn = get_stats_connection()
+ try:
+ print_stats(cmds, start, end)
+
+ for cmd in cmds:
+ print_cmd_stats (cmd, start, end)
+
+
+ finally:
+ conn.close()
+
+def print_recs(cmd,start, end, result=("%%")):
+ """
+ Data format for start and end: "dd/mm/yy" or "dd/mm/yy hh:mm:ss.mmm"
+ Result: "error", "abort, "success". Defaulr for all
+
+ """
+
+ conn = get_stats_connection()
+ try:
+ print_cmd_records(cmd,start, end, result)
+ finally:
+ conn.close()
+
+
+#Print all records:
+#
+
+#report("01/03/19","01/04/19")
diff --git a/script/data/samples.py b/script/data/samples.py
new file mode 100644
index 0000000..7110d57
--- /dev/null
+++ b/script/data/samples.py
@@ -0,0 +1,350 @@
+import json
+import re
+import org.python.core.PyDictionary as PyDictionary
+
+SAMPLE_INFO_KEYS = ["userName", "dewarName", "puckName", "puckBarcode", "puckType", "puckAddress",
+ "sampleName", "samplePosition", "sampleBarcode", "sampleStatus", "sampleMountCount"]
+samples_info = []
+
+
+def set_samples_info(info):
+ global samples_info
+ if (is_string(info)):
+ info = json.loads(info)
+ if not is_list(info):
+ raise Exception("Sample info must be a list (given object type is " + str(type(info)) + ")")
+ #Sanitize list
+ remove = []
+ for sample in info:
+ try:
+ if set(sample.keys()) != set(SAMPLE_INFO_KEYS):
+ raise Exception()
+ except:
+ remove.append(sample)
+ for el in remove:
+ info.remove(el)
+ print "Invalid samples info element: " + str(el)
+ samples_info = info
+ save_samples_info()
+ #Trust beamline on assignments, so update puck info
+ update_puck_table()
+
+
+def clear_samples_info():
+ set_samples_info([])
+
+def save_samples_info():
+ data = get_samples_info(True)
+ output_file = open( get_context().setup.expandPath("{context}/samples_info.json") , "w")
+ output_file.write(data)
+ output_file.close()
+ get_context().sendEvent("samples_updated", True)
+ save_puck_info()
+
+def restore_samples_info():
+ restore_puck_info()
+ try:
+ inputfile = open(get_context().setup.expandPath("{context}/samples_info.json"), "r")
+ info = inputfile.read()
+ except:
+ print >> sys.stderr, "Error reading sample info file: " + str(sys.exc_info()[1])
+ info = []
+ set_samples_info(info)
+
+def get_samples_info(as_json=True):
+ global samples_info
+ return json.dumps(to_list(samples_info)) if as_json else samples_info
+
+def has_puck_datamatrix(datamatrix):
+ if samples_info is not None:
+ for si in samples_info:
+ if si["puckBarcode"] == datamatrix:
+ return True
+ return False
+
+def add_puck_datamatrix(barcode, address = "", dewar = "Unknown", user = "Unknown", puck = "Unknown", type = "unipuck", sample_prefix = "Sample"):
+ if has_puck_datamatrix(barcode):
+ raise Exception("Datamatrix already defined: " + str(barcode))
+ for s in range(1,17):
+ info = \
+ { "userName": user, \
+ "dewarName": dewar, \
+ "puckName": puck, \
+ "puckBarcode": address if barcode is None else barcode, \
+ "puckType": type, \
+ "puckAddress": address,\
+ "sampleName": sample_prefix + " " + str(s), \
+ "samplePosition": str(s),\
+ "sampleStatus": "Unknown", \
+ "sampleMountCount": "0",
+ }
+ samples_info.append(info)
+ save_samples_info()
+
+def remove_puck_datamatrix(barcode):
+ remove = []
+ for si in samples_info:
+ if si["puckBarcode"] == barcode:
+ remove.append(si)
+ for el in remove: samples_info.remove(el)
+ save_samples_info()
+
+
+barcode_clean_re = re.compile("[^a-zA-Z0-9]")
+
+def is_same_datamatrix(table, reading):
+ if table == reading:
+ return True
+ table2 = barcode_clean_re.sub("", table.upper())
+ reading2 = barcode_clean_re.sub("", reading.upper())
+ if table2 == reading2:
+ log("Assigning aproximative datamatrix " + reading )
+ return True
+ return False
+
+
+def set_puck_datamatrix(puck, datamatrix):
+ if puck is None:
+ puck = ""
+ if datamatrix is None:
+ datamatrix = ""
+ if samples_info is not None:
+ for si in samples_info:
+ #if si["puckBarcode"] == datamatrix:
+ if is_same_datamatrix(si["puckBarcode"],datamatrix):
+ si["puckAddress"] = puck
+ elif si["puckAddress"] == puck:
+ si["puckAddress"] = ""
+ save_samples_info()
+
+def reset_puck_datamatrix(puck = None):
+ if samples_info is not None:
+ for si in samples_info:
+ if (si["puckAddress"] == puck) or (puck is None):
+ si["puckAddress"] = ""
+ save_samples_info()
+ for p in BasePlate.getChildren():
+ if (p.name == puck) or (puck is None):
+ p.id = None
+
+def get_puck_datamatrix():
+ ret = {}
+ for si in samples_info:
+ if si["puckBarcode"] is not None and si["puckBarcode"]!="":
+ ret[si["puckBarcode"]] = si["puckAddress"]
+ return ret
+
+def get_puck_address(barcode):
+ try:
+ return get_puck_datamatrix()[barcode]
+ except:
+ return None
+
+
+def update_puck_table():
+ dms = get_puck_datamatrix()
+ for barcode in dms.keys():
+ address = dms[barcode]
+ puck = get_puck_obj(address)
+ if puck is not None:
+ puck.id = barcode
+
+
+#Sample mount/unmount
+
+def same_address(puck_add_1, sample_pos_1, puck_add_2, sample_pos_2):
+ if str(puck_add_1) != str(puck_add_2):
+ return False
+ try:
+ sample_pos_1 = int(sample_pos_1)
+ except:
+ return False
+ try:
+ sample_pos_2 = int(sample_pos_2)
+ except:
+ return False
+ return sample_pos_1 == sample_pos_2
+
+
+def update_samples_info_sample_mount(puck_address, sample_position, sample_detected, sample_id):
+ try:
+ if (samples_info is not None) and (puck_address is not None):
+ for si in samples_info:
+ if same_address( si["puckAddress"], si["samplePosition"], puck_address, sample_position):
+ if sample_detected:
+ if si["sampleStatus"] != "Mounted":
+ si["sampleStatus"] = "Mounted"
+ try:
+ mount_count = int(si["sampleMountCount"])
+ except:
+ mount_count = 0
+ si["sampleMountCount"] = mount_count + 1
+ else:
+ si["sampleStatus"] = "Unknown"
+
+ if sample_id is not None:
+ si["sampleBarcode"] = sample_id
+
+ else:
+ if si["sampleStatus"] == "Mounted":
+ si["sampleStatus"] = "HasBeenMounted"
+ save_samples_info()
+ except:
+ pass
+
+
+def update_samples_info_sample_unmount(puck_address, sample_position):
+ try:
+ if (samples_info is not None) and (puck_address is not None):
+ for si in samples_info:
+ if same_address( si["puckAddress"], si["samplePosition"], puck_address, sample_position):
+ si["sampleStatus"] = "HasBeenMounted"
+ save_samples_info()
+ return
+ except:
+ pass
+
+def update_samples_info_sample_scan(puck_address, sample_position, sample_detected, sample_id):
+ try:
+ if (samples_info is not None) and (puck_address is not None):
+ for si in samples_info:
+ if same_address( si["puckAddress"], si["samplePosition"], puck_address, sample_position):
+ if sample_detected:
+ if si["sampleStatus"] == "Unknown":
+ si["sampleStatus"] = "Present"
+ else:
+ if si["sampleStatus"] == "Present":
+ si["sampleStatus"] = "Unknown"
+ if sample_id is not None:
+ si["sampleBarcode"] = sample_id
+ save_samples_info()
+ return
+ except:
+ pass
+
+
+
+test_sample_data = [ \
+ { "userName": "Alexandre", \
+ "dewarName": "TEST", \
+ "puckName": "My puck", \
+ "puckBarcode": "AAA0001", \
+ "puckType": "unipuck", \
+ "puckAddress": "A1",\
+ "sampleName": "MySample 1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": "Alexandre", \
+ "dewarName": "TEST", \
+ "puckName": "My puck", \
+ "puckBarcode": "AAA0001", \
+ "puckType": "unipuck", \
+ "puckAddress": "A1",\
+ "sampleName": "MySample 2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": "Alexandre", \
+ "dewarName": "TEST", \
+ "puckName": "My puck", \
+ "puckBarcode": "AAA0001", \
+ "puckType": "unipuck", \
+ "puckAddress": "A1",\
+ "sampleName": "MySample 3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": "Alexandre", \
+ "dewarName": "TEST", \
+ "puckName": "My puck", \
+ "puckBarcode": "AAA0001", \
+ "puckType": "unipuck", \
+ "puckAddress": "A1",\
+ "sampleName": "MySample 4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": "Alexandre", \
+ "dewarName": "TEST", \
+ "puckName": "My puck", \
+ "puckBarcode": "AAA0001", \
+ "puckType": "unipuck", \
+ "puckAddress": "A1",\
+ "sampleName": "MySample 5", \
+ "sampleBarcode": "", \
+ "samplePosition": 5,\
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+
+ { "userName": "Alexandre", \
+ "dewarName": "TEST", \
+ "puckName": "My puck", \
+ "puckBarcode": "AAA0002", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "MySample 1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": "Alexandre", \
+ "dewarName": "TEST", \
+ "puckName": "My puck", \
+ "puckBarcode": "AAA0002", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "MySample 2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": "Alexandre", \
+ "dewarName": "TEST", \
+ "puckName": "My puck", \
+ "puckBarcode": "AAA0002", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "MySample 3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": "Alexandre", \
+ "dewarName": "TEST", \
+ "puckName": "My puck", \
+ "puckBarcode": "AAA0002", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "MySample 4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": "Alexandre", \
+ "dewarName": "TEST", \
+ "puckName": "My puck", \
+ "puckBarcode": "AAA0002", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "MySample 5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ ]
+
\ No newline at end of file
diff --git a/script/data/set_samples_info.py b/script/data/set_samples_info.py
new file mode 100644
index 0000000..bc7e803
--- /dev/null
+++ b/script/data/set_samples_info.py
@@ -0,0 +1,4 @@
+
+
+
+set_samples_info(args[0])
\ No newline at end of file
diff --git a/script/devices/BarcodeReader.py b/script/devices/BarcodeReader.py
new file mode 100644
index 0000000..48b84ca
--- /dev/null
+++ b/script/devices/BarcodeReader.py
@@ -0,0 +1,83 @@
+
+
+class BarcodeReader(DeviceBase):
+
+ def __init__(self, name, microscan, microscan_cmd):
+ DeviceBase.__init__(self, name)
+ self.microscan = microscan
+ self.microscan_cmd = microscan_cmd
+
+
+ def doInitialize(self):
+ self.disable()
+ self.readout = None
+ self.processing = False
+ self.task_callable=None
+
+ def enable(self):
+ self.microscan_cmd.write("")
+ self.setState(State.Ready)
+
+ def disable(self):
+ self.microscan_cmd.write("")
+ self.setState(State.Disabled)
+
+ def get(self,timeout=1.0):
+ self.state.assertReady()
+ try:
+ self.setState(State.Busy)
+ self.microscan.flush()
+ ret = self.microscan.waitString(int(timeout * 1000))
+ if ret is not None:
+ ret = ret.strip()
+ self.setCache(ret, None)
+ return ret
+ except:
+ self.setCache(None, None)
+ return None
+ finally:
+ if self.state == State.Busy:
+ self.setState(State.Ready)
+
+ def doUpdate(self):
+ self.get()
+
+
+ def read(self,timeout=1.0):
+ if self.processing:
+ raise Exception("Ongoing read operation")
+ self.processing = True
+ try:
+ initial = self.state
+ if initial == State.Disabled:
+ self.enable()
+ try:
+ return self.get(timeout)
+ finally:
+ if initial == State.Disabled:
+ self.disable()
+ finally:
+ self.processing = False
+
+ def _read_task(self, timeout):
+ global readout
+ self.readout = self.read(timeout)
+ return self.readout
+
+ def start_read(self, timeout=1.0):
+ self.readout = None
+ self.task_callable = fork((self._read_task, (timeout,)))
+
+ def get_readout(self):
+ return self.readout
+
+ def wait_readout(self):
+ if self.task_callable is not None:
+ join(self.task_callable)
+ self.task_callable = None
+ return self.readout
+
+
+add_device(BarcodeReader("barcode_reader", mscan_pin, mscan_pin_cmd), force = True)
+add_device(BarcodeReader("barcode_reader_puck", mscan_puck, mscan_puck_cmd), force = True)
+
\ No newline at end of file
diff --git a/script/devices/Gonio.py b/script/devices/Gonio.py
new file mode 100644
index 0000000..0f264f5
--- /dev/null
+++ b/script/devices/Gonio.py
@@ -0,0 +1,43 @@
+
+
+def home_fast_table():
+ caput ("SAR-EXPMX1:ASYN.AOUT", "enable plc 1")
+
+def get_fx_pos():
+ return caget("SAR-EXPMX:MOT_FX.RBV", 'f')
+
+def set_fx_pos(pos):
+ return caput("SAR-EXPMX:MOT_FX.VAL", float(pos))
+
+
+def get_fy_pos():
+ return caget("SAR-EXPMX:MOT_FY.RBV", 'f')
+
+def set_fy_pos(pos):
+ return caput("SAR-EXPMX:MOT_FY.VAL", float(pos))
+
+def get_ry_pos():
+ return caget("SAR-EXPMX:MOT_ROT_Y.RBV", 'f')
+
+def set_ry_pos(pos):
+ return caput("SAR-EXPMX:MOT_ROT_Y.VAL", float(pos))
+
+def get_cz_pos():
+ return caget("SAR-EXPMX:MOT_CZ.RBV", 'f')
+
+def set_cz_pos(pos):
+ return caput("SAR-EXPMX:MOT_CZ.VAL", float(pos))
+
+def get_cx_pos():
+ return caget("SAR-EXPMX:MOT_CX.RBV", 'f')
+
+def set_cx_pos(pos):
+ return caput("SAR-EXPMX:MOT_CX.VAL", float(pos))
+
+
+def set_mount_position():
+ set_fx_pos(0.0)
+ set_fy_pos(0.0)
+ set_ry_pos(0.0)
+ set_cz_pos(0.0)
+ set_cx_pos(0.0)
\ No newline at end of file
diff --git a/script/devices/Hexiposi.py b/script/devices/Hexiposi.py
new file mode 100644
index 0000000..e787e56
--- /dev/null
+++ b/script/devices/Hexiposi.py
@@ -0,0 +1,175 @@
+import ch.psi.pshell.device.DiscretePositionerBase as DiscretePositionerBase
+import requests
+import json
+
+class Hexiposi(DiscretePositionerBase):
+ def __init__(self, name, url):
+ DiscretePositionerBase.__init__(self, name, ["A","B","C","D","E","F"])
+ self.PORT_SET=8002
+ self.PORT_GET=8002
+ if not url.startswith("http://"):
+ url = "http://" + url
+ if not url.endswith(":"):
+ url = url + ":"
+ self.url_set = url + str (self.PORT_SET)+ "/TellWeb/"
+ self.url_get = url + str (self.PORT_GET)+ "/TellWeb/"
+ self.moved = True
+ self.homing_state = State.Disabled
+ self.rback = self.UNKNOWN_POSITION
+ self.timeout = 3.0
+ self.offline = False
+
+ def doInitialize(self):
+ super(Hexiposi, self).doInitialize()
+ self.val = self.doReadReadback()
+
+ def get_response(self, response):
+ if (response.status_code!=200):
+ raise Exception (response.text)
+ return json.loads(response.text)
+
+ def get_status(self):
+ try:
+ self.status = self.get_response(requests.get(url=self.url_get+"get", timeout=self.timeout))
+ self.estop = self.status["estop"]
+ self.homed = self.status["homed"]
+ self.error = self.status["errorCode"]
+ self.remote = self.status["mode"] == "remote"
+ self.moving = self.status["errorCode"]
+ self.pos = self.status["position"]
+ self.moving = self.status["moving"]
+ self.offset = self.status["offset"]
+ self.dpos = self.status["discretePosition"]
+ if (self.homed==False): rback = self.UNKNOWN_POSITION
+ elif self.dpos == 1: rback = "B" # "A"
+ elif self.dpos == 2: rback = "C" # "B"
+ elif self.dpos == 4: rback = "D" # "C"
+ elif self.dpos == 8: rback = "E" # "D"
+ elif self.dpos == 16: rback = "F" # "E"
+ elif self.dpos == 32: rback = "A" # "F"
+ else: rback = self.UNKNOWN_POSITION
+ if (rback == self.UNKNOWN_POSITION) or (rback != self.rback):
+ self.moved = True
+ self.rback = rback
+ self.offline = False
+ return self.status
+ except:
+ self.offline = True
+ self.updateState()
+ raise
+
+ def set_deadband(self, value = 0.1): #degrees
+ ret = self.get_response(requests.get(url=self.url_set+"setDeadband?deadband=" + str(value), timeout=self.timeout))
+ if ret["deadbandOutput"] == value:
+ return value
+ raise Excepiton("Error setting deadband: " + str(ret))
+
+ def move_pos(self, pos):
+ return self.get_response(requests.get(url=self.url_set+"set?pos=" + str(pos), timeout=self.timeout))
+
+ def move_home(self):
+ ret = self.get_response(requests.get(url=self.url_set+"set?home=1", timeout=self.timeout))
+ try:
+ self.waitState(self.homing_state,1200)
+ except:
+ pass
+ return ret
+
+ def stop_move(self):
+ return self.get_response(requests.get(url=self.url_set+"set?stop=1", timeout=self.timeout))
+
+ def set_offset(self, offset):
+ return self.get_response(requests.get(url=self.url_set+"setOffset?offset="+str(offset), timeout=self.timeout))
+
+ def doUpdate(self):
+ self.get_status()
+ super(Hexiposi, self).doUpdate()
+
+
+ def doStop(self):
+ self.stop_move()
+
+ def doRead(self):
+ return str(self.val)
+
+ def doReadReadback(self):
+ self.get_status()
+ return self.rback
+
+ def doWrite(self, val):
+ #val = ord(val) - ord('A') +1
+ val = ord(val) - ord('B') +1
+ if val==0: val=6 #A
+ if val<1 or val>6:
+ raise Exception("Invalid value: " + str(val))
+ moving = val != self.val
+ self.val = val
+ self.move_pos(self.val)
+ #Workaround as state does not changes immediatelly
+ if moving:
+ #try:
+ # self.waitState(State.Busy,1200)
+ #except:
+ # print sys.exc_info()[1]
+ start = time.time()
+ while self.state != State.Busy:
+ if time.time() - start > 1.5:
+ print "Timeout waiting Hexiposi busy"
+ break
+ self.update()
+
+ def is_in_position(self, pos):
+ return self.take() == pos
+
+
+ def assert_in_position(self, pos):
+ if not is_in_position(pos):
+ raise Exception ("Hexiposi is not in position")
+
+ def assert_homed(self):
+ if self.homed == False:
+ raise Exception ("Hexiposi is not homed")
+
+ def assert_in_known_position(self):
+ self.get_status()
+ if self.rback == 'Unknown':
+ raise Exception("Hexiposi is in an unknown position, please home.")
+
+ #def isReady(self):
+ # self.get_status()
+ # return self.moving == False
+
+ def updateState(self):
+ if self.isSimulated():
+ self.setState(State.Ready)
+ elif self.offline:
+ self.setState(State.Offline)
+ elif self.homed == False:
+ self.setState(self.homing_state)
+ elif self.moving:
+ self.setState(State.Busy)
+ else:
+ self.setState(State.Ready)
+
+
+#http://myriox06da:8002/TellWeb/get
+dev = Hexiposi("hexiposi", "myriotell6d")
+
+#If no Rotation Lid is mounted set it to simulated
+#dev.setSimulated()
+
+add_device(dev, True)
+hexiposi.polling=1000
+#print dev.url
+#print dev.get_status()
+
+class hexiposi_position(ReadonlyRegisterBase):
+ def doRead(self):
+ try:
+ return float(hexiposi.pos)
+ except:
+ return float("nan")
+
+add_device(hexiposi_position(), True)
+hexiposi_position.polling = 1000
+hexiposi.set_deadband(1.0)
diff --git a/script/devices/LaserDistance.py b/script/devices/LaserDistance.py
new file mode 100644
index 0000000..086a508
--- /dev/null
+++ b/script/devices/LaserDistance.py
@@ -0,0 +1,27 @@
+class LaserDistance(ReadonlyRegisterBase):
+ def __init__(self):
+ ReadonlyRegisterBase.__init__(self, "laser_distance")
+
+ def doRead(self):
+ ret = ue.readable.read()
+ ret = None if ret is None else (0.0 if math.isnan(ret) else ret)
+ return ret
+
+class ListenerAI (DeviceListener):
+ def onValueChanged(self, device, value, former):
+ if laser_distance is not None:
+ value = None if value is None else (0.0 if math.isnan(value) else value)
+ laser_distance.setCache(value, None)
+
+
+for l in ue.listeners:
+ if Nameable.getShortClassName(l.getClass()) == "ListenerAI":
+ ue.removeListener(l)
+
+
+listenerAI = ListenerAI()
+ue.addListener(listenerAI)
+
+laser_distance=LaserDistance()
+add_device(laser_distance, True)
+laser_distance.update()
diff --git a/script/devices/LedCtrl.py b/script/devices/LedCtrl.py
new file mode 100644
index 0000000..da4e51d
--- /dev/null
+++ b/script/devices/LedCtrl.py
@@ -0,0 +1,46 @@
+import ch.psi.pshell.device.DiscretePositionerBase as DiscretePositionerBase
+
+
+class LedPositioner(DiscretePositionerBase):
+ def __init__(self):
+ DiscretePositionerBase.__init__(self, "led_ctrl", ["On", "Off"])
+ self.setState(State.Ready)
+ self.val = self.doReadReadback()
+
+ def doRead(self):
+ return self.val
+
+ def doReadReadback(self):
+ return "On" if get_led_state() else "Off"
+
+ def doWrite(self, val):
+ self.val = val
+ if self.val == "On":
+ set_led_state(True)
+ else:
+ set_led_state(False)
+
+
+add_device(LedPositioner(), True)
+led_ctrl.polling = 1000
+
+
+
+
+import ch.psi.pshell.device.ProcessVariableConfig as ProcessVariableConfig
+class LedLevel(ProcessVariableBase):
+ def __init__(self, name):
+ ProcessVariableBase.__init__(self, name, ProcessVariableConfig())
+
+ def doRead(self):
+ return get_led_level()
+
+ def doWrite(self, val):
+ return set_led_level(val)
+
+led_level = LedLevel("led_level")
+led_level.config.minValue = 0.0
+led_level.config.maxValue = 100.0
+led_level.config.unit = "%"
+add_device(led_level, True)
+led_level.polling = 1000
\ No newline at end of file
diff --git a/script/devices/OneWire.py b/script/devices/OneWire.py
new file mode 100644
index 0000000..20e590f
--- /dev/null
+++ b/script/devices/OneWire.py
@@ -0,0 +1,134 @@
+import traceback
+from datetime import datetime
+
+class Detector(ReadonlyRegisterBase):
+ def __init__(self, name):
+ ReadonlyRegisterBase.__init__(self, name)
+ self.reset()
+
+ def set_inputs(self, inputs):
+ self.inputs = inputs
+ if self.take() != inputs.values():
+ self.setCache(inputs.values(), None)
+ if self.getParent()!=None:
+ self.getParent().updateCache()
+ if (len(self.take()) == 0):
+ self.setState(State.Offline)
+ else:
+ self.setState(State.Ready)
+
+ def set_input(self, index, val):
+ self.inputs[index] = val
+ self.set_inputs(self.inputs)
+
+ def reset(self):
+ self.id = None
+ self.sn = None
+ self.status = None
+ self.type = None
+ self.set_inputs({})
+
+class Esera(TcpDevice):
+ def __init__(self, name, server, timeout = 1000, retries = 1):
+ TcpDevice.__init__(self, name, server)
+ self.setMode(self.Mode.FullDuplex)
+ self.detectors = []
+ for i in range(30):
+ self.detectors.append(Detector("Detector " + str(i+1)))
+ self.setChildren(self.detectors)
+ self.completed_initializatiod = False
+ self.debug = False
+
+ def start(self):
+ self.getLogger().info("Starting controller")
+ self.write("set,sys,run,1\n")
+
+ def stop(self):
+ self.getLogger().info("Stopping controller")
+ self.write("set,sys,run,0\n")
+
+ def list(self):
+ self.write("get,owb,listall1\n")
+
+ def req_data(self):
+ self.write("get,sys,data\n")
+
+ def doInitialize(self):
+ super(Esera, self).doInitialize()
+ self.init_timestamp = time.time()
+ try:
+ self.setState(State.Ready) #So can communicate
+ for det in self.detectors:
+ det.reset()
+ self.list()
+ time.sleep(1.0)
+ self.check_started()
+ self.req_data()
+ except:
+ print >> sys.stderr, traceback.format_exc()
+ self.getLogger().warning(traceback.format_exc())
+ raise
+
+ def doUpdate(self):
+ self.check_started()
+ self.req_data()
+
+ def updateCache(self):
+ #print "Update"
+ cache = []
+ for det in self.detectors:
+ cache.append(det.take())
+ self.setCache(cache, None)
+
+
+ def check_started(self):
+ if not self.completed_initializatiod:
+ init = True
+ for det in self.detectors:
+ if det.id == None:
+ init = False
+ break
+ if init:
+ self.completed_initializatiod = True
+ print("Completed initialization")
+ self.getLogger().info("Completed initialization")
+ self.start()
+
+ def onString(self, msg):
+ if self.debug:
+ print datetime.now() , " - " , msg
+ tokens = msg.split("|")
+ if len(tokens)>1:
+ try:
+ if msg[:3] == "LST":
+ #LST|1_OWD1|3AF361270000009E|S_0|DS2413|
+ if tokens[1] > 1:
+ index = int(tokens[1].split("_")[1][3:]) - 1
+ if index < len(self.detectors):
+ det = self.detectors[index]
+ det.id = tokens[1]
+ det.sn= tokens[2] if len(tokens)>2 else None
+ det.status = int(tokens[3][2:]) if len(tokens)>3 else None
+ det.type = tokens[4] if len(tokens)>4 else None
+ if det.status!= 0:
+ det.set_inputs({})
+ else:
+ for det in self.detectors:
+ if det.id is not None and msg.startswith(det.id):
+ det_id = int(tokens[0][len(det.id)+1:])
+ det.set_input(det_id, int(tokens[1]))
+ except:
+ print >> sys.stderr, traceback.format_exc()
+ self.getLogger().log(traceback.format_exc())
+
+
+
+
+
+
+
+add_device(Esera("onewire", "129.129.126.83:5000"), force = True)
+onewire.setPolling(500)
+add_device(onewire.detectors[0], force = True)
+add_device(onewire.detectors[1], force = True)
+add_device(onewire.detectors[2], force = True)
diff --git a/script/devices/RobotModbus.py b/script/devices/RobotModbus.py
new file mode 100644
index 0000000..cd8abaf
--- /dev/null
+++ b/script/devices/RobotModbus.py
@@ -0,0 +1,46 @@
+class RobotModbus(DeviceBase):
+ def __init__(self, name):
+ DeviceBase.__init__(self, name)
+ robot_req.write(0)
+
+ def execute(self, command, *argv):
+ if robot_req.read() != 0:
+ raise Exception("Ongoing command")
+ if robot_ack.read() != 0:
+ raise Exception("Robot is not ready")
+ robot_cmd.write(command)
+ args = [0] * robot_args.size
+ index = 0
+ for arg in argv:
+ args[index] = arg
+ index = index + 1
+ if index == robot_args.size:
+ raise Exception("Invalid number of arguments")
+ robot_args.write(to_array(args, 'i'))
+ try:
+ self.request()
+ err = robot_ack.take()
+ if err == 1:
+ ret = robot_ret.read()
+ return ret
+ if err == 2:
+ raise Exception("Invalid command: " + str(command))
+ raise Exception("Unknown error: " + str(err))
+ finally:
+ self.cancel_request()
+
+ def request(self):
+ robot_req.write(1)
+ while robot_ack.read() == 0:
+ time.sleep(0.001)
+
+ def cancel_request(self):
+ robot_req.write(0)
+ while robot_ack.read() != 0:
+ time.sleep(0.001)
+
+ def mount(self, puck, sample):
+ return self.execute('1', '1', puck, sample)
+
+add_device(RobotModbus("robot_mb"), force = True)
+
diff --git a/script/devices/RobotMotors.py b/script/devices/RobotMotors.py
new file mode 100644
index 0000000..07ba862
--- /dev/null
+++ b/script/devices/RobotMotors.py
@@ -0,0 +1,62 @@
+
+import ch.psi.pshell.device.PositionerConfig as PositionerConfig
+
+
+
+ROBOT_MOTORS = ["x" , "y", "z", "rx", "ry", "rz"]
+
+
+class RobotCartesianMotor (PositionerBase):
+ def __init__(self, robot, index):
+ PositionerBase.__init__(self, robot.name + "_" + ROBOT_MOTORS[index], PositionerConfig())
+ self.index = index
+ self.robot = robot
+
+ #ATTENTION: Always initialize cartesian motors before scanning (or call robot.set_motors_enabled(True))
+ def doInitialize(self):
+ self.setCache(self.doRead(), None)
+
+ def doRead(self):
+ return float("nan") if self.robot.cartesian_destination is None else float(self.robot.cartesian_destination[self.index])
+
+ def doWrite(self, value):
+ if self.robot.cartesian_destination is not None:
+ #print "Move " + ROBOT_MOTORS[self.index] + " to " + str(value)
+ self.robot.cartesian_destination[self.index] = float(value)
+ self.robot.set_pnt(robot.cartesian_destination , "tcp_p")
+ self.robot.movel("tcp_p", self.robot.tool , DESC_SCAN)
+
+ def doReadReadback(self):
+ return float("nan") if self.robot.cartesian_pos is None else float(self.robot.cartesian_pos[self.index])
+
+
+
+
+ROBOT_JOINT_MOTORS = ["j1" , "j2", "j3", "j4", "j5", "j6"]
+
+
+class RobotJointMotor (PositionerBase):
+ def __init__(self, robot, index):
+ PositionerBase.__init__(self, robot.name + "_" + ROBOT_JOINT_MOTORS[index], PositionerConfig())
+ self.index = index
+ self.robot = robot
+
+ def doInitialize(self):
+ self.setpoint = self.doReadReadback()
+ self.setCache(self.doRead(), None)
+
+ def doRead(self):
+ return self.setpoint
+
+ def doWrite(self, value):
+ #print "Move " + ROBOT_JOINT_MOTORS[self.index] + " to " + str(value)
+ self.setpoint = value
+ joint = self.robot.herej()
+ joint[self.index] = value
+ self.robot.set_jnt(joint, name="tcp_j")
+ self.robot.movej("tcp_j", self.robot.tool , DESC_SCAN)
+
+ def doReadReadback(self):
+ return self.robot.herej()[self.index] if self.robot.joint_pos is None else float(self.robot.joint_pos[self.index])
+
+
\ No newline at end of file
diff --git a/script/devices/RobotSC.py b/script/devices/RobotSC.py
new file mode 100644
index 0000000..3f2b727
--- /dev/null
+++ b/script/devices/RobotSC.py
@@ -0,0 +1,358 @@
+TOOL_CALIBRATION = "tCalib"
+TOOL_SUNA= "tSuna"
+TOOL_DEFAULT= TOOL_SUNA
+
+FRAME_TABLE = "fTable"
+
+DESC_FAST = "mFast"
+DESC_SLOW = "mSlow"
+DESC_SCAN = "mScan"
+DESC_DEFAULT = DESC_FAST
+
+AUX_SEGMENT = "X"
+
+
+DEFAULT_ROBOT_POLLING = 500
+TASK_WAIT_ROBOT_POLLING = 50
+
+
+run("devices/RobotTCP")
+
+
+simulation = False
+
+joint_forces = False
+
+class RobotSC(RobotTCP):
+ def __init__(self, name, server, timeout = 1000, retries = 1):
+ RobotTCP.__init__(self, name, server, timeout, retries)
+ self.set_tasks(["getDewar", "putDewar", "putGonio", "getGonio", "recover", "moveDewar", "moveCold", "movePark", "moveGonio","moveHeater", "moveScanner","moveHome", "moveAux"])
+ self.set_known_points(["pPark", "pGonioA", "pDewar", "pGonioG", "pScan", "pHeater", "pHeat", "pHeatB", "pLaser","pHelium", "pHome", "pCold", "pAux"])
+ self.setPolling(DEFAULT_ROBOT_POLLING)
+ self.last_command_timestamp = None
+ self.last_command_position = None
+ #self.setSimulated()
+
+ def move_dewar(self):
+ self.start_task('moveDewar')
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_dewar()
+ self.last_command_position = "dewar"
+ self.last_command_timestamp = time.time()
+
+ def move_cold(self):
+ self.start_task('moveCold')
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_cold()
+ self.last_command_position = "cold"
+ self.last_command_timestamp = time.time()
+
+ def move_home(self):
+ self.start_task('moveHome')
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_home()
+ self.last_command_position = "home"
+ self.last_command_timestamp = time.time()
+
+ def get_dewar(self, segment, puck, sample):
+ segment = self.toSegmentNumber(segment)
+ self.start_task('getDewar',segment, puck, sample, is_room_temp())
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_dewar()
+ self.last_command_position = "dewar"
+ self.last_command_timestamp = time.time()
+
+ def put_dewar(self, segment, puck, sample):
+ segment = self.toSegmentNumber(segment)
+ self.assert_dewar()
+ self.start_task('putDewar',segment, puck, sample, is_room_temp())
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ #self.assert_dewar()
+ self.assert_cold()
+ self.last_command_position = "dewar"
+ self.last_command_timestamp = time.time()
+
+ def put_gonio(self):
+ assert_detector_safe()
+ pin_offset = get_pin_offset()
+ pin_angle_offset = get_pin_angle_offset()
+ print "Pin offset = " + str(pin_offset)
+ self.start_task('putGonio', pin_offset)
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_gonio()
+ self.last_command_position = "gonio"
+ self.last_command_timestamp = time.time()
+
+ def get_gonio(self):
+ assert_detector_safe()
+ pin_offset = get_pin_offset()
+ print "Pin offset = " + str(pin_offset)
+ self.start_task('getGonio', pin_offset)
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_gonio()
+ self.last_command_position = "gonio"
+ self.last_command_timestamp = time.time()
+
+ def get_aux(self, sample):
+ self.assert_aux()
+ self.start_task('getAuxiliary', sample)
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_aux()
+ self.last_command_position = "aux"
+ self.last_command_timestamp = time.time()
+
+ def put_aux(self, sample):
+ self.assert_aux()
+ self.start_task('putAuxiliary', sample)
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_aux()
+ self.last_command_position = "aux"
+ self.last_command_timestamp = time.time()
+
+ def move_scanner(self):
+ self.start_task('moveScanner')
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_scanner()
+ self.last_command_position = "scanner"
+ self.last_command_timestamp = time.time()
+
+ def move_laser(self):
+ self.start_task('moveScanner')
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_laser()
+ self.last_command_position = "scanner"
+ self.last_command_timestamp = time.time()
+
+ #def do_scan(self):
+ # self.start_task('doScan')
+ # self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ # self.assert_scan_stop()
+
+ def move_gonio(self):
+ assert_detector_safe()
+ self.start_task('moveGonio')
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_gonio()
+ self.last_command_position = "gonio"
+ self.last_command_timestamp = time.time()
+
+
+ def move_park(self):
+ self.start_task('movePark')
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_park()
+ self.last_command_position = "park"
+ self.last_command_timestamp = time.time()
+
+ def move_heater(self, speed=-1, to_bottom=True):
+ self.start_task('moveHeater', speed, to_bottom)
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ if to_bottom:
+ self.assert_heater_bottom()
+ else:
+ self.assert_heater()
+ self.last_command_position = "heater"
+ self.last_command_timestamp = time.time()
+
+
+ def robot_recover(self):
+ self.start_task('recover')
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_home()
+ self.last_command_position = "home"
+ self.last_command_timestamp = time.time()
+
+ def move_aux(self):
+ self.start_task('moveAux')
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_aux()
+ self.last_command_position = "aux"
+ self.last_command_timestamp = time.time()
+
+ def get_calibration_tool(self):
+ self.start_task('getCalTool')
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_scanner()
+ self.last_command_position = "scanner"
+ self.last_command_timestamp = time.time()
+
+ def put_calibration_tool(self):
+ self.start_task('putCalTool')
+ self.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ self.assert_scanner()
+ self.command_timestamps["scanner"] = time.time()
+
+
+
+ def toSegmentNumber(self, segment):
+ if is_string(segment):
+ segment = ord(segment.upper()) - ord('A') +1
+ return segment
+
+
+ def on_event(self,ev):
+ #print "EVT: " + ev
+ pass
+ def on_change_working_mode(self, working_mode):
+ if get_device("hexiposi") is not None:
+ hexiposi.moved = True #Force image processing on first sample
+
+ def doUpdate(self):
+ #start = time.time()
+ RobotTCP.doUpdate(self)
+ global simulation
+ if not simulation:
+ if joint_forces:
+ if self.state != State.Offline:
+ self.get_joint_forces()
+ for dev in [jf1, jf2, jf3, jf4,jf5, jf6, jfc]:
+ dev.update()
+ #print time.time() -start
+
+ def start_task(self, program, *args, **kwargs):
+ #TODO: Check safe position
+ return RobotTCP.start_task(self, program, *args, **kwargs)
+
+ def stop_task(self):
+ RobotTCP.stop_task(self)
+ #TODO: Restore safe position
+
+
+ def set_remote_mode(self):
+ robot.set_profile("remote")
+
+ def set_local(self):
+ robot.set_profile("default")
+
+ def is_park(self):
+ return self.is_in_point("pPark")
+
+ def is_cold(self):
+ return self.is_in_point("pCold")
+
+ def is_home(self):
+ return self.is_in_point("pHome")
+
+ def is_dewar(self):
+ return self.is_in_point("pDewar")
+
+ def is_heater(self):
+ return self.is_in_point("pHeat")
+
+ def is_heater_home(self):
+ return self.is_in_point("pHeater")
+
+ def is_heater_bottom(self):
+ return self.is_in_point("pHeatB")
+
+ def is_gonio(self):
+ return self.is_in_point("pGonioA")
+
+ def is_helium(self):
+ return self.is_in_point("pHelium")
+
+ def is_scanner(self):
+ return self.is_in_point("pScan")
+
+ def is_aux(self):
+ return self.is_in_point("pAux")
+
+ def is_laser(self):
+ return self.is_in_point("pLaser")
+
+ def is_cleared(self):
+ #return self.is_home() or self.is_park() or self.is_dewar() or self.is_dewar_home()
+ return self.get_current_point() is not None
+
+ def assert_heater_home(self):
+ self.assert_in_point("pHeater")
+
+ def assert_cold(self):
+ self.assert_in_point("pCold")
+
+ def assert_heater(self):
+ self.assert_in_point("pHeat")
+
+ def assert_heater_bottom(self):
+ self.assert_in_point("pHeatB")
+
+ def assert_park(self):
+ self.assert_in_point("pPark")
+
+ def assert_home(self):
+ self.assert_in_point("pHome")
+
+ def assert_dewar(self):
+ self.assert_in_point("pDewar")
+
+ def assert_gonio(self):
+ self.assert_in_point("pGonioA")
+
+ def assert_helium(self):
+ self.assert_in_point("pHelium")
+
+ def assert_scanner(self):
+ self.assert_in_point("pScan")
+
+ def assert_aux(self):
+ self.assert_in_point("pAux")
+
+ def assert_laser(self):
+ self.assert_in_point("pLaser")
+
+ def assert_cleared(self):
+ if not self.is_cleared():
+ raise Exception("Robot not in cleared position")
+
+ def wait_ready(self):
+ robot.waitState(State.Ready, 1000) #robot.state.assertReady()
+
+if simulation:
+ add_device(RobotSC("robot","localhost:1000"),force = True)
+else:
+ add_device(RobotSC("robot", "TellRobot6D:1000"), force = True)
+ #add_device(RobotSC("robot", "129.129.110.110:1000"), force = True)
+
+#robot.latency = 0.005
+robot.set_default_desc(DESC_DEFAULT)
+robot.default_speed = 20
+robot.set_frame(FRAME_DEFAULT)
+robot.set_tool(TOOL_DEFAULT)
+robot.setPolling(DEFAULT_ROBOT_POLLING)
+
+robot.get_current_point() #TODO: REMOVE WHEN CURRENT POINT REPORTED BY POLLING MESSAGE
+
+class jf1(ReadonlyRegisterBase):
+ def doRead(self):
+ return None if robot.joint_forces == None else robot.joint_forces[0]
+class jf2(ReadonlyRegisterBase):
+ def doRead(self):
+ return None if robot.joint_forces == None else robot.joint_forces[1]
+class jf3(ReadonlyRegisterBase):
+ def doRead(self):
+ return None if robot.joint_forces == None else robot.joint_forces[2]
+class jf4(ReadonlyRegisterBase):
+ def doRead(self):
+ return None if robot.joint_forces == None else robot.joint_forces[3]
+class jf5(ReadonlyRegisterBase):
+ def doRead(self):
+ return None if robot.joint_forces == None else robot.joint_forces[4]
+class jf6(ReadonlyRegisterBase):
+ def doRead(self):
+ return None if robot.joint_forces == None else robot.joint_forces[5]
+class jfc(ReadonlyRegisterBase):
+ def doRead(self):
+ if robot.joint_forces == None:
+ return float('NaN')
+ if robot.powered == False:
+ return float('NaN')
+ return (robot.joint_forces[1]+74)/4 + (robot.joint_forces[2]+30)/4 + (robot.joint_forces[4]-0.8)/0.2
+
+if joint_forces:
+ add_device(jf1(), force = True)
+ add_device(jf2(), force = True)
+ add_device(jf3(), force = True)
+ add_device(jf4(), force = True)
+ add_device(jf5(), force = True)
+ add_device(jf6(), force = True)
+ add_device(jfc(), force = True)
\ No newline at end of file
diff --git a/script/devices/RobotTCP.py b/script/devices/RobotTCP.py
new file mode 100644
index 0000000..4727d68
--- /dev/null
+++ b/script/devices/RobotTCP.py
@@ -0,0 +1,919 @@
+import threading
+
+FRAME_DEFAULT = "world"
+FLANGE = "flange"
+
+MAX_NUMBER_PARAMETERS = 20
+
+run("devices/RobotMotors")
+
+class RobotTCP(TcpDevice, Stoppable):
+ def __init__(self, name, server, timeout = 1000, retries = 1):
+ TcpDevice.__init__(self, name, server)
+ self.timeout = timeout
+ self.retries = retries
+ self.header = None
+ self.trailer = "\n"
+ self.array_separator = '|'
+ self.cmd_separator = ' '
+ self.msg_id = 0
+ self.working_mode = "invalid"
+ self.status = "invalid"
+ self.powered = None
+ self.settled = None
+ self.empty = None
+ self.working_mode = None
+ self.status = None
+ self.lock = threading.Lock()
+ self.joint_forces = None
+ self.current_task = None
+ self.current_task_ret = None
+ self.high_level_tasks = []
+ self.known_points = []
+ self.current_points = []
+ self.cartesian_destination = None
+ #self.flange_pos = [None] * 6
+ self.cartesian_pos = [None] * 6
+ self.joint_pos = [None] * 6
+ self.cartesian_motors_enabled = False
+ self.cartesian_motors = []
+ self.joint_motors_enabled = False
+ self.joint_motors = []
+ self.tool = None
+ self.default_desc = None
+ self.tool_open = None
+ #self.tool_trsf = [0.0] * 6
+ self.frame = FRAME_DEFAULT
+ self.polling_interval = 0.01
+ self.reset = True
+ self.default_tolerance = 5
+ self.default_speed = 100
+ self.latency = 0
+ self.last_msg_timestamp = 0
+
+ self.task_start_retries = 3
+ self.exception_on_task_start_failure = True #Tasks may start and be finished when checked
+
+
+ def doInitialize(self):
+ super(RobotTCP, self).doInitialize()
+ self.reset = True
+
+ def set_tool(self, tool):
+ self.tool = tool
+ #self.tool_trsf = self.get_tool_trsf()
+ self.evaluate("tcp_curtool=" + tool)
+ if self.cartesian_motors_enabled:
+ self.update()
+ self.set_motors_enabled(True)
+ self.is_tool_open()
+
+ def get_tool(self):
+ return self.tool
+
+ def set_frame(self, frame):
+ self.frame = frame
+ self.evaluate("tcp_curframe=" + frame)
+ if self.cartesian_motors_enabled:
+ self.update()
+ self.set_motors_enabled(True)
+ self.waitCacheChange(5000)
+
+ def get_frame(self):
+ return self.frame
+
+ def set_default_frame(self):
+ self.set_frame(FRAME_DEFAULT)
+
+ def assert_tool(self, tool=None):
+ if tool is None:
+ if self.tool is None:
+ raise Exception("Tool is undefined")
+ elif self.tool != tool:
+ raise Exception("Invalid tool: " + self.tool)
+
+ def set_default_desc(self,default_desc):
+ self.default_desc=default_desc
+
+ def get_default_desc(self):
+ return self.default_desc
+
+ def set_tasks(self,tasks):
+ self.high_level_tasks=tasks
+
+ def get_tasks(self):
+ return self.high_level_tasks
+
+ def set_known_points(self, points):
+ self.known_points=points
+
+ def get_known_points(self):
+ return self.known_points
+
+ def get_current_points(self, tolerance = None):
+ ret = self.is_in_points(*self.known_points, tolerance = tolerance)
+ current_points = []
+ for i in range(len(ret)):
+ if ret[i] == True:
+ current_points.append(self.known_points[i])
+ return current_points
+
+ def get_current_point(self, tolerance = None):
+ current_points = self.get_current_points(tolerance)
+ if (current_points is not None) and ( len(current_points) >0):
+ return current_points[0]
+ return None
+
+ def get_current_points_cached(self):
+ return self.current_points
+
+ def get_current_point_cached(self):
+ if (self.current_points is not None) and (len (self.current_points) >0):
+ return self.current_points[0]
+ return None
+
+ def assert_in_known_point(self, tolerance = None):
+ if self.get_current_point(tolerance) is None:
+ raise Exception ("Robot not in known point")
+
+ def _sendReceive(self, msg_id, msg = "", timeout = None):
+ if self.latency >0:
+ timespan = time.time() - self.last_msg_timestamp
+ if timespan150):
+ raise Exception("Exceeded maximum message size")
+ self.getLogger().finer("TX = '" + str(tx)+ "'")
+ if (self.trailer != None): tx = tx + self.trailer
+ if self.isSimulated():
+ return ""
+ rx = self.sendReceive(tx, msg_id, self.trailer , 0, self.timeout if timeout is None else timeout, self.retries)
+ self.last_msg_timestamp = time.time()
+ rx=rx[:-1] #Remove 0A
+ self.getLogger().finer("RX = '" + str(rx) + "'")
+ if rx[:3] != msg_id:
+ if (time.time()-start) >= timeout:
+ raise Exception("Received invalid message id: " + str(rx[:3]) + " - expecting:" + msg_id )
+ if len(rx)<4:
+ raise Exception("Invalid message size: " + str(len(rx)) )
+ if rx[3] == "*":
+ raise Exception(rx[4:])
+ return rx[4:]
+
+ def call(self, msg, timeout = None):
+ self.lock.acquire()
+ try:
+ id = "%03d" % self.msg_id
+ self.msg_id = (self.msg_id+1)%1000
+ return self._sendReceive(id, msg, timeout)
+ finally:
+ self.lock.release()
+
+ def execute(self, command, *args, **kwargs):
+ timeout = None if (kwargs is None) or (not kwargs.has_key("timeout")) else kwargs["timeout"]
+ msg = str(command)
+ if len(args)>MAX_NUMBER_PARAMETERS:
+ raise Exception("Exceeded maximum number of parameters")
+ for i in range(len(args)):
+ msg += (self.cmd_separator if (i==0) else self.array_separator) + str(args[i])
+ rx = self.call(msg, timeout)
+ if rx.count(self.array_separator)>0:
+ return rx.split(self.array_separator)
+ return rx
+
+ def evaluate(self, cmd, timeout=None):
+ ret = self.execute('eval', cmd, timeout=timeout)
+ if is_string(ret):
+ if ret.strip() != "": raise Exception(ret)
+
+ def get_var(self, name):
+ return self.execute('get_var', name)
+
+ #Makes app crash
+ #def get_str(self, name='s'):
+ # return self.execute('get_str', name)
+
+ def get_arr(self, name, size):
+ return self.execute('get_arr', name, size)
+
+ def get_bool(self, name = "tcp_b"):
+ return True if (self.execute('get_bool', name).strip() == '1') else False
+
+ def get_int(self, name ="tcp_n"):
+ return int(self.get_var(name))
+
+ def get_float(self, name ="tcp_n"):
+ return float(self.get_var(name))
+
+ def get_int_arr(self, size, name="tcp_a"):
+ # not working. A Jython bug in PyUnicaode?
+ #return [int(x) for x in self.get_arr("tcp_a", size)]
+ ret = []
+ a=self.get_arr(name, size)
+ for i in range(size):
+ ret.append(int(a[i]))
+ return ret
+
+ def get_float_arr(self, size, name="tcp_a"):
+ #return [float(x) for x in self.get_arr("tcp_a", size)]
+ a=self.get_arr(name, size)
+ ret = [];
+ for i in range(size): ret.append(float(a[i]));
+ return ret
+
+ def get_trsf(self, name="tcp_t"):
+ a = self.execute('get_trf', name)
+ ret = []
+ for i in range(6): ret.append(float(a[i]))
+ return ret
+
+ def set_trsf(self, l, name="tcp_t"):
+ self.evaluate(name + "={" + str(l[0]) + ","+ str(l[1]) + ","+ str(l[2]) + ","+ str(l[3]) + ","+ str(l[4]) + ","+ str(l[5]) + "}")
+
+ def get_jnt(self, name="tcp_j"):
+ a = self.execute('get_jnt', name)
+ ret = []
+ for i in range(6): ret.append(float(a[i]))
+ return ret
+
+ def set_jnt(self, l, name="tcp_j"):
+ self.evaluate(name + "={" + str(l[0]) + ","+ str(l[1]) + ","+ str(l[2]) + ","+ str(l[3]) + ","+ str(l[4]) + ","+ str(l[5]) + "}")
+
+ def get_pnt(self, name="tcp_p"):
+ #a = self.execute('get_pnt', name)
+ #ret = []
+ #for i in range(6): ret.append(float(a[i]))
+ #return ret
+ return self.get_trsf(name+".trsf")
+
+ #trsf = (x,y,z,rx,ry,rz)
+ #TODO: config = (shoulder, elbow, wrist)
+ def set_pnt(self, trsf, name="tcp_p", config=None):
+ self.set_trsf(trsf, name+".trsf")
+
+ def get_tool_trsf(self, name=None):
+ if name is None:
+ self.assert_tool()
+ name = self.tool
+ return self.get_trsf(name+".trsf")
+
+ def set_tool_trsf(self, trsf, name=None):
+ if name is None:
+ self.assert_tool()
+ name = self.tool
+ self.set_trsf(trsf, name+".trsf")
+
+ def eval_int(self, cmd):
+ if self.isSimulated():
+ return 0
+ self.evaluate("tcp_n=" + cmd)
+ return self.get_int()
+
+ def eval_float(self, cmd):
+ if self.isSimulated():
+ return 0.0
+ self.evaluate("tcp_n=" + cmd)
+ return self.get_float()
+
+ def eval_bool(self, cmd):
+ if self.isSimulated():
+ return False
+ self.evaluate("tcp_b=" + cmd)
+ return self.get_bool()
+
+ #def eval_str(self, cmd):
+ # self.evaluate("s=" + cmd)
+ # return self.get_str()
+
+ def eval_jnt(self, cmd):
+ self.evaluate("tcp_j=" + cmd)
+ return self.get_jnt()
+
+ def eval_trf(self, cmd):
+ self.evaluate("tcp_t=" + cmd)
+ return self.get_trsf()
+
+ def eval_pnt(self, cmd):
+ self.evaluate("tcp_p=" + cmd)
+ return self.get_pnt()
+
+
+ #Robot control
+ def is_powered(self):
+ self.powered = self.eval_bool("isPowered()")
+ return self.powered
+
+ def enable(self):
+ if not self.is_powered():
+ self.evaluate("enablePower()")
+ time.sleep(1.0)
+ if not self.is_powered():
+ raise Exception("Cannot enable power")
+
+ #waits for power to be actually cut off
+ def disable(self):
+ self.evaluate("disablePower()", timeout=5000)
+
+ def get_monitor_speed(self):
+ self.speed = self.eval_int("getMonitorSpeed()")
+ return self.speed
+
+ def set_monitor_speed(self, speed):
+ ret = self.eval_int("setMonitorSpeed(" + str(speed) + ")")
+ if (ret==-1): raise Exception("The robot is not in remote working mode")
+ if (ret==-2): raise Exception("The monitor speed is under the control of the operator")
+ if (ret==-3): raise Exception("The specified speed is not supported")
+
+ def set_default_speed(self):
+ set_monitor_speed(self.default_speed)
+
+ def is_calibrated(self):
+ return self.eval_bool("isCalibrated()")
+
+ def save_program(self):
+ ret = self.execute('save', timeout=5000)
+ if str(ret) != "0": raise Exception("Error saving program: " + str(ret))
+
+ def _update_working_mode(self, mode, status):
+ cur_mode = self.working_mode
+ if mode==1:
+ self.working_mode = "manual"
+ self.status = "hold" if status==6 else "move"
+ elif mode==2:
+ self.working_mode = "test"
+ self.status = "hold" if status==3 else "move"
+ elif mode==3:
+ self.working_mode = "local"
+ self.status = "hold" if status==2 else "move"
+ elif mode==4:
+ self.working_mode = "remote"
+ self.status = "hold" if status==2 else "move"
+ else:
+ self.working_mode = "invalid"
+ self.status = "invalid"
+ if self.working_mode != cur_mode:
+ try:
+ self.on_change_working_mode(self.working_mode)
+ except:
+ pass
+
+ def read_working_mode(self):
+ try:
+ mode = self.eval_int("workingMode(tcp_a)")
+ status = int(self.get_var("tcp_a[0]"))
+ self._update_working_mode(mode, status)
+ self._update_state()
+ except:
+ self.working_mode = "invalid"
+ self.status = "invalid"
+ return self.working_mode
+
+ def get_emergency_stop_sts(self):
+ st = self.eval_int("esStatus()")
+ if (st== 1): return "active"
+ if (st== 2): return "activated"
+ return "off"
+
+ def get_safety_fault_signal(self):
+ fault = self.eval_bool("safetyFault(s)")
+ #if (fault):
+ # return get_str()
+ return fault
+
+ #Motion control
+ def stop(self):
+ self.evaluate("stopMove()")
+
+ def resume(self):
+ self.evaluate("restartMove()")
+
+ def reset_motion(self, joint=None, timeout=None):
+ #TODO: in new robot robot.resetMotion() is freezing controller
+ #self.evaluate("resetMotion()" if (joint is None) else ("resetMotion(" + joint + ")"))
+ if joint is None:
+ self.execute('reset', timeout=timeout)
+ else:
+ self.execute('reset', str(joint), timeout=timeout)
+
+ def is_empty(self):
+ self.empty = self.eval_bool("isEmpty()")
+ self._update_state()
+ return self.empty
+
+ def is_settled(self):
+ self.settled = self.eval_bool("isSettled()")
+ self._update_state()
+ return self.settled
+
+ def get_move_id(self):
+ return self.eval_int("getMoveId()")
+
+ def set_move_id(self, id):
+ return self.evaluate("setMoveId(" + str(id) + " )")
+
+ def get_joint_forces(self):
+ try:
+ self.evaluate("getJointForce(tcp_a)")
+ self.joint_forces = self.get_float_arr(6)
+ return self.joint_forces
+ except:
+ self.joint_forces = None
+ raise
+
+ def movej(self, joint_or_point, tool=None, desc=None, sync=False):
+ if desc is None: desc = self.default_desc
+ if tool is None: tool = self.tool
+ #If joint_or_point is a list assumes ir is a point
+ if not is_string(joint_or_point):
+ robot.set_pnt(joint_or_point , "tcp_p")
+ joint_or_point = "tcp_p"
+
+ #TODO: in new robot movel and movej is freezing controller
+ #ret = self.eval_int("movej(" + joint_or_point + ", " + tool + ", " + desc +")")
+ ret = int(self.execute('movej',joint_or_point, tool, desc))
+
+ if sync:
+ self.wait_end_of_move()
+ return ret
+
+ def movel(self, point, tool=None, desc=None, sync=False):
+ if desc is None: desc = self.default_desc
+ if tool is None: tool = self.tool
+ if not is_string(point):
+ robot.set_pnt(point , "tcp_p")
+ point = "tcp_p"
+ #TODO: in new robot movel and movej is freezing controller
+ #ret = self.eval_int("movel(" + point + ", " + tool + ", " + desc +")")
+ ret = int(self.execute('movel',point, tool, desc))
+
+ if sync:
+ self.wait_end_of_move()
+ return ret
+
+ def movec(self, point_interm, point_target, tool=None, desc=None, sync=False):
+ if desc is None: desc = self.default_desc
+ if tool is None: tool = self.tool
+
+ #TODO: in new robot movel and movej is freezing controller
+ #ret = self.eval_int("movec(" + point_interm + ", " + point_target + ", " + tool + ", " + desc +")")
+ ret = int(self.execute('movec', point_interm, point_target, tool, desc))
+
+ if sync:
+ self.wait_end_of_move()
+ return ret
+
+ def wait_end_of_move(self):
+ time.sleep(0.05)
+ self.update()
+ #time.sleep(0.01)
+ #self.waitCacheChange(-1)
+ self.waitReady(-1)
+ #self.waitState(State.Ready, -1)
+
+
+ #Tool - synchronized as can freeze communication
+ """
+ def open_tool(self, tool=None, timeout=3000):
+ #This function can timeout since it synchronizes move. Checking state before otherwise it can freeze the communication.
+ self.waitState(State.Ready, -1)
+ if tool is None: tool = self.tool
+ return self.evaluate("open(" + tool + " )", timeout=timeout)
+
+ def close_tool(self, tool=None, timeout=3000):
+ #This function can timeout since it synchronizes move. Checking state before otherwise it can freeze the communication.
+ self.waitState(State.Ready, -1)
+ if tool is None: tool = self.tool
+ return self.evaluate("close(" + tool + " )", timeout=timeout)
+ """
+ #Tool - Not synchronized calls: atention to open/close only when state is Ready
+ def open_tool(self, tool=None):
+ if tool is None: tool = self.tool
+ self.evaluate(tool + ".gripper=true")
+ self.tool_open = True
+
+ def close_tool(self, tool=None):
+ if tool is None: tool = self.tool
+ self.evaluate(tool + ".gripper=false")
+ self.tool_open = False
+
+ def is_tool_open(self, tool=None):
+ if tool is None: tool = self.tool
+ self.tool_open = robot.eval_bool(tool + ".gripper")
+ return self.tool_open
+
+
+ #Arm position
+ def herej(self):
+ return self.eval_jnt("herej()")
+
+ def distance_t(self, trsf1, trsf2):
+ return self.eval_float("distance(" + trsf1 + ", " + trsf2 + ")")
+
+ def distance_p(self, pnt1, pnt2):
+ return self.eval_float("distance(" + pnt1 + ", " + pnt2 + ")")
+
+ def compose(self, pnt, frame = None, trsf = "tcp_t"):
+ if frame is None: frame = self.frame
+ return self.eval_pnt("compose(" + pnt + ", " + frame + ", " + trsf + ")")
+
+ def here(self, tool=None, frame=None):
+ if tool is None: tool = self.tool
+ if frame is None: frame = self.frame
+ return self.eval_pnt("here(" + tool + ", " + frame + ")")
+
+ def joint_to_point(self, tool=None, frame=None, joint="tcp_j"):
+ if tool is None: tool = self.tool
+ if frame is None: frame = self.frame
+ return self.eval_pnt("jointToPoint(" + tool + ", " + frame + ", " + joint +")")
+
+ def point_to_joint(self, tool=None, initial_joint="tcp_j", point="tcp_p"):
+ if tool is None: tool = self.tool
+ if self.eval_bool("pointToJoint(" + tool + ", " + initial_joint + ", " + point +", j)"):
+ return self.get_jnt()
+
+ def position(self, point, frame=None):
+ if frame is None: frame = self.frame
+ return self.eval_trf("position(" + point + ", " + frame + ")")
+
+ #Profile
+ def get_profile(self):
+ return self.execute('get_profile', timeout=2000)
+
+ def set_profile(self, name, pwd = ""):
+ self.execute('set_profile', str(name), str(pwd), timeout=5000)
+
+
+ #Task control
+ def task_create(self, program, *args, **kwargs):
+ program = str(program)
+ priority = 10 if (kwargs is None) or (not kwargs.has_key("priority")) or (kwargs["priority"] is None) else kwargs["priority"]
+ name = str(program if (kwargs is None) or (not kwargs.has_key("name")) else kwargs["name"])
+
+ if self.get_task_status(name)[0] != -1:
+ raise Exception("Task already exists: " + name)
+
+ if priority<1 or priority > 100:
+ raise Exception("Invalid priority: " + str(priority))
+
+ cmd = program + '('
+ for i in range(len(args)):
+ val = args[i]
+ if type(val) == bool:
+ if val == True: val = "true"
+ elif val == False: val = "false"
+ cmd += str(val) + (',' if (i<(len(args)-1)) else '')
+ cmd+=')'
+
+ #TODO: in new robot exec taskCreate is freezing controller
+ #REMOVE if bug is fixed
+ self.execute('task_create',name, str(priority), program, *args)
+ #self.evaluate('taskCreate "' + name + '", ' + str(priority) + ', ' + cmd)
+
+
+
+ def task_suspend(self, name):
+ self.evaluate('taskSuspend("' + str(name)+ '")')
+
+ #waits until the task is ready for restart
+ def task_resume(self, name):
+ self.evaluate('taskResume("' + str(name)+ '",0)', timeout = 2000)
+
+ #waits for the task to be actually killed
+ def task_kill(self, name):
+ #self.evaluate('taskKill("' + str(name)+ '")', timeout = 5000)
+ self.execute('kill', str(name), timeout=5000)
+
+ def get_task_status(self, name):
+ if self.isSimulated():
+ return (-1,"Stopped")
+ code = self.eval_int('taskStatus("' + str(name)+ '")')
+ #TODO: String assignments in $exec causes application to freeze
+ #status = self
+ if code== -1: status = "Stopped"
+ elif code== 0: status = "Paused"
+ elif code== 1: status = "Running"
+ #else: status = self.execute('get_help', code)
+ else: status = "Error"
+ return (code,status)
+
+ def get_tasks_status(self, *pars):
+ ret = self.execute("task_sts", *pars)
+ ret = ret[0:len(pars)]
+ for i in range(len(ret)):
+ try:
+ ret[i] = int(ret[i])
+ except:
+ ret[i] = None
+ return ret
+
+ def _update_state(self):
+ #self.setState(State.Busy if self.status=="move" else State.Ready)
+ if self.state==State.Offline:
+ print "Communication resumed"
+ if self.reset or (self.state==State.Offline):
+ self.check_task()
+ if self.current_task is not None:
+ print "Ongoing task: " + self.current_task
+ if (not self.settled) or (self.current_task is not None): self.setState(State.Busy)
+ elif not self.empty: self.setState(State.Paused)
+ else: self.setState(State.Ready)
+
+ def doUpdate(self):
+ try:
+ start = time.time()
+ cur_task = self.current_task #Can change in background so cache it
+ if self.isSimulated():
+ sts = [1, 1,"1", 100, "1", "1", 0, 0, \
+ 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, \
+ ]
+ else:
+ sts = self.execute("get_status", cur_task)
+ self._update_working_mode(int(sts[0]), int(sts[1]))
+ self.powered = sts[2] == "1"
+ self.speed = int(sts[3])
+ self.empty = sts[4] == "1"
+ self.settled = sts[5] == "1"
+
+ #TODO: add tool open
+ if cur_task is not None:
+ if int(sts[6]) < 0:
+ log("Task "+ str(cur_task) + " finished with code: " + str(sts[7]), False)
+ try:
+ self.current_task, self.current_task_ret = None, int(sts[7])
+ except:
+ self.current_task, self.current_task_ret = None, None
+ for i in range(6):
+ self.joint_pos[i] = float(sts[8 + i])
+ for i in range(6):
+ self.cartesian_pos[i] = float(sts[14 + i])
+
+ ev_index = 20 #7
+ ev = sts[ev_index] if len(sts)>ev_index else ""
+ if len(ev.strip()) >0:
+ self.getLogger().info(ev)
+ self.on_event(ev)
+
+ self._update_state()
+ self.reset = False
+ self.setCache({"powered": self.powered,
+ "speed": self.speed,
+ "empty": self.empty,
+ "settled": self.settled,
+ "task": cur_task,
+ "mode": self.working_mode,
+ "status": self.status,
+ "open": self.tool_open,
+ "pos": self.get_current_point_cached() if self.state==State.Ready else None #TODO: make it calculated in robot by polling funtion
+ }, None)
+
+ if self.cartesian_motors_enabled:
+ for m in self.cartesian_motors:
+ m.readback.update()
+
+ if self.joint_motors_enabled:
+ for m in self.joint_motors:
+ m.readback.update()
+
+ except:
+ if self.state != State.Offline:
+ print >> sys.stderr, "Update error: " + str(sys.exc_info()[1])
+ self.setState(State.Offline)
+
+ #Cartesian space
+ """
+ def get_cartesian_pos(self):
+ self.assert_tool()
+ return self.eval_pnt("jointToPoint(" + self.tool + ", " + self.frame + ", herej())")
+ #self.set_jnt(self.herej())
+ #return self.joint_to_point(tool, frame)
+ """
+
+
+ #TODO: in new robot robot.evaluate("tcp_p=jointToPoint(tSuna, world, herej())") is freezing controller (cannot call herej directly)
+ #We can consider atomic because tcp_j is only accessed in comTcp
+ def get_cartesian_pos(self, tool=None, frame=None):
+ if tool is None:
+ self.assert_tool()
+ tool = self.tool
+ if frame is None:
+ frame = self.frame
+ #Do not work
+ #self.evaluate("tcp_j=herej(); tcp_p=jointToPoint(" + tool + ", " + frame + ", tcp_j)")
+ #return self.get_pnt()
+ a = self.execute('get_pos', tool, frame)
+ ret = []
+ for i in range(6): ret.append(float(a[i]))
+ return ret
+
+
+ def get_flange_pos(self, frame=None):
+ return get_cartesian_pos(FLANGE, frame)
+
+
+ def get_cartesian_destination(self, tool=None, frame=None):
+ if tool is None:
+ self.assert_tool()
+ tool = self.tool
+ if frame is None:
+ frame = self.frame
+ return self.here(tool, frame)
+
+ def get_distance_to_pnt(self, name):
+ #self.here(self.tool, self.frame) #???
+ self.set_pnt(self.get_cartesian_pos() )
+ return self.distance_p("tcp_p", name)
+
+ def is_in_point(self, p, tolerance = None): #Tolerance in mm
+ if (tolerance is None) and p in self.known_points:
+ #If checking a known point with default tolerance, updates the position cache
+ return p in self.get_current_points()
+ tolerance = self.default_tolerance if tolerance == None else tolerance
+ d = self.get_distance_to_pnt(p)
+ if d<0:
+ raise Exception ("Error calculating distance to " + p + " : " + str(d))
+ return d=0:
+ # raise Exception("Ongoing high-level task: " + task)
+ ts = self.get_tasks_status(*tasks)
+ for i in range(len(ts)):
+ if ts[i] > 0:
+ raise Exception("Ongoing high-level task: " + tasks[i])
+
+ self.clear_task_ret()
+
+ for i in range(self.task_start_retries):
+ self.task_create(program, *args, **kwargs)
+ (code, status) = self.get_task_status(program)
+ if code>=0: break
+ if i < self.task_start_retries-1:
+ ret = self.get_task_ret(False)
+ if ret == 0: #Did't start
+ log("Retrying starting : " + str(program) + str(args) + " - status: " + str(status) + " (" + str(code) + ")", False)
+ print "Retrying starting : " + str(program) + str(args) + " - status: " + str(status) + " (" + str(code) + ")"
+ else :
+ print "Retrying aborted : " + str(program) + str(args) + " - ret: " + str(ret) + " - status: " + str(status) + " (" + str(code) + ")"
+ break
+ else:
+ log("Failed starting : " + str(program) + str(args), False)
+ print "Failed starting : " + str(program) + str(args)
+ if self.exception_on_task_start_failure:
+ raise Exception("Cannot start task: " + program + str(args))
+
+ log("Task started: " + str(program) + str(args) + " - status: " + str(status) + " (" + str(code) + ")", False)
+ self.current_task, self.current_task_ret = program, None
+ self.update()
+ #self._update_state()
+
+ #TODO: remove
+ if self.current_task is None:
+ log("Task finished in first polling : " + str(program) , False)
+ print "Task finished in first polling : " + str(program)
+
+ return code
+
+ def stop_task(self):
+ tasks = [t for t in self.high_level_tasks]
+ if (self.current_task is not None) and (not self.current_task in tasks):
+ tasks.append(self.current_task)
+ for task in tasks:
+ #if self.get_task_status(task)[0]>=0:
+ self.task_kill(task)
+ self.reset_motion()
+
+ def get_task_ret(self, cached = True):
+ return self.current_task_ret if cached else self.eval_int("tcp_ret")
+
+ def clear_task_ret(self):
+ return self.evaluate("tcp_ret=0")
+
+ def get_task(self):
+ return self.current_task
+
+ def check_task(self):
+ if self.current_task is None:
+ for task in self.high_level_tasks:
+ if self.get_task_status(task)[0]>=0:
+ self.current_task, self.current_task_ret = task, None
+ log("Task detected: " + str(self.current_task), False)
+ return self.current_task
+
+ def wait_task_finished (self, polling = None):
+ cur_polling = self.polling
+ if polling is not None:
+ self.polling = polling
+ try:
+ while self.get_task() != None:
+ time.sleep(self.polling_interval)
+ finally:
+ if polling is not None:
+ self.polling = cur_polling
+ ret = self.get_task_ret()
+ return ret
+
+ def assert_no_task(self):
+ task = self.check_task()
+ if task != None:
+ raise Exception("Ongoing task: " + task)
+
+ def on_event(self,ev):
+ pass
+
+ def on_change_working_mode(self, working_mode):
+ pass
+
\ No newline at end of file
diff --git a/script/devices/SmartMagnet.py b/script/devices/SmartMagnet.py
new file mode 100644
index 0000000..0736fdf
--- /dev/null
+++ b/script/devices/SmartMagnet.py
@@ -0,0 +1,129 @@
+class SmartMagnet(DeviceBase):
+ def __init__(self, name):
+ #DeviceBase.__init__(self, name, get_context().pluginManager.getDynamicClass("SmartMagnetConfig")())
+ DeviceBase.__init__(self, name, DeviceConfig({
+ "holdingCurrent":0.0,
+ "restingCurrent":0.0,
+ "mountCurrent":0.0,
+ "unmountCurrent":0.0,
+ "reverseCurrent":0.0,
+ "reverseTime":0.0,
+ }))
+
+ def doInitialize(self):
+ super(SmartMagnet, self).doInitialize()
+ self.get_current()
+
+ def set_current(self, current):
+ self.setCache(current, None)
+ smc_current.write(current)
+
+ def get_current(self):
+ cur = smc_current.read()
+ self.setCache(cur, None)
+ return cur
+
+ def get_current_rb(self):
+ self.assert_status()
+ return smc_current_rb.read()
+
+ def get_status(self):
+ return smc_magnet_status.read()
+
+ def assert_status(self):
+ pass
+ #if self.get_status() == False:
+ # raise Exception("Smart Magnet is in faulty status.")
+
+ def is_mounted(self):
+ self.assert_status()
+ m1 = smc_mounted_1.read()
+ m2 = smc_mounted_2.read()
+ if m2==m1:
+ raise Exception("Smart Magnet has invalid detection.")
+ return m2
+
+ def set_supress(self, value):
+ smc_sup_det.write(value)
+
+ def get_supress(self):
+ return smc_sup_det.read()
+
+ def check_mounted(self, idle_time =1.0, timeout = -1, interval = 0.01):
+ self.assert_status()
+ start = time.time()
+ last = None
+ while True:
+ try:
+ det = self.is_mounted()
+ except:
+ det = None
+ if det != last:
+ settling_timestamp = time.time()
+ last = det
+ else:
+ if det is not None:
+ if (time.time()-settling_timestamp > idle_time):
+ return det
+ if timeout >= 0:
+ if (time.time() - start) > timeout:
+ raise Exception("Timeout waiting for Smart Magnet detection.")
+ time.sleep(interval)
+
+
+ def doUpdate(self):
+ try:
+ if self.get_supress():
+ self.setState(State.Paused)
+ elif self.is_mounted():
+ self.setState(State.Busy)
+ else:
+ self.setState(State.Ready)
+ except:
+ self.setState(State.Fault)
+
+ def set_holding_current(self):
+ self.set_current(self.config.getFieldValue("holdingCurrent"))
+
+ def set_resting_current(self):
+ self.set_current(self.config.getFieldValue("restingCurrent"))
+
+ def set_mount_current(self):
+ self.set_current(self.config.getFieldValue("mountCurrent"))
+
+ def set_unmount_current(self):
+ self.set_current(self.config.getFieldValue("unmountCurrent"))
+
+ def set_reverse_current(self):
+ self.set_current(self.config.getFieldValue("reverseCurrent"))
+
+ def set_default_current(self):
+ if self.is_mounted():
+ self.set_holding_current()
+ else:
+ self.set_resting_current()
+
+ def is_resting_current(self):
+ is_resting = 2.0 > abs( float(self.get_current()) - float(self.config.getFieldValue("restingCurrent")) )
+ return is_resting
+
+
+ def apply_reverse(self):
+ reverse_wait = float(self.config.getFieldValue("reverseTime"))
+ if reverse_wait >0:
+ self.set_reverse_current()
+ time.sleep(reverse_wait)
+
+ #Setting resting current to better detect sample
+ def apply_resting(self):
+ if not self.is_resting_current():
+ self.set_resting_current()
+
+
+
+
+add_device(SmartMagnet("smart_magnet"), force = True)
+
+smart_magnet.polling = 1000
+
+smart_magnet.set_default_current()
diff --git a/script/devices/Wago.py b/script/devices/Wago.py
new file mode 100644
index 0000000..4aae8be
--- /dev/null
+++ b/script/devices/Wago.py
@@ -0,0 +1,175 @@
+LED_LEVEL_ROOM_TEMPERATURE = 0.4
+LED_LEVEL_LN2 = 1.0
+
+
+###################################################################################################
+# Leds
+###################################################################################################
+
+def set_led_level(level):
+ level = max(min(float(level),100.0),0.0)
+ set_setting("led_level", level)
+ led_ctrl_1.write(led_ctrl_1.config.maxValue * level / 100.0)
+ led_ctrl_2.write(led_ctrl_2.config.maxValue * level / 100.0)
+ led_ctrl_3.write(led_ctrl_3.config.maxValue * level / 100.0)
+
+def get_led_level():
+ level = get_setting("led_level")
+ return float(0 if level is None else level)
+
+def set_led_state(value):
+ """
+ Turn leds on and off
+ """
+ if value:
+ set_led_level(100.0)
+ else:
+ set_led_level(0.0)
+
+def get_led_state():
+ """
+ Returns led state (on/off)
+ """
+ return led_ctrl_1.read() > 0
+
+#TODO: The range should be set automatically reading LN2 sensor.
+def set_led_range(room_temp = True):
+ """
+ Led range should be limitted in room temperature
+ """
+ max_val = LED_LEVEL_ROOM_TEMPERATURE if room_temp else LED_LEVEL_LN2
+ led_ctrl_1.config.maxValue = max_val
+ led_ctrl_1.config.save()
+ led_ctrl_2.config.maxValue = max_val
+ led_ctrl_2.config.save()
+ led_ctrl_3.config.maxValue = max_val
+ led_ctrl_3.config.save()
+ led_ctrl_1.initialize()
+ led_ctrl_2.initialize()
+ led_ctrl_3.initialize()
+ if led_ctrl_1.read() > max_val:
+ led_ctrl_1.write(max_val)
+ if led_ctrl_2.read() > max_val:
+ led_ctrl_2.write(max_val)
+ if led_ctrl_3.read() > max_val:
+ led_ctrl_3.write(max_val)
+ set_led_level(get_led_level())
+
+
+def is_led_room_temp():
+ return led_ctrl_1.config.maxValue <= LED_LEVEL_ROOM_TEMPERATURE
+
+
+
+
+###################################################################################################
+# Safety release
+###################################################################################################
+
+def release_local():
+ """
+ Release local safety
+ """
+ release_local_safety.write(False)
+ time.sleep(0.01)
+ release_local_safety.write(True)
+ time.sleep(0.01)
+ release_local_safety.write(False)
+
+def release_psys():
+ """
+ Release psys safety
+ """
+ if is_manual_mode():
+ raise Exception ("Cannot release PSYS in manual mode")
+ release_psys_safety.write(False)
+ time.sleep(0.01)
+ release_psys_safety.write(True)
+ time.sleep(0.01)
+ release_psys_safety.write(False)
+
+
+
+###################################################################################################
+# Drier
+###################################################################################################
+MAX_HEATER_TIME = 120000
+
+def set_air_stream(state):
+ """
+ """
+ valve_1.write(state)
+ valve_2.write(not state)
+
+
+set_heater_chrono = None
+
+def monitor_heater_time():
+ time.sleep(0.5)
+ try:
+ while get_heater():
+ if set_heater_chrono.isTimeout(MAX_HEATER_TIME):
+ set_heater(False)
+ log("Heater timeout expired: turned off", False)
+ return
+ time.sleep(0.1)
+ except:
+ print sys.exc_info()
+
+
+def get_heater():
+ """
+ """
+ return gripper_dryer.read()
+
+
+def set_heater(state):
+ """
+ """
+ global set_heater_chrono
+ if get_heater() != state:
+ gripper_dryer.write(state)
+ if state:
+ set_heater_chrono = Chrono()
+ fork(monitor_heater_time)
+
+
+def get_air_stream():
+ """
+ """
+ return valve_1.read()
+
+
+
+def set_pin_cleaner(state):
+ """
+ """
+ valve_7.write(state)
+ valve_8.write(not state)
+
+
+
+def get_pin_cleaner():
+ """
+ """
+ return valve_7.read()
+
+
+monitor_pin_cleaner_task = None
+
+def monitor_pin_cleaner(timeout):
+ global monitor_pin_cleaner_task
+ this = monitor_pin_cleaner_task
+ time.sleep(timeout)
+ if this == monitor_pin_cleaner_task:
+ set_pin_cleaner(False)
+
+
+DEFAULT_PIN_CLEANER_TIMEOUT = 5.0
+def start_pin_cleaner(timeout=DEFAULT_PIN_CLEANER_TIMEOUT):
+ global monitor_pin_cleaner_task
+ set_pin_cleaner(True)
+ set_pin_cleaner_chrono = Chrono()
+ monitor_pin_cleaner_task = fork((monitor_pin_cleaner,(timeout,),))[0]
+
+
diff --git a/script/hexiposi_positon.scd b/script/hexiposi_positon.scd
new file mode 100644
index 0000000..471fb41
--- /dev/null
+++ b/script/hexiposi_positon.scd
@@ -0,0 +1,11 @@
+[
+ [ [ true, "hexiposi_position", "Device", 1, 1, null ] ],
+ [ [ "1", null, null, null, null, null, null, null ],
+ [ "2", null, null, null, null, null, null, null ],
+ [ "3", null, null, null, null, null, null, null ],
+ [ "4", null, null, null, null, null, null, null ],
+ [ "5", null, null, null, null, null, null, null ] ],
+ [ [ ] ],
+ [ [ "", 1000, 100 ],
+ [ "", "" ] ]
+]
\ No newline at end of file
diff --git a/script/imgproc/CameraCalibration.py b/script/imgproc/CameraCalibration.py
new file mode 100644
index 0000000..a89510d
--- /dev/null
+++ b/script/imgproc/CameraCalibration.py
@@ -0,0 +1,156 @@
+import ch.psi.pshell.device.Camera as Camera
+import ch.psi.pshell.imaging.RendererMode as RendererMode
+import ch.psi.pshell.imaging.Calibration as Calibration
+from ch.psi.pshell.imaging.Overlays import *
+import ch.psi.pshell.imaging.Pen as Pen
+import ch.psi.utils.swing.SwingUtils as SwingUtils
+import javax.swing.SwingUtilities as SwingUtilities
+#from swingutils.threads.swing import callSwing
+#SIMULATION = ch.psi.pshell.imaging.FileSource
+"""
+img.camera.setColorMode(Camera.ColorMode.Mono)
+img.camera.setDataType(Camera.DataType.UInt8)
+img.camera.setGrabMode(Camera.GrabMode.Continuous)
+img.camera.setTriggerMode(Camera.TriggerMode.Fixed_Rate)
+img.camera.setExposure(50.00)
+img.camera.setAcquirePeriod(200.00)
+img.camera.setGain(0.0)
+img.config.rotationCrop=True
+"""
+
+MOVE_HEXIPOSI = not is_manual_mode()
+ROTATION_OFFSET = 180.0
+
+if MOVE_HEXIPOSI:
+ release_safety() #enable_motion()
+
+sensor_width,sensor_height = img.camera.getSensorSize()
+img.camera.setROI(0, 0,sensor_width, sensor_height)
+img.config.rotation=0
+img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight =0,0,-1,-1
+img.config.setCalibration(None)
+img.camera.stop()
+img.camera.start()
+
+
+p = show_panel(img)
+dlg = SwingUtilities.getWindowAncestor(p)
+dlg.setSize(800,800)
+frm=SwingUtils.getFrame(p)
+dlg.setLocationRelativeTo(frm)
+
+p.setMode(RendererMode.Fit)
+ov_text = Text(Pen(java.awt.Color.GREEN.darker()), "", java.awt.Font("Verdana", java.awt.Font.PLAIN, 24), java.awt.Point(20,20))
+ov_text.setFixed(True)
+p.addOverlay(ov_text)
+
+
+try:
+ #Find image center and Prosilica ROI
+ ov_text.update("Click on the center of the Dewar...")
+ p.refresh()
+ dc = p.waitClick(60000)
+ print dc
+ width, height = min(dc.x, sensor_width-dc.x)*2, min(dc.y, sensor_height-dc.y)*2
+ width, height = width - width%16, height - height%16
+ width, height = min(width,1000), min(height,1000)
+ print width, height
+ roi_x = int(dc.x- width/2)
+ roi_y = int(dc.y- height/2)
+ roi_w = int(width)
+ roi_h = int(height)
+ set_setting("roi_x", roi_x)
+ set_setting("roi_y", roi_y)
+ set_setting("roi_w", roi_w)
+ set_setting("roi_h", roi_h)
+ img.camera.setROI(roi_x, roi_y, width, height)
+except:
+ img.camera.setROI(int(get_setting("roi_x")), int(get_setting("roi_y")), int(get_setting("roi_w")), int(get_setting("roi_h")))
+finally:
+ img.camera.stop()
+ img.camera.start()
+
+
+#Configure source
+CC4 = (-129.9, -150)
+CD5 = (129.9, -150)
+CA5 = (-129.9, 150)
+CF4 = (129.9, 150)
+
+DX = 259.8
+DY = 300.0
+
+ROI_X = 470.0
+ROI_Y = 470.0
+
+def rotate(x,y, degrees):
+ rotation = math.radians(degrees)
+ rw, rh = img.getImage().getWidth(), img.getImage().getHeight()
+ ox, oy = x - (rw / 2), y - (rh / 2)
+ x = ox * math.cos(rotation) - oy * math.sin(rotation) + rw / 2;
+ y = oy * math.cos(rotation) + ox * math.sin(rotation) + rh / 2;
+ return x,y
+
+
+set_led_state(True)
+try:
+ if MOVE_HEXIPOSI: set_hexiposi("C")
+ ov_text.update("Click on the center of C4 (19) position...")
+ p.refresh()
+ pc4 = p.waitClick(60000)
+ print pc4
+ if MOVE_HEXIPOSI: set_hexiposi("D")
+ ov_text.update("Click on the center of D5 (13) position...")
+ p.refresh()
+ pd5 = p.waitClick(60000)
+ print pd5
+ if MOVE_HEXIPOSI: set_hexiposi("F")
+ ov_text.update("Click on the center of F4 (04) position...")
+ p.refresh()
+ pf4 = p.waitClick(60000)
+ print pf4
+ if MOVE_HEXIPOSI: set_hexiposi("A")
+ ov_text.update("Click on the center of A5 (28) position...")
+ p.refresh()
+ pa5 = p.waitClick(60000)
+ print pa5
+
+
+ vc1x, vc1y, vc2x, vc2y = (pc4.x + pd5.x )/2.0, (pc4.y + pd5.y )/2.0, (pa5.x + pf4.x )/2.0, (pa5.y + pf4.y )/2.0
+ hc1x, hc1y, hc2x, hc2y = (pc4.x + pa5.x )/2.0, (pc4.y + pa5.y )/2.0, (pd5.x + pf4.x )/2.0, (pd5.y + pf4.y )/2.0
+ cx, cy = (vc1x + vc2x)/2, (hc1y + hc2y)/2
+
+ a1 = math.degrees(math.atan((cx-vc1x)/(vc1y-cy)))
+ a2 = math.degrees(math.atan((cx-vc2x)/(vc2y-cy)))
+ a = (a1+a2)/2
+
+
+ dy = math.hypot(vc2y - vc1y, vc2x - vc1x)
+ dx = math.hypot(hc2x - hc1x, hc2y - hc1y)
+ print dy, dx, cx, cy
+ sx, sy = DX/dx, DY/dy
+
+
+ #Rotating center of puck
+ rcx, rcy = rotate(cx, cy, -a)
+
+
+
+ roi_w, roi_h = int(ROI_X / sx), int(ROI_Y / sy)
+ roi_x, roi_y = int(rcx-roi_w/2), int(rcy-roi_h/2)
+
+ print a, sx, sy, roi_w, roi_h
+
+ img.config.rotation=-a + ROTATION_OFFSET
+ img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight = roi_x, roi_y, roi_w, roi_h
+ img.config.setCalibration(Calibration(sx, sy, -roi_w/2, -roi_h/2))
+ img.config.save()
+
+ set_return ("Success calibrating the camera")
+
+finally:
+ set_led_state(False)
+ p.removeOverlay(ov_text)
+ img.refresh()
+
+
\ No newline at end of file
diff --git a/script/imgproc/CoverDetection.py b/script/imgproc/CoverDetection.py
new file mode 100644
index 0000000..904837a
--- /dev/null
+++ b/script/imgproc/CoverDetection.py
@@ -0,0 +1,98 @@
+###################################################################################################
+# Procedure to detect the cover orientation
+###################################################################################################
+assert_imaging_enabled()
+
+
+#Parameters
+FRAMES_INTEGRATION = 3
+STEP_SIZE = 2
+POSITION_NAMES = [ 'A','B','C','D', 'E', 'F']
+
+#POSITION_ANGLES = [ 330, 30, 90, 150, 210, 270 ]
+POSITION_ANGLES = [ 0, 60, 120, 180, 240, 300 ]
+POSITION_TOLERANCE = 3
+MINIMUM_CONFIDENCE = 3
+DEBUG = cover_detection_debug
+#REFERENCE_IMG = "ref2"
+REFERENCE_IMG = "ref1"
+BORDER = 7
+
+#Load reference image
+ref = load_image(str("{images}/cover/" + REFERENCE_IMG + ".png") , title="Line")
+
+#Pre-process camera image
+#ip = load_image("{images}/cover/Cover_000" + str(index) + ".png", title="Img")
+ip = integrate_frames(FRAMES_INTEGRATION)
+ip = grayscale(ip, True)
+smooth(ip)
+#bandpass_filter(ip, 30, 1000)
+edges(ip)
+auto_threshold(ip, method = "MaxEntropy")
+#binary_erode(ip, True)
+#binary_dilate(ip, True)
+ip.getProcessor().erode(1, 255)
+cx,cy = int(ip.width/2), int(ip.height/2)
+ip = sub_image(ip, cx-ref.width/2, cy-ref.height/2, ref.width, ref.height)
+
+if BORDER>0:
+ sip = sub_image(ip, BORDER,BORDER, ref.width-2*BORDER, ref.height-2*BORDER)
+ ip = pad_image(sip, BORDER, BORDER, BORDER, BORDER, fill_color=Color.WHITE)
+
+#Show ROI of pre-processed image
+if DEBUG:
+ image_panel = show_panel(ip.bufferedImage)
+
+
+#Calculate correlation between image and reference, rotating the reference from 0 to 360
+import ch.psi.pshell.imaging.Utils.integrateVertically as integrateVertically
+ydata = []
+xdata = range (0,360,STEP_SIZE)
+for i in xdata:
+ r = ref.duplicate()
+ r.getProcessor().setBackgroundValue(0.0)
+ r.getProcessor().rotate(float(i))
+ op = op_fft(r, ip, "correlate")
+ bi = op.getBufferedImage()
+ p = integrateVertically(bi)
+ ydata.append(sum(p))
+
+
+#Calculate angle of the highest correlation, and confidence level
+peaks = estimate_peak_indexes(ydata, xdata, (min(ydata) + max(ydata))/2, 25.0)
+peaks_x = map(lambda x:xdata[x], peaks)
+peaks_y = map(lambda x:ydata[x], peaks)
+if len(peaks_x) > 1:
+ #remoce close peaks between 350 deg and 10 deg
+ if ((peaks_x[0]<10) and (peaks_x[1]>350)) or ((peaks_x[1]<10) and (peaks_x[0]>350)):
+ peaks.pop(1)
+ peaks_x.pop(1)
+ peaks_y.pop(1)
+
+
+confidence = None if len(peaks_x)<2 else int(((float(peaks_y[0])/peaks_y[1])-1) * 1000)
+angle = (None if len(peaks_x)==0 else peaks_x[0])
+
+#From angle and confidence level estimate hexiposi position
+position = None
+if angle is not None:
+ for i in range(len(POSITION_NAMES)):
+ if abs(POSITION_ANGLES[i] - angle) <= POSITION_TOLERANCE:
+ position = POSITION_NAMES[i]
+
+#Plot the correlations values agains angle
+if DEBUG:
+ plot(ydata, xdata=xdata)
+
+#Output results
+if DEBUG:
+ print "Peaks", peaks
+ print "Peak indexes: " + str(peaks_x)
+ print "Peak values: " + str(peaks_y)
+ print "Angle: " , angle
+ print "Position: " , position
+ print "Confidence: " , confidence
+
+#Set return value
+set_return ([position, angle, confidence])
+
diff --git a/script/imgproc/CoverDetectionCalibration.py b/script/imgproc/CoverDetectionCalibration.py
new file mode 100644
index 0000000..36f6a54
--- /dev/null
+++ b/script/imgproc/CoverDetectionCalibration.py
@@ -0,0 +1,40 @@
+#Parameters
+FRAMES_INTEGRATION = 3
+MINIMUM_CONFIDENCE = 10
+DEBUG = cover_detection_debug
+REFERENCE_IMG = "ref1"
+ERODE_ITERATIONS = 2
+
+#Load reference image
+SIZE = [128,128]
+BORDER = 7
+
+hexiposi.move("A")
+#Pre-process camera image
+#ip = load_image("{images}/cover/Cover_000" + str(index) + ".png", title="Img")
+ip = integrate_frames(FRAMES_INTEGRATION)
+ip = grayscale(ip, True)
+smooth(ip)
+#bandpass_filter(ip, 30, 1000)
+edges(ip)
+
+auto_threshold(ip, method = "MaxEntropy")
+#binary_dilate(ip, True, 2)
+for i in range(ERODE_ITERATIONS):
+ ip.getProcessor().erode(1, 255)
+
+cx,cy = int(ip.width/2), int(ip.height/2)
+ip = sub_image(ip, cx-SIZE[0]/2, cy-SIZE[1]/2, SIZE[0], SIZE[1])
+
+invert(ip)
+ip = grayscale(ip, True)
+#smooth(ip)
+
+if BORDER > 0:
+ sip = sub_image(ip, BORDER,BORDER, SIZE[0]-2*BORDER, SIZE[1]-2*BORDER)
+ ip = pad_image(sip, BORDER, BORDER, BORDER, BORDER)
+if DEBUG:
+ image_panel = show_panel(ip.bufferedImage)
+
+save_image(ip, str("{images}/cover/" + REFERENCE_IMG + ".png") ,"png")
+
\ No newline at end of file
diff --git a/script/imgproc/CreateMask.py b/script/imgproc/CreateMask.py
new file mode 100644
index 0000000..98b3498
--- /dev/null
+++ b/script/imgproc/CreateMask.py
@@ -0,0 +1,29 @@
+
+mask_img = new_image(img.getOutput().getWidth(), img.getOutput().getHeight(), image_type="byte", title = "mask_img", fill_color = Color.BLACK)
+
+mask_radius = 14
+mask_points = []
+
+
+def to_img_coords(absolute_coords):
+ return [img.getCalibration().convertToImageX(absolute_coords[0]), img.getCalibration().convertToImageY(absolute_coords[1])]
+
+for p in _puck_list:
+ mask_points.append(to_img_coords(p.led_mini))
+ mask_points.append(to_img_coords(p.led_uni))
+
+
+
+i = mask_img.getBufferedImage()
+for p in mask_points:
+ #i.setRGB(p[0], p[1], 0xFFFFFF)
+ for x in range (p[0]-mask_radius, p[0]+mask_radius):
+ for y in range (p[1]-mask_radius, p[1]+mask_radius):
+ if math.hypot(x-p[0], y-p[1]) <= mask_radius:
+ i.setRGB(x,y, 0xFFFFFF)
+
+
+mask_img = load_image(i)
+#show_panel( mask_img.getBufferedImage())
+
+set_return(mask_img)
\ No newline at end of file
diff --git a/script/imgproc/LedDetectionFilter.py b/script/imgproc/LedDetectionFilter.py
new file mode 100644
index 0000000..a4818d8
--- /dev/null
+++ b/script/imgproc/LedDetectionFilter.py
@@ -0,0 +1,102 @@
+###################################################################################################
+# Example of using ImageJ functionalities through ijutils.
+###################################################################################################
+
+import datetime
+from ijutils import *
+import java.awt.Color as Color
+
+import ch.psi.pshell.imaging.Filter as Filter
+from ch.psi.pshell.imaging.Overlays import *
+import ch.psi.pshell.imaging.Pen as Pen
+
+
+integration_count = 10
+integration_continuous = False
+integration_partial = False
+frames = []
+roi = get_roi()
+
+
+color_roi = Color(0, 128, 0)
+
+renderer = show_panel(img)
+renderer.clearOverlays()
+ov_roi_shape = Ellipse(Pen(color_roi, 0,), java.awt.Point(roi[0], roi[1]), java.awt.Dimension(roi[2], roi[3]))
+ov_roi_bound = Rect(Pen(color_roi, 0, Pen.LineStyle.dotted), java.awt.Point(roi[0], roi[1]), java.awt.Dimension(roi[2], roi[3]))
+ov_roi_center = Crosshairs(Pen(color_roi, 0), java.awt.Point(roi_center[0],roi_center[1]), java.awt.Dimension(15,15))
+
+renderer.addOverlays([ov_roi_shape, ov_roi_bound,ov_roi_center])
+
+
+
+
+last_ret = (None, None)
+def detect_led(ip):
+ roi = get_roi()
+ global roi_center, roi_radius, integration_count, integration_continuous, integration_partial, frames
+ global count , last_ret
+ aux = sub_image(ip, roi[0], roi[1], roi[2], roi[3])
+ grayscale(aux)
+ #gaussian_blur(aux)
+ if (integration_count>1):
+ frames.append(aux)
+ if len(frames) >integration_count:
+ del frames[0]
+ if not integration_continuous:
+ if (len(frames)< integration_count):
+ if last_ret[1] is not None: invert(last_ret[1])
+ return last_ret
+ if (not integration_partial) and len(frames) > sys.stderr, traceback.format_exc()
+
+#if is_imaging_enabled():
+if get_device("img") is not None:
+ add_device(img.getContrast(), force = True)
+ add_device(img.getCamera(), force = True)
+
+
+###################################################################################################
+# Utility modules
+###################################################################################################
+
+run("data/samples")
+run("data/pucks")
+run("motion/tools")
+run("motion/mount")
+run("motion/unmount")
+run("motion/get_dewar")
+run("motion/put_dewar")
+run("motion/get_gonio")
+run("motion/put_gonio")
+run("motion/move_dewar")
+run("motion/move_gonio")
+run("motion/move_heater")
+run("motion/move_home")
+run("motion/move_park")
+run("motion/move_cold")
+run("motion/move_scanner")
+run("motion/move_aux")
+run("motion/get_aux")
+run("motion/put_aux")
+run("motion/dry")
+run("motion/trash")
+run("motion/homing_hexiposi")
+run("motion/calibrate_tool")
+run("motion/scan_pin")
+run("motion/robot_recover")
+run("motion/recover")
+run("tools/Math")
+if is_imaging_enabled():
+ run("imgproc/Utils")
+
+def system_check(robot_move=True):
+ if not air_pressure_ok.read():
+ raise Exception("Air pressure is not ok")
+ if not n2_pressure_ok.read():
+ raise Exception("N2 pressure is not ok")
+ hexiposi.assert_in_known_position()
+
+ if robot_move:
+ if not feedback_local_safety.read():
+ raise Exception("Local safety not released")
+ auto = not is_manual_mode()
+ if auto:
+ if not feedback_psys_safety.read():
+ raise Exception("Psys safety not released")
+ if not guiding_tool_park.read():
+ raise Exception("Guiding tool not parked")
+
+def system_check_msg():
+ try:
+ system_check(True)
+ return "Ok"
+ except:
+ return sys.exc_info()[1]
+
+def get_puck_dev(segment, puck):
+ if type(segment) is int:
+ segment = chr( ord('A') + (segment-1))
+
+ return Controller.getInstance().getPuck(str(segment).upper() + str(puck))
+
+def get_puck_elect_detection(segment, puck):
+ return str(get_puck_dev(segment, puck).detection)
+
+def get_puck_img_detection(segment, puck):
+ return str(Controller.getInstance().getPuck(str(segment).upper() + str(puck)).imageDetection)
+
+def assert_puck_detected(segment, puck):
+ if (segment == AUX_SEGMENT) and (puck == 1):
+ return
+ if get_puck_elect_detection(segment, puck) != "Present":
+ raise Exception ("Puck " + str(segment).upper() + str(puck) + " not present")
+
+
+def start_puck_detection():
+ run("tools/RestartPuckDetection")
+
+def check_puck_detection():
+ return run("tools/CheckPuckDetection")
+
+def stop_puck_detection():
+ run("tools/StopPuckDetection")
+
+
+
+def get_detected_pucks():
+ ret = []
+ for i in range(30):
+ p = BasePlate.getPucks()[i]
+ if (str(p.getDetection()) == "Present"):
+ ret.append(str(p.getName()))
+ return ret
+
+def get_pucks_info():
+ ret = []
+ for i in range(30):
+ p = BasePlate.getPucks()[i]
+ name = p.getName()
+ det = str(p.getDetection())
+ barcode = "" if p.getId() is None else p.getId()
+
+ ret.append({"puckAddress": name, "puckState": det, "puckBarcode":barcode})
+ return json.dumps(ret)
+
+
+###################################################################################################
+# Device initialization
+###################################################################################################
+
+try:
+ set_heater(False)
+ set_air_stream(False)
+ set_pin_cleaner(False)
+except:
+ print >> sys.stderr, traceback.format_exc()
+
+
+try:
+ release_local_safety.write(False)
+ release_psys_safety.write(False)
+except:
+ print >> sys.stderr, traceback.format_exc()
+
+try:
+ hexiposi.set_offset(16.5)
+ hexiposi.polling=500
+except:
+ print >> sys.stderr, traceback.format_exc()
+
+try:
+ robot.setPolling(DEFAULT_ROBOT_POLLING)
+ robot.set_tool(TOOL_DEFAULT)
+ robot.set_frame(FRAME_DEFAULT)
+ robot.set_motors_enabled(True)
+ robot.set_joint_motors_enabled(True)
+except:
+ print >> sys.stderr, traceback.format_exc()
+
+if is_imaging_enabled():
+ try:
+ import ch.psi.pshell.device.Camera as Camera
+ #img.camera.setColorMode(Camera.ColorMode.Mono)
+ #img.camera.setDataType(Camera.DataType.UInt8)
+ img.camera.setGrabMode(Camera.GrabMode.Continuous)
+ img.camera.setTriggerMode(Camera.TriggerMode.Fixed_Rate)
+ img.camera.setExposure(25.00)
+ img.camera.setAcquirePeriod(200.00)
+ img.camera.setGain(0.0)
+ #img.camera.setROI(200, 0,1200,1200)
+ """
+ img.camera.setROI(300, 200,1000,1000)
+ img.config.rotation=17
+ img.config.rotationCrop=True
+ img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight = 50,50,900,900
+ """
+ img.camera.setROI(int(get_setting("roi_x")), int(get_setting("roi_y")), int(get_setting("roi_w")), int(get_setting("roi_h")))
+
+ img.camera.stop()
+ img.camera.start()
+ except:
+ print >> sys.stderr, traceback.format_exc()
+
+#TODO: The Smart Magnet keeps moving sample if detecting is enabled
+# Detection keeps disabled unless during moount/unmount
+try:
+ smart_magnet.set_supress(True)
+except:
+ print >> sys.stderr, traceback.format_exc()
+
+#gripper_cam.paused = True
+###################################################################################################
+# Device monitoring
+###################################################################################################
+
+DEWAR_LEVEL_RT = 5.0
+is_room_temperature = False
+
+def is_room_temp():
+ return is_room_temperature
+
+
+class DewarLevelListener (DeviceListener):
+ def onValueChanged(self, device, value, former):
+ global is_room_temperature
+ if value is not None:
+ is_room_temperature = value <= DEWAR_LEVEL_RT
+dewar_level_listener = DewarLevelListener()
+
+for l in dewar_level.listeners:
+ #if isinstance(l, DewarLevelListener): #Class changes...
+ if Nameable.getShortClassName(l.getClass()) == "DewarLevelListener":
+ dewar_level.removeListener(l)
+
+dewar_level.addListener(dewar_level_listener)
+dewar_level_listener.onValueChanged(dewar_level, dewar_level.take(), None)
+
+
+
+
+class HexiposiListener (DeviceListener):
+ def onValueChanging(self, device, value, former):
+ robot.assert_cleared()
+
+hexiposi_listener = HexiposiListener()
+hexiposi.addListener(hexiposi_listener)
+
+###################################################################################################
+# Global variables & application state
+###################################################################################################
+
+
+context = get_context()
+
+cover_detection_debug = False
+
+in_mount_position = False
+
+
+def assert_mount_position():
+ print "Source: ", get_exec_pars().source
+ if not in_mount_position and get_exec_pars().source == CommandSource.server :
+ raise Exception("Not in mount position")
+
+
+def is_puck_loading():
+ return robot.state == State.Ready and robot.take()["pos"] == 'pPark' and \
+ feedback_psys_safety.take() == False and \
+ not guiding_tool_park.read()
+
+def set_pin_offset(val):
+ if abs(val) >5:
+ raise Exception("Invalid pin offset: " + str(val))
+ try:
+ set_setting("pin_offset",float(val))
+ except:
+ log("Error setting pin offset: " + str(sys.exc_info()[1]), False)
+
+def get_pin_offset():
+ try:
+ ret = float(get_setting("pin_offset"))
+ if abs(ret) >5:
+ raise Exception("Invalid configured pin offset: " + str(ret))
+ return ret
+ except:
+ log("Error getting pin offset: " + str(sys.exc_info()[1]), False)
+ return 0.0
+
+
+def set_pin_angle_offset(val):
+ if (abs(val) > 180.0) or (abs(val) < -180.0):
+ raise Exception("Invalid pin angle offset: " + str(val))
+ try:
+ set_setting("pin_angle_offset",float(val))
+ except:
+ log("Error setting pin angle offset: " + str(sys.exc_info()[1]), False)
+
+def get_pin_angle_offset():
+ try:
+ ret = float(get_setting("pin_angle_offset"))
+ if (abs(ret) > 180.0) or (abs(ret) < -180.0):
+ raise Exception("Invalid configured pin angle offset: " + str(ret))
+ return ret
+ except:
+ log("Error getting pin angle offset: " + str(sys.exc_info()[1]), False)
+ return 0.0
+
+def is_force_dry():
+ try:
+ dry_mount_counter = int(get_setting("dry_mount_counter"))
+ except:
+ dry_mount_counter = 0
+
+ try:
+ dry_timespan = time.time() - float( get_setting("dry_timestamp"))
+ except:
+ dry_timespan = 3600
+
+ try:
+ force_dry_mount_count = int(get_setting("force_dry_mount_count"))
+ if force_dry_mount_count>0 and dry_mount_counter>=force_dry_mount_count:
+ return True
+ except:
+ pass
+
+ try:
+ force_dry_timeout = float(get_setting("force_dry_timeout"))
+ if force_dry_timeout>0 and dry_timespan>=force_dry_timeout:
+ return True
+ except:
+ pass
+ return False
+
+def assert_detector_safe():
+ if detector_cleared.read() == False:
+ raise Exception ("Detector not in safe position: move it back")
+
+
+def onPuckLoadingChange(puck_loading):
+ set_led_state(puck_loading)
+ #pass
+
+update()
+add_device(Controller.getInstance().basePlate, True)
+restore_samples_info()
+
+
+print "Initialization complete"
+
\ No newline at end of file
diff --git a/script/motion/calibrate_tool.py b/script/motion/calibrate_tool.py
new file mode 100644
index 0000000..5357ef0
--- /dev/null
+++ b/script/motion/calibrate_tool.py
@@ -0,0 +1,32 @@
+def calibrate_tool():
+ """
+ """
+ print "calibrate_tool"
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ #Enabling
+ enable_motion()
+
+ (detected, dm) = move_scanner()
+
+ if detected:
+ print "Pin detected, trashing..."
+ trash()
+ (detected, dm) = move_scanner()
+ if detected:
+ raise Exception("Cannot trash pin")
+
+ robot.open_tool()
+ robot.get_calibration_tool()
+
+ run("calibration/ToolCalibration3")
+
+ robot.put_calibration_tool()
+
+ robot.save_program()
diff --git a/script/motion/dry.py b/script/motion/dry.py
new file mode 100644
index 0000000..a34a3ed
--- /dev/null
+++ b/script/motion/dry.py
@@ -0,0 +1,58 @@
+DEFAULT_DRY_HEAT_TIME = 40.0
+DEFAULT_DRY_SPEED = 0.3
+DEFAULT_DRY_WAIT_COLD = 40.0
+
+def dry(heat_time=None, speed=None, wait_cold = None):
+ """
+ heat_time (float): in seconds
+ speed (float): % of nominal speed
+ wait_cold(float): if negative, move to dewar after drying
+ Else move to cold and wait (in seconds) before returning.
+ """
+ print "dry"
+
+ if heat_time is None:
+ heat_time = DEFAULT_DRY_HEAT_TIME
+
+ if speed is None:
+ speed = DEFAULT_DRY_SPEED
+
+ if wait_cold is None:
+ wait_cold = DEFAULT_DRY_WAIT_COLD
+
+ if robot.simulated:
+ time.sleep(10.0)
+ return
+
+ #Initial chec
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ set_status("Drying")
+
+ #Enabling
+ enable_motion()
+
+ try:
+ set_heater(True)
+ robot.move_heater(speed, False)
+ time.sleep(heat_time)
+ robot.move_heater(speed, True)
+ set_air_stream(True)
+ robot.move_heater(speed, False)
+ finally:
+ set_heater(False)
+ set_air_stream(False)
+
+
+ set_setting("dry_mount_counter", 0)
+ set_setting("dry_timestamp",time.time())
+
+ if wait_cold >=0 :
+ robot.move_cold()
+ time.sleep(wait_cold)
+ else:
+ robot.move_park()
\ No newline at end of file
diff --git a/script/motion/get_aux.py b/script/motion/get_aux.py
new file mode 100644
index 0000000..67bfc7d
--- /dev/null
+++ b/script/motion/get_aux.py
@@ -0,0 +1,21 @@
+def get_aux(sample):
+ """
+ """
+ print "get_aux: ",sample
+
+ #Initial checks
+ assert_valid_sample(sample)
+
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ hexiposi.assert_homed()
+
+ #Enabling
+ enable_motion()
+
+ if not robot.is_aux():
+ robot.move_aux()
+
+ robot.get_aux(sample)
diff --git a/script/motion/get_dewar.py b/script/motion/get_dewar.py
new file mode 100644
index 0000000..d0559fc
--- /dev/null
+++ b/script/motion/get_dewar.py
@@ -0,0 +1,30 @@
+def get_dewar(segment, puck, sample, force=False):
+ """
+ """
+ print "get_dewar: ", segment, puck, sample, force
+
+ #Initial checks
+ assert_valid_address(segment, puck, sample)
+ assert_puck_detected(segment, puck)
+
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+ hexiposi.assert_homed()
+ #location = robot.get_current_point()
+
+
+ #Enabling
+ enable_motion()
+
+ set_hexiposi(segment)
+
+ if not force:
+ visual_check_hexiposi(segment)
+
+ if not robot.is_dewar():
+ robot.move_dewar()
+
+ robot.get_dewar(segment, puck, sample)
diff --git a/script/motion/get_gonio.py b/script/motion/get_gonio.py
new file mode 100644
index 0000000..2123e2a
--- /dev/null
+++ b/script/motion/get_gonio.py
@@ -0,0 +1,20 @@
+def get_gonio(force=False):
+ """
+ """
+ print "get_gonio: ", force
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ #Enabling
+ enable_motion()
+
+
+ if not robot.is_gonio():
+ robot.move_gonio()
+
+ robot.get_gonio()
diff --git a/script/motion/homing_hexiposi.py b/script/motion/homing_hexiposi.py
new file mode 100644
index 0000000..5c99f9e
--- /dev/null
+++ b/script/motion/homing_hexiposi.py
@@ -0,0 +1,18 @@
+def homing_hexiposi():
+ """
+ """
+ print "homing_hexiposi"
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+ #location = robot.get_current_point()
+
+ set_status("Homing hexiposi")
+ hexiposi.move_home()
+ hexiposi.waitState(State.Ready,-1)
+ hexiposi.move_pos(1)
+
+
\ No newline at end of file
diff --git a/script/motion/mount.py b/script/motion/mount.py
new file mode 100644
index 0000000..ab93351
--- /dev/null
+++ b/script/motion/mount.py
@@ -0,0 +1,153 @@
+mount_sample_id = None
+mount_sample_detected = None
+
+def mount(segment, puck, sample, force=False, read_dm=False, auto_unmount=False):
+ """
+ """
+ global mount_sample_id, mount_sample_detected
+ print "mount: ", segment, puck, sample, force
+
+ start = time.time()
+ #time.sleep(2)
+ is_aux = (segment == AUX_SEGMENT)
+
+ #ZACH
+ needs_chilling = not is_aux and (not robot.is_cold())
+ needs_drying = is_aux and robot.is_cold()
+
+ puck_address = get_puck_address(puck)
+ if puck_address is None:
+ puck_obj = get_puck_obj_by_id(puck)
+ if puck_obj is not None:
+ puck_address = puck_obj.name
+ if puck_address is not None:
+ print "puck address: ", puck_address
+ segment = puck_address[:1]
+ puck = int(puck_address[1:])
+ #Initial checks
+ assert_detector_safe()
+ assert_valid_address(segment, puck, sample)
+ assert_puck_detected(segment, puck)
+
+ if robot.simulated:
+ time.sleep(3.0)
+ mount_sample_detected = True
+ mount_sample_id = "YYY0001"
+ update_samples_info_sample_mount(get_puck_name(segment, puck), sample, mount_sample_detected, mount_sample_id)
+ set_setting("mounted_sample_position", get_sample_name(segment, puck, sample))
+ return [mount_sample_detected, mount_sample_id]
+
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+ hexiposi.assert_homed()
+ assert_mount_position()
+ do_unmount = False
+
+ try:
+ #ZACH
+ if needs_chilling:
+ robot.move_cold()
+ time.sleep(30.0)
+
+ if smart_magnet.get_supress() == True:
+ smart_magnet.set_supress(False)
+ time.sleep(0.2)
+ #To better dectect sample
+ #smart_magnet.apply_reverse()
+ #smart_magnet.apply_resting()
+ #time.sleep(0.5)
+
+ sample_det = smart_magnet.check_mounted(idle_time=0.25, timeout = 1.0)
+ Controller.getInstance().logEvent("Sample Detection", str(sample_det))
+ if sample_det == True:
+ if auto_unmount and (get_setting("mounted_sample_position") is not None):
+ #auto_unmount set to true so detection remains enabled
+ sample_det = unmount(force = True, auto_unmount = True)
+ do_unmount = True
+ if sample_det == True:
+ raise Exception("Pin detected on gonio")
+
+ set_status("Mounting: " + str(segment) + str(puck) + str(sample))
+ Controller.getInstance().logEvent("Mount Sample", str(segment) + str(puck) + str(sample))
+ #location = robot.get_current_point()
+
+ #Enabling. If did unmount then it is already enabled.
+ if not do_unmount:
+ enable_motion()
+
+ #ZACH
+ # a room temp pin is being mounted but the gripper is cold
+ if needs_drying:
+ dry(wait_cold=-1) # move to park after dry
+
+ if is_aux:
+ if not robot.is_aux():
+ robot.move_aux()
+
+ robot.get_aux(sample)
+
+ else:
+ set_hexiposi(segment)
+
+ if not force:
+ visual_check_hexiposi(segment)
+
+ if not robot.is_dewar():
+ robot.move_dewar()
+
+ robot.get_dewar(segment, puck, sample)
+
+
+ if read_dm:
+ barcode_reader.start_read(10.0)
+ robot.move_scanner()
+ #time.sleep(1.0)
+
+ robot.move_gonio()
+
+ if read_dm:
+ mount_sample_id = barcode_reader.get_readout()
+ print "Datamatrix: " , mount_sample_id
+ else:
+ mount_sample_id = None
+
+
+ robot.put_gonio()
+ cleaner_timer = float(get_setting("pin_cleaner_timer"))
+ if cleaner_timer > 0:
+ start_pin_cleaner(cleaner_timer)
+
+
+ try:
+ dry_mount_count = int(get_setting("dry_mount_counter"))
+ except:
+ dry_mount_count = 0
+ set_setting("dry_mount_counter", dry_mount_count+1)
+
+ if is_aux:
+ robot.move_home()
+ else:
+ robot.move_cold()
+
+ mount_sample_detected = smart_magnet.check_mounted(idle_time=0.25, timeout = 1.0)
+ Controller.getInstance().logEvent("Sample Detection", str(mount_sample_detected))
+ update_samples_info_sample_mount(get_puck_name(segment, puck), sample, mount_sample_detected, mount_sample_id)
+ if mount_sample_detected == False:
+ raise Exception("No pin detected on gonio")
+
+
+ if is_force_dry():
+ smart_magnet.set_default_current()
+ print "Auto dry"
+ log("Starting auto dry", False)
+ set_exec_pars(then = "dry()")
+
+ set_setting("mounted_sample_position", get_sample_name(segment, puck, sample))
+ return [mount_sample_detected, mount_sample_id]
+ finally:
+ smart_magnet.set_default_current()
+ smart_magnet.set_supress(True)
+
diff --git a/script/motion/move_aux.py b/script/motion/move_aux.py
new file mode 100644
index 0000000..94d6468
--- /dev/null
+++ b/script/motion/move_aux.py
@@ -0,0 +1,18 @@
+def move_aux():
+ """
+ """
+ print "move_aux"
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ #Enabling
+ enable_motion()
+
+
+ if not robot.is_aux():
+ robot.move_aux()
\ No newline at end of file
diff --git a/script/motion/move_cold.py b/script/motion/move_cold.py
new file mode 100644
index 0000000..89c8920
--- /dev/null
+++ b/script/motion/move_cold.py
@@ -0,0 +1,22 @@
+def move_cold():
+ """
+ """
+ print "move_cold"
+
+ if robot.simulated:
+ time.sleep(3.0)
+ return
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ #Enabling
+ enable_motion()
+
+
+ if not robot.is_cold():
+ robot.move_cold()
\ No newline at end of file
diff --git a/script/motion/move_dewar.py b/script/motion/move_dewar.py
new file mode 100644
index 0000000..3dfcbfe
--- /dev/null
+++ b/script/motion/move_dewar.py
@@ -0,0 +1,18 @@
+def move_dewar():
+ """
+ """
+ print "move_dewar"
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ #Enabling
+ enable_motion()
+
+
+ if not robot.is_dewar():
+ robot.move_dewar()
\ No newline at end of file
diff --git a/script/motion/move_gonio.py b/script/motion/move_gonio.py
new file mode 100644
index 0000000..82397f9
--- /dev/null
+++ b/script/motion/move_gonio.py
@@ -0,0 +1,18 @@
+def move_gonio():
+ """
+ """
+ print "move_gonio"
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ #Enabling
+ enable_motion()
+
+
+ if not robot.is_gonio():
+ robot.move_gonio()
diff --git a/script/motion/move_heater.py b/script/motion/move_heater.py
new file mode 100644
index 0000000..000e500
--- /dev/null
+++ b/script/motion/move_heater.py
@@ -0,0 +1,18 @@
+def move_heater():
+ """
+ """
+ print "move_heater"
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ #Enabling
+ enable_motion()
+
+
+ if not robot.is_heater():
+ robot.move_heater()
diff --git a/script/motion/move_home.py b/script/motion/move_home.py
new file mode 100644
index 0000000..30592d6
--- /dev/null
+++ b/script/motion/move_home.py
@@ -0,0 +1,18 @@
+def move_home():
+ """
+ """
+ print "move_home"
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ #Enabling
+ enable_motion()
+
+
+ if not robot.is_home():
+ robot.move_home()
diff --git a/script/motion/move_park.py b/script/motion/move_park.py
new file mode 100644
index 0000000..e1715c0
--- /dev/null
+++ b/script/motion/move_park.py
@@ -0,0 +1,18 @@
+def move_park():
+ """
+ """
+ print "move_park"
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ #Enabling
+ enable_motion()
+
+
+ if not robot.is_park():
+ robot.move_park()
\ No newline at end of file
diff --git a/script/motion/move_scanner.py b/script/motion/move_scanner.py
new file mode 100644
index 0000000..b8fe41f
--- /dev/null
+++ b/script/motion/move_scanner.py
@@ -0,0 +1,30 @@
+
+def move_scanner():
+ """
+ """
+ print "move_scanner"
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ #Enabling
+ enable_motion()
+
+ barcode_reader.start_read(10.0)
+ if not robot.is_scanner():
+ robot.move_scanner()
+
+ time.sleep(0.25)
+ dm = barcode_reader.get_readout()
+ if dm is None:
+ detected = is_pin_detected_in_scanner()
+ else:
+ detected = True
+
+ print ("Detected: " + str( detected) + " - Datamatrix: " + str(dm))
+
+ return (detected, dm)
diff --git a/script/motion/put_aux.py b/script/motion/put_aux.py
new file mode 100644
index 0000000..c41ee81
--- /dev/null
+++ b/script/motion/put_aux.py
@@ -0,0 +1,21 @@
+def put_aux(sample):
+ """
+ """
+ print "put_aux: ",sample
+
+ #Initial checks
+ assert_valid_sample(sample)
+
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ hexiposi.assert_homed()
+
+ #Enabling
+ enable_motion()
+
+ if not robot.is_aux():
+ robot.move_aux()
+
+ robot.put_aux(sample)
diff --git a/script/motion/put_dewar.py b/script/motion/put_dewar.py
new file mode 100644
index 0000000..7d5c74d
--- /dev/null
+++ b/script/motion/put_dewar.py
@@ -0,0 +1,30 @@
+def put_dewar(segment, puck, sample, force=False):
+ """
+ """
+ print "put_dewar: ", segment, puck, sample, force
+
+ #Initial checks
+ assert_valid_address(segment, puck, sample)
+ assert_puck_detected(segment, puck)
+
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+ hexiposi.assert_homed()
+
+ #Enabling
+ enable_motion()
+
+ set_hexiposi(segment)
+
+ if not force:
+ visual_check_hexiposi(segment)
+
+ #location = robot.get_current_point()
+
+ if not robot.is_dewar():
+ robot.move_dewar()
+
+ robot.put_dewar(segment, puck, sample)
diff --git a/script/motion/put_gonio.py b/script/motion/put_gonio.py
new file mode 100644
index 0000000..c23463f
--- /dev/null
+++ b/script/motion/put_gonio.py
@@ -0,0 +1,23 @@
+def put_gonio(force=False):
+ """
+ """
+ print "put_gonio: ", force
+
+
+ if robot.simulated:
+ time.sleep(3.0)
+ return
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ #Enabling
+ enable_motion()
+
+ if not robot.is_gonio():
+ robot.move_gonio()
+ robot.put_gonio()
diff --git a/script/motion/recover.py b/script/motion/recover.py
new file mode 100644
index 0000000..f4e61af
--- /dev/null
+++ b/script/motion/recover.py
@@ -0,0 +1,179 @@
+import org.apache.commons.math3.geometry.euclidean.threed.Segment as Segment
+import org.apache.commons.math3.geometry.euclidean.threed.Vector3D as Vector3D
+import org.apache.commons.math3.geometry.euclidean.threed.Line as Line3D
+
+RECOVER_DESC = "mRecovery"
+RECOVER_TOOL = TOOL_DEFAULT
+
+known_segments = [ ("pGonioA", "pGonioG", 10), \
+ ("pPark", "pScan", 40), \
+ ("pHome", "pPark", 60), \
+ ("pScan", "pHeater", 50), \
+ ("pHome", "pDewar", 10), \
+ ("pHeater", "pHeatB", 10), \
+ ("pHome", "pAux", 50), \
+ ]
+
+
+def get_robot_position():
+ return robot.get_cartesian_pos()
+
+
+def get_dist_to_line(segment):
+ tolerance = segment[2]
+ p1, p2 = robot.get_pnt(segment[0]), robot.get_pnt(segment[1])
+ p = get_robot_position()
+ v = Vector3D(p[0], p[1], p[2])
+ v1 = Vector3D(p1[0], p1[1], p1[2])
+ v2 = Vector3D(p2[0], p2[1], p2[2])
+ l = Line3D(v1, v2, 0.01)
+ return l.distance(v)
+
+def get_dist_to_segment(segment):
+ tolerance = segment[2]
+ p1, p2 = robot.get_pnt(segment[0]), robot.get_pnt(segment[1])
+ p = get_robot_position()
+ v = Vector3D(p[0], p[1], p[2])
+ v1 = Vector3D(p1[0], p1[1], p1[2])
+ v2 = Vector3D(p2[0], p2[1], p2[2])
+ l = Line3D(v1, v2, 0.01)
+ d = l.distance(v)
+
+ pj = get_projection_at_line(segment)
+
+ d1, d2 = v1.distance(v), v2.distance(v)
+ dp1, dp2 = v1.distance(pj), v2.distance(pj)
+ d12 = v1.distance(v2)
+
+
+ if (dp1 + dp2) > (d12 + tolerance):
+ d = max(d,min(d1,d2))
+ return d
+
+def is_on_segment(segment):
+ tolerance = segment[2]
+ d = get_dist_to_segment(segment)
+
+ if d > tolerance:
+ #print "Current robot position " + str(p) + " not on segment " + str(segment) + " - distance=" + str(d)
+ return False
+ #print "Current robot position " + str(p) + " on segment " + str(segment) + " - distance=" + str(d)
+ return True
+
+def get_projection_at_line(segment):
+ tolerance = segment[2]
+ p1, p2 = robot.get_pnt(segment[0]), robot.get_pnt(segment[1])
+ p = get_robot_position()
+ v = Vector3D(p[0], p[1], p[2])
+ v1 = Vector3D(p1[0], p1[1], p1[2])
+ v2 = Vector3D(p2[0], p2[1], p2[2])
+ l = Line3D(v1, v2, 0.01)
+ a = l.getAbscissa(v)
+ lv = l.pointAt(a)
+ return lv
+
+
+def get_current_segment():
+ for segment in known_segments:
+ if is_on_segment(segment):
+ return segment
+ return None
+
+def get_current_distance():
+ for segment in known_segments:
+ if is_on_segment(segment):
+ return get_dist_to_segment(segment)
+ return None
+
+
+def move_to_segment(segment):
+ tolerance = segment[2]
+ p = get_robot_position()
+ v = Vector3D(p[0], p[1], p[2])
+ lv = get_projection_at_line(segment)
+ dlv = lv.distance(v)
+ if dlv> (tolerance + 0.1):
+ raise Exception( "Error moving from " + str(p) + " to segment - distance=" + str(dlv))
+ d = [lv.x, lv.y, lv.z, p[3], p[4], p[5]]
+ print "Moving from " + str(p) + " to segment " + str(segment) + " - distance=" + str(dlv) + " - dest=" + str(d)
+
+ try:
+ robot.movel(d, tool=RECOVER_TOOL, desc=RECOVER_DESC, sync=True)
+ print "Done"
+ except:
+ print sys.exc_info()[1]
+
+#Moves to first point of the segment ehich is safer, unless in the vicinity of the second
+def move_to_safest_point(segment, vicinity_tolerance = 100):
+ d1, d2 = robot.get_distance_to_pnt(segment[0]), robot.get_distance_to_pnt(segment[1])
+ #Always moving to primary point
+ if False : #(d2<=d1) and (d2 <= vicinity_tolerance):
+ print "Moving to secondary point " + str(segment[1] + " - d1=" + str(d1) + " d2=" + str(d2) )
+ robot.movel(segment[1], tool=RECOVER_TOOL, desc=RECOVER_DESC, sync=True)
+ else:
+ print "Moving to primary point " + str(segment[0] + " - d1=" + str(d1) + " d2=" + str(d2) )
+ robot.movel(segment[0], tool=RECOVER_TOOL, desc=RECOVER_DESC, sync=True)
+ print "Done"
+ #print "Recovered to point " + str(robot.get_curjoint_or_pointrent_point())
+
+def is_in_dewar():
+ z_hom = robot.get_pnt('pHome')[2]
+ z_cur=get_robot_position()[2]
+ if z_cur < (z_hom + 30):
+ return False
+ d_dwr = robot.get_distance_to_pnt('pDewar')
+ if d_dwr > 300:
+ return False
+ return True
+
+
+def recover(move_park = True):
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+
+ if robot.get_current_point() is not None:
+ raise Exception("Robot is in known location")
+
+ set_status("Recovering")
+
+ #Enabling
+ enable_motion()
+
+
+ is_on_known_segment = False
+ for segment in known_segments:
+ if is_on_segment(segment):
+ #try:
+ # robot.set_monitor_speed(5)
+ is_on_known_segment = True
+ move_to_segment(segment)
+ move_to_safest_point(segment)
+ location = robot.get_current_point()
+ if location is None:
+ raise Exception("Robot didn't reach known point")
+ print "Success recovered to point: " + str(location)
+ if move_park:
+ robot.move_park()
+ return "Success recovering to park position"
+ else:
+ return "Success recovering to point: " + str(location)
+ #finally:
+ # robot.set_default_speed()
+ if not is_on_known_segment:
+ print ("Robot is not in known segment")
+ if is_in_dewar():
+ robot.robot_recover()
+ if move_park:
+ robot.move_park()
+ return "Success recovering from dewar to park position"
+ else:
+ return "Success recovering from dewar"
+ else:
+ raise Exception("Robot is not in known segment nor inside the dewar")
+
+
+
+
+
\ No newline at end of file
diff --git a/script/motion/robot_recover.py b/script/motion/robot_recover.py
new file mode 100644
index 0000000..c25d712
--- /dev/null
+++ b/script/motion/robot_recover.py
@@ -0,0 +1,16 @@
+def robot_recover():
+ """
+ """
+ print "robot_recover"
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+
+ set_status("Recovering robot")
+
+ #Enabling
+ enable_motion()
+
+ robot.robot_recover()
diff --git a/script/motion/scan_pin.py b/script/motion/scan_pin.py
new file mode 100644
index 0000000..77bb83c
--- /dev/null
+++ b/script/motion/scan_pin.py
@@ -0,0 +1,99 @@
+###TODO: REMOVE ME
+def system_check(robot_move=True):
+ pass
+
+
+def scan_pin(segment, puck, sample, force=False):
+ pin_name = get_sample_name(segment, puck, sample)
+
+ print "scan pin", pin_name
+ #Initial checks
+ assert_valid_address(segment, puck, sample)
+ #assert_puck_detected(segment, puck)
+ is_aux = (segment == AUX_SEGMENT)
+
+ if robot.simulated:
+ time.sleep(0.5)
+ return "Present"
+
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ ###robot.assert_in_known_point()
+
+ #Enabling
+
+ set_status("Scanning pin: " + str(pin_name))
+
+ enable_motion()
+
+ if is_aux:
+ if not robot.is_aux():
+ robot.move_aux()
+
+ robot.get_aux(sample)
+ else:
+ # set_hexiposi(segment)
+ # if not force:
+ # visual_check_hexiposi(segment)
+
+ if not robot.is_dewar():
+ robot.move_dewar()
+
+ robot.get_dewar(segment, puck, sample)
+
+ (detected, dm) = move_scanner()
+ update_samples_info_sample_scan(get_puck_name(segment, puck), sample, detected, dm)
+
+ if is_aux:
+ robot.move_aux()
+ robot.put_aux( sample)
+ else:
+ robot.move_dewar()
+ robot.put_dewar(segment, puck, sample)
+ ret = "Empty"
+ if detected:
+ if (dm is None) or (len(dm.strip())==0):
+ ret = "Present"
+ else:
+ ret = str(dm)
+ return ret
+
+
+def scan_puck(segment, puck, force=False):
+ if segment == AUX_SEGMENT:
+ raise Exception("Cannot scan auxiliary puck")
+ ret = []
+ for i in range(16):
+ ret.append(scan_pin (segment, puck, i+1, force))
+ return ret
+
+
+def scan_gripper():
+ print "scan gripper"
+ #Initial checks
+
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ #Enabling
+
+ set_status("Scanning gripper")
+
+ enable_motion()
+
+ (detected, dm) = move_scanner()
+
+ robot.move_home()
+
+ ret = "Empty"
+ if detected:
+ if (dm is None) or (len(dm.strip())==0):
+ ret = "Present"
+ else:
+ ret = str(dm)
+ return ret
diff --git a/script/motion/tools.py b/script/motion/tools.py
new file mode 100644
index 0000000..58bb7fc
--- /dev/null
+++ b/script/motion/tools.py
@@ -0,0 +1,180 @@
+POSITION_TOLERANCE = 50
+
+
+def is_manual_mode():
+ """
+ return if operating in local mode. TODO: should be based on IO, not on robot flag.
+ """
+ return robot.working_mode == "manual"
+
+def release_safety():
+ """
+ Release sefety signals acording to working mode
+ """
+ if air_pressure_ok.take() != True:
+ raise Exception("Cannot release safety: air preassure not ok")
+ if n2_pressure_ok.take() != True:
+ raise Exception("Cannot release safety: n2 pressure not ok")
+ auto = not is_manual_mode()
+ if auto:
+ if feedback_psys_safety.read() == False:
+ release_psys()
+ time.sleep(0.5)
+ if feedback_psys_safety.read() == False:
+ raise Exception("Cannot enable power: check doors")
+
+ if feedback_local_safety.read() == False:
+ release_local()
+ time.sleep(0.5)
+ if feedback_local_safety.read() == False:
+ raise Exception("Cannot enable power: check sample changer emergency stop button")
+
+def enable_motion():
+ """
+ Check safety and enable arm power if in remote mode
+ """
+ release_safety()
+ system_check(robot_move=True)
+ auto = not is_manual_mode()
+ if auto:
+ if not robot.state.isNormal():
+ raise Exception("Cannot enable power: robot state is " + str(robot.state))
+ robot.enable()
+
+def set_hexiposi(pos, force = False):
+ """
+ Set the hexiposi position in remote mode, or wait for it to be set in manual mode
+ """
+ robot.assert_cleared()
+ if force == False:
+ if hexiposi.position == pos:
+ return
+
+ if is_manual_mode():
+ set_status("Move Hexiposi to position " + str(pos) + " ...")
+ try:
+ hexiposi.waitInPosition(pos, -1)
+ finally:
+ set_status(None)
+ else:
+ hexiposi.move(pos)
+
+#Can be used if cover has following error (no checking readback)
+def _set_hexiposi(pos):
+ hexiposi.moveAsync(pos)
+ time.sleep(1.0)
+ hexiposi.waitReady(-1)
+
+
+def visual_check_hexiposi(segment):
+ if is_imaging_enabled():
+ #if is_manual_mode(): ?
+ if hexiposi.moved:
+ #Clearing for image processing
+ if not robot.is_park():
+ print "Moving robot to park to clear camera view..."
+ robot.move_park()
+ assert_img_in_cover_pos(segment)
+ hexiposi.moved = False
+
+
+
+def wait_end_of_move():
+ robot.update()
+ while (not robot.settled) or (not robot.empty) or (not robot.isReady()) :
+ time.sleep(0.01)
+
+
+def move_to_home():
+ #robot.reset_motion("jHome")
+ robot.movej("pHome", robot.tool , DESC_SCAN)
+ wait_end_of_move()
+
+def move_to_laser(from_point = "pHome"):
+ robot.reset_motion()
+ tool = robot.tool
+ d = robot.get_distance_to_pnt("pLaser")
+ if d<0:
+ raise Exception ("Error calculating distance to laser: " + str(d))
+ if d6):
+ raise Exception ("Invalid segment: " + str(segment))
+ if (puck<=0) or (puck >5):
+ raise Exception ("Invalid puck: " + str(puck))
+ if (sample<=0) or (sample >16):
+ raise Exception ("Invalid sample: " + str(sample))
+ if get_puck_dev(segment, puck).isDisabled():
+ raise Exception ("Puck is disabled")
+
+def assert_valid_sample(sample):
+ if (sample<=0) or (sample >16):
+ raise Exception ("Invalid sample: " + str(sample))
+
+def get_puck_name(segment, puck):
+ try:
+ assert_valid_address(segment, puck, 1)
+ if type(segment) is int:
+ segment = chr( ord('A') + (segment-1))
+ elif is_string(segment):
+ segment = segment.upper()
+ else:
+ return None
+ return segment + str(puck)
+ except:
+ return None
+
+def get_sample_name(segment, puck, sample):
+ puck_name = get_puck_name(segment, puck)
+ return None if (puck_name is None) else puck_name + str(sample)
+
+
+def is_pin_detected_in_scanner():
+ samples = []
+ for i in range(10):
+ samples.append(laser_distance.read())
+ time.sleep(0.05)
+ av = mean(samples)
+ for s in samples:
+ if s<=1:
+ return False
+ if abs(s-av) > 0.1:
+ return False
+ return True
\ No newline at end of file
diff --git a/script/motion/trash.py b/script/motion/trash.py
new file mode 100644
index 0000000..8b37f2c
--- /dev/null
+++ b/script/motion/trash.py
@@ -0,0 +1,36 @@
+def trash():
+ """
+ """
+ print "trash"
+
+ if robot.simulated:
+ time.sleep(3.0)
+ return
+
+ #Initial checks
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+
+ #Enabling
+ enable_motion()
+
+ robot.move_heater(to_bottom = False)
+ robot.move_heater(to_bottom = True)
+
+ try:
+ for i in range(3):
+ robot.open_tool()
+ time.sleep(0.5)
+ robot.close_tool()
+ time.sleep(0.5)
+ finally:
+ robot.open_tool()
+
+
+ robot.move_heater(to_bottom = False)
+ robot.move_cold()
+
+
\ No newline at end of file
diff --git a/script/motion/unmount.py b/script/motion/unmount.py
new file mode 100644
index 0000000..6f9ce22
--- /dev/null
+++ b/script/motion/unmount.py
@@ -0,0 +1,108 @@
+def unmount(segment = None, puck = None, sample = None, force=False, auto_unmount = False):
+ """
+ Returns if sample is detected in the end
+ """
+ print "unmount: ", segment, puck, sample, force
+
+ #ZACH
+ is_aux = (segment == AUX_SEGMENT)
+ needs_chilling = not is_aux and (not robot.is_cold())
+ needs_drying = is_aux and robot.is_cold()
+
+ if (segment is None) or (puck is None) or (sample is None):
+ pos = get_setting("mounted_sample_position")
+ if pos is None:
+ raise Exception("Mounted sample position is not defined")
+ segment, puck , sample = pos[0:1], int(pos[1]), int(pos[2:])
+ print "Mounted sample position: ", segment, puck , sample
+
+
+ #Initial checks
+ if not auto_unmount:
+ print "assert detector safe"
+ assert_detector_safe()
+ print "assert valid address"
+ assert_valid_address(segment, puck, sample)
+ print "asser puck detected"
+ assert_puck_detected(segment, puck)
+
+ if robot.simulated:
+ time.sleep(3.0)
+ update_samples_info_sample_unmount(get_puck_name(segment, puck), sample)
+ set_setting("mounted_sample_position", None)
+ return False
+
+ print "assert no task"
+ robot.assert_no_task()
+ print "reset motion"
+ robot.reset_motion()
+ print "wait ready"
+ robot.wait_ready()
+ print "assert cleared"
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+ print "assert homed"
+ hexiposi.assert_homed()
+ print "assert mount pos"
+ assert_mount_position()
+
+ set_status("Unmounting: " + str(segment) + str(puck) + str(sample))
+ Controller.getInstance().logEvent("Unmount Sample", str(segment) + str(puck) + str(sample))
+
+ try:
+ if smart_magnet.get_supress() == True:
+ smart_magnet.set_supress(False)
+ time.sleep(0.2)
+
+ #smart_magnet.apply_reverse()
+ #smart_magnet.apply_resting()
+
+ if not force:
+ sample_det = smart_magnet.check_mounted(idle_time=0.5, timeout = 3.0)
+ Controller.getInstance().logEvent("Sample Detection", str(sample_det))
+ if sample_det == False:
+ raise Exception("No pin detected on gonio")
+
+ #Enabling
+ enable_motion()
+
+ if not is_aux:
+ set_hexiposi(segment)
+
+ if not force:
+ visual_check_hexiposi(segment)
+ if needs_chilling:
+ robot.move_cold()
+ time.sleep(30.)
+ else:
+ if needs_drying:
+ dry(wait_cold=-1)
+ #location = robot.get_current_point()
+
+ if not robot.is_gonio():
+ robot.move_gonio()
+
+ #smart_magnet.set_unmount_current()
+
+ robot.get_gonio()
+
+ smart_magnet.apply_reverse()
+ smart_magnet.apply_resting()
+ mount_sample_detected = smart_magnet.check_mounted(idle_time=0.25, timeout = 1.0)
+ Controller.getInstance().logEvent("Sample Detection", str(mount_sample_detected))
+
+ if is_aux:
+ robot.move_aux()
+ robot.put_aux( sample)
+ else:
+ #TODO: Should check if smart magnet detection is off?
+ update_samples_info_sample_unmount(get_puck_name(segment, puck), sample)
+ robot.move_dewar()
+ robot.put_dewar(segment, puck, sample)
+ set_setting("mounted_sample_position", None)
+
+ return mount_sample_detected
+ finally:
+ if not auto_unmount:
+ smart_magnet.set_default_current()
+ smart_magnet.set_supress(True)
diff --git a/script/setup/ExposureScan.py b/script/setup/ExposureScan.py
new file mode 100644
index 0000000..7a1d438
--- /dev/null
+++ b/script/setup/ExposureScan.py
@@ -0,0 +1,33 @@
+import java.awt.Rectangle as Rectangle
+
+import ch.psi.pshell.imaging.Data as Data
+class Exposure(Writable):
+ def write(self,pos):
+ #cam.setExposure(pos)
+ img.camera.setExposure(pos)
+exposure=Exposure()
+
+
+class Contrast(Readable):
+ def read(self):
+ data = img.getData()
+ #roi = Data(data.getRectSelection(500,300,700,600), False)
+ #return data.getGradientVariance(False, Rectangle(480,0,600,670))
+ return data.getGradientVariance(False, None)
+contrast=Contrast()
+
+
+#a= lscan(exposure,img.getContrast(), 0.5, 1.0, 0.01, 0.5)
+#a= lscan(exposure,contrast, 0.2, 0.4, 0.01, 0.7)
+ret= lscan(exposure,contrast, 10.0, 150.0, 5.0, 0.5)
+y, x = ret.getReadable(0), ret.getPositions(0)
+
+#(n, m, s) = fit(a.getReadable(0), xdata=a.getPositions(0))
+#if m is None:
+# m=max(a.getReadable(0))
+m=x[y.index(max(y))]
+p=get_plots()[0]
+p.addMarker(m, p.AxisId.X, str(m), Color.RED)
+
+print "Setting exposure = ", m
+exposure.write(m)
diff --git a/script/setup/Layout.py b/script/setup/Layout.py
new file mode 100644
index 0000000..5c584f4
--- /dev/null
+++ b/script/setup/Layout.py
@@ -0,0 +1,292 @@
+###################################################################################################
+#DEFINITIONS
+###################################################################################################
+
+PLATE_SIZE = 480
+BLOCK_ROI_TOLERANCE = 12 #mm
+LED_TOLERANCE = 8 #mm Distance between LEDs = 18mm
+PUCK_SIZE = 65
+
+DET_UNIPUCK = "unipuck"
+DET_MINISPINE = "minispine"
+DET_ERROR = "error"
+DET_EMPTY = "empty"
+DET_UNKNOWN = "unknown"
+
+BLOCKS = ('A', 'B', 'C', 'D', 'E', 'F')
+
+#Layout table
+puck_layout = (
+ #Num Elm A0 Index A1 Uni Mini Center Angle Xuni Yuni Xmini=Xc Ymini==Yc
+ (1 , 'A', 0 , 1, 0.00 , 57.00 , 75.00 , 66.00 , 0.00 , 0.00 , 57.00 , 0.00 , 75.00 ),
+ (2 , 'A', 0 , 2, 0.00 , 132.00, 150.00, 141.00, 0.00 , 0.00 , 132.00 , 0.00 , 150.00 ),
+ (3 , 'F', 0 , 5, 19.11, 180.40, 198.40, 189.40, 19.11 , 59.06 , 170.46 , 64.95 , 187.47 ),
+ (4 , 'F', 0 , 4, 40.89, 180.40, 198.40, 189.40, 40.89 , 118.09 , 136.38 , 129.87 , 149.98 ),
+ (5 , 'F', 0 , 3, 30.00, 111.90, 129.90, 120.90, 30.00 , 55.95 , 96.91 , 64.95 , 112.50 ),
+ (6 , 'F', 60 , 1, 0.00 , 57.00 , 75.00 , 66.00 , 60.00 , 49.36 , 28.50 , 64.95 , 37.50 ),
+ (7 , 'F', 60 , 2, 0.00 , 132.00, 150.00, 141.00, 60.00 , 114.32 , 66.00 , 129.90 , 75.00 ),
+ (8 , 'E', 60 , 5, 19.11, 180.40, 198.40, 189.40, 79.11 , 177.15 , 34.08 , 194.83 , 37.48 ),
+ (9 , 'E', 60 , 4, 40.89, 180.40, 198.40, 189.40, 100.89, 177.15 , -34.08 , 194.83 , -37.48 ),
+ (10, 'E', 60 , 3, 30.00, 111.90, 129.90, 120.90, 90.00 , 111.90 , 0.00 , 129.90 , 0.00 ),
+ (11, 'E', 120, 1, 0.00 , 57.00 , 75.00 , 66.00 , 120.00, 49.36 , -28.50 , 64.95 , -37.50 ),
+ (12, 'E', 120, 2, 0.00 , 132.00, 150.00, 141.00, 120.00, 114.32 , -66.00 , 129.90 , -75.00 ),
+ (13, 'D', 120, 5, 19.11, 180.40, 198.40, 189.40, 139.11, 118.09 , -136.38, 129.87 , -149.98),
+ (14, 'D', 120, 4, 40.89, 180.40, 198.40, 189.40, 160.89, 59.06 , -170.46, 64.95 , -187.47),
+ (15, 'D', 120, 3, 30.00, 111.90, 129.90, 120.90, 150.00, 55.95 , -96.91 , 64.95 , -112.50),
+ (16, 'D', 180, 1, 0.00 , 57.00 , 75.00 , 66.00 , 180.00, 0.00 , -57.00 , 0.00 , -75.00 ),
+ (17, 'D', 180, 2, 0.00 , 132.00, 150.00, 141.00, 180.00, 0.00 , -132.00, 0.00 , -150.00),
+ (18, 'C', 180, 5, 19.11, 180.40, 198.40, 189.40, 199.11, -59.06 , -170.46, -64.95 , -187.47),
+ (19, 'C', 180, 4, 40.89, 180.40, 198.40, 189.40, 220.89, -118.09, -136.38, -129.87, -149.98),
+ (20, 'C', 180, 3, 30.00, 111.90, 129.90, 120.90, 210.00, -55.95 , -96.91 , -64.95 , -112.50),
+ (21, 'C', 240, 1, 0.00 , 57.00 , 75.00 , 66.00 , 240.00, -49.36 , -28.50 , -64.95 , -37.50 ),
+ (22, 'C', 240, 2, 0.00 , 132.00, 150.00, 141.00, 240.00, -114.32, -66.00 , -129.90, -75.00 ),
+ (23, 'B', 240, 5, 19.11, 180.40, 198.40, 189.40, 259.11, -177.15, -34.08 , -194.83, -37.48 ),
+ (24, 'B', 240, 4, 40.89, 180.40, 198.40, 189.40, 280.89, -177.15, 34.08 , -194.83, 37.48 ),
+ (25, 'B', 240, 3, 30.00, 111.90, 129.90, 120.90, 270.00, -111.90, 0.00 , -129.90, 0.00 ),
+ (26, 'B', 300, 1, 0.00 , 57.00 , 75.00 , 66.00 , 300.00, -49.36 , 28.50 , -64.95 , 37.50 ),
+ (27, 'B', 300, 2, 0.00 , 132.00, 150.00, 141.00, 300.00, -114.32, 66.00 , -129.90, 75.00 ),
+ (28, 'A', 300, 5, 19.11, 180.40, 198.40, 189.40, 319.11, -118.09, 136.38 , -129.87, 149.98 ),
+ (29, 'A', 300, 4, 40.89, 180.40, 198.40, 189.40, 340.89, -59.06 , 170.46 , -64.95 , 187.47 ),
+ (30, 'A', 300, 3, 30.00, 111.90, 129.90, 120.90, 330.00, -55.95 , 96.91 , -64.95 , 112.5 ),
+ )
+
+###################################################################################################
+#Puck class
+###################################################################################################
+class Puck:
+ def __init__(self, id, block, index, angle, center, led_uni, led_mini):
+ self.id = id
+ self.block = block
+ self.index = index
+ self.angle = angle
+ self.center = center
+ self.led_uni = led_uni
+ self.led_mini = led_mini
+ self.detect = DET_UNKNOWN
+
+ def __str__(self):
+ return "Number: " + str(self.id) + "\nBlock: " + str(self.block) + "\nIndex: " + str(self.index) + "\nAngle: " + str(self.angle) + \
+ "\nCenter: " + str(self.center) + "\nLed Unipuck: " + str(self.led_uni) + "\nLed Minispine: " + str(self.led_mini)
+
+ def get_name(self):
+ return str(self.block) + str(self.index)
+
+ def match(self, x, y):
+ if math.hypot(x-self.led_uni[0], y-self.led_uni[1]) <= LED_TOLERANCE:
+ return DET_UNIPUCK
+ if math.hypot(x-self.led_mini[0], y-self.led_mini[1]) <= LED_TOLERANCE:
+ return DET_MINISPINE
+ return None
+
+
+
+_block_ids = []
+_puck_list = []
+_block_list = []
+
+for p in(puck_layout):
+ puck = Puck(p[0], p[1], p[3], p[8], (p[11],p[12]), (p[9],p[10]), (p[11],p[12]))
+ _puck_list.append(puck)
+ if puck.block not in (_block_ids):
+ _block_ids.append(puck.block)
+
+def get_puck(id):
+ for p in _puck_list:
+ if id==p.id:
+ return p
+ return None
+
+def get_pucks(block = None):
+ ret = []
+ for p in _puck_list:
+ if (block is None) or (block==p.block):
+ ret.append(p)
+ return ret
+
+
+###################################################################################################
+#Block class
+###################################################################################################
+
+class Block:
+ def __init__(self, id, angle_range, x_range, y_range):
+ self.id = id
+ self.angle_range = angle_range
+ self.x_range = x_range
+ self.y_range = y_range
+ self.roi = (self.x_range[0] - BLOCK_ROI_TOLERANCE, self.y_range[0] - BLOCK_ROI_TOLERANCE,
+ self.x_range[1] + BLOCK_ROI_TOLERANCE, self.y_range[1] + BLOCK_ROI_TOLERANCE)
+
+ def __str__(self):
+ return "Id: " + str(self.id) + "\nAngle: " + str(self.angle_range) + "\nX: " + str(self.x_range) + "\nY: " + str(self.y_range)
+
+
+for id in _block_ids:
+ pucks = get_pucks(id)
+ angles, x, y = [], [], []
+ for p in pucks:
+ angles.append(p.angle)
+ x.append(p.led_uni[0])
+ x.append(p.led_mini[0])
+ y.append(p.led_uni[1])
+ y.append(p.led_mini[1])
+ el = Block(id,(min(angles), max(angles)), (min(x), max(x)), (min(y), max(y)))
+ _block_list.append(el)
+
+def get_block(id):
+ for e in _block_list:
+ if id==e.id:
+ return e
+ return None
+
+def get_blocks():
+ return _block_list
+
+
+
+
+###################################################################################################
+#Detection utilities
+###################################################################################################
+
+
+def _detect_puck(point_list, puck):
+ puck.detect = DET_ERROR
+ for point in point_list:
+ match = puck.match(point[0], point[1])
+ if match is not None:
+ if match==DET_UNIPUCK:
+ puck.detect = DET_EMPTY if (puck.detect==DET_MINISPINE) else DET_UNIPUCK
+ elif match==DET_MINISPINE:
+ puck.detect = DET_EMPTY if (puck.detect==DET_UNIPUCK) else DET_MINISPINE
+
+def detect_pucks(point_list, id=None):
+ if (id is None) or (id in BLOCKS):
+ for puck in get_pucks(id):
+ _detect_puck(point_list, puck)
+ else:
+ puck = get_puck(int(id))
+ print puck
+ _detect_puck(point_list, puck)
+
+
+def clear_detection(block_id=None):
+ for puck in get_pucks(block_id):
+ puck.detect = DET_UNKNOWN
+ return get_puck_detection_dict(block_id)
+
+
+def get_puck_detection(det_type, block_id=None):
+ ret = []
+ for puck in get_pucks(block_id):
+ if puck.detect == det_type:
+ ret.append(puck)
+ return ret
+
+def get_unipucks(block_id=None):
+ return get_puck_detection(DET_UNIPUCK, block_id)
+
+def get_minispines(block_id=None):
+ return get_puck_detection(DET_MINISPINE, block_id)
+
+def get_empties(block_id=None):
+ return get_puck_detection(DET_EMPTY, block_id)
+
+def get_unknowns(block_id=None):
+ return get_puck_detection(DET_UNKNOWN, block_id)
+
+def get_det_errors(block_id=None):
+ return get_puck_detection(DET_ERROR, block_id)
+
+def get_puck_detection_dict(block_id):
+ ret = {}
+ pucks = []
+ for puck in get_unipucks(block_id):
+ pucks.append(puck.get_name())
+ pucks.sort()
+ ret["Unipuck"] = pucks
+ pucks = []
+ for puck in get_minispines(block_id):
+ pucks.append(puck.get_name())
+ pucks.sort()
+ ret["Minispine"] = pucks
+ pucks = []
+ for puck in get_det_errors(block_id):
+ pucks.append(puck.get_name())
+ pucks.sort()
+ ret["Error"] = pucks
+ pucks = []
+ for puck in get_empties(block_id):
+ pucks.append(puck.get_name())
+ pucks.sort()
+ ret["Empty"] = pucks
+ pucks = []
+ for puck in get_unknowns(block_id):
+ pucks.append(puck.get_name())
+ pucks.sort()
+ ret["Unknown"] = pucks
+ return ret
+
+###################################################################################################
+#Plotting
+###################################################################################################
+
+from plotutils import *
+
+def plot_base_plate(points = None, show_detect = True, title = None, p = None):
+ colors = (Color.RED, Color.BLUE, Color.MAGENTA, Color(128,0,128), Color(0,128,0), Color(255,128,0))
+ if p is None: p = plot(None, title=title)[0]
+ p.getAxis(p.AxisId.Y).setInverted(True)
+ plot_circle(p, 0, 0, PLATE_SIZE/2, width = 0, color = Color.GRAY, name = "Plate")
+ plot_point(p, 0, 0, size = 10, color = Color.GRAY, name = "Center")
+ #p.setLegendVisible(True)
+ for block in get_blocks():
+ (xmin, xmax) = block.x_range
+ (ymin, ymax) = block.y_range
+ (xmin, ymin, xmax, ymax ) = block.roi
+ index = get_blocks().index(block)
+ r = plot_rectangle(p, xmin, ymin, xmax, ymax, width =0, color=colors[index], name = block.id)
+ #In the first time the plot shows, it takes some time for the color to be assigned
+ #while r.color is None:
+ # time.sleep(0.001)
+
+ if block.id in ('A', 'F'):
+ x, y = (xmin + xmax)/2, ymax + 5
+ elif block.id in ('C', 'D'):
+ x, y = (xmin + xmax)/2, ymin - 5
+ elif block.id == 'B':
+ x, y = xmax + 5, (ymin + ymax)/2
+ elif block.id == 'E':
+ x, y = xmin - 5, (ymin + ymax)/2
+
+ p.addText(x,y, str(block.id), r.color)
+
+ for puck in get_pucks(block.id):
+ (xu, yu) = puck.led_uni
+ (xm, ym) = puck.led_mini
+ plot_point(p, xu, yu, size = 3, color = r.color, name = str(puck.id)+"u")
+ plot_point(p, xm, ym, size = 7, color = r.color, name = str(puck.id)+"m")
+ plot_circle(p, xu, yu, LED_TOLERANCE, width = 0, color = r.color, name = str(puck.id)+"uc")
+ plot_circle(p, xm, ym, LED_TOLERANCE, width = 0, color = r.color, name = str(puck.id)+"mc")
+ p.addText((xu+xm)/2, (yu+ym)/2, str(puck.id), r.color)
+ c,w = Color.GRAY,0
+ if show_detect:
+ if puck.detect == DET_UNIPUCK:
+ c,w = Color.BLACK,1
+ elif puck.detect == DET_MINISPINE:
+ c,w = Color(150, 100, 50),1
+ elif puck.detect == DET_ERROR:
+ c = Color(128,0,0)
+ plot_circle(p, xm, ym, PUCK_SIZE/2, width = w, color = c , name = str(puck.id))
+ if points is not None:
+ for point in points:
+ c, w = Color.GRAY, 1
+ for puck in get_pucks():
+ match = puck.match(point[0], point[1])
+ if match is not None:
+ w=2
+ c = Color.DARK_GRAY if match == "minispine" else Color.BLACK
+
+
+ plot_cross(p,point[0], point[1], size = 12, width = w, color = c, name = "P"+ str(points.index(point)))
+ #plot_point(p,point[0], point[1], size = 5, color = Color.BLACK, name = "Pc"+ str(points.index(point)))
diff --git a/script/tasks/ColdPositionTimeout.py b/script/tasks/ColdPositionTimeout.py
new file mode 100644
index 0000000..197e829
--- /dev/null
+++ b/script/tasks/ColdPositionTimeout.py
@@ -0,0 +1,23 @@
+cold_position_timeout = int(get_setting("cold_position_timeout"))
+if cold_position_timeout > 0:
+ if robot.last_command_position == "cold":
+ if (time.time() - robot.last_command_timestamp) > cold_position_timeout:
+ if robot.is_cold():
+ log("Detected cold position timeout", False)
+ if get_context().state == State.Ready:
+ if robot.state == State.Ready:
+ if feedback_psys_safety.take() == True:
+ #TODO: Chan
+ get_context().evalLine("dry(wait_cold = -1)") #Dry and park : use get_context().evalLine to change application state
+ else:
+ raise Exception("Cannot clear cold position: feedback_psys_safety = False ")
+ else:
+ raise Exception("Cannot clear cold position: robot state: " + str(robot.state))
+ else:
+ raise Exception("Cannot clear cold position: system state: " + str(get_context().state))
+
+
+
+
+
+
\ No newline at end of file
diff --git a/script/tasks/LedMonitoring.py b/script/tasks/LedMonitoring.py
new file mode 100644
index 0000000..5182a77
--- /dev/null
+++ b/script/tasks/LedMonitoring.py
@@ -0,0 +1,26 @@
+DEWAR_LEVEL_LED = 25.0
+
+try:
+ _level = dewar_level.read()
+except:
+ log("Cannot read Dewar level", False)
+ _level = 0.0
+
+try:
+ _led_room_temp = is_led_room_temp()
+except:
+ log("Cannot get LED configuration", False)
+ _led_room_temp = False
+
+if _level <= DEWAR_LEVEL_LED:
+ if not _led_room_temp:
+ log_str="LED Monitoring: Setting LEDs to room temperature range"
+ log(log_str, False)
+ print (log_str)
+ set_led_range(room_temp = True)
+else:
+ if _led_room_temp:
+ log_str="LED Monitoring: Setting LEDs to LN2 range"
+ log(log_str, False)
+ print (log_str)
+ set_led_range(room_temp = False)
diff --git a/script/tasks/MangnetMonitoring.py b/script/tasks/MangnetMonitoring.py
new file mode 100644
index 0000000..8450895
--- /dev/null
+++ b/script/tasks/MangnetMonitoring.py
@@ -0,0 +1,24 @@
+try:
+ if feedback_local_safety.take() ==False:
+ magnet_release_state = magnet_release.read()
+ if former_magnet_release_state != magnet_release_state:
+ if magnet_release_state:
+ print "Pressed release button"
+ smart_magnet.set_resting_current()
+ smart_magnet_changed = True
+ else:
+ print "Released release button"
+ smart_magnet.set_default_current()
+ smart_magnet_changed = False
+ former_magnet_release_state = magnet_release_state
+
+ else:
+ if smart_magnet_changed:
+ smart_magnet.set_default_current()
+ smart_magnet_changed = False
+ former_magnet_release_state = False
+
+except:
+ former_magnet_release_state = False
+ smart_magnet_changed = False
+
\ No newline at end of file
diff --git a/script/test/CameraCalibration.py b/script/test/CameraCalibration.py
new file mode 100644
index 0000000..02e7d9d
--- /dev/null
+++ b/script/test/CameraCalibration.py
@@ -0,0 +1,71 @@
+import ch.psi.pshell.device.Camera as Camera
+import ch.psi.pshell.imaging.RendererMode as RendererMode
+from ch.psi.pshell.imaging.Overlays import *
+
+"""
+img.camera.setColorMode(Camera.ColorMode.Mono)
+img.camera.setDataType(Camera.DataType.UInt8)
+img.camera.setGrabMode(Camera.GrabMode.Continuous)
+img.camera.setTriggerMode(Camera.TriggerMode.Fixed_Rate)
+img.camera.setExposure(50.00)
+img.camera.setAcquirePeriod(200.00)
+img.camera.setGain(0.0)
+img.config.rotationCrop=True
+
+
+"""
+#img.camera.setROI(200, 0,1200,1200)
+
+img.camera.setROI(0, 0,1600,1200)
+img.config.rotation=0
+img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight =0,0,-1,-1
+img.config.setCalibration(None)
+img.camera.stop()
+img.camera.start()
+
+#img.camera.setROI(300, 200,1000,1000)
+#img.config.rotation=17
+#img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight = 50,50,900,900
+
+p = show_panel(img)
+p.setMode(RendererMode.Fit)
+ov_text = Text(Pen(java.awt.Color.GREEN.darker()), "", java.awt.Font("Verdana", java.awt.Font.PLAIN, 24), java.awt.Point(20,20))
+ov_text.setFixed(True)
+
+
+
+p.addOverlay(ov_text)
+try:
+ ov_text.update("Click on upper reference...")
+ p1 = p.waitClick(60000)
+ print p1
+ ov_text.update("Click on left reference...")
+ p2 = p.waitClick(60000)
+ print p2
+ ov_text.update("Click on right reference...")
+ p3 = p.waitClick(60000)
+ print p3
+
+ x, y, z = p1.x+p1.y*1j, p2.x+p2.y*1j, p3.x+p3.y*1j
+ w = z-x
+ w /= y-x
+ c = (x-y)*(w-abs(w)**2)/2j/w.imag-x
+ cx, cy, r = -c.real, -c.imag, abs(c+x)
+ a = math.degrees(math.atan((cx-p1.x)/(p1.y-cy)))
+
+ print cx, cy, r, a
+
+ #img.camera.setROI(int((1600-cx)/2),int((1200-cy)/2),1000,1000)
+ img.camera.setROI(int(cx-r),int(cy-r),int(2*r),int(2*r))
+ img.config.rotation=-a
+ #remove rotation border
+ d=int(r/11)
+ img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight =d,d, int(2*r-2*d), int(2*r-2*d)
+ #img.config.setCalibration(None)
+ img.camera.stop()
+ img.camera.start()
+
+finally:
+ p.removeOverlay(ov_text)
+
+
\ No newline at end of file
diff --git a/script/test/CoverDetection.py b/script/test/CoverDetection.py
new file mode 100644
index 0000000..24a228b
--- /dev/null
+++ b/script/test/CoverDetection.py
@@ -0,0 +1,116 @@
+###################################################################################################
+# Procedure to detect the cover orientation
+###################################################################################################
+import ch.psi.pshell.imaging.Utils.integrateVertically as integrateVertically
+img.backgroundEnabled=False
+
+REF = (0,96,125)
+
+line = load_image("{images}/line.png", title="Line")
+#line = load_image("{images}/line360.png", title="Line")
+
+line.getProcessor().setBackgroundValue(0.0)
+
+
+#ip = get_image()
+ip = integrate_frames(10)
+ip = grayscale(ip, True)
+
+
+smooth(ip)
+#bandpass_filter(ip, 30, 1000)
+edges(ip)
+
+#invert(ip)
+#auto_threshold(ip, method = "Default")
+
+
+#auto_threshold(ip, method = "Li")
+auto_threshold(ip, method = "MaxEntropy")
+
+"""
+for m in AutoThresholder.getMethods():
+ print m
+ aux = ip.duplicate()
+ auto_threshold(aux, method = m)
+ binary_fill_holes(aux, dark_background=False)
+ renderer = show_panel(aux.bufferedImage)
+ time.sleep(1.0)
+"""
+#binary_dilate(ip, dark_background=False)
+#binary_fill_holes(ip, dark_background=False)
+#binary_open(ip, dark_background=Tr)
+
+renderer = show_panel(ip.bufferedImage)
+
+
+
+
+
+
+
+
+#line = sub_image(line, 325, 325, 512, 512)
+#ip = sub_image(ip, 325, 325, 512, 512)
+line = sub_image(line, 453, 453, 256, 256)
+ip = sub_image(ip, 453, 453, 256, 256)
+#op = op_fft(ip, line, "correlate")
+
+
+renderer = show_panel(ip.bufferedImage)
+
+#renderer = show_panel(op.bufferedImage)
+#line.show()
+ydata = []
+xdata = range (0,180,1)
+for i in xdata:
+ l = line.duplicate()
+ l.getProcessor().setBackgroundValue(0.0)
+ l.getProcessor().rotate(float(i))
+ op = op_fft(ip, l, "correlate")
+ bi = op.getBufferedImage()
+ p = integrateVertically(bi)
+ ydata.append(sum(p))
+
+ #renderer = show_panel(op.bufferedImage)
+ #time.sleep(0.001)
+
+def moving_average(arr, n) :
+ ret = []
+ for i in range(len(arr)):
+ ret.append(mean(arr[max(i-n,0):min(i+n,len(arr)-1)]))
+ return ret
+av = moving_average(ydata, 1)
+
+p = plot(ydata, xdata=xdata)[0]
+
+p.addSeries(LinePlotSeries("Moving Average"))
+p.getSeries(1).setData(xdata, av)
+
+peaks = estimate_peak_indexes(ydata, xdata, (min(ydata) + max(ydata))/2, 25.0)
+left, right = min(peaks), max(peaks)
+if xdata[left]<5 and xdata[right]>(xdata[-1]-5):
+ #del peaks[0 if ydata[right] > ydata[left] else -1]
+ peaks.remove(right if ydata[right] > ydata[left] else left)
+
+peaks = sorted(peaks[:3])
+peaks_x = map(lambda x:xdata[x], peaks)
+peaks_y = map(lambda x:ydata[x], peaks)
+
+print "Peaks", peaks
+print "Peak indexes: " + str(peaks_x)
+print "Peak values: " + str(peaks_y)
+
+
+for i in range(len(peaks)):
+ peak = xdata[peaks[i]]
+ p.addMarker(peak, None, "N="+str(round(peak,2)), Color(80,0,80))
+ if ((peaks[i]>160) and (REF[i]<20)):
+ peaks[i] = peaks[i] - 180.0
+
+print "Peaks x: " + str(peaks_x)
+
+
+d = mean(arrabs(arrsub(REF, peaks_x)))
+
+print "Angle = ", d
\ No newline at end of file
diff --git a/script/test/PuckDetection.py b/script/test/PuckDetection.py
new file mode 100644
index 0000000..003ef68
--- /dev/null
+++ b/script/test/PuckDetection.py
@@ -0,0 +1,24 @@
+###################################################################################################
+# Example of using ImageJ functionalities through ijutils.
+###################################################################################################
+
+from ijutils import *
+import java.awt.Color as Color
+
+
+#Image Loading
+ip = load_image("{images}/test2.png", title="Image")
+
+
+#Puck Detection
+aux = grayscale(ip, in_place=False)
+aux.show()
+plot(get_histogram(aux))
+
+subtract_background(aux)
+threshold(aux,0,50); aux.repaintWindow()
+binary_fill_holes(aux); aux.repaintWindow()
+(results,output_img)=analyse_particles(aux, 10000,50000,
+ fill_holes = False, exclude_edges = True,print_table=True,
+ output_image = "outlines", minCirc = 0.0, maxCirc = 1.0)
+output_img.show()
\ No newline at end of file
diff --git a/script/test/PuckDetectionTest.py b/script/test/PuckDetectionTest.py
new file mode 100644
index 0000000..2995f9a
--- /dev/null
+++ b/script/test/PuckDetectionTest.py
@@ -0,0 +1,11 @@
+import datetime
+index = 0
+prefix = str(datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
+
+while True:
+ suffix = "%04d - " % index
+ print (suffix),
+ run("imgproc/LedDetectionProc.py")
+ index=index+1
+ save_image(image, "{images}/" +prefix + "_" + suffix +".png", "png")
+
\ No newline at end of file
diff --git a/script/test/RobotCartesianScan.py b/script/test/RobotCartesianScan.py
new file mode 100644
index 0000000..4a5225e
--- /dev/null
+++ b/script/test/RobotCartesianScan.py
@@ -0,0 +1,28 @@
+import plotutils
+from mathutils import fit_gaussian, Gaussian
+
+robot.enable()
+move_to_laser()
+
+#robot.reset_motion("jLaser")
+
+#import ch.psi.pshell.device.Timestamp as Timestamp
+#sensor = Timestamp()
+
+#ret = lscan(robot_z, sensor, -50.0, 0.0, 0.5, latency = 0, relative = True)
+#ret = lscan(robot_x, sensor, -50.0, 0.0, 0.5, latency = 0, relative = True)
+
+robot.set_motors_enabled(True)
+ret = lscan(robot_x, ue.readable, -1.5, 1.5, 0.1, latency = 0.01, relative = True)
+
+x,y = ret.getPositions(0), ret.getReadable(0)
+y = [100.0-v for v in y]
+(norm, mea, sigma) = fit(y, xdata=x)
+print "Maximum at " + str(mea)
+
+
+
+robot.set_motors_enabled(True)
+ret = lscan(robot_rz, ue.readable, 0.0, 40.0, 1.0, latency = 0.01, relative = True, range = "auto")
+
+
diff --git a/script/test/SampleDataInput.py b/script/test/SampleDataInput.py
new file mode 100644
index 0000000..1f00cd6
--- /dev/null
+++ b/script/test/SampleDataInput.py
@@ -0,0 +1,1861 @@
+USER_NAME = "My User"
+DEWAR_NAME = "My Dewar"
+
+test_sample_data = [ \
+
+#Puck A1
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Isabelle Chip", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "A1",\
+ "sampleName": "flat_Base_Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Isabelle Chip", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "A1",\
+ "sampleName": "flat_Base_Pin_2", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Isabelle Chip", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "A1",\
+ "sampleName": "regular_Base_Pin_1", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Isabelle Chip", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "A1",\
+ "sampleName": "regular_Base_Pin_2", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+
+# Puck B1
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "IDatamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "IDatamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "IDatamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ \"sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "IDatamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "IDatamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+
+# Puck B2
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+
+# Puck B3
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+
+# Puck B4
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "u"dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+
+# Puck C1
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+
+# Puck C2
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+
+# Puck D1
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+
+# Puck D2
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus""sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "u"dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+# Puck D3
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+# Puck D4
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "XXX", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ ]
+
+
+set_samples_info(test_sample_data)
\ No newline at end of file
diff --git a/script/test/SampleDataInput_Dominik.py b/script/test/SampleDataInput_Dominik.py
new file mode 100644
index 0000000..8ff4ae7
--- /dev/null
+++ b/script/test/SampleDataInput_Dominik.py
@@ -0,0 +1,1862 @@
+USER_NAME = "My User"
+DEWAR_NAME = "My Dewar"
+
+test_sample_data = [ \
+ #Puck A1 \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Isabelle Chip", \
+ "puckBarcode": "CA00CF1471", \
+ "puckType": "unipuck", \
+ "puckAddress": "",\
+ "sampleName": "flat_Base_Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Isabelle Chip", \
+ "puckBarcode": "CA00CF1471", \
+ "puckType": "unipuck", \
+ "puckAddress": "",\
+ "sampleName": "flat_Base_Pin_2", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Isabelle Chip", \
+ "puckBarcode": "CA00CF1471", \
+ "puckType": "unipuck", \
+ "puckAddress": "",\
+ "sampleName": "regular_Base_Pin_1", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Isabelle Chip", \
+ "puckBarcode": "CA00CF1471", \
+ "puckType": "unipuck", \
+ "puckAddress": "",\
+ "sampleName": "regular_Base_Pin_2", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ # Puck B1 \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "IDatamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "IDatamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "IDatamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "IDatamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "IDatamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_1", \
+ "puckBarcode": "DMBW1", \
+ "puckType": "unipuck", \
+ "puckAddress": "B1",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ \
+ # Puck B2 \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW2", \
+ "puckType": "unipuck", \
+ "puckAddress": "B2",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ \
+ # Puck B3 \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_2", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_3", \
+ "puckBarcode": "DMBW3", \
+ "puckType": "unipuck", \
+ "puckAddress": "B3",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ \
+ # Puck B4 \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "DMBW4", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "DMBW4", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "DMBW4", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "DMBW4", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "DMBW4", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "DMBW4", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "DMBW4", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "DMBW4", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "DMBW4", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "DMBW4", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "DMBW4", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Black_White_4", \
+ "puckBarcode": "DMBW4", \
+ "puckType": "unipuck", \
+ "puckAddress": "B4",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ \
+ # Puck C1 \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_1", \
+ "puckBarcode": "DMGA1", \
+ "puckType": "unipuck", \
+ "puckAddress": "C1",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ \
+ # Puck C2 \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "DMGA2", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "DMGA2", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "DMGA2", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "DMGA2", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "DMGA2", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "DMGA2", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "DMGA2", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "DMGA2", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "Datamatrix_Grey_Alu_2", \
+ "puckBarcode": "DMGA2", \
+ "puckType": "unipuck", \
+ "puckAddress": "C2",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ \
+ # Puck D1 \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_1", \
+ "puckBarcode": "NODM1", \
+ "puckType": "unipuck", \
+ "puckAddress": "D1",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ \
+ # Puck D2 \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_2", \
+ "puckBarcode": "NODM2", \
+ "puckType": "unipuck", \
+ "puckAddress": "D2",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ \
+ # Puck D3 \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_3", \
+ "puckBarcode": "NODM3", \
+ "puckType": "unipuck", \
+ "puckAddress": "D3",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ \
+ # Puck D4
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_1", \
+ "samplePosition": 1,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_2", \
+ "samplePosition": 2,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_3", \
+ "samplePosition": 3,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_4", \
+ "samplePosition": 4,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_5", \
+ "samplePosition": 5,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_6", \
+ "samplePosition": 6,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_7", \
+ "samplePosition": 7,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_8", \
+ "samplePosition": 8,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_9", \
+ "samplePosition": 9,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_10", \
+ "samplePosition": 10,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_11", \
+ "samplePosition": 11,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_12", \
+ "samplePosition": 12,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_13", \
+ "samplePosition": 13,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_14", \
+ "samplePosition": 14,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_15", \
+ "samplePosition": 15,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ { "userName": USER_NAME, \
+ "dewarName": DEWAR_NAME, \
+ "puckName": "No_Datamatrix_4", \
+ "puckBarcode": "NODM4", \
+ "puckType": "unipuck", \
+ "puckAddress": "D4",\
+ "sampleName": "Pin_16", \
+ "samplePosition": 16,\
+ "sampleBarcode": "", \
+ "sampleStatus": "Present", \
+ "sampleMountCount": 0,
+ } , \
+ ]
+set_samples_info(test_sample_data)
\ No newline at end of file
diff --git a/script/test/SampleDetection.py b/script/test/SampleDetection.py
new file mode 100644
index 0000000..4638b7a
--- /dev/null
+++ b/script/test/SampleDetection.py
@@ -0,0 +1,23 @@
+###################################################################################################
+# Example of using ImageJ functionalities through ijutils.
+###################################################################################################
+
+from ijutils import *
+import java.awt.Color as Color
+
+#Image Loading
+ip = load_image("{images}/test2.png", title="Image")
+
+aux = grayscale(ip, in_place=False)
+aux.show()
+
+invert(aux); aux.repaintWindow()
+#gaussian_blur(aux); aux.repaintWindow()
+subtract_background(aux); aux.repaintWindow()
+auto_threshold(aux); aux.repaintWindow()
+binary_open(aux); aux.repaintWindow()
+#binary_fill_holes(aux); aux.repaintWindow()
+(results,output_img)=analyse_particles(aux, 250,1000,
+ fill_holes = False, exclude_edges = True,print_table=True,
+ output_image = "outlines", minCirc = 0.7, maxCirc = 1.0)
+output_img.show()
diff --git a/script/test/TestAlign.py b/script/test/TestAlign.py
new file mode 100644
index 0000000..0cbe1a7
--- /dev/null
+++ b/script/test/TestAlign.py
@@ -0,0 +1,9 @@
+
+v = 2.0
+#while(true):
+for i in range(100):
+ v = v * (-1.0)
+ robot_j4.initialize()
+ robot_j4.moveRel(v)
+ robot.align()
+
\ No newline at end of file
diff --git a/script/test/TestBugPcAPI b/script/test/TestBugPcAPI
new file mode 100644
index 0000000..5be0f3e
--- /dev/null
+++ b/script/test/TestBugPcAPI
@@ -0,0 +1,4 @@
+while True:
+ img.initialize()
+ img.waitNext(10000)
+ time.sleep(2.0)
\ No newline at end of file
diff --git a/script/test/TestBugPcAPI.py b/script/test/TestBugPcAPI.py
new file mode 100644
index 0000000..7a3d186
--- /dev/null
+++ b/script/test/TestBugPcAPI.py
@@ -0,0 +1,30 @@
+import ch.psi.pshell.prosilica.Prosilica as Prosilica
+import ch.psi.pshell.device.Camera as Camera
+
+
+add_device(Prosilica("img", 25001, "PacketSize=1522;PixelFormat=Mono8;BinningX=1;BinningY=1;RegionX=300;RegionY=200;Width=1000;Height=1000;MulticastEnable=Off"), True)
+
+img.camera.setGrabMode(Camera.GrabMode.Continuous)
+img.camera.setTriggerMode(Camera.TriggerMode.Fixed_Rate)
+img.camera.setExposure(50.00)
+img.camera.setAcquirePeriod(200.00)
+img.camera.setGain(0.0)
+#img.camera.setROI(200, 0,1200,1200)
+"""
+img.camera.setROI(300, 200,1000,1000)
+img.config.rotation=17
+img.config.rotationCrop=True
+img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight = 50,50,900,900
+"""
+img.camera.setROI(int(get_setting("roi_x")), int(get_setting("roi_y")), int(get_setting("roi_w")), int(get_setting("roi_h")))
+
+img.camera.stop()
+img.camera.start()
+
+
+show_panel(img)
+#while True:
+# img.initialize()
+# img.waitNext(1000)
+# time.sleep(0.1)
+
diff --git a/script/test/TestBugPcAPI2.py b/script/test/TestBugPcAPI2.py
new file mode 100644
index 0000000..5e92b37
--- /dev/null
+++ b/script/test/TestBugPcAPI2.py
@@ -0,0 +1,6 @@
+import ch.psi.pshell.imaging.MjpegSource as MjpegSource
+MjpegSource2 = get_context().pluginManager.getDynamicClass("MjpegSource2")
+add_device(MjpegSource("gripper_cam", "http://axis-accc8e9cc87b.psi.ch/axis-cgi/mjpg/video.cgi"), True)
+#gripper_cam.polling=1000
+gripper_cam.monitored = True
+show_panel(gripper_cam)
\ No newline at end of file
diff --git a/script/test/TestBugPcAPI3.py b/script/test/TestBugPcAPI3.py
new file mode 100644
index 0000000..6acb775
--- /dev/null
+++ b/script/test/TestBugPcAPI3.py
@@ -0,0 +1,4 @@
+while True:
+ img.initialize()
+ img.waitNext(1000)
+ time.sleep(0.1)
\ No newline at end of file
diff --git a/script/test/TestCalib.py b/script/test/TestCalib.py
new file mode 100644
index 0000000..2cc311b
--- /dev/null
+++ b/script/test/TestCalib.py
@@ -0,0 +1,30 @@
+
+print "calibrate_tool"
+
+#Initial checks
+robot.assert_no_task()
+robot.reset_motion()
+robot.wait_ready()
+robot.assert_cleared()
+#robot.assert_in_known_point()
+
+#Enabling
+enable_motion()
+
+(detected, dm) = move_scanner()
+
+if detected:
+ print "Pin detected, trashing..."
+ trash()
+ (detected, dm) = move_scanner()
+ if detected:
+ raise Exception("Cannot trash pin")
+
+robot.open_tool()
+robot.get_calibration_tool()
+
+run("calibration/ToolCalibration3")
+
+robot.put_calibration_tool()
+
+robot.save_program()
diff --git a/script/test/TestCameraStability1.py b/script/test/TestCameraStability1.py
new file mode 100644
index 0000000..e4660e9
--- /dev/null
+++ b/script/test/TestCameraStability1.py
@@ -0,0 +1,11 @@
+for i in range(10):
+ time.sleep(2)
+ move_home()
+ time.sleep(1)
+ move_park()
+ start = time.time()
+ while get_img_cover_pos() != 'A':
+ print ".",
+ time.sleep(0.001)
+ print "Time = " , ( time.time() - start)
+
\ No newline at end of file
diff --git a/script/test/TestCameraStability2.py b/script/test/TestCameraStability2.py
new file mode 100644
index 0000000..c6ef878
--- /dev/null
+++ b/script/test/TestCameraStability2.py
@@ -0,0 +1,14 @@
+cover_detection_debug=True
+while True:
+ for pos in ['A', 'B', 'C', 'D', 'E', 'F']:
+ print "Moving to ", pos
+ hexiposi.move(pos)
+ move_home()
+ move_park()
+ time.sleep(2.0)
+ ret = run("imgproc/CoverDetection")
+ det = ret[0]
+ print "Detected: ", det
+ if det != pos:
+ raise Exception("Position error")
+
diff --git a/script/test/TestCameraStability3.py b/script/test/TestCameraStability3.py
new file mode 100644
index 0000000..bcf1327
--- /dev/null
+++ b/script/test/TestCameraStability3.py
@@ -0,0 +1,9 @@
+for i in range(10):
+ time.sleep(1)
+ move_home()
+ time.sleep(1)
+ move_park()
+ start = time.time()
+ time.sleep(1.0)
+ print run("imgproc/LedDetectionProc.py")
+
\ No newline at end of file
diff --git a/script/test/TestCmdSynchronization.py b/script/test/TestCmdSynchronization.py
new file mode 100644
index 0000000..098998d
--- /dev/null
+++ b/script/test/TestCmdSynchronization.py
@@ -0,0 +1,32 @@
+import java.util.logging.Level
+
+def get_pos_str():
+ return "point: " + str(robot.get_current_point()) + " - here: " + str(robot.here()) + " - herej: " + str(robot.herej())
+
+enable_motion()
+
+get_context().setLogLevel(java.util.logging.Level.FINER)
+try:
+ while True:
+ #robot.move_dewar()
+ #robot.move_park()
+
+ log("Moving dewar", False)
+ flag = robot.start_task('moveDewar')
+ print "moveDewar: ", flag
+ log("Waiting", False)
+ ret = robot.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ log("Moving dewar finished (" + str(ret) + ") - pos: " + get_pos_str(), False)
+ robot.assert_dewar()
+
+
+ log("Moving park", False)
+ flag = robot.start_task('movePark')
+ print "movePark: ", flag
+ log("Waiting", False)
+ ret = robot.wait_task_finished(TASK_WAIT_ROBOT_POLLING)
+ log("Moving park finished (" + str(ret) + ") - pos: " + get_pos_str(), False)
+ robot.assert_park()
+
+finally:
+ get_context().setLogLevel(java.util.logging.Level.INFO)
\ No newline at end of file
diff --git a/script/test/TestCoverDetection.py b/script/test/TestCoverDetection.py
new file mode 100644
index 0000000..e21e2c0
--- /dev/null
+++ b/script/test/TestCoverDetection.py
@@ -0,0 +1,19 @@
+
+ca = []
+aa = []
+pa = []
+
+#for i in range(6):
+ #index = i+1
+for i in ['A', 'B', 'C', 'D', 'E', 'F']:
+ hexiposi.move(i)
+ [position, angle, confidence] = run("imgproc/CoverDetection")
+ print [position, angle, confidence]
+ pa.append(position)
+ aa.append(angle)
+ ca.append(confidence)
+
+print "---"
+print "Position: " ,pa
+print "Angle: " ,aa
+print "Confidence: " ,ca, " mean: ", mean(ca)
\ No newline at end of file
diff --git a/script/test/TestEuclidean.py b/script/test/TestEuclidean.py
new file mode 100644
index 0000000..4376dc7
--- /dev/null
+++ b/script/test/TestEuclidean.py
@@ -0,0 +1,23 @@
+import org.apache.commons.math3.geometry.euclidean.threed.Segment as Segment
+import org.apache.commons.math3.geometry.euclidean.threed.Vector3D as Vector3D
+import org.apache.commons.math3.geometry.euclidean.threed.Line as Line
+
+
+p = Vector3D(0, 0, 3)
+
+p1 = Vector3D(0,0,0)
+p2 = Vector3D(0,1,1 )
+tolerance = 0.001
+
+l = Line(p1, p2, tolerance)
+
+
+print l.distance(p)
+print p1.distance(p)
+print p2.distance(p)
+print "---"
+
+print l.getAbscissa(p)
+print l.pointAt(l.getAbscissa(p))
+
+#print l.closestPoint(Line(p, p, 0.01))
\ No newline at end of file
diff --git a/script/test/TestLaserScan.py b/script/test/TestLaserScan.py
new file mode 100644
index 0000000..a977ba0
--- /dev/null
+++ b/script/test/TestLaserScan.py
@@ -0,0 +1,12 @@
+robot.set_motors_enabled(True)
+steps_x = 10
+steps_y = 8
+#ret = ascan([robot_x, robot_z], ue.readable, [-10.0, -10.0], [10.0, 10.0], [10,10], latency = 0.01, relative = True , zigzag=True)
+ret = ascan([robot_x, robot_z], ue.readable, [-10.0, -10.0], [10.0, 10.0], [steps_y,steps_x], latency = 0.01, relative = True , zigzag=False)
+data = Convert.transpose(Convert.toBidimensional(to_array(ret.getReadable(0),'d'),steps_x+1,steps_y+1))
+plot(data, title="data")
+
+data = ret.getData(0)
+plot(data, title="data2")
+
+
diff --git a/script/test/TestLayout.py b/script/test/TestLayout.py
new file mode 100644
index 0000000..7404a8e
--- /dev/null
+++ b/script/test/TestLayout.py
@@ -0,0 +1,21 @@
+
+
+
+points = [(100, 140), (130, 77), (120, 130), (110, 100)]
+clear_detection()
+detect_pucks(points)
+#detect_pucks(points, 'A')
+#detect_pucks(points, '4')
+plot_base_plate(points)
+
+
+
+#plot_detected_leds(points)
+
+
+
+block_id = None
+print get_unipucks(block_id)
+print get_minispines(block_id)
+print get_empties(block_id)
+print get_det_errors(block_id)
\ No newline at end of file
diff --git a/script/test/TestMicrohawk.py b/script/test/TestMicrohawk.py
new file mode 100644
index 0000000..0ea517e
--- /dev/null
+++ b/script/test/TestMicrohawk.py
@@ -0,0 +1,10 @@
+import ch.psi.pshell.serial.TcpDevice as TcpDevice
+import ch.psi.pshell.serial.UdpDevice as UdpDevice
+
+
+microscan = TcpDevice("microscan", "MicroHAWK38C528:2001")
+#microscan = UdpDevice("microscan", "MicroHAWK38C528:2001")
+microscan.initialize()
+
+
+
diff --git a/script/test/TestRecover.py b/script/test/TestRecover.py
new file mode 100644
index 0000000..340853f
--- /dev/null
+++ b/script/test/TestRecover.py
@@ -0,0 +1,15 @@
+print "Pos=" + str(robot.get_cartesian_pos())
+for p in robot.get_known_points():
+ print p + " = " + str(get_pnt(p))
+
+print "-------------"
+
+for segment in known_segments:
+ is_on_segment(segment)
+
+print "-------------"
+for segment in known_segments:
+ try:
+ move_to_segment(segment)
+ except:
+ print sys.exc_info()[1]
\ No newline at end of file
diff --git a/script/test/TestRelays.py b/script/test/TestRelays.py
new file mode 100644
index 0000000..adcd828
--- /dev/null
+++ b/script/test/TestRelays.py
@@ -0,0 +1,12 @@
+for i in range(500):
+ relay1.write(True)
+ time.sleep(1.2)
+ relay1.write(False)
+ time.sleep(1.2)
+"""
+for i in range(5):
+ relays.write(to_array([True,]*16, 'z'))
+ time.sleep(0.2)
+ relays.write(to_array([False,]*16, 'z'))
+ time.sleep(0.2)
+"""
\ No newline at end of file
diff --git a/script/test/TestRemoveBackground.py b/script/test/TestRemoveBackground.py
new file mode 100644
index 0000000..7376f07
--- /dev/null
+++ b/script/test/TestRemoveBackground.py
@@ -0,0 +1,31 @@
+number_frames = 5
+number_backgrounds = 5
+minimum_size = 78 # r = 5 # 150
+maximum_size = 750 # r = 15 #1500
+min_circ = 0.2
+
+threshold_method = "MaxEntropy"
+threshold_method,threshold_range = "Manual", (0, 215)
+
+exclude_edges = True
+led_latency = 0.5 #0.1
+
+set_led_state(False)
+time.sleep(led_latency)
+img.waitNext(2000)
+
+background = average_frames(number_backgrounds)
+#background = integrate_frames(number_backgrounds)
+
+set_led_state(True)
+time.sleep(led_latency)
+img.waitNext(2000)
+image = average_frames(number_frames)
+#image = integrate_frames(number_frames)
+
+set_led_state(False)
+
+op_image(image, background, "subtract", float_result=True, in_place=True)
+image=grayscale(image)
+
+show_panel(image.getBufferedImage())
\ No newline at end of file
diff --git a/script/test/TestRobot.py b/script/test/TestRobot.py
new file mode 100644
index 0000000..d64599f
--- /dev/null
+++ b/script/test/TestRobot.py
@@ -0,0 +1,41 @@
+robot.task_create("simulateEvents",3, name = "test", priority = 20)
+print robot.get_task_status("test")
+print robot.get_task_status("tests")
+
+robot.task_suspend("test")
+print robot.get_task_status("test")
+robot.task_resume("test")
+print robot.get_task_status("test")
+
+robot.task_kill("test")
+print robot.get_task_status("test")
+
+
+print robot.is_powered()
+print robot.get_monitor_speed()
+#print robot.set_monitor_speed(20)
+#print robot.enable()
+print robot.disable()
+print robot.is_calibrated()
+print robot.read_working_mode()
+print robot.get_emergency_stop_sts()
+print robot.get_safety_fault_signal()
+print robot.stop()
+print robot.resume()
+print robot.reset_motion()
+print robot.is_empty()
+print robot.is_settled()
+print robot.get_move_id()
+print robot.set_move_id(10)
+print robot.get_joint_forces()
+#print robot.open("gripper")
+#print robot.close("gripper")
+print robot.herej()
+print robot.distance_t("t", "t")
+print robot.distance_p("p", "p")
+print robot.compose( "p", "world", "t")
+print robot.here("gripper", "world")
+print robot.joint_to_point("gripper", "world", "j")
+print robot.point_to_joint("gripper", "j", "p")
+print robot.position("p", "world")
+print robot.mount(1, 2)
diff --git a/script/test/TestRobot2.py b/script/test/TestRobot2.py
new file mode 100644
index 0000000..68398b8
--- /dev/null
+++ b/script/test/TestRobot2.py
@@ -0,0 +1,72 @@
+import traceback
+
+robot.task_create("simulateEvents",3, name = "test", priority = 20)
+
+step = 0
+try:
+ while(True):
+ start = time.time()
+ step = 1
+ robot.is_powered()
+ step = 2
+ robot.get_task_status("test")
+ step = 3
+ robot.get_monitor_speed()
+ step = 4
+ #robot.set_monitor_speed(20)
+ #robot.enable()
+ step = 5
+ #robot.disable()
+ step = 6
+ robot.is_calibrated()
+ step = 7
+ robot.read_working_mode()
+ step = 8
+ robot.get_emergency_stop_sts()
+ step = 9
+ robot.get_safety_fault_signal()
+ step = 10
+ robot.stop()
+ step = 11
+ robot.resume()
+ step = 12
+ robot.reset_motion()
+ step = 13
+ robot.is_empty()
+ step = 14
+ robot.is_settled()
+ step = 15
+ robot.get_move_id()
+ step = 16
+ robot.set_move_id(10)
+ step = 17
+ robot.get_joint_forces()
+ step = 18
+ #robot.open_tool("gripper")
+ #robot.close_tool("gripper")
+ robot.herej()
+ step = 19
+ robot.distance_t("t", "t")
+ step = 20
+ robot.distance_p("p", "p")
+ step = 21
+ robot.compose( "p", "world", "t")
+ step = 22
+ robot.here("gripper", "world")
+ step = 23
+ robot.joint_to_point("gripper", "world", "j")
+ step = 24
+ robot.point_to_joint("gripper", "j", "p")
+ step = 25
+ robot.position("p", "world")
+ step = 26
+ robot.mount(1, 2)
+ #print time.time()-start
+except:
+ print >> sys.stderr, traceback.format_exc()
+finally:
+ print "Step: " + str(step)
+ try:
+ robot.task_kill("test")
+ except:
+ pass
\ No newline at end of file
diff --git a/script/test/TestRobotCmds.py b/script/test/TestRobotCmds.py
new file mode 100644
index 0000000..4225281
--- /dev/null
+++ b/script/test/TestRobotCmds.py
@@ -0,0 +1,32 @@
+
+import java.lang.System as System
+
+index = 0
+max_time = 0
+while True:
+ start = System.currentTimeMillis()
+ robot.execute(1,1,1)
+ time.sleep(0.01)
+ robot.execute(2,1,1)
+ time.sleep(0.01)
+ robot.execute(1,1,1)
+ time.sleep(0.01)
+ robot.execute(2,1,1)
+ time.sleep(0.01)
+ robot.execute(1,1,1)
+ time.sleep(0.01)
+ robot.execute(2,1,1)
+ time.sleep(0.01)
+ robot.execute(1,1,1)
+ time.sleep(0.01)
+ robot.execute(2,1,1)
+ time.sleep(0.01)
+ robot.execute(1,1,1)
+ time.sleep(0.01)
+ robot.execute(2,1,1)
+ time.sleep(0.01)
+ cur_time = System.currentTimeMillis() - start
+ max_time = max(cur_time, max_time)
+ print index, cur_time, max_time
+ index = index + 1
+
\ No newline at end of file
diff --git a/script/test/TestRobotCmds2.py b/script/test/TestRobotCmds2.py
new file mode 100644
index 0000000..048e20e
--- /dev/null
+++ b/script/test/TestRobotCmds2.py
@@ -0,0 +1,25 @@
+if robot_req.read() != 0:
+ raise Exception("Ongoing command")
+if robot_ack.read() != 0:
+ raise Exception("Robot is not ready")
+robot_cmd.write(1)
+args = [0,0,0,0,0,0]
+
+robot_args.write(to_array(args, 'i'))
+
+
+robot_req.write(1)
+while robot_ack.read() == 0:
+ time.sleep(0.001)
+
+err = robot_ack.take()
+if err == 1:
+ ret = robot_ret.read()
+ print ret
+if err == 2:
+ print ("Invalid command: " + str(command))
+print ("Unknown error: " + str(err))
+robot_req.write(0)
+while robot_ack.read() != 0:
+ time.sleep(0.001)
+
diff --git a/script/test/cycle_time b/script/test/cycle_time
new file mode 100644
index 0000000..79c790e
--- /dev/null
+++ b/script/test/cycle_time
@@ -0,0 +1,4 @@
+start =time.time()
+unmount('A',2,5, force=True)
+mount('A',2,5, force=True, read_dm=False)
+print time.time()-start
\ No newline at end of file
diff --git a/script/test/imgtest.py b/script/test/imgtest.py
new file mode 100644
index 0000000..de442c2
--- /dev/null
+++ b/script/test/imgtest.py
@@ -0,0 +1,47 @@
+###################################################################################################
+# Example of using ImageJ functionalities through ijutils.
+###################################################################################################
+
+from ijutils import *
+import java.awt.Color as Color
+
+import ch.psi.pshell.imaging.Filter as Filter
+from ch.psi.pshell.imaging.Overlays import *
+import ch.psi.pshell.imaging.Pen as Pen
+
+
+
+def detect_pucks(ip):
+ aux = grayscale(ip, in_place=False)
+ threshold(aux,0,50)
+ binary_fill_holes(aux)
+ return analyse_particles(aux, 10000,50000,
+ fill_holes = False, exclude_edges = True,print_table=True,
+ output_image = "outlines", minCirc = 0.4, maxCirc = 1.0)
+
+def detect_samples(ip):
+ aux = grayscale(ip, in_place=False)
+ invert(aux)
+ subtract_background(aux)
+ auto_threshold(aux)
+ binary_open(aux)
+ return analyse_particles(aux, 300,800,
+ fill_holes = False, exclude_edges = True,print_table=True,
+ output_image = "outlines", minCirc = 0.4
+ , maxCirc = 1.0)
+
+
+class MyFilter(Filter):
+ def process(self, image, data):
+ ip = load_image(image)
+ (results_puck,output_puck) = detect_pucks(ip)
+ (results_samples,output_samples) = detect_samples(ip)
+ set_lut(output_puck, outline_lut1[0], outline_lut1[1], outline_lut1[2])
+ set_lut(output_samples, outline_lut2[0], outline_lut2[1], outline_lut2[2])
+ op_image(ip, output_samples, "xor")
+ op_image(ip, output_puck, "xor")
+ return ip.getBufferedImage()
+
+#Setting the filter to a source
+img.setFilter(MyFilter())
+
diff --git a/script/test/ip b/script/test/ip
new file mode 100644
index 0000000..e79bb62
--- /dev/null
+++ b/script/test/ip
@@ -0,0 +1,15 @@
+from ijutils import *
+import java.awt.Color as Color
+
+ip = load_image(img.getImage())
+grayscale(ip)
+#ip=binning(ip,2)
+gaussian_blur(ip)
+#bandpass_filter(ip,20, 100)
+auto_threshold(ip)
+
+#Particle Analysis
+(results,output_img)=analyse_particles(ip, 500,2000, print_table=True)
+output_img.show()
+
+ip.show()
\ No newline at end of file
diff --git a/script/test/mount_profile.py b/script/test/mount_profile.py
new file mode 100644
index 0000000..89ebd80
--- /dev/null
+++ b/script/test/mount_profile.py
@@ -0,0 +1,144 @@
+mount_sample_id = None
+mount_sample_detected = None
+
+def mount(segment, puck, sample, force=False, read_dm=False, auto_unmount=False):
+ """
+ """
+ global mount_sample_id, mount_sample_detected
+ print "mount: ", segment, puck, sample, force
+
+ start = time.time()
+
+ #time.sleep(2)
+ is_aux = (segment == AUX_SEGMENT)
+
+ #ZACH
+ needs_chilling = not is_aux and (not robot.is_cold())
+ needs_drying = is_aux and robot.is_cold()
+
+ puck_address = get_puck_address(puck)
+ if puck_address is None:
+ puck_obj = get_puck_obj_by_id(puck)
+ if puck_obj is not None:
+ puck_address = puck_obj.name
+ if puck_address is not None:
+ print "puck address: ", puck_address
+ segment = puck_address[:1]
+ puck = int(puck_address[1:])
+ #Initial checks
+ assert_valid_address(segment, puck, sample)
+ assert_puck_detected(segment, puck)
+
+ if robot.simulated:
+ time.sleep(3.0)
+ mount_sample_detected = True
+ mount_sample_id = "YYY0001"
+ update_samples_info_sample_mount(get_puck_name(segment, puck), sample, mount_sample_detected, mount_sample_id)
+ set_setting("mounted_sample_position", get_sample_name(segment, puck, sample))
+ return [mount_sample_detected, mount_sample_id]
+
+ robot.assert_no_task()
+ robot.reset_motion()
+ robot.wait_ready()
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+ hexiposi.assert_homed()
+ assert_mount_position()
+
+ print "Pass 1: ", time.time() - start; start = time.time()
+ try:
+ #ZACH
+ if needs_chilling:
+ robot.move_cold()
+ time.sleep(30.0)
+
+ if smart_magnet.get_supress() == True:
+ smart_magnet.set_supress(False)
+ time.sleep(0.2)
+ #To better dectect sample
+ smart_magnet.apply_resting()
+ time.sleep(0.5)
+ if smart_magnet.check_mounted(idle_time=0.25, timeout = 1.0) == True:
+ print "Pass 1b: ", time.time() - start; start = time.time()
+ if auto_unmount and (get_setting("mounted_sample_position") is not None):
+ #auto_unmount set to true so detection remains enabled
+ unmount(force = True, auto_unmount = True)
+ else:
+ raise Exception("Pin detected on gonio")
+ print "Pass 2: ", time.time() - start; start = time.time()
+ set_status("Mounting: " + str(segment) + str(puck) + str(sample))
+ #location = robot.get_current_point()
+
+ #Enabling
+ enable_motion()
+
+ print "Pass 3: ", time.time() - start; start = time.time()
+ #ZACH
+ # a room temp pin is being mounted but the gripper is cold
+ if needs_drying:
+ dry(wait_cold=-1) # move to park after dry
+
+ if is_aux:
+ if not robot.is_aux():
+ robot.move_aux()
+ print "Pass 3b: ", time.time() - start; start = time.time()
+ robot.get_aux(sample)
+
+ else:
+ set_hexiposi(segment)
+ print "Pass 4: ", time.time() - start; start = time.time()
+ if not force:
+ visual_check_hexiposi(segment)
+
+ if not robot.is_dewar():
+ robot.move_dewar()
+ print "Pass 4b: ", time.time() - start; start = time.time()
+ robot.get_dewar(segment, puck, sample)
+ print "Pass 5: ", time.time() - start; start = time.time()
+
+ if read_dm:
+ barcode_reader.start_read(10.0)
+ robot.move_scanner()
+ #time.sleep(1.0)
+
+ robot.move_gonio()
+
+ if read_dm:
+ mount_sample_id = barcode_reader.get_readout()
+ print "Datamatrix: " , mount_sample_id
+ else:
+ mount_sample_id = None
+ print "Pass 6: ", time.time() - start; start = time.time()
+
+ robot.put_gonio()
+ print "Pass 7: ", time.time() - start; start = time.time()
+
+ try:
+ dry_mount_count = int(get_setting("dry_mount_counter"))
+ except:
+ dry_mount_count = 0
+ set_setting("dry_mount_counter", dry_mount_count+1)
+
+ if is_aux:
+ robot.move_home()
+ else:
+ robot.move_cold()
+ print "Pass 8: ", time.time() - start; start = time.time()
+ mount_sample_detected = smart_magnet.check_mounted(idle_time=0.25, timeout = 1.0)
+ update_samples_info_sample_mount(get_puck_name(segment, puck), sample, mount_sample_detected, mount_sample_id)
+ if mount_sample_detected == False:
+ raise Exception("No pin detected on gonio")
+
+
+ if is_force_dry():
+ smart_magnet.set_default_current()
+ print "Auto dry"
+ log("Starting auto dry", False)
+ set_exec_pars(then = "dry()")
+ print "Pass 9: " , time.time() - start; start = time.time()
+ set_setting("mounted_sample_position", get_sample_name(segment, puck, sample))
+ return [mount_sample_detected, mount_sample_id]
+ finally:
+ smart_magnet.set_default_current()
+ smart_magnet.set_supress(True)
+
diff --git a/script/test/onewire.py b/script/test/onewire.py
new file mode 100644
index 0000000..5141067
--- /dev/null
+++ b/script/test/onewire.py
@@ -0,0 +1,122 @@
+import traceback
+
+class Detector(ReadonlyRegisterBase):
+ def __init__(self, name):
+ ReadonlyRegisterBase.__init__(self, name)
+ self.id = None
+ self.sn = None
+ self.status = None
+ self.type = None
+ self.set_inputs({})
+
+ def set_inputs(self, inputs):
+ self.inputs = inputs
+ self.setCache(inputs.values(), None)
+ if (len(self.take()) == 0):
+ self.setState(State.Offline)
+ else:
+ self.setState(State.Ready)
+
+ def set_input(self, index, val):
+ self.inputs[index] = val
+ self.set_inputs(self.inputs)
+
+class Esera(TcpDevice):
+ def __init__(self, name, server, timeout = 1000, retries = 1):
+ TcpDevice.__init__(self, name, server)
+ self.setMode(self.Mode.FullDuplex)
+ self.detectors = []
+ self.complete = False
+
+ def start(self):
+ self.write("set,sys,run,1\n")
+
+ def stop(self):
+ self.write("set,sys,run,0\n")
+
+ def list(self):
+ self.write("get,owb,listall1\n")
+
+ def req_data(self):
+ self.write("get,sys,data\n")
+
+ def doInitialize(self):
+ super(Esera, self).doInitialize()
+ try:
+ self.setState(State.Ready) #So can communicate
+ #self.stop()
+ #time.sleep(0.1)
+ #self.flush()
+ self.detectors = []
+ for i in range(30):
+ self.detectors.append(Detector("Detector " + str(i+1)))
+ self.list()
+ time.sleep(0.5)
+ self.start()
+ self.req_data()
+ except:
+ print >> sys.stderr, traceback.format_exc()
+ getLogger().log(traceback.format_exc())
+ raise
+
+ def doUpdate(self):
+ if not self.complete:
+ init = True
+ for det in self.detectors:
+ if det.id == None:
+ init = False
+ break
+ if init:
+ self.complete = True
+ self.start()
+
+ self.req_data()
+ #def onByte(self, rx):
+ # print rx
+
+ def onString(self, msg):
+ print msg
+ tokens = msg.split("|")
+ if len(tokens)>1:
+ try:
+ if msg[:3] == "LST":
+ #LST|1_OWD1|3AF361270000009E|S_0|DS2413|
+ if tokens[1] > 1:
+ index = int(tokens[1].split("_")[1][3:]) - 1
+ if index < len(self.detectors):
+ det = self.detectors[index]
+ det.id = tokens[1]
+ det.sn= tokens[2] if len(tokens)>2 else None
+ det.status = int(tokens[3][2:]) if len(tokens)>3 else None
+ det.type = tokens[4] if len(tokens)>4 else None
+ if det.status!= 0:
+ det.set_inputs({})
+ else:
+ for det in self.detectors:
+ if det.id is not None and msg.startswith(det.id):
+ det_id = int(tokens[0][len(det.id)+1:])
+ det.set_input(det_id, int(tokens[1]))
+ except:
+ print >> sys.stderr, traceback.format_exc()
+ getLogger().log(traceback.format_exc())
+
+
+
+
+#count = 1
+#while (True):
+# print onewire.waitString("\n", 1000)#
+#
+# print count
+# count = count + 1
+
+
+
+
+
+
+add_device(Esera("onewire", "129.129.126.83:5000"), force = True)
+onewire.setPolling(1000)
+add_device(onewire.detectors[0], force = True)
+add_device(onewire.detectors[1], force = True)
+add_device(onewire.detectors[2], force = True)
diff --git a/script/test/test.py b/script/test/test.py
new file mode 100644
index 0000000..92fcaca
--- /dev/null
+++ b/script/test/test.py
@@ -0,0 +1,24 @@
+from ijutils import *
+import java.awt.Color as Color
+
+
+#ip = load_array(img.getData().getMatrix())
+ip = load_image(img.getOutput())
+#ip = load_image("{images}/test3.png", title="Image")
+
+
+aux = grayscale(ip, in_place=False)
+aux.show()
+
+#convolve(aux, KERNEL_SOBEL); aux.repaintWindow()
+
+invert(aux); aux.repaintWindow()
+subtract_background(aux); aux.repaintWindow()
+auto_threshold(aux); aux.repaintWindow()
+binary_open(aux); aux.repaintWindow()
+
+(table, image) = analyse_particles(aux, 250,1000,
+ fill_holes = False, exclude_edges = True,print_table=True,
+ output_image = "outlines", minCirc = 0.82, maxCirc = 1.0)
+
+image.show()
\ No newline at end of file
diff --git a/script/test/test_hexiposi.py b/script/test/test_hexiposi.py
new file mode 100644
index 0000000..324a480
--- /dev/null
+++ b/script/test/test_hexiposi.py
@@ -0,0 +1,8 @@
+index = 1
+while(True):
+ for pos in ['A', 'B', 'C', 'D', 'E', 'F']:
+ hexiposi.move(pos)
+ visual_check_hexiposi(pos)
+ print "Ok: " + pos
+ print index
+ index = index + 1
\ No newline at end of file
diff --git a/script/test/test_segments.py b/script/test/test_segments.py
new file mode 100644
index 0000000..54a8898
--- /dev/null
+++ b/script/test/test_segments.py
@@ -0,0 +1,16 @@
+p=robot.get_cartesian_pos()
+print "Pos: ", p
+print "Cache pos:", robot.cartesian_pos
+print "Cache dest: ", robot.cartesian_destination
+
+
+print "Points: ", robot.get_current_points()
+for segment in known_segments:
+ if is_on_segment(segment):
+ print " On : " + str(segment) + " - Dist:" + str(get_dist_to_segment(segment))
+
+
+
+p2 = robot.get_cartesian_pos()
+if arrsub( p2, p) != [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]:
+ print "Pos: ", p2
\ No newline at end of file
diff --git a/script/test/test_swingutils.py b/script/test/test_swingutils.py
new file mode 100644
index 0000000..65b354b
--- /dev/null
+++ b/script/test/test_swingutils.py
@@ -0,0 +1,24 @@
+import ch.psi.pshell.imaging.RendererMode as RendererMode
+import ch.psi.pshell.imaging.Calibration as Calibration
+from ch.psi.pshell.imaging.Overlays import *
+import ch.psi.utils.swing.SwingUtils as SwingUtils
+import javax.swing.SwingUtilities as SwingUtilities
+from swingutils.threads.swing import callSwing
+
+
+p = show_panel(img)
+dlg = SwingUtilities.getWindowAncestor(p)
+dlg.setSize(800,800)
+frm=SwingUtils.getFrame(p)
+dlg.setLocationRelativeTo(frm)
+
+def update_frame(frm):
+ SwingUtilities.updateComponentTreeUI(frm)
+ frm.validate()
+ frm.repaint()
+#$callSwing(update_frame, frm)
+
+
+x=0
+for i in range(0,10000000):
+ x=x+1
\ No newline at end of file
diff --git a/script/test/then.py b/script/test/then.py
new file mode 100644
index 0000000..fcbe1bb
--- /dev/null
+++ b/script/test/then.py
@@ -0,0 +1,3 @@
+time.sleep(3.0)
+
+set_exec_pars(then = "time.sleep(5.0)")
\ No newline at end of file
diff --git a/script/test/transfer_profile.py b/script/test/transfer_profile.py
new file mode 100644
index 0000000..00be4cb
--- /dev/null
+++ b/script/test/transfer_profile.py
@@ -0,0 +1,23 @@
+
+
+measures = []
+#smart_magnet.measures = []
+
+
+for m in range(1):
+ print "Step ", m
+ start = time.time()
+ #mount('A',3,m+1, force=True, read_dm=False, auto_unmount=True)
+ #mount('A',5,m+1, force=True, read_dm=False, auto_unmount=True)
+
+ #mount('A',3,1, force=True, read_dm=False, auto_unmount=True)
+ #unmount('A',3,1, force=True)
+ #mount('A',3,1, force=True, read_dm=False, auto_unmount=True)
+ measures.append( time.time()-start)
+
+print "Total transfer: ", measures
+print "Time: ", mean(measures), "+-", stdev(measures)
+
+
+#print "SM cehck: ", smart_magnet.measures
+#print "Time: ", mean(smart_magnet.measures), "+-", stdev(smart_magnet.measures)
\ No newline at end of file
diff --git a/script/test/unmount_profile.py b/script/test/unmount_profile.py
new file mode 100644
index 0000000..5adcdb3
--- /dev/null
+++ b/script/test/unmount_profile.py
@@ -0,0 +1,98 @@
+def unmount(segment = None, puck = None, sample = None, force=False, auto_unmount = False):
+ """
+ """
+ print "unmount: ", segment, puck, sample, force
+ start = time.time()
+ #ZACH
+ is_aux = (segment == AUX_SEGMENT)
+ needs_chilling = not is_aux and (not robot.is_cold())
+ needs_drying = is_aux and robot.is_cold()
+
+ if (segment is None) or (puck is None) or (sample is None):
+ pos = get_setting("mounted_sample_position")
+ if pos is None:
+ raise Exception("Mounted sample position is not defined")
+ segment, puck , sample = pos[0:1], int(pos[1]), int(pos[2:])
+ print "Mounted sample position: ", segment, puck , sample
+
+ #Initial checks
+ print "assert valid address"
+ assert_valid_address(segment, puck, sample)
+ print "asser puck detected"
+ assert_puck_detected(segment, puck)
+
+ if robot.simulated:
+ time.sleep(3.0)
+ update_samples_info_sample_unmount(get_puck_name(segment, puck), sample)
+ set_setting("mounted_sample_position", None)
+ return
+
+ print "assert no task"
+ robot.assert_no_task()
+ print "reset motion"
+ robot.reset_motion()
+ print "wait ready"
+ robot.wait_ready()
+ print "assert cleared"
+ robot.assert_cleared()
+ #robot.assert_in_known_point()
+ print "assert homed"
+ hexiposi.assert_homed()
+ print "assert mount pos"
+ assert_mount_position()
+ print "Pass A: " , time.time() - start; start = time.time()
+ set_status("Umounting: " + str(segment) + str(puck) + str(sample))
+
+ try:
+ if smart_magnet.get_supress() == True:
+ smart_magnet.set_supress(False)
+ time.sleep(0.2)
+
+ smart_magnet.apply_resting()
+
+ if not force:
+ if smart_magnet.check_mounted(idle_time=0.5, timeout = 3.0) == False:
+ raise Exception("No pin detected on gonio")
+ print "Pass B: " , time.time() - start; start = time.time()
+ #Enabling
+ enable_motion()
+ print "Pass C: " , time.time() - start; start = time.time()
+
+ if not is_aux:
+ set_hexiposi(segment)
+ print "Pass D: " , time.time() - start; start = time.time()
+ if not force:
+ visual_check_hexiposi(segment)
+ if needs_chilling:
+ robot.move_cold()
+ time.sleep(30.)
+ else:
+ if needs_drying:
+ dry(wait_cold=-1)
+ #location = robot.get_current_point()
+ print "Pass E: " , time.time() - start; start = time.time()
+ if not robot.is_gonio():
+ robot.move_gonio()
+ print "Pass F: " , time.time() - start; start = time.time()
+ #smart_magnet.set_unmount_current()
+
+ robot.get_gonio()
+ print "Pass G: " , time.time() - start; start = time.time()
+ #smart_magnet.apply_reverse()
+ #smart_magnet.apply_resting()
+
+ if is_aux:
+ robot.move_aux()
+ robot.put_aux( sample)
+ else:
+ #TODO: Shuld check if smart magnet detection is off?
+ update_samples_info_sample_unmount(get_puck_name(segment, puck), sample)
+ robot.move_dewar()
+ print "Pass H: " , time.time() - start; start = time.time()
+ robot.put_dewar(segment, puck, sample)
+ print "Pass I: " , time.time() - start; start = time.time()
+ set_setting("mounted_sample_position", None)
+ finally:
+ if not auto_unmount:
+ smart_magnet.set_default_current()
+ smart_magnet.set_supress(True)
diff --git a/script/tools/CheckGripper.py b/script/tools/CheckGripper.py
new file mode 100644
index 0000000..603c756
--- /dev/null
+++ b/script/tools/CheckGripper.py
@@ -0,0 +1,23 @@
+
+
+
+vector = [1.0,0.0]
+
+
+
+class GripperTool(RegisterBase):
+ def doRead(self):
+ return 1.0 if robot.is_tool_open() else 0.0
+
+ def doWrite(self, val):
+ if val:
+ robot.open_tool()
+ else:
+ robot.close_tool()
+
+
+add_device(GripperTool("gripper_tool"), True)
+
+
+vscan(gripper_tool, [laser_distance,], vector, latency = 3, passes=50)
+
diff --git a/script/tools/CheckPuckDetection.py b/script/tools/CheckPuckDetection.py
new file mode 100644
index 0000000..d9bf425
--- /dev/null
+++ b/script/tools/CheckPuckDetection.py
@@ -0,0 +1,6 @@
+USR,PWD = "pi", "raspberry"
+HOST,PORT = "tell6d-raspberrypi", 22
+CMD= "sudo systemctl status puck_detection.service"
+
+ret = run("tools/SshExec")
+set_return(ret)
\ No newline at end of file
diff --git a/script/tools/Math.py b/script/tools/Math.py
new file mode 100644
index 0000000..c76ce33
--- /dev/null
+++ b/script/tools/Math.py
@@ -0,0 +1,68 @@
+###################################################################################################
+# Math utilities
+###################################################################################################
+
+
+from mathutils import estimate_peak_indexes, fit_gaussians, create_fit_point_list, Gaussian
+import java.awt.Color as Color
+
+import mathutils
+mathutils.MAX_ITERATIONS = 100000
+
+def fit(ydata, xdata = None, draw_plot = True):
+ if xdata is None:
+ xdata = frange(0, len(ydata), 1)
+ max_y= max(ydata)
+ index_max = ydata.index(max_y)
+ max_x= xdata[index_max]
+ #print "Max index:" + str(index_max),
+ #print " x:" + str(max_x),
+ #print " y:" + str(max_y)
+
+ if draw_plot:
+ plots = plot([ydata],["data"],[xdata], title="Fit" )
+ p = None if plots is None else plots[0]
+
+ gaussians = fit_gaussians(ydata, xdata, [index_max,])
+ if gaussians[0] is None:
+ if draw_plot and (p is not None):
+ p.addMarker(max_x, None, "Max="+str(round(max_x,4)), Color.GRAY)
+ print "Fitting error"
+ return (None, None, None)
+
+ (norm, mean, sigma) = gaussians[0]
+ if draw_plot:
+ fitted_gaussian_function = Gaussian(norm, mean, sigma)
+ scale_x = [float(min(xdata)), float(max(xdata)) ]
+ points = max((len(xdata)+1), 100)
+ resolution = (scale_x[1]-scale_x[0]) / points
+ fit_y = []
+ fit_x = frange(scale_x[0],scale_x[1],resolution, True)
+ for x in fit_x:
+ fit_y.append(fitted_gaussian_function.value(x))
+ #Server
+ if p is None:
+ plot([ydata,fit_y],["data","fit"],[xdata,fit_x], title="Fit")
+ draw_plot = False
+ else:
+ p.addSeries(LinePlotSeries("fit"))
+ p.getSeries(1).setData(fit_x, fit_y)
+
+ if abs(mean - xdata[index_max]) < abs((scale_x[0] + scale_x[1])/2):
+ if draw_plot:
+ p.addMarker(mean, None, "Mean="+str(round(mean,4)), Color.MAGENTA.darker())
+ #print "Mean -> " + str(mean)
+ return (norm, mean, sigma)
+ else:
+ if draw_plot:
+ p.addMarker(max_x, None, "Max="+str(round(max_x,4)), Color.GRAY)
+ #print "Invalid gaussian fit: " + str(mean)
+ return (None, None, None)
+
+
+def enforce_monotonic(x):
+ epsilon = 1e-8
+ for i in range(len(x)-1):
+ if x[i+1]<=x[i]:
+ x[i+1] = x[i]+ epsilon
+ return x
\ No newline at end of file
diff --git a/script/tools/RestartPuckDetection.py b/script/tools/RestartPuckDetection.py
new file mode 100644
index 0000000..8f14c00
--- /dev/null
+++ b/script/tools/RestartPuckDetection.py
@@ -0,0 +1,8 @@
+USR,PWD = "pi", "raspberry"
+HOST,PORT = "tell6d-raspberrypi", 22
+CMD= "sudo systemctl stop puck_detection.service;sudo systemctl start puck_detection.service"
+
+ret = run("tools/SshExec")
+set_return(ret)
+
+puck_detection.initialize()
\ No newline at end of file
diff --git a/script/tools/SshExec.py b/script/tools/SshExec.py
new file mode 100644
index 0000000..c9e4f50
--- /dev/null
+++ b/script/tools/SshExec.py
@@ -0,0 +1,61 @@
+import com.jcraft.jsch.Channel as Channel
+import com.jcraft.jsch.ChannelShell as ChannelShell
+import com.jcraft.jsch.JSch as JSch
+import com.jcraft.jsch.JSchException as JSchException
+import com.jcraft.jsch.Session as Session
+import java.lang.System as System
+import java.io.PrintStream as PrintStream
+
+
+#Parameters:
+#CMD
+#USR
+#PWD
+#HOST
+#PORT
+
+jsch= JSch()
+session=jsch.getSession(USR, HOST, PORT)
+session.setPassword(PWD)
+session.setConfig("StrictHostKeyChecking", "no")
+session.connect()
+
+#channel=session.openChannel("shell")
+#input_stream=channel.getInputStream()
+#output_stream = channel.getOutputStream()
+#print_stream = PrintStream(output_stream, True)
+#print_stream.println("ls")
+
+channel=session.openChannel("exec")
+channel.setCommand(CMD)
+channel.setInputStream(None)
+channel.setOutputStream(System.out)
+channel.setErrStream(System.err)
+input_stream=channel.getInputStream()
+
+
+def wait_ret():
+ global input_stream
+ rx = ""
+ while True:
+ while (input_stream.available() > 0):
+ i = input_stream.read()
+ if i < 0:
+ break
+ rx=rx+chr(i)
+ if channel.closed:
+ break
+ time.sleep(0.1)
+ return rx
+
+
+channel.connect()
+
+try:
+ ret = wait_ret()
+except:
+ channel.disconnect()
+ session.disconnect()
+ raise
+
+set_return(ret)
\ No newline at end of file
diff --git a/script/tools/StopPuckDetection.py b/script/tools/StopPuckDetection.py
new file mode 100644
index 0000000..9c5b27b
--- /dev/null
+++ b/script/tools/StopPuckDetection.py
@@ -0,0 +1,8 @@
+USR,PWD = "pi", "raspberry"
+HOST,PORT = "tell6d-raspberrypi", 22
+CMD= "sudo systemctl stop puck_detection.service"
+
+ret = run("tools/SshExec")
+set_return(ret)
+
+