mieki256's diary



2021/03/04(木) [n年前の日記]

#1 [hsp][raspberrypi][linux] キーボードに割り当てられたeventを取得できるか実験

Raspberry Pi用HSPが、キーボードやマウスを検出できない件について。とりあえず、/proc/bus/input/devices の内容から、キーボードに割り当てられた event* を取得できそうかどうか試してみたり。

以下のやり取りの中で、/proc/bus/input/devices を参照することでキーボードの event番号?を取得する方法が紹介されていて、2つほど、サンプルソースが提示されてる。

_c - Determine Linux keyboard events device - Stack Overflow
それぞれ、手元の環境でも動くように書き直してみたり。いやまあ、前述のサンプルをほとんどコピペしたようなものだけど…。

動作確認した環境は以下。
_getkbdpath.cpp
#include <string>
#include <cstdio>

static const std::string CMD_GET_KBD_DEV_NUM = "grep -E 'Handlers|EV=' /proc/bus/input/devices | grep -B1 'EV=1200..' | grep -Eo 'event[0-9]+' | grep -Eo '[0-9]+' | tr -d '\n'";

static const std::string CMD_COUNT_KBD_DEV = "grep -E 'Handlers|EV=' /proc/bus/input/devices | grep -B1 'EV=1200..' | grep -Eo 'event[0-9]+' | wc -l";

std::string execCmd(const char *cmd)
{
  FILE *pipe = popen(cmd, "r");
  char buf[2048];
  std::string r = "";
  while (!feof(pipe))
    if (fgets(buf, 2048, pipe) != NULL)
      r += buf;
  pclose(pipe);
  return r;
}

std::string getKbdDevPath()
{
  std::string kbdCnt = "";
  std::string devNum = "";
  kbdCnt += execCmd(CMD_COUNT_KBD_DEV.c_str());
  if (kbdCnt[0] == '0')
  {
    // Not found keyboard
    return "";
  }
  else if (kbdCnt[0] == '1')
  {
    devNum += execCmd(CMD_GET_KBD_DEV_NUM.c_str());
    if (devNum[0] == '\0')
    {
      // Not found keyboard
      return "";
    }
    // found keyboard
    return "/dev/input/event" + devNum;
  }
  printf("Multiple keyboards exist\n");
  return "";
}

int main()
{
  std::string devPath = getKbdDevPath();
  if (devPath[0] == '\0')
  {
    printf("Not found keyboard\n");
  }
  else
  {
    printf("keyboard: %s\n", devPath.c_str());
  }
}

_getkbdpath2.cpp
#include <stdio.h>
#include <string.h>
#include <string>

std::string getInputDevPath()
{
    const char *pdevsName = "/proc/bus/input/devices";
    std::string devPath = "";
    char buf[8196];
    FILE *fp;

    if ((fp = fopen(pdevsName, "r")) == NULL)
    {
        printf("[ERR] Cannot open '%s'\n", pdevsName);
        return "";
    }

    int rd = fread(buf, sizeof(*buf), sizeof(buf) / sizeof(*buf), fp);

    fclose(fp);

    if (rd < 6)
    {
        printf("[ERR] Wrong size was read from devs file\n");
        return "";
    }
    buf[rd] = 0;

    char *pHandlers, *pEV = buf;
    do
    {
        pHandlers = strstr(pEV, "Handlers=");
        pEV = strstr(pHandlers, "EV=");
    } while (pHandlers && pEV && 0 != strncmp(pEV + 3, "1200", 4));

    if (pHandlers && pEV)
    {
        char *pevent = strstr(pHandlers, "event");
        if (pevent)
        {
            devPath += "/dev/input/event";
            devPath.push_back(pevent[5]);
        }
        else
        {
            printf("[ERR] Abnormal keyboard event device\n");
        }
    }
    else
    {
        printf("[ERR] Keyboard event device not found\n");
    }

    return devPath;
}

int main()
{
    std::string r = "keyboard: " + getInputDevPath();
    printf("%s\n", r.c_str());
}

g++ を使ってコンパイル。
g++ -o getkbdpath getkbdpath.cpp
g++ -o getkbdpath2 getkbdpath2.cpp
getkbdpath と getkbdpath2 という実行ファイルができる。

Raspberry Pi Zero W 上で実行。キーボードは Logicool K400r を接続。
$ ./getkbdpath
keyboard: /dev/input/event0

$ ./getkbdpath2
keyboard: /dev/input/event0
タッチパッド付キーボードでありながら、/dev/input/by-id 以下で event-kbd を返してくれない Logicool K400r でも、割り当てられた event番号を取得することができた。こういう方法でも判別できるのだな…。

問題点。 :

/proc/bus/input/devices の中に、EV=1200.. が1つだけ出現する場合は、これでなんとかなるけれど。2つ以上出現する場合は、ちょっと困ったことになるなと…。

例えば、手持ちの機器の中には、以下のような製品があるのだけど。
  • USB接続ワイヤレスキーボード BUFFALO BSKBW03WH。/dev/input/by-id 以下で、event-kbd の他に event-mouse も返してくる。
  • USB有線接続マウス A4Tech XL-755BK。/dev/input/by-id 以下で、event-mouse の他に event-kbd も返してくる。しかも、/proc/bus/input/devices の中で、EV=1200.. まで返してくる。

