TCP/IP Protocol

This is the documentation of the Remote2 protocol used to remotely control Zahner Zennium Workstations over a TCP/IP connection. This protocol is also used by the Python library, the C++ Library and the DevCli.dll. The user does not have to deal with this TCP/IP Protocol when using the libraries or the DLL.

It was developed to integrate Zahner Zennium Potentiostats into third party applications for more complex measurement tasks and for automation purposes.

The measurement methods EIS, IE (current voltage curve), CV and DC sequences are supported. Also constant current or constant voltage can be output and current and voltage can be measured. Single frequency impedance measurement is also possible.

Measurement System Architecture

../_images/system_structure.png

The Zahner software for controlling the Workstations (Zennium series) consists of two parts. On the computer, the Term software is executed. The Thales measurement software, which communicates with the Term, runs on the measuring device.

The Term is the interface for operating Thales on the measuring device. The Term performs for example the GUI operations, the hard disk accesses or the TCP/IP communication for the Thales software.

Term Communication Basics

The Term software provides port 260 for network connections. The client can establish one or multiple socket connections to this port.

Connection Concept

With multiple connections, the client requires a unique Connection Name for each connection.

Default names are “Logging” for Zahner Online Display data and “ScriptRemote” for using the Remote2 . These connections are allowed to be established only once. The names of other connections can be freely assigned, only the characters a-z and A-Z are allowed. Commands can only be sent after the connection has been established and registered.

Message Packet Structure

Via the socket connection, the client application registers itself at the Term with a Connection Name.

Note

Essentials about the packet figures:

  • Binary bytes are written as HEX with the prefix x.

  • ASCII characters are not specially marked.

  • The packets arrive at the client with the left field first.

The registration packet is structured as follows:

Message Part

Length Connection Name

Initialization Byte Sequence

Connection Name

Size in bytes

2

6

Length Connection Name

Description

little-endian uint16

x02 xd0 xff xff xff xff

Name

After the connection is registered with the registration packet, the following message packets are used for communication. The registration is explained in detail step by step in the next section. The message packets consisting of 2 bytes payload length, 1 byte packet type and the payload:

Message Part

Length

Packet Type

Payload

Size in bytes

2

1

Length

Description

little-endian uint16

explanation in the following table

user data

The colors red, green and blue for the individual components of the packet are always used in the following.

The following table lists the packet types:

Packet Type

Description/Usage

0

Broadcast Packet that must be ignored from the client

2

Generic read/write

4

Logout of the connection

128

Administrative commands

129

File length transfer

130

File name transfer

131

Transfer of file contents in 20480 byte blocks

General hints

Note

The message length in the protocol does not contain the packet type, so you must always read message length + 1 from the socket.

Packets with type 0 must be read correctly and can be ignored. These are sent as a broadcast from the underlying system layer.

The commands take different amounts of time. Setting values or reading voltage, for example, is faster than measuring impedance.

Connect to the Term

To connect to the Term, the packets explained in the previous section are used. This is explained in the following section with an example. Here every step must be observed including the waiting times, which are necessary.

1. Establish socket connection

First, a socket connection to port 260 must be established.

2. 400 ms waiting time

3. Register connection at the Term

After establishing the socket connection, the client must register at the Term software with its name. In this example “ScriptRemote” is used as connection/device name to use the Thales Remote2.

Each column of the table corresponds to one byte in the registration packet. The packet length is 12 (x0c), because “ScriptRemote” has 12 letters.

x0c

x00

x02

xd0

xff

xff

xff

xff

S

c

r

i

p

t

R

e

m

o

t

e

There is no response to this command.

4. 800 ms waiting time

After these steps, the connection can be used to control the Term and Thales.

Disconnect from the Term

1. Send logout command

As explained in the previous section, the logout packet must be sent to inform the Term that you are disconnecting.

x02

x00

x04

xff

xff

There is no response to this command.

2. 400 ms waiting time

3. Disconnect socket

After the waiting time you can close your socket connection to the Term.

Remote control with Remote2

When the connection to the Term has been established, Thales can be controlled remotely. For this, the runtime Remote2 must be started, this is explained in the following section.

The Remote2 commands can then be sent via TCP/IP. This is also explained using examples.

Start Remote2 runtime

The runtime can also be started via GUI as an alternative to this explanation. In this manual only the remote start of the Remote2 runtime is explained.

With the following packet, which is sent to the Term, the Remote2 runtime is started:

x0e

x00

x80

2

,

S

c

r

i

p

t

R

e

m

o

t

e

