カテゴリー: デジタル

着実な進化を遂げたLogicoolのハイエンドマウス『MX Master 3』

ロジクール アドバンスド ワイヤレスマウス MX Master 3 MX2200sGR Unifying Bluetooth 高速スクロールホイール 充電式 FLOW 7ボタン windows Mac iPad OS 対応 無線 マウス MX2200 グラファイト 国内正規品 2年間無償保証作業効率の向上とストレス軽減のためPCと組み合わせて使うマウスには拘っていて、自宅では『MX Master MX2000』、職場でも『パフォーマンスマウス M950t』とその時々のロジクール製ハイエンドモデルを購入し使用しています。

人間工学に基づいたエルゴノミクスデザインや高精細なレーザーセンサー搭載で両者とも操作性は申し分なかったのですが、M950tはバッテリー容量が少なく毎日の充電が欠かせないことに加え、どちらも充電端子がmicroUSBなのでスマホなどで使うUSB Type-Cケーブルとは別に旧規格のケーブルを持ち歩かなければならないことなどを若干面倒に感じはじめたので、思い切ってUSB Type-C端子を備えたロジクールの現行ハイエンドマウス『MX Master 3』を導入してみました。

外観チェック

早速、MX Master 3を開封。

MX MASTER 3のパッケージ

MX Masterの初代にあたるMX2000では扉付化粧箱の立派なパッケージが採用されていましたが、MX Master 3は随分シンプルになりましたね。

Moto G7 PlusがAndroid 10にバージョンアップ

日本国内でもMoto G7 Plus向けにAndroid 10に対応したシステムアップデートの配信が先週始まったようで、わたしの端末も週末までに無事バージョンアップを完了。

「おめでとうございます! Android 10はこちらです!」で始まる通知は見るからに詐欺広告ですが(苦笑)…安心してください、公式ですよ。

Moto G7 PlusがAndroid 10にバージョンアップ

バージョンアップに際しては40%以上のバッテリー残量が必要。また、作業には20分近くを要しその間は重たくなってアプリなどは扱い辛くなるので事前に準備を整えてからアップデートに臨むが吉。

BelkinのPowerDelivery対応のUSBカーチャージャー『BOOST CHARGE 車載充電器』

ベルキン USB-C カーチャージャー 充電器 車載 USB-Cケーブル付き PD対応 iPhone Android対応 27W 急速充電  Quick Charge 4+ ブラック F7U076BT04-BLK-Aインプレッサ G4のコンソールボックス内に設置されたアクセサリーソケットには以前購入したベルキンの『マイクロカーチャージャー(F8M730BTBLK)』を挿しっぱなしにしてスマホやタブレットの充電に利用してきたのですが、4~5年前の製品のため給電用のUSBポートはType-Aのみ。USB PowerDelivery対応のType-Cポートなどというナウい端子は備わっていません。

これでは急速充電が可能な最近のスマホを繋いでも充電スピードは従来と変わらず折角のメリットが活かせないので、PowerDeliveryに対応したベルキンの『BOOST CHARGE 車載充電器(F7U076BT04-BLK-A)』に買い替え。Amazon.co.jpなどで見かける怪しい中国ブランドの製品もの多くはノイズ対策が不十分で悪影響が大きいと聞くので今回も手堅くベルキンを選択した次第です。

マイクロカーチャージャーと同様、こちらの商品も各国共通のユニバーサルパッケージになっているようで英語ベースの外装。

Belkin BOOST CHARGE 車載充電器

中にはカーチャージャー本体と長さ1.2mのUSB Type-Cケーブル、それに日本語の記述を含む多言語対応の説明書。USB Type-Cケーブルだけ別途購入しようとすると1,000円は下らないので、付属するのはありがたいですね。

Amazonアソシエイト用リンクの簡単作成ツール「Associates Link Generator (PA-API v5対応)」

先日の記事でも少し触れましたが…Amazonの製品カタログ上の画像を利用したアソシエイト用リンクを取得するため2017年にひっそり公開したChrome拡張「Associates Link Generator」のPA-API v5対応が完了。旧バージョンからの移行による混乱を防ぐためアイコンを変え、新しいアイテムとして公開しました。

想定ユーザはかなり限定されますが、ブログ記事の執筆等でAmazon商品の画像やリンクの挿入に時間を割かれている方の負担軽減になれば幸いです。

Amazon PA-API v5.0をJavaScript(Chrome拡張)で実装してみる

Amazonの製品カタログデータにアクセスできる公式API「Product Advertising API」(以下、PA-API)のバージョン5.0が昨年公開され、来月にも完全移行(旧バージョンでの利用が不可になる)が予定されています。

ブログ等を書く際の使い勝手向上のため自分本位に開発・公開しているChrome拡張「Associates Link Generator」も今のままでは使用出来なくなってしまうので新版リリースの準備を始めたのですが、Amazonが用意してくれているScratchpad(≠実働サンプル)にはJAVA、PHP、cURLあたりの実装例しか載っていなかったのでPHP版を参考にChrome拡張で使えるJavaScriptのClassを作成。

お約束ですが…参考にされる場合、自己責任でお願いします。(フォローやサポートは致しかねます)

'use strict';

export class AwsV4 {
  constructor(accessKey, secretKey) {
    this.accessKey       = accessKey;
    this.secretKey       = secretKey;
    this.path            = null;
    this.regionName      = null;
    this.serviceName     = null;
    this.httpMethodName  = null;
    this.queryParametes  = [];
    this.awsHeaders      = [];
    this.payload         = "";

    this.HMACAlgorithm   = 'AWS4-HMAC-SHA256';
    this.aws4Request     = 'aws4_request';
    this.strSignedHeader = null;
    this.xAmzDate        = this._getTimeStamp();
    this.currentDate     = this._getDate();
  }

