PythonのPyAutoGuiでマウスを動かしTeamsの退席中表示を回避する
PyAutoGui ライブラリを使ってPythonでマウスを動かしTeamsの退席中表示を回避する方法を解説します。
この記事は、前回の投稿「Teamsの「退席中」表示をPythonで回避してみる」で紹介したコードの中身を説明しようと思います。よかったらこちらの記事も参考にしてください。
Teamsの退席中表示の回避方法について、色々なアイデアを次の記事でもまとめています。よかったらこちらも参考にどうぞ。
Teamsの退席中表示を回避する方法【アイデア11選】
Pythonでマウスを操作するために必要なモジュール :PyAutoGui
今回は、PyAutoGUIライブラリを使用します。
PyAutoGUIはPythonからマウスやキーボードを自動操作できるライブラリです。
PyAutoGUIのインストール方法
PyAutoGuiは外部のライブラリのため、プログラムを実行する前にインストールする必要があります。
次のコマンドでインストールします。
pip install pyautogui
Macの場合は、次のインストールも必要と書かれています。
プログラムを動かした際に、モジュールが足りませんと表示されたら次のインストールも検討してみてください。
※僕もMacで動作確認しましたが、pip install pyautogui のみで今回のコードは動きました。もう少し複雑なGUI操作まで必要な際に必要なライブラリかもしれません。
pip install pyobjc-core
pip install pyobjc
PyAutoGUIの主要関数
PyAutoGUIは、次のような情報の取得や操作を行うことができます。
pyautogui.moveTo(x,y) | マウス座標を(x,y)まで移動 |
pyautogui.move(x,y) | マウス座標を(x,y)だけ移動する |
pyautogui.position() | マウスの現在位置(x,y)を取得 |
(mx, my) = pyautogui.size() | ディスプレイの解像度を取得 |
pyautogui.press('shift') | キーボードのshiftボタンを押す |
今回は使いませんが、クリックも可能です。
pyautogui.click() | マウスボタンをクリックする |
pyautogui.mouseDown() | マウスボタンを押す(押した状態をキープ) |
pyautogui.mouseUp() | マウスボタンを離す |
これを見るだけでも基本的な操作は全てできそうなので、様々な操作の自動化に活用できそうですね。
座標の定義(PyAutoGUIの関数上の定義)
プログラム上で使われる座標は次の通りです。
原点 :ディスプレイの左上
x :ディスプレイの横方向、右側ほどxの値が増える
y :ディスプレイの縦方向、下側ほどyの値が増える
Teamsの退席中表示の回避するプログラムの要件
ざっくり次を満たすプログラムにしようと思います。
- 一定時間マウスが動かなければ、自動でマウスを動かす
- マウス操作がある場合は、プログラムは何もせずに待機
- 動作開始時に、待機時間(マウス操作がない判定を行うまでの時間)を指定可能にする
- マウスを自動で動かす場合は、丸い軌跡を描くように動かす(ここだけちょっとおしゃれに)
Teamsの退席中表示の回避するプログラムの実装方針
上の要件の中で、要件の1〜3は一般的なPythonの扱いで実装可能そうです。
一方で、要件4 は今回始めて使うPyAutoGUIの実装部分で、最も未知の部分が多い部分です(僕の場合)。
このため、不安な部分から実装しようという考えから、今回は4から実装していくことにしました。
Step1 PyAutoGUIを使って丸い軌跡でマウスを動かす(要件の4)
まずは、マウスを動かすための関数move_mouse()は次の通りです。
import pyautogui
from time import sleep, strftime
import math
def move_mouse_gohey():
r = 60
(mx, my) = pyautogui.size()
pyautogui.moveTo(round(mx/2), round(my/2 -r-r))
rad2deg = 360 / math.pi
move_num = 40
for t in range (move_num):
round_t = 3
step = 1/(move_num/round_t)
x = r*math.cos(step*t*2*math.pi)
y = r*math.sin(step*t*2*math.pi)
pyautogui.move(x,y)
pyautogui.press('shift')
ここから順番に中身を見ていこうと思います。
r = 60
丸い軌跡を描くための、丸の半径を設定しておきます。単位はピクセルです。
(mx, my) = pyautogui.size()
pyautogui.moveTo(round(mx/2), round(my/2 -r-r))
size()関数で、ディスプレイ全体の解像度を取得し、マウスカーソルを中央に移動させます。
rad2deg = 360 / math.pi
move_num = 40
for t in range (move_num):
round_t = 3
step = 1/(move_num/round_t)
x = r*math.cos(step*t*2*math.pi)
y = r*math.sin(step*t*2*math.pi)
pyautogui.move(x,y)
pyautogui.press('shift')
move_numで何回マウスカーソルを動かすかを設定しています。
暫定で40回としていますが、あまりに多いと時間がかかりすぎますし、少なすぎるとマウスを動かしたとしてもTeamsアプリが反応してくれない可能性があるので、これらを両立できる値なら問題ないと思います。
round_tという変数で、マウスを何回転させるかを定義しています。
動かす回数と回転数から何度ずつマウスを動かせばよいかを割り算し、円の公式でx, yを決めて動かします。
最後のpress()では、マウス操作に加えてシフトキー入力も念の為行っています。
Step2 動作開始時に、待機時間(マウス操作がない判定を行うまでの時間)を指定可能にする(要件の3)
続いて、待機時間を起動時にユーザーが設定できるような仕組みを作りたいと思います。
待機時間を取得するための関数をinitialize()として書きました。
def initialize():
val = 0
print("Enterで動作開始 / 1入力+Enterで待機時間設定")
val = input()
if val == "1":
print("Setting:何分間マウス操作がない場合に、ゆらゆらしますか?[1〜30で指定可能です]")
val = input()
if val.isdecimal() and int(val)>1 and int(val)<31 :
print("動作を開始します。", val, "分間マウス操作がない場合は、ゆらゆらします。")
else:
val = 3
print("動作を開始します。", val, "分間マウス操作がない場合は、ゆらゆらします。")
else:
val = 3
print("動作を開始します。", val, "分間マウス操作がない場合は、ゆらゆらします。")
return int(val)
動作開始時にEnterを押せば、デフォルトの待機時間3分で動作します。
待機時間を変更したい場合は、1を入力後にEnterを押すと、待機時間設定モードに入り、再度入力された数値を待機時間として受け取れるようにしました。
Step3 PC操作の状態に合わせて、マウスを自動で動かす
(要件の2と1)
最後に、要件の1と2を同時に解説していきます。
ここでは、PC操作の状態に合わせてマウスを動かすかどうかの判断し、制御していく方法の解説になります。
要件1 :一定時間マウスが動かなければ、マウスを自動で動かす
要件2 :マウス操作がある場合は、プログラムは何もせずに待機
def move_mouse_top():
wait_min = initialize()
count_sleep = 0
print(format(strftime('%H:%M:%S')), "Count:", count_sleep, "Min")
pos_orig = pyautogui.position()
wait_min = int(wait_min)
# 推奨
# max_min = 60*8 # 8 hours
# check_min = 60 #[sec]
# 動作確認用
max_min = 10 # 10 [min]
check_min = 5 #[sec]
for idx in range(max_min):
sleep(check_min)
pos_current = pyautogui.position()
dx = pos_orig.x - pos_current.x
dy = pos_orig.y - pos_current.y
dist = pow(dx*dx + dy*dy, 0.5)
pos_orig = pos_current
if dist < 20: count_sleep +=1 else: count_sleep = 0 print(format(strftime('%H:%M:%S')), "Count:", count_sleep, "Min") if count_sleep > wait_min - 1:
print("moved")
move_mouse_gohey()
count_sleep = 0
print(format(strftime('%H:%M:%S')), "Count", count_sleep, "Min")
こちらも順番に説明していきます。
def move_mouse_top():
wait_min = initialize()
count_sleep = 0
print(format(strftime('%H:%M:%S')), "Count:", count_sleep, "Min")
pos_orig = pyautogui.position()
initialize()で待機時間を設定取得します。
wait_min = int(wait_min)
また、この後マウスが動いたかどうかを判定するために、現在のポインタの位置(pos_orig)を取得しておきます。
# 推奨
# max_min = 60*8 # 8 hours
# check_min = 60 #[sec]
# 動作確認用
max_min = 10 # 10 [min]
check_min = 5 #[sec]
for idx in range(max_min):
sleep(check_min)
pos_current = pyautogui.position()
dx = pos_orig.x - pos_current.x
dy = pos_orig.y - pos_current.y
dist = pow(dx*dx + dy*dy, 0.5)
pos_orig = pos_current
if dist < 20:
count_sleep +=1
else:
count_sleep = 0
print(format(strftime('%H:%M:%S')), "Count:", count_sleep, "Min")
最初にcount_sleepとして、PCを操作していないときのカウンタを作っておきます。
check_min時間(1分を想定)経過したら、前回取得したポインタの位置から現在のポインタ位置までの距離を計算します。
今回は20ピクセル以上離れた場合は操作したと判定し、PC操作していないカウントを0にリセットします。
20ピクセル以下の場合は、PC操作していないカウントに1を足します。
if count_sleep > wait_min - 1:
print("moved")
move_mouse_gohey()
count_sleep = 0
print(format(strftime('%H:%M:%S')), "Count", count_sleep, "Min")
PCを操作していないカウント値が起動時に設定した待機時間となると、move_mosue_gohey()を呼び出しマウスを動かします。
その後、カウント値を0に戻し、再度マウス状態の監視を継続します。
途中で設定したmax_min回マウス操作有無のチェックを行った後にプログラムを終了します。
以上が今回実装したプログラムの詳細になります。
コードをこれだけ説明た上で大変申し訳ございませんが、今回のプログラムで実際にTeamsツールで退席中表示を回避できるかまで確認できておりません。
もし興味のある方は、モラルの範囲で、自己責任でご確認いただけると幸いですm(_ _)m
最初にも紹介しましたが、コード全体は「Teamsの「退席中」表示をPythonで回避してみる」に書いてあります。
最後に
いかがだったでしょうか?
Pythonを使えば、ちょっと面倒くさいなという処理を簡単に自動化することができます。
今回のプログラムは、どこまでまともに使えるものかは分かりませんが、どちらかというと、Python勉強中という方に、マウスを動かすぞ!という目的を持って、プログラムを書いてみるという学習用途で利用して頂くことを期待しております。
追記
今回の記事をTwitterや他のブログ等でも一部取り上げていただきありがとうございます。こんなプログラム書いてほしいとかあったらぜひTwitterのほうにコメントお願いします。