With the packet type 128 (x80) the string 2,ScriptRemote is sent to start the runtime. The string length is 14 (x0e). This string is always the same because only the connection with the name “ScriptRemote” can use the Remote2.

The Term responds with:

x18

x00

x80

1

2

8

,

S

c

r

i

p

t

R

e

m

o

t

e

,

5

,

6

,

0

,

0

The Term responds with packet type 128 (x80) and the string 128,ScriptRemote,5,6,0,0. The response length is accordingly 24 (x18).

Send Remote2 commands

Remote2 commands are sent with the packet type 2. The commands must be extended with the following string: “1:<command>:”. This string is the payload.

As an example, the voltage is measured with the following packet:

x0c

x00

x02

1

:

P

O

T

E

N

T

I

A

L

:

The Remote2 command to measure the voltage is called POTENTIAL, so the payload 1:POTENTIAL: is sent to read the voltage.

The Remote2 response to this packet is sent in the payload as follows: potential= 9.998674e-01V\r. The full packet can be seen below. The two blank characters are displayed as empty boxes.

x1a

x00

x02

p

o

t

e

n

t

i

a

l

=

9

.

9

9

8

6

7

4

e

-

0

1

V

\r

As another example, the voltage is set. All other Remote2 commands can be sent with the same syntax.

With the command Pset=1.0 1 V is set. This command is sent with the following packet:

x0b

x00

x02

1

:

P

s

e

t

=

1

.

0

:

Successful commands are responded with OK\r.

x03

x00

x02

O

K

\r

All numbers can be transmitted as floating point numbers.

Administrative functions

Note

In this examples ScriptRemote is used as connection name. You must use the name that was used by the registration at the Term software.

Query Heartbeat

The Heartbeat indicates the time when communication last took place between the Term and the Thales. This can be used to monitor the system. The heartbeat time is in milliseconds. If the Heartbeat time becomes longer and longer, the Thales software may have crashed.

The complete documentation of the Heartbeat can be found in the DevCli-Manual Page 8.

For low frequency impedance measurements below 1 Hz, the time increases with lower frequency. Here you have to test which time you choose as limit. In general it is to be considered that in the case of ranging processes (changing the current range) the time is not deterministic. The limit time should not be the number of measuring periods, because with a ranging process the measurement starts again at this frequency point.

With the packet type 128 (x80) the string 1,ScriptRemote is sent to query the Heartbeat. The string length is 14 (x0e).

x0e

x00

x80

1

,

S

c

r

i

p

t

R

e

m

o

t

e

The Term responds with packet type 128 (x80) and the string 128,ScriptRemote,500. This means 500 ms heartbeat time. The response length is accordingly 20 (x14).

x14

x00

x80

1

2

8

,

S

c

r

i

p

t

R

e

m

o

t

e

,

5

0

0

Query workstation serial number

This function returns only the serial number of the workstation, which is determined by the Term software. The serial number of the active potentiostat, including EPC devices, can be read with the Remote2 command ALLNUM.

With the packet type 128 (x80) the string 3,ScriptRemote is sent to query the serial number. The string length is 14 (x0e).

x0e

x00

x80

3

,

S

c

r

i

p

t

R

e

m

o

t

e

,

6

The Term software responds as an example in this case with serial number 43230.

x16

x00

x80

1

2

8

,

S

c

r

i

p

t

R

e

m

o

t

e

,

4

3

2

3

0

Enable and disable mouse grabbing

Thales moves the cursor back into the Thales window after measurements, for example. To prevent this in remote operation, where it is not necessary, mouse grabbing can be switched off. It is also possible to reset mouse grabbing to the default state in the ini file or to turn it on.

With the packet type 128 (x80) the string 3,ScriptRemote,0,OFF is sent to disable mouse grabbing. The string length is 20 (x14).

ON instead of OFF switches mouse grabbing on. RS resets it to the state of the ini file.

x14

x00

x80

3

,

S

c

r

i

p

t

R

e

m

o

t

e

,

0

,

O

F

F

The Term responds with:

x13

x00

x80

1

2

8

,

S

c

r

i

p

t

R

e

m

o

t

e

,

0

File exchange

This feature requires at least Thales/Term version 5.8.1.

The Term software always saves the Thales measurement files on the C hard disk in a subdirectory of Thales. The control can be done from another computer over the network, which means that you do not have access to the file system of the computer on which the Term is running.

Therefore the feature has been added that you can receive files over the network using the Term TCP/IP connection. It is possible to enable that automatically all files with the specified extensions, are also sent over network to the client, when they are written to the hard disk

