Sending commands to devices in python

dillan teagle
Jun 13 · 2 min read

I have recently started working with a company where its business model is wrapped around IOT devices in the field. I was recently tasked to write a python program that will send commands from a server to a device.

To send a command, we first must understand and choose what protocol we will use. I will be sending this command using TCP protocol, and building a packet that is encoded and eligible for delivery on behalf of another host.

Make sure that you have tested the tcp connection between both parties.

Verify that your designated port is open, then test the connection, it is possible that your ip tables / firewall rules could be blocking tcp connections from external hosts. To do this run an Ncat command,

nc -vv address port

Also you can run this command to listen on a port for an incoming connection

nc -vlp 9100

If all is good, you should receive a message that says the connection is established.

The first step is to create a socket and establish the connection between the two parties.

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((dns, 9100))

Once the connection has been established, its time to send a command. To send a packet, you must first encode the command. Most common use case is command.encode(“utf-8”)

In this case, I am storing the string value in a byte array and concatenating ASCII 27 and ASCII 13 at the beginning and end. Now its ready to be sent as a packet. I am setting the socket to half closed until I receive a response.

packet = bytearray("\x1b" + command + "\x0d")s.send(packet)
s.shutdown(socket.SHUT_WR)

To retrieve the response, use s.recv() and the size of the packet will be noted in the method. Upon receiving the message, we parse the packet and now we have a response.

result = s.recv(1024)response = result.split('\0', 1)[0].strip()

This example only shows a script that is used with Ansible to send commands to many devices. In order for the device to receive and respond, it will also need a python script that will accept the connection, receive, parse and respond.

import socketimport sysdef send_command(dns, command):try:    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    s.connect((dns, 9100))except (socket.error,socket.herror,socket.gaierror) as (errno,

strErr):
raise Exception("Failed to connect to device" + dns + ": " +

strErr)
try: packet = bytearray("\x1b" + command + "\x0d") s.send(packet) s.shutdown(socket.SHUT_WR) result = s.recv(1024) response = result.split('\0', 1)[0].strip() print(response) return responseexcept (socket.error,socket.herror,socket.gaierror) as (errno, strErr): raise Exception("Failed to communicate with device" + dns + ": " + strErr)finally: s.close()
def main(): dns = sys.argv[1] command = sys.argv[2] send_command(dns, command)
if __name__ == "__main__":
main()

Finally, I will run the file and pass in the required args.

python name_of_file.py "host" "command"

Written by

https://www.github.com/teaglebuilt

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade