how do I create a class that Inheritates from serial using the python serial module?
I need to create a module so another user can import to his code and create an object by just passing the COM.
This is my module, called py232
from serial import Serial
class serialPort(Serial):
def __init__(self, COM):
serial.__init__(self)
self.COMPort = COM
self.baudrate = 9600
self.bytesize = 8
self.stopbits = serial.STOPBITS_ONE
self.parity = serial.PARITY_NONE
self.timeout = 2
#serialPort = serial.Serial(port=self.COMPort, baudrate= self.baudrate, stopbits= self.stopbits, parity= self.parity, timeout= self.timeout)
self.createSerial()
def createSerial(self):
sPort = serial.Serial(port = self.COMPort, baudrate=self.baudrate, bytesize=self.bytesize, timeout= self.timeout, stopbits = self.stopbits, parity=self.parity)
return sPort
I am trying to use it in another script:
import py232
s = py232.serialPort('COM6')
s.sndSerial('test')
Why don't you just create an instance of serial in a function. No need to create a sub-class.
from serial import Serial
def create_serial(port):
s = Serial(
port,
baudrate=9600,
bytesize=8,
timeout=2,
# etc
)
return s
It can then be used in another script.
import py232
s = py232.create_serial('COM6')
Related
I am trying to create a file in an ESP32 named "PassWord" containing a password, using Micropython Serial. The code below works with a "hardwired" password, but I would like to be able to send the contents of a variable that was typed in by the user. The sending script is running in Win10 using Python 3.7.9
import serial
import time
def Send(s):
ser.write((s +'\r\n').encode())
time.sleep(.3)
z = ser.read(ser.in_waiting)
portx = "COM6"
bps = 115200
timex = 5
ser = serial.Serial(portx,bps,timeout=timex)
Send("f = open('Password,'w')")
Send("f.write('MyPassWord\\n')")
Send("f.close()")
You could do something like this. Just made this as an exaggerated example so you can learn. You could put this whole thing into the send function input if you wanted.
import serial
import time
MyPassWord = "This is the password"
def Send(s):
ser.write((s +'\r\n').encode())
time.sleep(.3)
z = ser.read(ser.in_waiting)
portx = "COM6"
bps = 115200
timex = 5
ser = serial.Serial(portx,bps,timeout=timex)
StringToSend = """f.write('""" + MyPassWord+ """\\n')"""
Send("f = open('Password,'w')")
Send(StringToSend)
Send("f.close()")
So I'm doing a project where I want my Raspberry Pi 4 to communicate through Modbus. I've bought a shield to enable RS485 communication from the Pi and I've been modifying the demo code (Software/Test Codes/MODBUS/rtumaster.py) and have been using a slave simulator on my computer to test.
I'm reaching out because I've gotten stuck on trying to read data from my slave. The command seems to go through okay (or the slave simulator doesn't complain is perhaps better to say), but I don't know how to get the data into my program. I've been trying something like this:
read = logger.info(master.execute(1, cst.READ_INPUT_REGISTERS, 5, 1))
And then trying to print that value to check, but it just returns 'None' instead of my value.
Any help is appreciated.
Current code:
## To install dependencies:
## sudo pip3 install modbus-tk
##################################################################################################
import serial
import fcntl
import os
import struct
import termios
import array
#import modbus lib
import modbus_tk
import modbus_tk.defines as cst
import modbus_tk.modbus as modbus
#import modbus_tk.modbus_rtu as modbus_rtu
from modbus_tk import modbus_rtu
# RS485 ioctls define
TIOCGRS485 = 0x542E
TIOCSRS485 = 0x542F
SER_RS485_ENABLED = 0b00000001
SER_RS485_RTS_ON_SEND = 0b00000010
SER_RS485_RTS_AFTER_SEND = 0b00000100
SER_RS485_RX_DURING_TX = 0b00010000
# rs 485 port
ser1 = serial.Serial("/dev/ttySC0",19200)
ser2 = serial.Serial("/dev/ttySC1",9600)
def rs485_enable():
buf = array.array('i', [0] * 8) # flags, delaytx, delayrx, padding
#enable 485 chanel 1
fcntl.ioctl(ser1, TIOCGRS485, buf)
buf[0] |= SER_RS485_ENABLED|SER_RS485_RTS_AFTER_SEND
buf[1] = 0
buf[2] = 0
fcntl.ioctl(ser1, TIOCSRS485, buf)
#enable 485 chanel 2
fcntl.ioctl(ser2, TIOCGRS485, buf)
buf[0] |= SER_RS485_ENABLED|SER_RS485_RTS_AFTER_SEND
buf[1] = 0
buf[2] = 0
fcntl.ioctl(ser2, TIOCSRS485, buf)
#end of rs485_enable():
if __name__ == '__main__':
logger = modbus_tk.utils.create_logger("console")
rs485_enable()
#set modbus master
master = modbus_rtu.RtuMaster(
serial.Serial(port= '/dev/ttySC0',
baudrate=9600,
bytesize=8,
parity='N',
stopbits=1,
xonxoff=0)
)
master.set_timeout(5.0)
master.set_verbose(True)
logger.info("connected")
read = logger.info(master.execute(1, cst.READ_INPUT_REGISTERS, 5, 1))
print("Value is: ", read)
I've written some api to communicate with a website using websocketapp. It works fine only on 2 pc. If i put my code on every other pc the websocket doesnt receive any message and closes. I've tried a lot of different machines and operating systems, many version of python (included the same that works), wireless and wired connection but nothing changed. There's no error or exception. What can it be?
EDIT: i don't own the website or the server. All other methods send messages and parse the response in on_socket_message
import requests
import websocket
import time
from threading import Thread
from datetime import datetime
import json
from position import Position
from constants import ACTIVES
class IQOption():
practice_balance = 0
real_balance = 0
server_time = 0
positions = {}
instruments_categories = ["cfd","forex","crypto"]
top_assets_categories = ["forex","crypto","fx-option"]
instruments_to_id = ACTIVES
id_to_instruments = {y:x for x,y in ACTIVES.items()}
market_data = {}
binary_expiration_list = {}
open_markets = {}
digital_strike_list = {}
candle_data = []
latest_candle = 0
position_id = 0
quotes =[]
position_id_list=[]
def __init__(self,username,password,host="iqoption.com"):
self.username = username
self.password = password
self.host = host
self.session = requests.Session()
self.generate_urls()
self.socket = websocket.WebSocketApp(self.socket_url,on_open=self.on_socket_connect,on_message=self.on_socket_message,on_close=self.on_socket_close,on_error=self.on_socket_error)
def generate_urls(self):
"""Generates Required Urls to operate the API"""
#https://auth.iqoption.com/api/v1.0/login
self.api_url = "https://{}/api/".format(self.host)
self.socket_url = "wss://{}/echo/websocket".format(self.host)
self.login_url = self.api_url+"v1.0/login"
self.profile_url = self.api_url+"profile"
self.change_account_url = self.profile_url+"/"+"changebalance"
self.getprofile_url = self.api_url+"getprofile"
def login(self):
"""Login and set Session Cookies"""
print("LOGIN")
data = {"email":self.username,"password":self.password}
self.log_resp = self.session.request(url="https://auth.iqoption.com/api/v1.0/login",data=data,method="POST")
requests.utils.add_dict_to_cookiejar(self.session.cookies, dict(platform="9"))
self.__ssid = self.log_resp.cookies.get("ssid")
print(self.__ssid)
self.start_socket_connection()
time.sleep(1) ## artificial delay to complete socket connection
self.log_resp2 = self.session.request(url="https://eu.iqoption.com/api/getprofile",method="GET")
ss = self.log_resp2._content.decode('utf-8')
js_ss=json.loads(ss)
self.parse_account_info(js_ss)
self.balance_id = js_ss["result"]["balance_id"]
self.get_instruments()
self.get_top_assets()
self.setOptions()
#self.getFeatures()
time.sleep(1)
print(js_ss["isSuccessful"])
return js_ss["isSuccessful"]
def on_socket_message(self,socket,message):
#do things
def on_socket_connect(self,socket):
"""Called on Socket Connection"""
self.initial_subscriptions()
print("On connect")
def initial_subscriptions(self):
self.send_socket_message("ssid",self.__ssid)
self.send_socket_message("subscribe","tradersPulse")
def on_socket_error(self,socket,error):
"""Called on Socket Error"""
print(message)
def on_socket_close(self,socket):
"""Called on Socket Close, does nothing"""
def start_socket_connection(self):
"""Start Socket Connection"""
self.socket_thread = Thread(target=self.socket.run_forever)
self.socket_thread.start()
def send_socket_message(self,name,msg):
#print(msg)
data = {"name":name,"msg":msg}
self.socket.send(json.dumps(data))
Here is an example running under Gevent Websockets. This makes it ASYNC (which I suspect is part of your problem) and allows for bidirectional communication.
import gevent
from gevent import monkey, signal, Timeout, sleep, spawn as gspawn
monkey.patch_all()
from gevent.pywsgi import WSGIServer
from geventwebsocket.handler import WebSocketHandler
from geventwebsocket import WebSocketError
import bottle
from bottle import get, route, template, request, response, abort, static_file
import ujson as json
#route('/static/<filepath:path>')
def server_static(filepath):
return static_file(filepath, root='static')
#route('/ws/remote')
def handle_websocket():
wsock = request.environ.get('wsgi.websocket')
if not wsock:
abort(400, 'Expected WebSocket request.')
while 1:
try:
message = ''
with Timeout(2, False) as timeout:
message = wsock.receive()
if message:
message = json.loads(message)
if 'command' in message:
r.command(message['command'])
except WebSocketError:
break
except Exception as exc:
print(str(exc))
#get('/')
def remote():
return template('templates/remote.tpl', title='WebsocketTest', websocket=WEBSOCKET, command='command', status=status)
if __name__ == '__main__':
r=None
status="Connecting..."
gspawn(initialize)
print 'Started...'
HOST = socket.gethostbyname(socket.gethostname())
HOST = 'localhost'
WEBSOCKET = 'ws://{}/ws/remote'.format(HOST)
botapp = bottle.app()
server = WSGIServer(("0.0.0.0", 80), botapp, handler_class=WebSocketHandler)
def shutdown():
print('Shutting down ...')
server.stop(timeout=60)
exit(signal.SIGTERM)
gevent.signal(signal.SIGTERM, shutdown)
gevent.signal(signal.SIGINT, shutdown) #CTRL C
server.serve_forever()
Then in your HTML you really should use reconnecting websocket library
https://github.com/joewalnes/reconnecting-websocket
<button id="TRIGGERED" type="button" class="btn btn-outline-primary">TRIGGER</button>
<script type="text/javascript" src="/static/reconnecting-websocket.min.js"></script>
<script>
var ws = new ReconnectingWebSocket('{{websocket}}');
ws.reconnectInterval = 3000;
ws.maxReconnectAttempts = 10;
ws.onmessage = function (evt) {
var wsmsg = JSON.parse(evt.data);
console.log(evt.data)
};
$("button").click(function() {
<!--console.log(this.id);-->
ws.send(JSON.stringify({'{{command}}': this.id}));
});
</script>
I am using a USB microwave source, which communicates via a virtual COM port.
Communication is done via python. Everything works fine, as long as I am executing the code blockingly.
However, as soon as any communication is done in a thread
I get a SerialException: Attempting to use a port that is not open. Is there an obvious reason, why this is happening? Nothing else, at least originating from my software, is trying to communicate with the port during that time.
The highest level script:
from serial import SerialException
import deer
import windfreak_usb
try:
deer.mw_targets = windfreak_usb.WindfreakSynthesizer()
except SerialException:
deer.mw_targets.port.close()
deer.mw_targets = windfreak_usb.WindfreakSynthesizer()
deer_mes = deer.DeerMeasurement(f_start=0.9e9,
f_end=1.2e9,
df=3e6,
f_nv=1.704e9,
seq=["[(['mw'],28),([],tau),(['mw', 'mwy'],56),([],tau),(['mw'],28),([],100)]",
"[(['mw'],28),([],tau),(['mw', 'mwy'],56),([],tau),(['mw'],84),([],100)]"],
power_nv=10,
power_targets=3,
tau=700
)
deer_mes.run(10e6) # <- this works perfectly, as it is the blocking version
# deer_mes.start(10e6) # <- raises the SerialException at the line indicated below
deer.mw_targets.port.close()
A reduced form of the microwave source (windfreak_usb.py):
import serial
import synthesizer
class WindfreakSynthesizer(synthesizer.Synthesizer):
def __init__(self):
synthesizer.Synthesizer.__init__(self)
self.port = serial.Serial(
port='COM14',
baudrate=9600,
timeout=10
)
self.off()
def __del__(self):
self.port.close()
def off(self):
self.port.write('o0')
def power(self, p):
p = int(p)
self.port.write('a{}'.format(p))
A reduced form of the measurement class (deer.py):
import threading
import time
import numpy
import os
from PyQt4 import QtCore
from PyQt4.QtCore import QObject
import matplotlib.pyplot as plt
import hardware
import matpickle
import pulsed
import pulser
import savepath
import synthesizer
if 'pg' not in globals():
pg = pulser.Pulser()
if 'mw_targets' not in globals():
mw_targets = synthesizer.Synthesizer()
timeout = 30
CurrentMeasurement = None # global variable pointing to the currently active measurement
class DeerMeasurement(QObject):
update = QtCore.pyqtSignal()
def __init__(self, f_start, f_end, df, f_nv, seq, power_nv, power_targets, tau, sweeps_per_iteration=50e3,
switching_time=300e-6):
super(QObject, self).__init__()
""" setting all parameters as self.parameter """
self.power_targets = power_targets
self.fs = numpy.arange(f_start, f_end + df, df)
self.abort = threading.Event()
self.save_deer()
def run(self, sweeps):
global CurrentMeasurement
if CurrentMeasurement is not None:
print('Deer Warning: cannot start measurement while another one is already running. Returning...')
return
CurrentMeasurement = self
# Start measurement
print('Deer measurement started.')
mw_targets.power(self.power_targets) # <- This causes the SerialException.
""" Here comes the actual measurement, that is never executed, as the line above kills the thread already with the SerialException. """
def start(self, sweeps, monitor=None):
"""Start Measurement in a thread."""
if monitor is not None:
monitor.register(self)
if not hasattr(self, 'mes_thread'):
# noinspection PyAttributeOutsideInit
self.mes_thread = threading.Thread(target=self.run, args=(sweeps,))
self.mes_thread.start()
else:
print('Already threading')
Any help is highly appreciated, as running the measurement outside a thread is not an option.
Best regards!
For part 1 of the project, you will implement a simple go-back-N protocol similar to TCP. This protocol is called the 352RDPv1.
(unfortunately my python knowledge is not that strong, I am being forced to code it in python)
I must implement: init(udp_port1, udpport2)
socket()
connect(address)
I am given the following pseudo code:
import binascii
import socket as syssock
import struct
import sys
# this init function is global to the class and
# defines the UDP ports all messages are sent
# and received from.
def init(UDPportTx,UDPportRx): # initialize your UDP socket here
# create a UDP/datagram socket
# bind the port to the Rx (receive) port number
pass
class socket:
def __init__(self): # fill in your code here
# create any lists/arrays/hashes you need
return
def connect(self,address): # fill in your code here
global UDPportTx # example using a variable global to the Python module
# create a new sequence number
# create a new packet header with the SYN bit set in the flags (use the Struct.pack method)
# also set the other fields (e.g sequence #)
# add the packet to the outbound queue
# set the timeout
# wait for the return SYN
# if there was a timeout, retransmit the SYN packet
# set the outbound and inbound sequence numbers
return
I have given a shot so far at a few methods but I know I have errors and my program does not work.
import binascii
import socket as syssock
import struct
from collections import namedtuple
import sys
import select
version = 0x1
header_len = 7
payload_len = 0
flags = 0
SOCK352_SYN = 0x01
SOCK352_FIN = 0x02
SOCK352_ACK = 0x04
SOCK352_RESET = 0x08
SOCK352_HAS_OPT = 0xA0
sequence_no = 0
ack_no = 0
timeout = 0.2
#given these values to set them to
def init(UDPportTx,UDPportRx):
global sock
global useRx
global useTx
useTx = int(UDPportTx)
useRx = int(UDPportRx)
sock = syssock.syssock(syssock.AF_INET, syssock.SOCK_DGRAM)
sock.bind(('', useRx))
print "Listening on port :", useRx
pass
class socket:
def __init__(self):
global pkt
pkt = namedtuple("pkt",["version", "flags", "sequence_no", "ack_no", "payload_len"])
return
def connect(self, address):
global header_raw
udpPkt = struct.Struct('!BLBBB')
header_raw = udpPkt.pack(version, SOCK352_SYN, sequence_no, ack_no, payload_len)
sock.sendto(header_raw, ('', useTx))
return
I believe I am having errors in these first few methods and before I move onto the others I need to figure in I want to see if anyone is able to help me understand how to handle these few to begin.