A new TCP/IP socket connection must be established for file transfer.

In this example a connection is used which is registered with the name FileExchange at Thales software. This is the connection name that the Python library uses as default.

Acquire single file

This command sends a file from the remote computer to the client via the Thales software. The client must send to the Thales software the path of the file on the computer on which Thales is running.

In a Python GitHub example , the process is shown, using an example, of how to set the naming of the file so that you know the file path of the resulting impedance file.

The next section shows how all files are sent automatically and the last section in this chapter shows in which format the files are received.

In the following example packet the file C:\THALES\temp\myeis.ism is requested from the Thales software.

x29

x00

x80

3

,

F

i

l

e

E

x

c

h

a

n

g

e

,

1

,

C

:

\

T

H

A

L

E

S

\

t

e

m

p

\

m

y

e

i

s

.

i

s

m

The Term responds with the packets which are explained in this section.

Acquire alle files filtered by extension

With this function it can be switched on that automatically all files are sent by the Term, which have the specified endings. In some cases, backup files such as the “lastshot.ism” are also sent.

Whenever a file with the specified extensions is written to the hard disk, Thales also sends the file to the client via the socket connection.

Note

For this operation a second thread is needed which processes the packets from the Thales software whenever packets arrive.

The following command enables the automatic sending of all files with .ism, .isc and .isw extensions to the client. The payload is the string: 3,FileExchange,4,ON,*.ism*.isc*.isw

It is not recommended to include .txt files in the filter, because Thales software writes temporary .txt files at runtime, which are also sent.

x23

x00

x80

3

,

F

i

l

e

E

x

c

h

a

n

g

e

,

4

,

O

N

,

*

.

i

s

m

*

.

i

s

c

*

.

i

s

w

The Term responds with the following packet:

x13

x00

x84

1

2

8

,

F

i

l

e

E

x

c

h

a

n

g

e

,

O

N

The command is sent as packet type 128 (x80) and the response is packet type 132 (x84). With OFF instead of ON the automatic transmission can be disabled.

File receive protocol

For each file there are at least 3 message packets with the packet types 130, 129, 131 in exactly this order. The packet types are shown in the table above.

In the following, the 3 packets are explained in the order in which they arrive.

Packet 130 (x82) - Transfer of the file name

Even if only a single file is requested, the file name is sent again, then the process of automatic reception is identical to that of single files. For automatic reception, the file name is required in order to be able to identify the measurement data for example for PAD4 channels.

As an example, the packet of the measurement file myeis.ism is explained here.

x18

x00

x82

C

:

\

T

H

A

L

E

S

\

t

e

m

p

\

m

y

e

i

s

.

i

s

m

Packet 129 (x81) - Transfer of the file length

The length of the complete measurement file in bytes is sent with the next packet. This number of bytes must then be received with the 3rd packet type.

x04

x00

x81

1

1

5

3

The size of the file in this example is 1153 bytes.

Packet 131 (x83) - Transfer of the binary file content

The file content is transferred binary, that means the received bytes can be written directly into a file and then you have the file with the measurement data. The file must have the same extension, for example, so that it can be recognized by the Zahner Analysis.

If the file is too large for one packet, the file is split into several type 131 packets. This means that as many payload bytes must be read with type 131 packets until the number of bytes transmitted in the 129 packet has been received.

The 1153 bytes would be transmitted as one packet. In the following, a section of the packet is shown. Not all 1153 bytes are shown as boxes.

x81

x04

x83

Byte 0

Byte 1152

How the files are divided into packets is always different. The following is an example where a 40,000 byte file is split into two 20,000 byte packets.

Packet 1:

x40

x9C

x83

Byte 0

Byte 19 999

Packet 2:

x40

x9C

x83

Byte 20 000

Byte 39 999

Example communication packets

The following examples show how communication takes place with the different packet types. The examples have been broken down from the Python GitHub examples and the Python console features are shown. Each individual packet is not shown in boxes and is not color coded. In this section, everything is no longer explained in detail.

For the complete message the Python bytearray is displayed. If the first 3 bytes contain printable characters they are displayed as ASCII instead of HEX. Each packet is a contiguous block, which starts with a timestamp. The timestamp is followed by a send if it was sent by Python and a read if it was read by Python.

Python registration process

11:38:11.390758 send:
payload_length: 12
registration_packet: bytearray(b'\x0c\x00\x02\xd0\xff\xff\xff\xffScriptRemote')
complete packet:bytearray(b'\x0c\x00\x02\xd0\xff\xff\xff\xffScriptRemote')
connection successfull

11:38:12.206173 send:
payload_length: 20 message_type: 128
payload: bytearray(b'3,ScriptRemote,0,OFF')
complete packet:bytearray(b'\x14\x00\x803,ScriptRemote,0,OFF')

11:38:12.206173 read:
payload_length: 18 message_type: 128
payload: b'128,ScriptRemote,0'
complete packet:b'\x12\x00\x80128,ScriptRemote,0'

11:38:12.206173 send:
payload_length: 14 message_type: 128
payload: bytearray(b'2,ScriptRemote')
complete packet:bytearray(b'\x0e\x00\x802,ScriptRemote')

11:38:12.222163 read:
payload_length: 24 message_type: 128
payload: b'128,ScriptRemote,5,6,0,0'
complete packet:b'\x18\x00\x80128,ScriptRemote,5,6,0,0'

Current and voltage measurement

08:57:36.123597 send:
payload_length: 12 message_type: 2
payload: bytearray(b'1:POTENTIAL:')
complete packet:bytearray(b'\x0c\x00\x021:POTENTIAL:')

08:57:36.241663 read:
payload_length: 26 message_type: 2
payload: b'potential=  1.935760e+00V\r'
complete packet:b'\x1a\x00\x02potential=  1.935760e+00V\r'
Potential: 1.93576

08:57:36.241663 send:
payload_length: 10 message_type: 2
payload: bytearray(b'1:CURRENT:')
complete packet:bytearray(b'\n\x00\x021:CURRENT:')

08:57:36.365799 read:
payload_length: 24 message_type: 2
payload: b'current=  1.983870e-08A\r'
complete packet:b'\x18\x00\x02current=  1.983870e-08A\r'
Current: 1.98387e-08

EIS measurement

11:38:18.655770 send:
payload_length: 6 message_type: 2
payload: bytearray(b'1:EIS:')
complete packet:bytearray(b'\x06\x00\x021:EIS:')

11:38:51.168324 read:
payload_length: 9 message_type: 2
payload: b'EIS DONE\r'
complete packet:b'\t\x00\x02EIS DONE\r'

CV measurement

11:37:27.985056 send:
payload_length: 5 message_type: 2
payload: bytearray(b'1:CV:')
complete packet:bytearray(b'\x05\x00\x021:CV:')

11:38:00.431160 read:
payload_length: 8 message_type: 2
payload: b'CV DONE\r'
complete packet:b'\x08\x00\x02CV DONE\r'

IE measurement

11:38:00.894866 send:
payload_length: 5 message_type: 2
payload: bytearray(b'1:IE:')
complete packet:bytearray(b'\x05\x00\x021:IE:')

11:38:39.961808 read:
payload_length: 8 message_type: 2
payload: b'IE DONE\r'
complete packet:b'\x08\x00\x02IE DONE\r'

Single file transfer

11:38:51.209188 send:
payload_length: 41 message_type: 128
payload: bytearray(b'3,FileExchange,1,C:\\THALES\\temp\\myeis.ism')
complete packet:bytearray(b')\x00\x803,FileExchange,1,C:\\THALES\\temp\\myeis.ism')

11:38:51.210188 read:
payload_length: 24 message_type: 130
payload: b'C:\\THALES\\temp\\myeis.ism'
complete packet:b'\x18\x00\x82C:\\THALES\\temp\\myeis.ism'

11:38:51.210188 read:
payload_length: 4 message_type: 129
payload: b'1153'
complete packet:b'\x04\x00\x811153'

