python-vxi11-server
python-vxi11-server copied to clipboard
vxi11_server
Hello I have this issue, but I have Installed the module
import vxi11_server as Vxi11
ModuleNotFoundError:No module named 'vxi11_server'
I don't know how to fix it
Thanks (for your woks this can help me)
Hi, There is no need to install this library.
- Simply clone it onto your machine
- cd into the demo_servers folder and run the example server.
- open a second shell and run the example client.
Give that a shot and lets see what happens. c.
Hello 👋 back again
So the server run, but the client have an error
Traceback (most recent call last):
File "time_client.py", Line 1, in
the example clients that come with this library are written for the python-vxi11 client library.
Go to https://github.com/python-ivi/python-vxi11 and follow the instructions there to install the client library. If you have another client library (such as national instruments) then you need to follow their instructions.
Have you had success communicating with an existing device using vxi11?
One step at a time. Good luck, c.
Just a question is it possible to control Raspberry Pi GPIOs ? How can I do that ? Something like default_instr.write('pin1:on') but have success to communicating
Louis.
Here is where i would start on this project.
- Come up with a command syntax. Following your suggestion:
- 'set:pin.x:state'
- 'get:pin.x'
- and so forth.
- On the raspberry pi, copy time-device.py to gpio-device.py and edit:
- in device_init() open the gpio library
- in device_write() parse the command syntax and act on it.
- in device_read() return results from the device_write()
- On the client computer, copy time-client.py to gpio-client.py and edit:
- my_instr.write('set:pin.1:on')
- my_instr.write('get:pin.1')
- pin1_state = my_instr.read()
If you like, you might open a repository in your github account for a barebones vxi11 gpio device, then I might be able to offer more focused suggestions.
Hello this is what I've done for now https://github.com/ChevalierLouis/vxi11-gpio-device
Very Nice.
To be clear, you have a functioning requests/flask pair that you would like to replace with a vxi client/server pair?
If so, i would start on the client side by factoring out all the requests functionality into a class or module called, say, remote_gpio_requests.py making every effort to maintain functionality. Copy that to remote_gpio_vxi11.py and replace the requests logic with vxi11 logic. You can then switch between flask or vxi11 or the next-big-thing with hopefully just an import change.
On the server side, i would start a new project (they both could run concurrently) using time_device.py as boilerplate.
You've got a lot of good work there. You should reuse as much of it as you can.
Yes it's what I would like to replace requests/flask with vxi, in fact this is my 2nd or 3rd program in python usually I use arduino esp, I write code in c++ since 2014. For me python have similarities, but classes in python is really abstract for me.
For the client part this will be really easy but the server I don't know how to make the thing who understands the "request" instr.write('*the command?'). I've tried to add a def something(self, other things.): in vxi11.py but no results (errors everywhere)
Thanks to help me(sorry for my English).
referring to 'class TimeDevice(Vxi11.InstrumentDevice)' in the time-device.py example, TimeDevice() is the custom class the developer creates to manage communication with his device (yours might be named GpioDevice()). It extends a Vxi11.InstrumentDevice which means that python imports every function found in InstrumentDevice into the TimeDevice class, for better or for worse.
Contained in the library's instrument_device.py is the InstrumentDevice class itself. When the instrument server receives rpc's from the client it parses them and asks python to call the appropriate function in InstrumentDevice. Since TimeDevice extended the InstrumentDevice, Python first looks in TimeDevice for that function and calls it if it exists. If not, the function in the base class, InstrumentDevice, is called. Since TimeDevice overrides device_read(), it is the TimeDevice device_read() that is called. Since TimeDevice does not override device_write(), it is the InstrumentDevice device_write() that is called.
So to proceed, you might try copy & paste the device_write(...) function from the InstrumentDevice class into your copy of TimeDevice, and replace the code in the final else with your action returning err_no_error. To be clear, there should be no need to modify the library itself, bugs not withstanding.... Override only the functions you need in your device class.
which vxi11 client library are you using?
Heres a thought: modify a clean version of the time device example pair, so that you write a timezone to the time device, and it returns the current time with that timezone applied. That should get you started and make the transition to gpio easy. Just be careful not to fall into the python time rabbit hole.
(sorry for my French ;-)
I will try this tomorrow I am a bit tired. Thanks
for the lib I use the one on the link from your read.me
So I have made this and it works (what did you think?)
def device_write(self, opaque_data, flags, io_timeout): # 11
error = vxi11.ERR_NO_ERROR
if False:
error = vxi11.ERR_IO_TIMEOUT
elif False:
error = vxi11.ERR_IO_ERROR
elif False:
error = vxi11.ERR_ABORT
else:
error = vxi11.ERR_OPERATION_NOT_SUPPORTED
print (opaque_data)#opaque_data type= byte
b=opaque_data
s=str(b,'UTF-8')#on converti en string
#on recupere le pin
starta = s.find("set:pin.")+len("set:pin.")
enda = s.find(":o")
pinact = s[starta:enda]
#on recupere l'etat
starts = s.find("set:pin."+pinact)+len("set:pin."+pinact)+1
ends = len(s)
pinstate = s[starts:ends]
# On met a l'état bas
# Pour chaque GPIOs du dictionaire:
for pin in actuator:
GPIO.output(actuator[pin], GPIO.LOW)
# on change l'état pour l'actioneur demendé
if pinstate == "on":
GPIO.output(actuator[pinact], GPIO.HIGH)
print(pinact+" "+pinstate)
if pinstate == "off":
GPIO.output(actuator[pinact], GPIO.LOW)
print(pinact+" "+pinstate)
for pin in actuator:
status[pin] = GPIO.input(actuator[pin])
print ("lecture des nouveaux etats des pins :")
print (status)
return error
but this work however it prints somme erros (who don't make crash the gui)
def command():
send=str(v.get())
if returnEntry() == "":
time_instr = vxi11.Instrument("TCPIP::"+result+"::inst1::INSTR")
time_instr.write('set:pin.E'+send+':on')
else:
time_instr = vxi11.Instrument("TCPIP::"+returnEntry()+"::inst1::INSTR")
time_instr.write('set:pin.E'+send+':on')
I have done it and it works correctly I will put it on my git there is some miner errors but it's fine
thanks a lot
Hello back did you know if I can close an re-open the server just with code?
Hi Louis
see if I get you right: if you close an instrument the instrument handler the server used for it will get deleted. if you reopen the instrument again the server instanciates a new instrument handler from your class. if you want to have persistent settings with your instrument, you have to either create a kind of "class registry dictionary" for them or use global variables.
bye Ulf
hello back I have continue continue to work on it and i whant to improuve it : so I have make a device read :
def device_read(self, request_size, term_char, flags, io_timeout): #= 12
"The device_read RPC is used to read data from the device to the controller"
error = vxi11.ERR_NO_ERROR
opaque_data = b""
if False:
error = vxi11.ERR_IO_TIMEOUT
elif False:
error = vxi11.ERR_IO_ERROR
elif False:
error = vxi11.ERR_ABORT
else:
error = vxi11.ERR_OPERATION_NOT_SUPPORTED
for pin in actuator1:
status1[pin] = GPIO.input(actuator1[pin])
for pin in actuator2:
status2[pin] = GPIO.input(actuator2[pin])
data1=str(status1)
data2=str(status2)
opaque_data=data1.encode("ascii")
print (opaque_data)
reason = ReadRespReason.END
result = error, reason, opaque_data
return result
I have a problem with encoding
have a nice day
Hi Louis,
Python isnt my first language. You need to help me out a bit... What problem are you having with the encoding?
for me also this is my first real project with it .
like the time server I want to use device ready to send the gpio current state a take the result to do things
so I use for loops to read all my gpios
for pin in actuator1:
status1[pin] = GPIO.input(actuator1[pin])
for pin in actuator2:
status2[pin] = GPIO.input(actuator2[pin])
the values are in JSON(I think) so i convert them in String
data1=str(status1)
data2=str(status2)
opaque_data=data1.encode("ascii") #then in ascii
to send them when device read is send
This is what i think i see:
- You use a loop to build a dictonary of gpio input values
- convert the dictionary to a string
- encode the string to binary.
It seems that should work. Perhaps the problem is with the decoding on the application side? What error message are you getting, and is it on the client or server end?
Also of note: the ERR constants are prefixed with vxi11 while the ReadRespReason is not. It may or may not mater depending on how the imports are defined.
I will tell you tomorrow because I am not in front of the pi
This is the error
Traceback (most recent call last):
File "C:\Users\louis\Desktop\atem\GUI+RPIS\atem widows GUI\test.py", line 318, in
but I don't knox how too fix it
This is a simple one, I make a Quizz from it: What does you code return in the error variable if you reuse this code from the examples:
error = vxi11.ERR_NO_ERROR
if False:
error = vxi11.ERR_IO_TIMEOUT
elif False:
error = vxi11.ERR_IO_ERROR
elif False:
error = vxi11.ERR_ABORT
else:
error = vxi11.ERR_OPERATION_NOT_SUPPORTED
I have this:
Louis,
look at your server code of def device_read
- as posted above -
your read() returns this error.
or, in other words: after line 280 of your code, your errror
variable holds vxi11.ERR_OPERATION_NOT_SUPPORTED
this way the client program will allways throw an error because you programmed it this way.
you have to adapt the example code (the thing with the if False..elif.. else
) to fit your program flow or throw it away and return one of the mentioned error conditions as result of your device_read method.
bye
Ulf
Thanks I will try it
hello, i'm still working on the server but i have to change board. When I do an inst read it displays nothing
client: import vxi11
instr = vxi11.Instrument('TCPIP::192.168.1.36::inst1::INSTR')
state=instr.read()
print(state)
serveur:
def device_read(self, request_size, term_char, flags, io_timeout): #= 12
"The device_read RPC is used to read data from the device to the controller"
error = vxi11.ERR_NO_ERROR
opaque_data = b""
for pin, id in actuator.items():
cmd ='gpioget '+ id
status =os.system(cmd)
states=str(status)
oapque_data=bytes(states,'ascii')#I try assci utf-8 ....
print(oapque_data)
reason = ReadRespReason.END
result = error, reason, opaque_data
return result
Have a nice day
louis,
Hi Louis, Glad to hear you are making progress.
These are the things that i might attack first:
- try to align your device_read with the demo server device_read. In particular, try setting
error = vxi11.Error.NO_ERROR
reason = vxi11.ReadRespReason.END
If these give you problems then we can take it from there. - Next, determine if the
print(opaque_data)
is giving you the results you expect. I think not as the for loop may not be appending to status. Perhaps you wantstates += str(status)
inside the for loop? (dont forget to initialize states before the for...) - Related, as i read the python docs for os.system() it is unclear to me what will be returned. If you are still having trouble you might write a small test program to explore os.system() without the added baggage of the vxi11 libraries etc to determine if that is in fact the command you want to be using.
- Finally, i see an inconsistency in the spelling of opaque. It most likely is not of consequence, but if its not a bug now, it will certainly become one ;-)
But after all that said, it sounds like this may be a new platform. Have you verified an unmodified version of the time-device.py runs properly on the new hardware?
c
thank you I will correct the errors. Is it possible to do device_read(get: E1)? this will simplify the code
Hello, you are indeed right os.system () only returns a 0 when the command is done. I need to learn how the gpiod lib works in python