Serial communication inside a custom library - python

I made a custom library to communicate with my own board. The codes in library work but when i call the library itself i get an error.
I assumed the library is not working, so i put a print function in the library. It seems, that function works and the functions with serial communication are the problem.
I checked the communication code by itself but it works each time. Assuming there are some things to handle when using serial in a custom library, which i dont know any.
iDealibrary.py
import serial
import time
ser=serial.Serial('COM5',9600)
def ConnectIdeaLab():
ser.sendBreak()
a=ser.read()
b=ser.read()
if(a==b'O' and b ==b'K' ):
ser.write(b'b')
ser.write(b'b')
ser.write(b'b')
ser.write(b'a')
ser.write(b'a')
c=ser.read()
if(c==b'!'):
ser.write(bytes([3]))
print("iDeaLab Moduna Girildi!")
time.sleep(0.005)
ser.sendBreak()
#this is the connection function.
def printanything(parametre):
print("writing: ",parametre)
#this is the print function to check if library is working.
example.py
import iDealibrary
iDealibrary.ConnectIdeaLab()
iDealibrary.printanything("selam")
#this does not work
I expect the last code to connect and print iDealab moduna girildi. Instead, i get
raise SerialException("ClearCommError failed ({!r})".format(ctypes.WinError()))

I managed to solve the problem. Mad Physicist is right, the problem is serial port stays open. When i try to re-run the program it tries to open a port which is already open.
After adding a CloseSerial function in my library and calling it on the example, the problem solved.
#File name iDealibrary.py
def CloseSerial():
ser.close()
#File name example.py
iDealibrary.ConnectIdeaLab()
iDealibrary.CloseSerial()

Related

How do I start a COM server? Code is in Python

I want to run Python code as a COM server. Eventually I want to run an RTD server available here. But first I want to know what exactly you have to do to getting any COM server running. So let's focus on this example.
class HelloWorld:
_reg_clsid_ = "{7CC9F362-486D-11D1-BB48-0000E838A65F}"
_reg_desc_ = "Python Test COM Server"
_reg_progid_ = "Python.TestServer"
_public_methods_ = ['Hello']
_public_attrs_ = ['softspace', 'noCalls']
_readonly_attrs_ = ['noCalls']
def __init__(self):
self.softspace = 1
self.noCalls = 0
def Hello(self, who):
self.noCalls = self.noCalls + 1
# insert "softspace" number of spaces
return "Hello" + " " * self.softspace + who
if __name__=='__main__':
import win32com.server.register
win32com.server.register.UseCommandLine(HelloWorld)
Ok, this works in the way that there were no errors and server is registered, hence it is available in the HKEY_CLASSES_ROOT registry. But what can I do with this? Some say you have to compile a instance and have a .dll or .exe file. WHat else do I have to do?
Well, I ran your example. The registry key for the server is at:
HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{7CC9F362-486D-11D1-BB48-0000E838A65F}
It has two subkeys... one for LocalServer32 and one for InProcServer32
I created a simple VBA macro in Excel:
Sub d()
Set obj = CreateObject("Python.TestServer")
MsgBox obj.Hello("joe")
End Sub
Macro ran just fine. My version of Excel is 64-bit. I ran the macro and then fired up Task Manager while the message box was being displayed. I could see pythonw.exe running in the background.
The only difference between my python script and yours is probably the name and also that I added a line to print to make sure I was executing the function:
if __name__=='__main__':
import win32com.server.register
print("Going to register...")
win32com.server.register.UseCommandLine(HelloWorld)
When I ran the 64-bit csript.exe test, it worked... as expected... when I ran the 32-bit version it failed.
I know why...sort of...
The registry entry for InProcServer32 is pythoncom36.dll
That's no good. It is an incomplete path. I tried modifying the path variable on my shell to add to one of the 3 places where the DLL existed on my system, but it didn't work. Also, tried coding the path in the InProcServer32. That didn't work.. kept saying it couldn't find the file.
I ran procmon, and then I observerved that it couldn't load vcruntime140.dll. Found the directory under python where those files were, and added to my path. It got further along. If I cared enough, I might try more. Eventually using procmon, I could find all the problems. But you can do that.
My simple solution was to rename the key InProcServer32 for the CLSID to be _InProcServer32. How does that work? Well, the system can't find InProcServer32 so it always uses LocalServer32--for 32-bit and 64-bit processes. If you need the speed of in process then you'd need to fix the problem by using procmon and being relentless until you solved all the File Not Found errors and such. But, if you don't need the speed of in process, then just using the LocalServer32 might solve the problem.
Caveats I'm using an Anaconda distro that my employer limits access to and I can only install it from the employee store. YMMV.

Serial Communication: python

I am using Python Anaconda 2.7. I would like to toggle the port using serial communication, But I am getting error: AttributeError: 'module' object has no attribute 'Serial'
My sample program is:
import serial
import time
#remember to adjust “COM3”
port = serial.Serial("COM3", 19200, timeout=0.5)
#turn on port 2, sleep 2 seconds, turn off port 2
port.write(b"\nF2\r")
time.sleep(2.0)
port.write(b"\nF2\r")
#turn on port 2 and 7, sleep 2 seconds, turn off port 2 and 7
port.write(b"\nF2\r\nF7\r")
time.sleep(2)
port.write(b"\nF2\r\nF7\r")
#close the port
port.close()
I have tried many solutions:
changing file name from 'serial.py' to 'any_other_name.py' and vise versa
deleting related .pyc file
Installing 'pip install pyserial'
Doing From serial import serial
When I run the same program from psychopy, it is working really fine. I don't know How to solve it. If some one can give me suggestions that It would be great help for me. Thanking you in advance.
Ravi
Your code seems good, so the problem you encounter is probably due to a bad import.
You really should avoid to name your python script like "standard" modules (serial.py, string.py...), because by doing this, you expose yourself to accidentally import those files instead of the correct one (probably what happened to you).
If you need to be sure of what you're importing, try this :
import serial
print serial.__file__ # this will tell you the position of the file you've imported and help you to be sure of what you're using.
# in case you're not importing a module, only a class... try this :
help(serial) # even without any help, it will give you at the end the path where this object is defined :)