この2つを組み合わせると最悪の状態が発生する。キーボードを1つ、マウスを1つしか接続してないのに、/proc/bus/input/devices 内ではキーボードが2つ存在することになってしまう。

一応、この組み合わせの場合の情報もアップしておくけど…。

_buffalo_bskbw03wh_and_a4tech_xl755bk.md

この場合…。
  • grep を駆使して探す方法では、正しいevent番号が得られない。
  • C/C++の関数を駆使する方法では、最初に見つかったevent番号しか得られない。

つまり…。
  • /proc/bus/input/devices の内容を解析して、キーボードに割り当てられたevent*を取得するやり方は、/dev/input/by-id 以下に event-kbd が出現しないキーボード製品についても対応できるメリットがある。
  • しかし、キーボード(event-kbd)なのにマウス(event-mouse)でもあると言い出したり、マウス(event-mouse)なのにキーボード(event-kbd)でもあると言い出す製品群には結局対応できない。どれが本当に使えるキーボードなのか、判別する方法がない。

後者の解決策が思いつかない…。手詰まりかなあ…。

他の案。 :

このあたりの問題を緩和する他の方法は無いのかなと考えてみたり。

例えば、HSP対応(?)のキーボードとマウスなのか確認できるスクリプトを別途用意しておいて…。そのスクリプトを動かしてみて、「Keyboard, Mouse : Good」と言ってくるならHSPは使えますよ、でも「Keyboard, Moues : Bad」と言ってくるなら使えないので別のキーボードやマウスを探して繋いでみてね、てなことにしておく。とか。

あるいは、keyboard.ini だの mouse.ini というファイルがもし存在していて、/dev/input/event0 だの /dev/input/event4 だのが書いてあるなら、それをキーボードやマウスとして使うことにする、てな仕様にしておくとか。どうしても自動検出できない場面に遭遇したら、それらファイルを新規作成して環境に合わせたファイルパスを記述すれば一応動くよ、と。

まあ、何にせよ、 _現状のRaspberry Pi用HSPはキーボードやマウスとの相性があるよ、 ということで…。プログラム側での解決策は、自分の知識状態では思いつかんです…。手詰まりです。

それにしても、他のプログラム類は、このへんどうやって解決してるのだろう…。

#2 [zatta] LEDシーリングライトを入手したけど問題発生

しばらく前から部屋の蛍光灯が怪しくて。2つついてる丸型蛍光灯の1つが切れかかってるようで、点いたり消えたりを繰り返すのと、もう1つの蛍光灯をつけていても「ジーッ」という音が鳴る。音が鳴るのは安定器とやらがもう寿命だそうで、本来は器具そのものを交換しなければいけないらしい。しかし、今時、どこの店頭でも蛍光灯用の器具なんて、もはや売ってないわけで…。

この際、せっかくだからLEDライトに交換しようという話になって、親父さんがケイヨーD2で値段を調べてくる、という話をしていたのだけど。

値段を調べてくるだけ、だったはずが、親父さんは、いきなり製品を購入してきてしまった…。アイリスオーヤマ CL12D-EH。7,680円ほど。事前に親父さん自身がヨドバシのサイトで、ポイント還元後で6,500円ぐらいの製品があると調べていたのに…。店員さんに「新製品ですよ」と言われてその気になってしまったらしい。

この、CL12D-EH。ググってみても謎の製品で。DCMオンラインという通販サイトでしか、型番を見かけない。アイリスオーヤマのサイトでも一切情報が無い。ケイヨーD2はDCMグループなので、故に店頭にも置いてあったのだろうけど。おそらく、DCMグループでのみ扱う型番の製品なのではあるまいか、それでググっても情報が出てこないのではないか。にしても、発売時期すら不明なのはちょっとアレ。本当に新製品なんだろうか。実は結構古い製品だったりしないか。親父さんはまんまと騙されたのでは。でも、古い製品なら誰かしらが購入して、どこかしらに感想等を書いてるよな…。ということは、本当に新製品なのか…?

さておき。取り付けようとして、今まで使ってた蛍光灯器具を外してみたところ、天井についている角形引掛けシーリング?の形状を見て目が点に。取扱説明書に書いてある、取り付けられないタイプ ―― 端子が表面に露出してあるタイプにしか見えない…。大きさもちょっと小さいし、高さも足りないようで、LEDシーリングライトについてきた丸いアダプタがスカスカと動いてしまって固定できない。階下の2部屋にはLEDシーリングライトを取り付けているのだから、部屋のソレもOKだろうと安易に思い込んでいた。失敗した。面倒でも事前に確認しておくべきだった…。

ググってみたけど、たぶん以下のタイプだろう…。

_引掛けシーリング : 火星電気商会

さて、どうしよう…。電気工事をしてくれる業者さんにお願いして、シーリングを交換してもらうしかないのだろうか。

ただ、ググったところ、増改アダプタなるものをつけてどうにかできる場面もあるようで…。

_引っ掛けシーリングの取付け方法
_古い引掛けシーリングにLEDシーリングライトが付かない!?でも増改アダプタで解決した話 | ミズタマブログ

しかし、端子が露出しているタイプは、何かをぶら下げて使うことを全く考慮してない時代に設計製造されているので、実際にぶら下げてしまうと強度的に危ない、という話が前述のページで出ているわけで…。増改アダプタをつけても、そのあたりの強度が改善されるはずもなく。さて、どうしたもんか。

以上、1 日分です。

過去ログ表示

Prev - 2021/03 -
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project