Reading serial port with pymodbus3 - python-3.x

I'm working on a serial port using pymodbus3.
When I run the following code the output is 'None'. Whereas I can get response from the device when test for the serial port with modpoll.
How can I fix this issue?
from pymodbus3.client.sync import ModbusSerialClient as mbc
def PortTest(self):
client = mbc(method="rtu", port="/dev/ttyUSB0", stopbits=1, bytesize=8, parity='N', baudrate=9600)
try:
client.connect()
coil = client.read_coils(0, 1)
print(coil)
client.close()
except OSError as err:
raise EnvironmentError(err)
pass

pymodbus3 has a bug. Uninstall it and replace it with the python 3 branch of pymodbus 1.2.0. Go to github and download it.
https://github.com/bashwork/pymodbus/tree/python3

Related

Python Test Code for URL on IP-Address only

I'm a bit lost in Google-results.
I have a webserver running through a Python built-in module.
This works and provides an area to download automation configuration for devices.
However, I like to build an availability test to provide better code.
If http service is not available, then proceed with tftp server.
I tested with urllib2, but then the website gets timed out. If I try the same code with a named uri 'www.google.com' then the response code 200 is provided.
Any thoughts to provide a good solution?
in the code I provide a ping test.
now like to add 'service-available' test. on TRUE - proceed with GET.
should work on IP-ADDRESS eg.: 10.1.1.1:80
Thank you for the help.
code ex:
import httplib2
h = httplib2.Http(".cache")
(resp_headers, content) = h.request("http://10.10.1.1:80/", "GET")
print(resp_headers)
print(content)
Try this. On a successful ping, the script will attempt to connect to an HTTP service. If the request times out or is not successful (e.g., status 404), it will call your TFTP function:
import shlex
import socket
import subprocess
import httplib2
ip_address = "10.1.1.1"
print("Attempting to ping...")
p = subprocess.Popen(shlex.split("ping -c 3 {0}".format(ip_address)), stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, _ = p.communicate()
rc = p.returncode
if rc != 0 or "100% packet loss" in output.decode():
raise RuntimeError("Unable to connect to {0}.".format(ip_address))
print("Ping successful.")
print("Attempting to connect to an HTTP service....")
h = httplib2.Http(cache=".cache", timeout=10)
response = {}
content = ""
try:
response, content = h.request("http://{0}:80".format(ip_address), method="GET")
if 200 <= int(response["status"]) <= 299:
print("Connected to HTTP service.")
for key, value in response.items():
print(key, ":", value)
print(content.decode())
else:
print("Request not OK. Attempting to connect to a TFTP service...")
# Call to TFTP function goes here
except socket.timeout:
print("Request timed out. Attempting to connect to a TFTP service...")
# Call to TFTP function goes here

Building a webserver on ESP32 using MicroPython

Before reading my question, my english skill is poor, so please send me feedback or advise in easy words. Thank you.
What I Want To Do
I want to build a webserver on ESP32-WROOM-32(ESP32-DevKitc_V4) with MicroPython(v1.16 on 2021-06-23: latest firmware available). My Goal is building a webserver inside ESP32 and collecting the data of sensors connected to ESP32 periodically.
Environment
Windows10(64bit)
MicroPython (v1.16 on 2021-06-23)
Editor : Thonny Editor (v3.3.11)
ESP32 Devkitc_v4
ampy (v1.1.0)
What I did
Firstly I wrote a code according to this article : RandomNerdTutorial: ESP32/ESP8266 MicroPython Web Server – Control Outputs. My code is as follows:
import network
import usys
try:
import usocket as socket
except:
import socket
def connect(SSID,PASS):
AP = network.WLAN(network.AP_IF)
if AP.isconnected():
print("Already connected.")
return AP
else:
AP.active(True)
AP.connect(SSID,PASS)
while not AP.isconnected():
print(".",end="")
utime.sleep(0.5)
if AP.isconnected():
print("Network connection is established.")
return AP
else:
print("Connection failed.")
return False
wifi = connect("myssid","mypass")
if not wifi:
usys.exit(0)
html_strings = """
<!DOCTYPE html>
<html lang='ja'>
<head>
<meta charset='utf-8'>
<title>SERVER TEST</title>
</head>
<body>
<h1>SERVER TEST</h1>
</body>
</html>
"""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
addr = socket.getaddrinfo(("0,0,0,0",80))[0][-1]
s.bind(addr)
s.listen(1)
print("Linstening on ", addr)
while True:
conn,addr = s.accept()
print("connected from : ",addr)
request = conn.recv(1024)
respose = html_strings
conn.send("HTTP/1.0 200 OK\r\n")
conn.send("Content-type: text/html\r\n")
conn.send("\r\n")
conn.send(response)
conn.close()
I connect ESP32 board with USB cable to PC and Windows10 recognize this device as COM4. I wrote this code on Thonny Editor on windows10(64bit) and then transfer this code as main.py using ampy command on command line like this:
> ampy --port COM4 put main.pye
Tansfer was always successful and then connecting ESP32 from Thonny editor. firstly this message is shown in the shell console like this:
MicroPython v1.16 on 2021-06-23; ESP32 module with ESP32
Type "help()" for more information.
And then when I press reset button on ESP32, Error was shown like this:
Traceback(most recent call last)
File "main.py", line 48, in <module>
TypeError: function mising 1 required positional arguments
The line 48 corresponds this line:
addr = socket.getaddrinfo(("0,0,0,0",80))
According to the official documentation Docs » MicroPython libraries » usocket – socket module,it seems that prividing only two parameters: hostname nad port is enough. I also tried by writing like this:
addr = socket.getaddrinfo(('',80))[#][-1]
But the result was same. I do not understand what is the required another positional argument. So I want advice or feedback to solve this issue.
Thank you for your cooperation.
The getaddrinfo method expects two arguments:
socket.getaddrinfo('hostname', port)
You are passing a single argument -- a 2-tuple. Instead of:
addr = socket.getaddrinfo(("0.0.0.0", 80))
You want:
addr = socket.getaddrinfo("0.0.0.0",80)
Note that I've removed one set of parentheses.
Here's a complete example at the REPL:
>>> import socket
>>> s = socket.socket()
>>> addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
>>> s.bind(addr)
>>> s.listen(1)
>>> conn,addr = s.accept()
>>> addr
('192.168.1.175', 43384)
>>> conn.send('HTTP/1.0 200 OK\r\n')
17
>>> conn.close()

Camera Control via RS-422 Serial Port

I am currently doing research and writing a simple program in controlling a camera through the serial port, RS-422 to be more specific. I got the camera control protocol documentation from the manufacturer. I've been reading and testing for a few days now but unfortunately, I haven't managed to make it work. I used Python (3.7) to speed up the testing. Below is my sample code:
import serial
ser_port = serial.Serial(
port='COM4',
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
)
sccp_cmd_null = [0x00]
sccp_cmd = [0xE7, 0x40, 0x11, 0x43, 0x00, 0x00] # Chroma Key "GREEN"
if ser_port.isOpen():
# Try sending a break code first
try:
print("Sending Break Code: ", serial.to_bytes(sccp_cmd_null))
ser_port.write(serial.to_bytes(sccp_cmd_null))
except:
print("Failed Sending Break Code!")
# Try Sending The Commands
try:
print("Sending Commands: ", serial.to_bytes(sccp_cmd))
ser_port.write(serial.to_bytes(sccp_cmd))
except:
print("Failed Sending Commands!")
ser_port.close()
Please note that this is my first time writing code that deals with Serial Ports.
Thank you in advanced for those who can provide help ^_^

Python Can't decode byte : Invalid start byte

So I'm building this socket application, and it works just fine on my computer. But when i start server socket on another laptop, it just crashes with a invalid start byte error:
How do i proper encode the program to work with all laptops
This is the error i get on :
Other laptops.
My laptop.
I have tried to change the encoding, but I'm just not quite sure where i have to change it.
Class Listener:
def __init__(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_address = (socket.gethostbyname(socket.gethostname()), 10000)
self.sock.bind(self.server_address)
print(f"LISTENER : {str(self.server_address[0])} port {str(self.server_address[1])}")
def listen(self):
self.sock.listen(1)
while True:
print("Connection Open")
print(" Waiting for connections")
self.connection, self.client_address = self.sock.accept()
try:
print(f"Connection from {str(self.client_address)}")
while True:
data = self.connection.recv(1024)
if data:
message = str(data)
if not "print" in message.lower(): # This just checks if the client wants to print system information from the server
Validate(message) # this checks for a command the server have to do
else:
self.connection.sendall(pickle.dumps(self.computerinfomation))
else:
self.listen()
except Exception as e:
print(e)
I want it to work on other laptops as well, and i just cant see why it wont.
Furas came with a solution.
I changed the
message = str(data)
to
message = str(data, encoding="utf-8")
I did the same on the client side
Not going to lie. I just changed the encoding = utf-16.
Example:
df = pd.read_csv(C:/folders path/untitled.csv, encoding = "utf-16")

Aiomas RPC Python 3.6

My goal is to bind TCP RPC server aiomas and clients in different programming languages.
I'm setting the connection, but neither the response from the server nor the response is received.
The documentation says:
https://media.readthedocs.org/pdf/aiomas/1.0.3/aiomas.pdf
Page 26: - On the RPC level, it a three-tuple:
[function, [arg0, arg1, ...], {kwarg0: val0, kwarg1: val1}]
function is a string containing the name of an exposed functions; The type of the arguments and keyword arguments may vary depending on the function.
This simple server:
import aiomas
class Server:
router = aiomas.rpc.Service()
#aiomas.expose
def ping(self, i):
print('Ping receive data: {}'.format(i))
return i
if __name__ == '__main__':
server = aiomas.run(aiomas.rpc.start_server(
('127.0.0.1', 5000),
Server())
)
print('Server run')
aiomas.run(server.wait_closed())
And this my problem tcp client
import socket
import pickle
MESS = ['ping', [1]]
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 5000))
s.settimeout(1.5)
s.send(pickle.dumps(MESS))
data = s.recv(1024)
s.close()
Tell me please what's wrong. It is necessary to understand in order to realize this in other languages.Much grateful for any hint
I read the documentation several times, But I did not understand how to compose the header of the package. As a result, I figured out that the last byte is the length of the package. Everything worked.
Here is an example package
data='[0, 0, ["methood", ["args"], {"kwargs":"if exists"}]]'
hex(len(data)) --> 0x35
b'\x00\x00\x00\x35[0, 0, ["methood", ["args"], {"kwargs":"if exists"}]]'

Resources