11:38:51.210188 read:
payload_length: 1153 message_type: 131
payload: b'\x00\x00\xff\xff\xff\xfe\x00\x00\x00\x00\x00\x0f@\x8f@\x00\x00\x00\x00\x00@\x98\xc3\x99\x99\x99\x99\x9a@\xa3\x9f\xcc\xcc\xcc\xcc\xcd@\xaf\x1a33334@\xb8\xa5\x99\x99\x99\x99\x9a@\xc3\x88\x00\x00\x00\x00\x00@\xb8\xa5\x99\x99\x99\x99\x9a@\xaf\x1a33334@\xa3\x9f\xcc\xcc\xcc\xcc\xcd@\x98\xc3\x99\x99\x99\x99\x9a@\x8f@\x00\x00\x00\x00\x00@\x83\xb7\xae\x14z\xe1H@x\xe1\xc2\x8f\\(\xf6@of\x14z\xe1G\xae@c\xcf\xae\x14z\xe1H@Y\x00\x00\x00\x00\x00\x00A0\xa3\xd5Ae\xe7\nA$\xf5M\x95\xf6:\xcfA\x1a\x93v\xc0\x112$A\x10\xe3\x0ej4\x9e\x8eA\x05W\x18\xfc\xc6\x9a\x1e@\xfa\xed\x7f\x14\xd8@\x7fA\x05R\x84"\'\xdb\x1fA\x10\xdf@\xb7X\xae\xb4A\x1a\x93\x1cv\x95\xc9\xa5A%\x05\x14\xe7\x83U>A0\xa7\xf9\xf6\xe2\xdb@A:U\xf7b%\xef\xd3AD\xba\x00\xc7\xacB\x04APeM\xaf\x14\xcf\xa2AY\xf1:5\xe7\xa4]Ad{E\x85\xb6\\\xb6\xbf\xf8\xd9G\xc6\xcd\xc8\x00\xbf\xf8\xcewH\xb74O\xbf\xf8\xe9u\x94`\x1dQ\xbf\xf8\xec7\x10\xb4\xf0\x94\xbf\xf8\xf8\xe7\x93#n\x95\xbf\xf9\x05\x99%\x81\x9b8\xbf\xf8\xf5>)\x93\x9e\x0b\xbf\xf8\xf2q\xa2\xb7\x17H\xbf\xf8\xd5\xbd\x8a\xb3/J\xbf\xf8\xc5\x14\x87\xfa8B\xbf\xf8\xbd\xeb\xa6^U\xcf\xbf\xf8\xc9\x97n\xdb\xfeY\xbf\xf8\x8eB/\xbb\xc3\x1e\xbf\xf8d\xf5\xbf\x997X\xbf\xf8\x0e\xfe\x04\xca\xfd\x86\xbf\xf7f\xbd\x8a\xff6\x8eA\xd3\xc4\x05\xeb\xd8(\xf6A\xd3\xc4\x05\xec\x96\x14{A\xd3\xc4\x05\xec\xef\xd7\nA\xd3\xc4\x05\xedO\xef\x9eA\xd3\xc4\x05\xed\xaa\xd0\xe5A\xd3\xc4\x05\xee\tx\xd5A\xd3\xc4\x05\xeecC\x96A\xd3\xc4\x05\xee\xbe$\xdeA\xd3\xc4\x05\xef\x19\xe3TA\xd3\xc4\x05\xefs\x9d\xb2A\xd3\xc4\x05\xef\xce~\xfaA\xd3\xc4\x05\xf0*=qA\xd3\xc4\x05\xf0\x84\x00\x00A\xd3\xc4\x05\xf0\xf4Q\xecA\xd3\xc4\x05\xf1`\x83\x12A\xd3\xc4\x05\xf1\xc1\xc2\x90\x03\xe7\x03\xe6\x03\xe7\x03\xe7\x03\xe8\x03\xe8\x03\xe7\x03\xe7\x03\xe7\x03\xe6\x03\xe5\x03\xe6\x03\xe4\x03\xe4\x03\xe6\x03\xe6\x00\x06120122\x00\x00\x00\x110.0v, aMPL: 100Mv\x00\x07-1.62Pa\x00\n-0.2+-0.0c\x00\x1311:38:21 - 11:38:48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00?\xf0\x00\x00\x00\x00\x00\x00@\x14\x00\x00\x00\x00\x00\x00@4\x00\x00\x00\x00\x00\x00@\x14\x00\x00\x00\x00\x00\x00@\x14\x00\x00\x00\x00\x00\x00@\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xb0\xc6\xf7\xa0\xb5\xed\x8d\x00\x00\x00\x00\x00\x00\x00\x00?\xf4q\xb0\xd28\xae%\xc1\xe0\x00\x00\x00\x00\x00\x00@Y\x00\x00\x00\x00\x00\x00@\xc3\x88\x00\x00\x00\x00\x00@\x8f@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xb0\xc6\xf7\xa0\xb5\xed\x8d@N\x00\x00\x00\x00\x00\x00?0bM\xd2\xf1\xa9\xfc>\x11.\x0b\xe8&\xd6\x95?tz\xe1G\xae\x14{@Y\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xe0\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xdf\xc2\xc0\x1d\xceD\xa4\xbdou(\x03\x0fi\xdd>\xdf\xc2\xc0\x1d\xceD\xa4\xbdrk.I\xe7\x0b\xc7>\xdf\xc2\xc0\x1d\xceD\xa4\xbdu\xfd|v\xa5\x82\xf6>\xdf\xc2\xc0\x1d\xceD\xa4\xbdrT\xf2\x8f\xebQ\xf5>\xdf\xc2\xc0\x1d\xceD\xa4\xbdt\x1fP\x08\xba]|>\xdf\xc2\xc0\x1d\xceD\xa4\xbdu\xfd\x97V*4\x8d>\xdf\xc2\xc0\x1d\xceD\xa4\xbdv\x9e\xf7a\xb3n\x83>\xdf\xc2\xc0\x1d\xceD\xa4\xbdu+\xa7\xc9ry\x0b>\xdf\xc2\xc0\x1d\xceD\xa4\xbdt\xfa|k\x0f$\xb0>\xdf\xc2\xc0\x1d\xceD\xa4\xbdr\xbe\xb2\x8a\xb0\x8d\xf0>\xdf\xc2\xc0\x1d\xceD\xa4\xbdr\xea\xa3\xa1\x10\x89\xa3>\xdf\xc2\xc0\x1d\xceD\xa4\xbdqZJ\xee\n\x19\xe2>\xdf\xc2\xc0\x1d\xceD\xa4\xbdr\xbf\xacv5\xceM>\xdf\xc2\xc0\x1d\xceD\xa4\xbdshR\xd0]\xe7\xdf>\xdf\xc2\xc0\x1d\xceD\xa4\xbdr\x0b\x82 \xe4h1>\xdf\xc2\xc0\x1d\xceD\xa4\xbds\xec\xb70\xe4\x00X'
complete packet:b'\x81\x04\x83\x00\x00\xff\xff\xff\xfe\x00\x00\x00\x00\x00\x0f@\x8f@\x00\x00\x00\x00\x00@\x98\xc3\x99\x99\x99\x99\x9a@\xa3\x9f\xcc\xcc\xcc\xcc\xcd@\xaf\x1a33334@\xb8\xa5\x99\x99\x99\x99\x9a@\xc3\x88\x00\x00\x00\x00\x00@\xb8\xa5\x99\x99\x99\x99\x9a@\xaf\x1a33334@\xa3\x9f\xcc\xcc\xcc\xcc\xcd@\x98\xc3\x99\x99\x99\x99\x9a@\x8f@\x00\x00\x00\x00\x00@\x83\xb7\xae\x14z\xe1H@x\xe1\xc2\x8f\\(\xf6@of\x14z\xe1G\xae@c\xcf\xae\x14z\xe1H@Y\x00\x00\x00\x00\x00\x00A0\xa3\xd5Ae\xe7\nA$\xf5M\x95\xf6:\xcfA\x1a\x93v\xc0\x112$A\x10\xe3\x0ej4\x9e\x8eA\x05W\x18\xfc\xc6\x9a\x1e@\xfa\xed\x7f\x14\xd8@\x7fA\x05R\x84"\'\xdb\x1fA\x10\xdf@\xb7X\xae\xb4A\x1a\x93\x1cv\x95\xc9\xa5A%\x05\x14\xe7\x83U>A0\xa7\xf9\xf6\xe2\xdb@A:U\xf7b%\xef\xd3AD\xba\x00\xc7\xacB\x04APeM\xaf\x14\xcf\xa2AY\xf1:5\xe7\xa4]Ad{E\x85\xb6\\\xb6\xbf\xf8\xd9G\xc6\xcd\xc8\x00\xbf\xf8\xcewH\xb74O\xbf\xf8\xe9u\x94`\x1dQ\xbf\xf8\xec7\x10\xb4\xf0\x94\xbf\xf8\xf8\xe7\x93#n\x95\xbf\xf9\x05\x99%\x81\x9b8\xbf\xf8\xf5>)\x93\x9e\x0b\xbf\xf8\xf2q\xa2\xb7\x17H\xbf\xf8\xd5\xbd\x8a\xb3/J\xbf\xf8\xc5\x14\x87\xfa8B\xbf\xf8\xbd\xeb\xa6^U\xcf\xbf\xf8\xc9\x97n\xdb\xfeY\xbf\xf8\x8eB/\xbb\xc3\x1e\xbf\xf8d\xf5\xbf\x997X\xbf\xf8\x0e\xfe\x04\xca\xfd\x86\xbf\xf7f\xbd\x8a\xff6\x8eA\xd3\xc4\x05\xeb\xd8(\xf6A\xd3\xc4\x05\xec\x96\x14{A\xd3\xc4\x05\xec\xef\xd7\nA\xd3\xc4\x05\xedO\xef\x9eA\xd3\xc4\x05\xed\xaa\xd0\xe5A\xd3\xc4\x05\xee\tx\xd5A\xd3\xc4\x05\xeecC\x96A\xd3\xc4\x05\xee\xbe$\xdeA\xd3\xc4\x05\xef\x19\xe3TA\xd3\xc4\x05\xefs\x9d\xb2A\xd3\xc4\x05\xef\xce~\xfaA\xd3\xc4\x05\xf0*=qA\xd3\xc4\x05\xf0\x84\x00\x00A\xd3\xc4\x05\xf0\xf4Q\xecA\xd3\xc4\x05\xf1`\x83\x12A\xd3\xc4\x05\xf1\xc1\xc2\x90\x03\xe7\x03\xe6\x03\xe7\x03\xe7\x03\xe8\x03\xe8\x03\xe7\x03\xe7\x03\xe7\x03\xe6\x03\xe5\x03\xe6\x03\xe4\x03\xe4\x03\xe6\x03\xe6\x00\x06120122\x00\x00\x00\x110.0v, aMPL: 100Mv\x00\x07-1.62Pa\x00\n-0.2+-0.0c\x00\x1311:38:21 - 11:38:48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00?\xf0\x00\x00\x00\x00\x00\x00@\x14\x00\x00\x00\x00\x00\x00@4\x00\x00\x00\x00\x00\x00@\x14\x00\x00\x00\x00\x00\x00@\x14\x00\x00\x00\x00\x00\x00@\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xb0\xc6\xf7\xa0\xb5\xed\x8d\x00\x00\x00\x00\x00\x00\x00\x00?\xf4q\xb0\xd28\xae%\xc1\xe0\x00\x00\x00\x00\x00\x00@Y\x00\x00\x00\x00\x00\x00@\xc3\x88\x00\x00\x00\x00\x00@\x8f@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xb0\xc6\xf7\xa0\xb5\xed\x8d@N\x00\x00\x00\x00\x00\x00?0bM\xd2\xf1\xa9\xfc>\x11.\x0b\xe8&\xd6\x95?tz\xe1G\xae\x14{@Y\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xe0\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xdf\xc2\xc0\x1d\xceD\xa4\xbdou(\x03\x0fi\xdd>\xdf\xc2\xc0\x1d\xceD\xa4\xbdrk.I\xe7\x0b\xc7>\xdf\xc2\xc0\x1d\xceD\xa4\xbdu\xfd|v\xa5\x82\xf6>\xdf\xc2\xc0\x1d\xceD\xa4\xbdrT\xf2\x8f\xebQ\xf5>\xdf\xc2\xc0\x1d\xceD\xa4\xbdt\x1fP\x08\xba]|>\xdf\xc2\xc0\x1d\xceD\xa4\xbdu\xfd\x97V*4\x8d>\xdf\xc2\xc0\x1d\xceD\xa4\xbdv\x9e\xf7a\xb3n\x83>\xdf\xc2\xc0\x1d\xceD\xa4\xbdu+\xa7\xc9ry\x0b>\xdf\xc2\xc0\x1d\xceD\xa4\xbdt\xfa|k\x0f$\xb0>\xdf\xc2\xc0\x1d\xceD\xa4\xbdr\xbe\xb2\x8a\xb0\x8d\xf0>\xdf\xc2\xc0\x1d\xceD\xa4\xbdr\xea\xa3\xa1\x10\x89\xa3>\xdf\xc2\xc0\x1d\xceD\xa4\xbdqZJ\xee\n\x19\xe2>\xdf\xc2\xc0\x1d\xceD\xa4\xbdr\xbf\xacv5\xceM>\xdf\xc2\xc0\x1d\xceD\xa4\xbdshR\xd0]\xe7\xdf>\xdf\xc2\xc0\x1d\xceD\xa4\xbdr\x0b\x82 \xe4h1>\xdf\xc2\xc0\x1d\xceD\xa4\xbds\xec\xb70\xe4\x00X'

