Is there any event I can listen to when a new keyboard attaches in Python? I'd like to disable the internal laptop keyboard and run xmodmap for the new keyboard. My only idea right now is polling xinput list and then grep USB. Is there a better way to do it?
It's years since I've done anything like this, so I don't have any code examples for you, but I think for the problem you're looking at, you should consider a udev rule.
This looks like a good resource for udev: https://linuxconfig.org/tutorial-on-how-to-write-basic-udev-rules-in-linux
If I remember correctly (It's a VERY long time since I made a custom udev rule; I might NOT remember correctly), one thing you could do is execute a python script when something's plugged in, and that something happens to be a USB keyboard.
Related
I have this really strange problem, basically I want to start xpdf (or Libreoffice) from my Python script, that is started by a systemd-service. When I start the script from terminal everything is working fine, but when I plug in my USB device that start the Service, I'll get this Error in my syslog:
sh[2321]: Error: Can't open Display
This error has something to do with X11, that's what my Google searches tell me.
So, my question is: How can I properly run a program like xpdf or libreoffice from Python?
import subprocess
subprocess.call("/usr/bin/xpdf")
This is it, basically. I know that it has something to do with the graphical enviroment, but I don't know how I can solve it.
The X display system has very good security to stop random local processes from just displaying stuff to the local screen (It was more a problem in the old days of expensive Sun and SGI systems where computer labs would often let users telnet to other boxes. Much fun could be had!).
If the user running the xpdf is the same user as the one who's logged into the X session, then you simply need to tell xpdf where to connect it's UI to. This is usually done by exporting DISPLAY=:0 to the environment, which means "connect to the first local screen". Most X programs also support -display :0 argument.
So do:
/usr/bin/xpdf -display :0
or:
DISPLAY=:0 /usr/bin/xpdf
It's very unlikely that you have more than one X session so :0 will work 99% of the time.
Since the issue is that xpdf isn't finding a display to connect to, we have two basic options: find and authenticate with an existing display, or make a new one. The latter is usually easier, something like:
xinit /usr/bin/xpdf -fullscreen $PDFFILE -- :2
This would start a new X display :2 running only xpdf, not even a window manager.
It finally worked, after trying and going crazy for around 2 weeks.
What worked was
os.system("DISPLAY=:0 /usr/bin/xpdf)
I know that subprocess.call is the better way to call the program, but it doesn't seem to work right now.
I'll try the way that Yann suggested later on, but for now I'm just overwhelmed with joy that it just works.
Thank you all for your help, I really appreciate it!
I am really impressed by this MarlIO project and want to implement something similar using Python. However, I got the emulator OpenEmu working, however, I don't know how to control the game using Python.
Isn't it just a matter of sending a few keystrokes?! Man, it is not that straightforward on a Mac.
In [41]: cmd1
Out[41]: '\nosascript -e \'tell application "System Events" to key code 48 using {command down}\' \n'
In [42]: cmd2
Out[42]: '\nosascript -e \'tell application "System Events" to keystroke "a"\' \n'
I want to first use COMMAND+TAB to switch to the openEmu and then hit a to jump. However, when I ran the two commands, it only switched to the OpenEmu, looks like the keystroke a did not got sent.
However, when I ran 'cmd2' separately, it was clearly working.
Then I testedit against a different application - sublime, and it seemed to work there.
Can anyone point me to the right direction what I really did wrong with OpenEmu?
I did something like that a few months ago. The keystrokes are sent. However, System Event keystrokes last virtually no time, so the emulator's input mechanism doesn't pick them up.
I couldn't find a way to ask for a duration with AppleScript, so I ended up solving the problem using Quartz event taps, which let you do, for instance, "start pressing key, sleep 0.1s, stop pressing key". I did it in Swift, but you should be able to do it in Python with the ctype module.
Also note that it might be difficult to synchronize on a frame basis with the emulator. I raised that problem with the project maintainers, but I turned away because of the relatively cold response.
I work on a project to control my PC with a remote, and a infrared receptor on an Arduino.
I need to simulate keyboard input with a process on linux who will listen arduino output and simulate keyboard input. I can dev it with Python or C++, but i think python is more easy.
After many search, i found many result for... windows u_u
Anyone have a library for this ?
thanks
EDIT: I found that /dev/input/event3 is my keyboard. I think write in to simulate keyboard, i'm searching how do that
To insert input events into the Linux input subsystem, use the user-mode input device driver, uinput. This might help: http://thiemonge.org/getting-started-with-uinput (Note that while the tutorial references /dev/input/uinput, the correct file on my Ubuntu 12.04 PC is /dev/uinput.
The most generic solution is to use pseudo-terminals: you connect tttyn to the standard in and standard out of the program you want to monitor, and use pttyn to read and write to it.
Alternatively, you can create two pipes, which you connect to the standard in and standard out of the program to be monitored before doing the exec. This is much simpler, but the pipes look more like a file than a terminal to the program being monitored.
I have a long running python process running headless on a raspberrypi (controlling a garden) like so:
from time import sleep
def run_garden():
while 1:
/* do work */
sleep(60)
if __name__ == "__main__":
run_garden()
The 60 second sleep period is plenty of time for any changes happening in my garden (humidity, air temp, turn on pump, turn off fan etc), BUT what if i want to manually override these things?
Currently, in my /* do work */ loop, i first call out to another server where I keep config variables, and I can update those config variables via a web console, but it lacks any sort of real time feel, because it relies on the 60 second loop (e.g. you might update the web console, and then wait 45 seconds for the desired effect to take effect)
The raspberryPi running run_garden() is dedicated to the garden and it is basically the only thing taking up resources. So i know i have room to do something, I just dont know what.
Once the loop picks up the fact that a config var has been updated, the loop could then do exponential backoff to keep checking for interaction, rather than wait 60 seconds, but it just doesnt feel like that is a whole lot better.
Is there a better way to basically jump into this long running process?
Listen on a socket in your main loop. Use a timeout (e.g. of 60 seconds, the time until the next garden update should be performed) on your socket read calls so you get back to your normal functionality at least every minute when there are no commands coming in.
If you need garden-tending updates to happen no faster than every minute you need to check the time since the last update, since read calls will complete significantly faster when there are commands coming in.
Python's select module sounds like it might be helpful.
If you've ever used the unix analog (for example in socket programming maybe?), then it'll be familiar.
If not, here is the select section of a C sockets reference I often recommend. And here is what looks like a nice writeup of the module.
Warning: the first reference is specifically about C, not Python, but the concept of the select system call is the same, so the discussion might be helpful.
Basically, it allows you to tell it what events you're interested in (for example, socket data arrival, keyboard event), and it'll block either forever, or until a timeout you specify elapses.
If you're using sockets, then adding the socket and stdin to the list of events you're interested in is easy. If you're just looking for a way to "conditionally sleep" for 60 seconds unless/until a keypress is detected, this would work just as well.
EDIT:
Another way to solve this would be to have your raspberry-pi "register" with the server running the web console. This could involve a little bit extra work, but it would give you the realtime effect you're looking for.
Basically, the raspberry-pi "registers" itself, by alerting the server about itself, and the server stores the address of the device. If using TCP, you could keep a connection open (which might be important if you have firewalls to deal with). If using UDP you could bind the port on the device before registering, allowing the server to respond to the source address of the "announcement".
Once announced, when config. options change on the server, one of two things usually happen:
A) You send a tiny "ping" (in the general sense, not the ICMP host detection protocol) to the device alerting it that config options have changed. At this point the host would immediately request the full config. set, acquiring the update with it.
B) You send the updated config. option (or maybe the entire config. set) back to the device. This decreases the number of messages between the device and server, but would probably take more work as it seems like more a deviation from your current setup.
Why not use an event based loop instead of sleeping for a certain amount of time.
That way your loop will only run when a change is detected, and it will always run when a change is detected (which is the point of your question?).
You can do such a thing by using:
python event objects
Just wait for one or all of your event objects to be triggered and run the loop. You can also wait for X events to be done, etc, depending if you expect one variable to be updated a lot.
Or even a system like:
broadcasting events
There is some way to get the device path of a mouse and keyboard using Xlib based in a looping with XNextEvent? I need to know what /dev/input/event* generates a event specific like mouse press and keyboard key F1 press.
I'm using evdev for input devices in Xorg, I searched documentation and cannot find a way.
I accept too suggestion of some app that I can use to identify input device based in events like mouse press and keyboard press.
Thanks.
Edit: If there is a way to make this using another lib, preferable one with bindings for python, please let me know.
I realize that Xlib do not have a method to get the file descriptor of the input devices, so I figured out another way to resolve this case, is not ready yet, but apparently is the best way to follow, just posting here for someone with the same problem.
I'm using the module python-evdev (installed with pip in ubuntu), with this module I can monitor the devices is /dev/input/event*, so I just need to start a thread for each device that I previous identified which is a mouse or keyboard (using the module evdev and checking if device have "capabilities(verbose=True)" with event codes like ecodes.KEY_F1 and ecodes.BTN_MOUSE), and when a event occur, write to a shared variable, that I should monitor.
For the graphic interface running in Xorg, without Windows Managers, I using python-glade2, works like a charm, I run a Xorg with python-glade2 app using xinit.