<jupyter_start><jupyter_text>Communicating via TCPThis notebook shows how to implement a TCP Server on Particle Argon and communicate with the server from a laptop using a ``netcat`` utility.  Particle CLI  Installation<jupyter_code>%%capture
!bash <( curl -sL https://particle.io/install-cli )<jupyter_output><empty_output><jupyter_text>Utility functions<jupyter_code>import re
import subprocess

# regular expression to strip ansi control characters
ansi = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')

# decode byte string and strip ansi control characters
def decode_bytes(byte_string):
    if isinstance(byte_string, bytes):
        result = byte_string.decode("utf-8")
    return ansi.sub("", result)

# streamline call to the particle-cli
def particle(args, particle_cli="/root/bin/particle"):
    process = subprocess.run([particle_cli] + args,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
    process.stdout = decode_bytes(process.stdout)
    process.stderr = decode_bytes(process.stderr)
    return process<jupyter_output><empty_output><jupyter_text>Login to Particle  Select a deviceThe following cell downloads a list of all user devices and creates a list of device names. Here we choose the first name in the list for the rest of this notebook. If this is not the device to be used, then modify this cell accordingly.<jupyter_code>import getpass

# prompt for username and password
username = getpass.getpass(prompt="Username: ")
password = getpass.getpass(prompt="Password: ")

# attempt login
output = particle(["login", "--username", username, "--password", password])

# report results
if output.returncode:
    print(f"Return code = {output.returncode}")
    print(output.stderr)
else:
    print(output.stdout)
devices = [line.split()[0] for line in particle(["list"]).stdout.splitlines()]
device_name = devices[0]
print(particle(["list", device_name]).stdout)<jupyter_output>jck_argon_01 [e00fce68eaceb1faa7cf7193] (Argon) is online<jupyter_text>Project Considerations  ImplementationMacOS    nc -4 -n 192.168.xxx.xxx pppp  Create Project<jupyter_code>print(particle(["project", "create", "--name", "myproject", "."]).stdout)<jupyter_output>Initializing project in directory myproject...
> A new project has been initialized in directory myproject<jupyter_text>Change working directoryThe Particle CLI assumes one is working in the top  project directory.<jupyter_code>%cd /content/myproject<jupyter_output>/content/myproject<jupyter_text>Create source file<jupyter_code>%%writefile src/myproject.ino

/* 
Demonstrate bidirectional communication with Particle using TCPServer and
client. After flashing this firmware, check the Particle console for the local
IP address. Connect to the local IP address using netcat

    nc -4 -n 192.168.xxx.xxx 23

Type H and L will turn the on-board LED on and off.
*/

TCPServer server = TCPServer(23);
TCPClient client;

const int led = D7;
long int timeout;
char c;

void setup() {
    server.begin();
    Particle.publish("Server IP", WiFi.localIP().toString().c_str(), PRIVATE);
    pinMode(led, OUTPUT);
    timeout = millis();
}

void loop() {
    char c;
    long int begin;
    String line = "";
    if (millis() <= timeout) {
        digitalWrite(led, HIGH);
    } else {
        digitalWrite(led, LOW);
    }
    if (client.connected()) {
        while (client.available()) {
            /* get next char */
            c = client.read();
            if ('H' == c) {
                server.print("Turn LED on.");
                timeout = millis() + 5000;
            } else if ('L' == c) {
                server.print("Turn LED off.");
                timeout = millis();
            } else if ('S' == c) {
                if (digitalRead(led)) {
                    server.print("LED is on.");
                } else {
                    server.print("LED is off.");
                }
            } else if ('X' == c) {
                server.print("Close client connection.");
                client.stop();
            } else {
                server.write(c);
            }
        }
    } else {
        /* get next client */
        client = server.available();
        if (client.connected()) {
            server.println("Enter: ");
            server.println("   H to turn LED on for 5 seconds");
            server.println("   L to turn LED off");
            server.println("   S for LED status");
            server.println("   X to close client connection");
        }
    }
}<jupyter_output>Overwriting src/myproject.ino<jupyter_text>Compiling<jupyter_code>print(particle(["compile", "argon", "--saveTo", "myproject.bin"]).stdout)<jupyter_output>Compiling code for argon

Including:
    src/myproject.ino
    project.properties

attempting to compile firmware
downloading binary from: /v1/binaries/5f97068ce15235e4909ac925
saving to: myproject.bin
Memory use:
   text	   data	    bss	    dec	    hex	filename
  11852	    108	   1148	  13108	   3334	/workspace/target/workspace.elf

Compile succeeded.
Saved firmware to: /content/myproject/myproject.bin<jupyter_text>Flash firmware<jupyter_code>print(particle(["flash", device_name, "myproject.bin"]).stdout)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.116793893129771, 'fraction_numerical': 0.015458015267175572, 'mean_word_length': 3.037750385208012, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 29, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '545415', 'license': 'MIT', 'n_tokens_mistral': 1637, 'n_tokens_neox': 1548, 'n_words': 438, 'path': 'notebooks/B.06-Communicating _via_TCP.ipynb', 'repo_name': 'jckantor/cbe61622', 'size': '5240'}