Как отправлять и выполнять несколько событий в одном файловом потоке, записывая в «/dev/input/EventX»

Я пишу в определенный файл eventX в /dev/input/, чтобы вызвать «аппаратные» события. Проблема в том, что события выполняются только после того, как файл закрыт, и для запуска новых событий файл необходимо снова открыть. Как будто все события помещаются в очередь, а затем, когда файл закрывается, они выполняются. Например

Задача: выполнить нажатие мышью.

# Path is specific to my machine for the mouse
with open("/dev/input/event2") as controller: 
    send_mouse_click_event(controller) # This is put into a queue

print("File has closed") # here the press event triggers

send_mouse_click_event, который зависит от функции send, определяется следующим образом

# First a `send` function is used to interact with file
# it is basically the inverse of https://stackoverflow.com/a/16682549/13616163
def send(file_stream, type: int, code: int, value: int):
    timeval = str(time.time()).split(".") # Time that the event happend is requried, but seems to be redundant  
    if timeval[0][0] == '0': # the second part of `time.time()` must not start with a `0`
        utime = utime[1:len(utime)] 
    timeval = [int(item) for item in utime]
    # Convert to the following formats (long int, long int, ushort, ushort, uint)
    event: bytes = struct.pack('llHHI', *utime, type, code, value)
    file_stream.write(event)

# Now the specific events to trigger a mouse click
def send_mouse_click_event(filestream, value: int):
    # 0x90001 is always send before a click
    send(filestream, 4, 4, 0x90001)
    # 0x110 is indicating the LEFT CLICK
    # value is either 0 for mouse RELEASE and 1 for PRESS
    send(filestream, 1, 0x110, value)
    # (0, 0, 0) is indiciating the end of an event
    send(filestream, 0, 0, 0)

Мой вопрос: есть ли какое-либо событие, которое я могу send() указать, что я хочу выполнить все элементы, помещенные в очередь.

Закрытие и открытие файла — дорогостоящая операция, и необходимость делать это несколько раз снижает производительность. Должен быть лучший способ держать файловый поток открытым.

Является ли flush(filestream, 0, 0, 0) вызовом одной из ваших функций Python? Вызывает ли он метод файлового потока .flush()?

Ian Abbott 14.12.2020 15:44

Нет, это метод send, изменил его при редактировании. Виноват.

Countour-Integral 14.12.2020 15:50

В этом случае либо вызовите filestream.flush(), либо откройте поток с отключенной буферизацией. Также убедитесь, что поток является двоичным, а не текстовым.

Ian Abbott 14.12.2020 16:00

Кажется, это помогает. Никогда не знал, что можно писать в файл, не закрывая его. Вы можете опубликовать свой комментарий в качестве ответа, если хотите.

Countour-Integral 14.12.2020 17:07

Также загляните в проект hid-replay.

0andriy 15.12.2020 21:08
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
114
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если буферизация не была отключена в вызове open путем установки для параметра buffering значения 0, файловый поток будет либо полностью буферизован, либо буферизован построчно. Это зависит от типа открываемого файла и режима открытия, но потоки двоичных файлов никогда не устанавливаются в режим линейной буферизации.

В буферизованном режиме метод write будет записывать в буфер, но содержимое буфера не будет записываться в базовый файл до тех пор, пока либо буфер не будет заполнен, либо новая строка не будет записана в режиме буферизации строк.

Методы flush и close будут записывать содержимое буфера в базовый файл. Метод close также впоследствии закрывает файл.

В коде OP добавление file_stream.flush() в конец функции send будет записывать содержимое буфера в базовый файл каждый раз, когда вызывается функция send. Альтернативой является добавление filestream.flush() в конец функции send_mouse_click_event, чтобы данные, записанные тремя вызовами send, были сброшены в базовый файл за один раз.

Другие вопросы по теме