Raspberry PI GPIO Keyboard/Mouse Input - pi

Trying to create very simple keyboard and mouse controller using the Raspberry Pi's GPIO pins. Would love to use the code in a educational setting, so trying to build super easy, readable code for children/students. But the code is acting somewhat strange, it keeps outputting the same keystrokes:
import gpiozero
from pynput.mouse import Button, Controller as MouseController
from pynput.keyboard import Key, Controller as KeyboardController
keyboard = KeyboardController()
mouse = MouseController()
Up = gpiozero.Button(26, bounce_time=0.02)
LeftMouse = gpiozero.Button(17, bounce_time=0.02)
while True:
if Up.is_pressed:
print("Up")
keyboard.press(Key.up)
Up.wait_for_release()
keyboard.release(Key.up)
elif LeftMouse.is_pressed:
print("Left Mouse button")
mouse.press(button.left)
LeftMouse.wait_for_release()
mouse.release(button.left)
Using Python 3.7.3. No matter which GPIO I trigger (26 or 17), the code always outputs 'Up' and press the keyboard 'up' button. It must be something stupid, but I can't seem to figure it out. Would love to keep using the if/elif, so I can expand the code later with more GPIO buttons. Any idea's anyone?

Although I am not very experienced in the GPIO of Raspberry, I think your code is almost alright. I suspected that the reason of always having 'Up' outcomes, which meant the 2nd mouse condition statement was bypass, was probably due to the word 'button' being not consistent with the module you called in the first line? Below is the one after using 'Button' throughout. Probably when you triggered pin 17, it did pass through the printing stage but it could not penetrate further. It will no choice but to select the first keyboard statement. So, it would end up with 'Up' all the way.
from pynput.mouse import Button, Controller as MouseController
elif LeftMouse.is_pressed:
print("Left Mouse button")
mouse.press(Button.left)
LeftMouse.wait_for_release()
mouse.release(Button.left)
I also found the below link quite useful in order to make sure the packages imported and defined properly.
pynput - Importing keyboard and mouse
Looking forward to hearing from your update.

Related

When is a widget property available to an iPython / Jupyter cell?