Heartbeat

11:37:27.568548 send:
payload_length: 14 message_type: 128
payload: bytearray(b'1,ScriptRemote')
complete packet:bytearray(b'\x0e\x00\x801,ScriptRemote')

11:37:27.569548 read:
payload_length: 18 message_type: 128
payload: b'128,ScriptRemote,0'
complete packet:b'\x12\x00\x80128,ScriptRemote,0'

CV Setup

11:37:27.864108 send:
payload_length: 14 message_type: 2
payload: bytearray(b'1:SENDCVSETUP:')
complete packet:bytearray(b'\x0e\x00\x021:SENDCVSETUP:')

11:37:27.985056 read:
payload_length: 311 message_type: 2
payload: b'OK;CVSETUP;CV_Pstart=1.0000e+00;CV_Tstart=2;CV_Pupper=2.0000e+00;CV_Plower=0.0000e+00;CV_Pend=1.0000e+00;CV_Tend=2;CV_Srate=5.0000e-01;CV_Periods=2;CV_PpPer=400;CV_Imi=-3.0000e-02;CV_Ima=3.0000e-02;CV_Odrop=0.0000e+00;CV_Sstart=0.0000e+00;CV_Send=2.0000e+01;CV_AutoReStart=0;CV_AutoScale=0;CV_AFGena=0;ENDSETUP\r'
complete packet:b'7\x01\x02OK;CVSETUP;CV_Pstart=1.0000e+00;CV_Tstart=2;CV_Pupper=2.0000e+00;CV_Plower=0.0000e+00;CV_Pend=1.0000e+00;CV_Tend=2;CV_Srate=5.0000e-01;CV_Periods=2;CV_PpPer=400;CV_Imi=-3.0000e-02;CV_Ima=3.0000e-02;CV_Odrop=0.0000e+00;CV_Sstart=0.0000e+00;CV_Send=2.0000e+01;CV_AutoReStart=0;CV_AutoScale=0;CV_AFGena=0;ENDSETUP\r'
OK;CVSETUP;CV_Pstart=1.0000e+00;CV_Tstart=2;CV_Pupper=2.0000e+00;CV_Plower=0.0000e+00;CV_Pend=1.0000e+00;CV_Tend=2;CV_Srate=5.0000e-01;CV_Periods=2;CV_PpPer=400;CV_Imi=-3.0000e-02;CV_Ima=3.0000e-02;CV_Odrop=0.0000e+00;CV_Sstart=0.0000e+00;CV_Send=2.0000e+01;CV_AutoReStart=0;CV_AutoScale=0;CV_AFGena=0;ENDSETUP