Exscript control cisco execute 'reload' command

I'm ultimately trying to create some basic functions to control my cisco test lab devices using Exscript. Exscript has done everything perfectly for me up to this point and I'm just pulling a few functions for example.
What I'm having trouble with is creating this reload_start() function that executes the reload command, rebooting my Cisco device and reverting any changes I've made in my test run. I've tried dozens of different combinations of character strings to execute but cannot get it to work around the additional prompts that come up when typing 'reload'
In contrast, my copy_to_running_config() function works just fine, simply by adding '\n' at the end of the string.
I've not yet jumped into Exscript's prompt functions(get_prompt(), expect_prompt(), waitfor(), etc), and I'm guessing this is the avenue I need to explore, but I cannot find examples of this that deal with my specific goal.
from Exscript import Account
from Exscript.protocols import Telnet
from Exscript.protocols.drivers import ios
def __init__(self, ip):
self.ip = ip
self.account = Account('admin', 'key')
self.conn = Telnet()
self.conn.set_driver('ios')
self.conn.connect(ip)
self.conn.login(self.account)
self.conn.execute('terminal length 0')
def enable(self):
self.conn.execute('enable')
def copy_to_running_config(self, config):
self.enable()
self.conn.execute('copy flash:{0} running-config \n'.format(config))
res = self.conn.response
self.conn.execute('exit')
return res
def reload_start(self):
self.enable()
self.conn.execute('reload \n no \n')
print self.conn.response
Any help or input would be greatly appreciated!
Your Function reload_start should look like this:
def reload_start(self):
self.enable()
self.conn.set_prompt(r'Save\? \[yes/no\]\:')
self.conn.execute('reload')
self.conn.set_prompt(r'Proceed with reload\? \[confirm\]')
self.conn.execute('no')
self.conn.set_prompt()
self.conn.execute('confirm')
print self.conn.response
You have to set the Regular Expression for the prompt before executing the command. Otherwise Exscrpt is not be able to determine when to send the next command.
Nevertheless, if the configuration wasn't changed and the router doesn't ask you to save, the script above would not work because it would wait for the save-question.

Python: internally defined open() causes "Type Error", "argument requires no arguments, 1 given"

This is quite likely something simple that I have an issue with, but I do not have another machine to figure out if it's my laptop's python version right now.
When I run my program, I recieve the following error: "Type Error: function open() requires no arguments (2 given)"
The code snippet in question:
import tkinter as tk
from tkinter import filedialog as fdg
def update_queue():
conf_file = open("config.txt", "a")
fd = fdg.LoadFileDialog(master)
file = fd.go(pattern="*.jpg")
conf_file.write(file)
conf_file.close()
I'm not yet too good with Python, and would appreciate any pointers ("Your code looks twistier than last night's burnt spaghetti" counts as well) as to why the open() function fails.
Also of note, if I call open outside of a defined function, it opens the file, and can complete all actions done on it, but if I close the file, I cannot re open the file from within a function. I attempted to use the os file functions, but recieved the error "LoadFileDialog does not work with buffer-defined file functions." Understandable.
If I use conf_file.flush(), assuming I opened it outside of a function, will it flush whatever I write/append, so that I can read from the file again later?
EDIT: What I mean, is, will this work all the time, or would this be considered a hack?
is that the whole code? make sure you did not import another open function somewhere. or redefined it.
Assuming that open() was declared later on and you just didn't include it in the code, you probably declared it as
def open():
#code here
If this is the case, you just didn't add in the arguments when declaring the function and it should be:
def open(x, y):
#code here
where x and y could be anything you like.
Please come back and post the rest of your code (i highly doubt this is all of it) to get better answers. What is truly going on is at most a speculation on out part.

Accessing samba shares with gio in python

I am trying to make a simple command line client for accessing shares via the Python bindings of gio (yes, the main requirement is to use gio).
I can see that comparing with it's predecessor gnome-vfs, it provides some means to do authentication stuff (subclassing MountOperation), and even some methods which are quite specific to samba shares, like set_domain().
But I'm stuck with this code:
import gio
fh = gio.File("smb://server_name/")
If that server needs authentication, I suppose that a call to fh.mount_enclosing_volume() is needed, as this methods takes a MountOperation as a parameter. The problem is that calling this methods does nothing, and the logical fh.enumerate_children() (to list the available shares) that comes next fails.
Anybody could provide a working example of how this would be done with gio ?
The following appears to be the minimum code needed to mount a volume:
def mount(f):
op = gio.MountOperation()
op.connect('ask-password', ask_password_cb)
f.mount_enclosing_volume(op, mount_done_cb)
def ask_password_cb(op, message, default_user, default_domain, flags):
op.set_username(USERNAME)
op.set_domain(DOMAIN)
op.set_password(PASSWORD)
op.reply(gio.MOUNT_OPERATION_HANDLED)
def mount_done_cb(obj, res):
obj.mount_enclosing_volume_finish(res)
(Derived from gvfs-mount.)
In addition, you may need a glib.MainLoop running because GIO mount functions are asynchronous. See the gvfs-mount source code for details.

Categories

Resources