I'm getting ready to create a communications widget for use in a Jupyter application. I'm trying to understand when the widget's "value" property can be accessed ... it looks like the "value" can be read anytime, but won't match the widget model "value" until cell execution stops (i.e., the widget's browser state isn't updated back to the widget's kernel state).
To test this, I tried creating a small slider widget, waiting for 10 seconds, and then reading the widget "value" property ... all in the same cell. In the 10 seconds, the user (i.e., me) has time to change the slider to something like "5".
Here's a small test that can be run in a cell. When the sleep() happens, I move the slider to value "5".
from ipywidgets import *
import time
slider = IntSlider(
value=7,
min=1,
max=10.0,
step=1,
description="Input:",
)
display(slider)
time.sleep(10) # move slider to 5
print("done " + str(slider.value))
I expected "done 5" but got "done 7", implying to me that "value" is updated only after the cell completes.
Is this always true? And is there a way to force synchronization between the widget's browser state and its state in the kernel?
(I do get the expected "done 5" if I move the print() to the following cell.)
Thanks!
There is basically at present no way to automatically force code running in a cell
to wait for an event or change in a widget. Things like time.sleep(3) will only
freeze the cell and a slider created in the same cell will not display until the
sleep is complete.
The user could create a slider in cell 1 and then execute a sleep in cell 2 and then adjust the slider and the code in cell 2 may see the change after the sleep
but in this case the synchronization is directed by the user and is not automatic.
You can also start Python code from a widget event, but the Python code does not "run in a cell" and the "prints" will not go to the standard cell output area but
the output can be captured in other ways,.
In the following screenshot I use the "Output" widget to capture output from a widget event
The basic problem is that all communication between widgets and kernels is via
one-way messages -- there are no "return values" or "acknowledgements" of any kind.
Please see https://github.com/AaronWatters/jp_proxy_widget/blob/master/notebooks/Tutorial.ipynb for more discussion.
As it turns out, there does seem to be a library that uses something like asyncio to achieve an inline wait. It's called jupyter-ui-poll at https://github.com/Kirill888/jupyter-ui-poll. The author says it's available on PyPI at https://pypi.org/project/jupyter-ui-poll/
Very promising! ... otherwise, I'm forced to agree with you.

qt app that takes in textedit barcode scanned, how to change focus between two fields

So for me the plan is like this:
I scan a barcode, it gets in first textedit;
I scan another barcode, it gets in the second textedit,
in this case i use focus and keyboard event.
my problem is when i scan first code it is fine but when I scan the second code, some of letters go to second texedit some go to first texedit.
I don't understand what is the problem
here is my code
void CWidget::keyPressEvent(QKeyEvent *event)
{
if(focusWidget() == ui->lePath && !ui->lePath->text().isEmpty())
{
ui->leInformation->setFocus(); //leInformation second edit
ui->leInformation->setFocusPolicy(Qt::StrongFocus);
ui->leInformation->KeyPressEvent(event);
}
else
{
ui->lePath->setFocus(); //lePath - first edit text, first code scanned //goes here
ui->lePath->setFocusPolicy(Qt::StrongFocus);
ui->lePath->KeyPressEvent(event);
}
}
like is a strange think cause sometimes works sometimes no, if both codes scanned have digits they work but if the second scanned code has uppercase letters they go from the first uppercase letters they are wrote to first edit. but if they are lowercase they are fine again. I m thinking it is a problem with keyboard event how they deal with uppercase. somehow maybe with shift, and they change between two edits.
if there is someone who has an idea on how i can properly write that keyboard event, please help thanks
here B should have been on the second. I'm being sure on how uppercase are being entered on keyboard event is about shift + letter and shift moves you to the other edit but how i can change this

Client doesn't have a name/class at startup

I'm trying to start an application (Spotify) on a particular tag. Rules aren't applied and now I'm inspecting the client class by printing the class in a notification in the "manage" signal. This results in an empty notification.
client.connect_signal("manage", function (c, startup)
naughty.notify({title=c.class})
end)
When I restart awesome, it does print the client class, so why isn't it working when the client is initially started?
Using xprop, it also prints the class:
WM_CLASS(STRING) = "spotify", "Spotify"
Sounds like a bug in Spotify (and I think I heard about this one before). I would guess that Spotify does not follow ICCCM and only sets its WM_CLASS property after it made its window visible and not before.
I fear that you cannot do much about this except for complaining to Spotify devs to fix their stuff.
You could work around this by starting a timer in the manage signal that checks if a window turns out to be spotify a short time later. Alternatively, you could do something like client.connect_signal("property::class", function(c) if c.class == "Spotify" then print("This is now a spotify window") end end) to react to change to a window's class (of course you'd want to do something more useful to Spotify's windows than printing them).
(Per the ICCCM, a window is not allowed to change its class while it is visible, but who cares about standards...)
I had a similar issue with the claws-mail client. Inspecting it via xprop, it shows
WM_CLASS(STRING) = "claws-mail", "Claws-mail"
but awesome just did’t apply the rules for it. The trick was giving awesome-wm both of these class names in the rules section by providing a set of characters to chose from:
rule = {class = "[Cc]laws%-mail"}
I hope this works for your spotify application, too.
For further reading about patterns in lua I suggest this:
https://www.lua.org/pil/20.2.html

Send future clients to right monitor in awesome?

I'm trying to implement a very customized implementation of awesome.
I have two monitors. I'd like to have my first client always open on the left monitor (a Chrome window in kiosk mode), then all clients after open up on the right monitor.
Are there any custom layouts that accomodate this?
I'd be willing to program it myself, but I'm not sure how to bind a script to some kind of "new client" event.
The new client event is the manage event. It is emitted whenever, well, a new client gets managed by awesome.
To send the first client that ever appears to screen 1 and all following ones to screen 2, you could do something like this:
local first = true
client.connect_signal("manage", function(c)
if first then
c.screen = 1
else
c.screen = 2
end
first = false
end)

How to read any keypress in interactive R (e.g. cursor-up or shift)?

How do you read any arbitrary keypress in R (interactive-mode), such as cursor-up or shift, and return the actual key(s) pressed?
Ideally in a device-independent, OS-independent way (I'm on Mac OS 10.8.x)
I'm talking about reading any actual arbitrary keypress including cursor-keys or modifier-keys, so scan() and readline() won't do it - cursor-keys get intercepted by the interactive console. And not just waiting for a keypress.
It's not clear this is easy or device-independent. I looked at documentation:
interactive(), options('device'), R_INTERACTIVE_DEVICE, R_DEFAULT_DEVICE
I read R-internals, which says "a graphics device... can handle requests/opportunities to take action such as... wait for an event, for example a mouse click or keypress." but it doesn't say much more.
I tried grDevices::getGraphicsEvent() but got:
> getGraphicsEvent('waiting for cursor keys', onKeybd=function(key) { print(key) } )
Error in setGraphicsEventEnv(which, as.environment(list(...))) :
this graphics device does not support event handling
It seems like if you dig deep enough you could use a toolkit-specific and/or OS-specific hack, e.g. with Quartz. This guy suggests Sudoku::playSudoku(), which uses Quartz to handle mouse and key input. I have Quartz. But a Quartz-specific solution won't work on Windows. This all seems quite messy.
Can someone please demystify all this?

Resources