Help us understand the problem. What is going on with this article?

MacBook Proの充電器の情報をメニューバーに表示するElectronアプリをつくった

MacBook Proで使われてるType-Cの充電は条件により充電速度が変わってきます。

例えば、私の場合RAVPowerのType-AとType-Cの両方が使え 最大60W まで供給できる充電器を普段使いしています。


しかしType-AとType-CにそれぞれiPhoneとMacBook Proへ同時に充電しようとすると、45W に供給される電力が低下してしまいます。

この状態で頑張って仕事していると、徐々バッテリーが減っていってしまいます。
減らないにしても充電速度がかなり遅くなる。



充電器、ケーブル、PD対応など、Type-C関連は仕様が複雑過ぎるので、繋いでみないと正直わかりません。
充電できたとしても、この供給電力の情報はかなり奥まったところにあるので確認しづらい。
ならメニューバーに表示するアプリをつくってしまえ!

つくった

Charger Information for Mac というアプリをElectronでつくりました。

https://github.com/narikei/Charger-Information-for-Mac

アプリを導入すると画面上部のメニューバーに充電器の供給電力が表示されます。
スクリーンショット 2019-12-08 16.29.41.png

スクリーンショット 2019-12-08 16.28.41.png

充電情報の取得

Macの場合この詳しい充電器の供給電力の情報はシステムレポートから確認しないといけないのですが、
ioreg コマンドで取得することができます。

$ ioreg -rn AppleSmartBattery | grep '"AdapterDetails"'
      "AdapterDetails" = {"Watts"=30,"Current"=1500,"PMUConfiguration"=0,"Voltage"=20000}

Watts: 電力(W)
Current: 電流(mA)
Voltage: 電圧(mV)
とそれぞれ取得できます。
電流と電圧は1/1000で計算すると単位からmがとれてわかりやすい。

Node.jsからMacのコマンドを叩く

child_process でOSのコマンドを実行することができます。
execSync は同期。

const { execSync } = require('child_process');
const stdout = execSync('ioreg -rn AppleSmartBattery | grep \\\"AdapterDetails\\\"');

メニューバーへアイコンの表示

Tray というモジュールを使いメニューバーにアイコンを追加できます。

const { app, Tray, Menu, MenuItem } = require('electron');
const ICON_PATH = 'icon.png';
app.on('ready', () => {
  const appIcon = new Tray(ICON_PATH);
  const menu = new Menu();

  menu.append(new MenuItem({
    label: 'item',
    click: () => {
      alert('click item');
    },
  });
  menu.append(new MenuItem({ type: 'separator' }));
  menu.append(new MenuItem({ role: 'quit' }));

  appIcon.setContextMenu(menu);
});



こんな感じの記述で充電状態と非充電状態でアイコンを変えられます。

  if (!isCharging()) {
    appIcon.setImage(ICON_MISSED_PATH);
    return;
  }

  appIcon.setImage(ICON_CHARGING_PATH);

Dockからアイコンを非表示にする

Electronアプリを実行すると、Dockにアイコンが表示されますが、
こういった常駐型のアプリではDockにあっても邪魔なだけなので非表示にします。
app.dock.hide() で非表示になる。

const { app } = require('electron');
app.on('ready', () => {
  app.dock.hide();
});

充電情報を通知する

Notification モジュールを使いMacの通知機能に投げることができます。
充電情報が変化したときに、通知できるようにしました。

スクリーンショット 2019-12-08 16.28.10.png

const { app, Notification } = require('electron');
app.on('ready', () => {
  const notification = new Notification({
    title: '⚡Charging',
    body: 'Power: 30W\nVoltage: 20V / Current: 1.5A',
    silent: true,
  });
  notification.show();
});

\nで改行できますが、どうも最初の1つ以降は無視されるっぽい。。。

ダークモード対応する

ダークモードなる存在を完全に忘れていた。(https://github.com/narikei/Charger-Information-for-Mac/issues/2

const { app, nativeTheme } = require('electron');
app.on('ready', () => {
  if (nativeTheme.shouldUseDarkColors) {
    charging_path = ICON__WHITE_PATH;
    return;
  }

  appIcon.setImage(ICON__BLACK_PATH);
});

アプリケーション化する

Electronのビルドにはいくつかやり方があるのですが、
個人的には electron-builder でパッケージングするのが簡単

追加

devDependencies にしないとビルド時に怒られます。

$ yarn add --dev electron-builder

アイコンの作成

icons.iconset というディレクトリーを作り、その中に各サイズのアイコン画像を入れ、
electron-builder に渡してあげるだけで良い。

スクリーンショット 2019-12-08 18.11.21.png

(今回Dockに表示されないし、導入時にしか見る機会はないが一応、、、)

ビルド情報を記述

ビルド情報は package.json に記述していきます。

package.json
{
  "name": "charger-information-for-mac",
  "main": "main.js",
  "scripts": {
    "build": "electron-builder"
  },
  "devDependencies": {
    "electron": "^7.1.2",
    "electron-builder": "^21.2.0"
  },
  "build": {
    "appId": "com.ozonicsky.charger-information-for-mac",
    "productName": "Charger Information",
    "icon": "icons.iconset",
    "mac": {
      "target": "dmg"
    }
  }
}

ビルドする

$ yarn build

おわり

コードはすべてこちらに公開しております。
https://github.com/narikei/Charger-Information-for-Mac

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away