  setPath(path) {
    this.path = path;
  }

  setServiceName(serviceName) {
    this.serviceName = serviceName;
  }

  setRegionName(regionName) {
    this.regionName = regionName;
  }

  setPayload(payload) {
    this.payload = payload;
  }

  setRequestMethod(method) {
    this.httpMethodName = method;
  }

  addHeader(headerName, headerValue) {
    this.awsHeaders[headerName] = headerValue;
  }

  _prepareCanonicalRequest() {
    let canonicalURL = '';
    canonicalURL += this.httpMethodName + "\n";
    canonicalURL += this.path + "\n" + "\n";
    let signedHeaders = '';
    for (let key in this.awsHeaders) {
      signedHeaders += key + ";";
      canonicalURL  += key + ":" + this.awsHeaders[key] + "\n";
    }
    canonicalURL += "\n";
    this.strSignedHeader = signedHeaders.slice(0, - 1);
    canonicalURL += this.strSignedHeader + "\n";
    canonicalURL += this._generateHex(this.payload);
    return canonicalURL;
  }

  _prepareStringToSign(canonicalURL) {
    let stringToSign = '';
    stringToSign += this.HMACAlgorithm + "\n";
    stringToSign += this.xAmzDate + "\n";
    stringToSign += this.currentDate + "/" + this.regionName + "/" + this.serviceName + "/" + this.aws4Request + "\n";
    stringToSign += this._generateHex(canonicalURL);
    return stringToSign;
  }

  _calculateSignature(stringToSign) {
    const signatureKey    = this._getSignatureKey (this.secretKey, this.currentDate, this.regionName, this.serviceName);
    const signature       = this._hash_hmac(stringToSign, signatureKey);
    const strHexSignature = CryptoJS.enc.Hex.stringify(signature).toLowerCase();
    return strHexSignature;
  }

  _ksort(obj) {
    const keys = Object.keys(obj).sort();
    let sortedObj = {};
    for (let i in keys) {
      sortedObj[keys[i]] = obj[keys[i]];
    }
    return sortedObj;
  }

  getHeaders() {
    this.awsHeaders['x-amz-date'] = this.xAmzDate;
    this.awsHeaders = this._ksort(this.awsHeaders);

    const canonicalURL = this._prepareCanonicalRequest();
    const stringToSign = this._prepareStringToSign(canonicalURL);
    const signature    = this._calculateSignature(stringToSign);

    if (signature) {
      this.awsHeaders ['Authorization'] = this._buildAuthorizationString(signature);
      return this.awsHeaders;
    }
  }

  _buildAuthorizationString($strSignature) {
    return this.HMACAlgorithm + " " + "Credential=" + this.accessKey + "/" + this._getDate () + "/" + this.regionName + "/" + this.serviceName + "/" + this.aws4Request + "," + "SignedHeaders=" + this.strSignedHeader + "," + "Signature=" + $strSignature;
  }

  _generateHex(data) {
    return CryptoJS.enc.Hex.stringify(CryptoJS.SHA256(data)).toLowerCase();
  }

  _hash_hmac(s, k) {
    return CryptoJS.HmacSHA256(s, k);
  }

  _getSignatureKey(key, date, regionName, serviceName) {
    const kSecret  = "AWS4" + key;
    const kDate    = this._hash_hmac(date, kSecret);
    const kRegion  = this._hash_hmac(regionName, kDate);
    const kService = this._hash_hmac(serviceName, kRegion);
    const kSigning = this._hash_hmac(this.aws4Request, kService);
    return kSigning;
  }

  _getTimeStamp() {
    return new Date().toISOString().replace(/-|:|\.[0-9]{3}/g, "");
  }

  _getDate() {
    return new Date().toISOString().replace(/-/g, "").substr(0,8);
  }
}

動作には別途CryptoJSが必要です。

Power Delivery対応のコンパクトなモバイルバッテリー『Anker PowerCore 10000 PD Redux』

Anker PowerCore 10000 PD Redux(モバイルバッテリー 10000mAh 大容量)【PSE認証済 / Power Delivery対応 /低電流モード搭載】 iPhone & Android 各種対応USB Type-Cに対応したデバイスの普及でレガシー規格となりつつあるmicroUSB。

充電速度やケーブルの汎用性で劣るmicroUSBに未来を見出すことはもはや不可能ですし、一部の機器のためだけに複数のケーブルを持ち続けるのも面倒なのでType-Cへの一本化を段階的に…ということで、2013年に購入した容量6,000mAhのモバイルバッテリー『cheero Power Plus 2 mini』の後釜としてType-CによるPower Deliveryにも対応した『Anker PowerCore 10000 PD Redux』を購入しました。

わたしにとって山行時や屋外撮影時がモバイルバッテリーの主な活用シーン。スマホの充電や撮影中に結露を防ぐためのレンズヒーターへの給電などが使途でバッテリー容量は大きいにこしたことはありませんが、ザックや撮影機材などヘビーな装備との兼ね合いで無駄に重たく嵩張るモバイルバッテリーは持ち歩けません。

そんなわたしにとって手のひらサイズの『cheero Power Plus 2 mini』はジャストサイズで長らく重宝していたのですが、6年半近い使用でバッテリーの劣化が否めなくなってきたのでこれに代わるアイテムとして目星をつけたのが『Anker PowerCore 10000 PD Redux』になります。

Anker PowerCore 10000 PD Redux

バッテリー容量10,000mAhで昇降圧に伴うロスを考慮しても容量3,000mAhのMoto G7 Plusなら2回はフル充電出来ます。