IE Setup

11:38:00.769706 send:
payload_length: 14 message_type: 2
payload: bytearray(b'1:SENDIESETUP:')
complete packet:bytearray(b'\x0e\x00\x021:SENDIESETUP:')

11:38:00.894866 read:
payload_length: 354 message_type: 2
payload: b'OK;IESETUP;IE_EckPot1=1.0000e+00;IE_EckPot2=1.1000e+00;IE_EckPot3=9.0000e-01;IE_EckPot4=1.0000e+00;IE_EckPot1rel=0;IE_EckPot2rel=0;IE_EckPot3rel=0;IE_EckPot4rel=0;IE_Resolution=2.0000e-02;IE_WZmin=1.0;IE_WZmax=15;IE_Torel=1.0000e-02;IE_Toabs=1.0000e-03;IE_Odrop=0.0000e+00;IE_SweepMode=0;IE_Srate=5.0000e-02;IE_Imi=-1.0000e-02;IE_Ima=1.0000e-02;ENDSETUP\r'
complete packet:b'b\x01\x02OK;IESETUP;IE_EckPot1=1.0000e+00;IE_EckPot2=1.1000e+00;IE_EckPot3=9.0000e-01;IE_EckPot4=1.0000e+00;IE_EckPot1rel=0;IE_EckPot2rel=0;IE_EckPot3rel=0;IE_EckPot4rel=0;IE_Resolution=2.0000e-02;IE_WZmin=1.0;IE_WZmax=15;IE_Torel=1.0000e-02;IE_Toabs=1.0000e-03;IE_Odrop=0.0000e+00;IE_SweepMode=0;IE_Srate=5.0000e-02;IE_Imi=-1.0000e-02;IE_Ima=1.0000e-02;ENDSETUP\r'
OK;IESETUP;IE_EckPot1=1.0000e+00;IE_EckPot2=1.1000e+00;IE_EckPot3=9.0000e-01;IE_EckPot4=1.0000e+00;IE_EckPot1rel=0;IE_EckPot2rel=0;IE_EckPot3rel=0;IE_EckPot4rel=0;IE_Resolution=2.0000e-02;IE_WZmin=1.0;IE_WZmax=15;IE_Torel=1.0000e-02;IE_Toabs=1.0000e-03;IE_Odrop=0.0000e+00;IE_SweepMode=0;IE_Srate=5.0000e-02;IE_Imi=-1.0000e-02;IE_Ima=1.0000e-02;ENDSETUP