MacVim(gVim)のインサートモードでShift+Spaceの全角スペース入力ができない

前提条件は、

  • MacはMojave(後にCatalina)
  • 日本語入力はGoogle日本語入力
  • Karabiner-ElementsではShift Spaceに何も設定してない
  • VimはMacVim-KaoriYa
    • :map :imap で確認してもShift + Spaceの設定無し

github.com

この状態で、MacVim-KaoriYaのgVimにおいてGoogle日本語入力中にShift Spaceが半角スペースになってしまう。
ちなみにターミナル上のVimではShift Spaceで全角スペースが入力できている。

ググっても同様の症状は見当たらず。
どうにもわからなかったので、Vimの設定でShift + Spaceで全角スペースが入力できるようにしてしまった・・・。

~/.gvimrc に以下を設定

imap <S-Space>   (←ここに全角スペースが書いてある)

f:id:gozuk16:20191110162205p:plain

これで、gVimでもShift + Spaceで全角スペースが入力できるようになりました。
ちょっと副作用で英数モードでも入るようになっちゃったけど、それも意外と便利かもしれない・・・

Macのログインシェルをzsh+Preztoに変更した

どうでもいい話ですが、昔はtcshを常用していましたが今はzshを使ってます。
でも最近はデフォルトのbashのままのサーバもあったりして自分も丸くなったなーと思うけど、新しく買ったMacbook Air使ってて流石に不便なので頑張りました。

zshに変更

Homebrewでzshをインストールしてデフォルトのログインシェルを変更

$ brew install zsh
$ sudo vi /etc/chsh
/usr/local/bin/zsh ←追加

$ chsh -s /usr/local/bin/zsh

Prezto導入

インストール

git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"
$ setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done
ln: /Users/gozu/.zshrc: File exists

.zshrcがすでに存在するとだめみたい

$ mv .zshrc .zshrc.org

$ setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done
ln: /Users/gozu/.zlogin: File exists
ln: /Users/gozu/.zlogout: File exists
ln: /Users/gozu/.zpreztorc: File exists
ln: /Users/gozu/.zprofile: File exists
ln: /Users/gozu/.zshenv: File exists

lrwxr-xr-x   1 gozu  staff      35 11  4 17:24 .zlogin -> /Users/gozu/.zprezto/runcoms/zlogin
lrwxr-xr-x   1 gozu  staff      36 11  4 17:24 .zlogout -> /Users/gozu/.zprezto/runcoms/zlogout
lrwxr-xr-x   1 gozu  staff      38 11  4 17:24 .zpreztorc -> /Users/gozu/.zprezto/runcoms/zpreztorc
lrwxr-xr-x   1 gozu  staff      37 11  4 17:24 .zprofile -> /Users/gozu/.zprezto/runcoms/zprofile
lrwxr-xr-x   1 gozu  staff      35 11  4 17:24 .zshenv -> /Users/gozu/.zprezto/runcoms/zshenv
lrwxr-xr-x   1 gozu  staff      34 11  4 17:26 .zshrc -> /Users/gozu/.zprezto/runcoms/zshrc

中途半端に処理が行われていたようなので消してもう一度

$ rm .zlogin.org
$ rm .zlogout.org
$ rm .zpreztorc
$ rm .zprofile
$ rm .zshenv
$ rm .zshrc

$ setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done

OK!
新しいセッションを開けばPrestoで起動します。

設定

デフォルトのテーマが見ずらいのでテーマを変えます。

  • 一覧
$ prompt -l
Currently available prompt themes:
agnoster cloud damoekri giddie kylewest minimal nicoulaj paradox peepcode powerlevel10k powerlevel9k powerline pure skwp smiley sorin steeef adam1 adam2 bart bigfade clint default elite2 elite fade fire off oliver pws redhat restore suse walters zefram
  • プレビュー
$ prompt -p
(全部出るけど所々文字化け)

PowerLine対応フォントが入ってないのでRictyの対応版をインストールします。
ここはいつも使っている本家のRicty入れておきます。(Diminishedの方が楽だけど使い慣れてるので)

www.konosumi.net

$ brew tap sanemat/font
$ brew install ricty
(snip)
==> ricty
***************************************************
Generated files:
  /usr/local/opt/ricty/share/fonts/RictyDiscord-Regular.ttf
      /usr/local/opt/ricty/share/fonts/Ricty-Oblique.ttf
      /usr/local/opt/ricty/share/fonts/Ricty-Bold.ttf
      /usr/local/opt/ricty/share/fonts/RictyDiscord-Oblique.ttf
      /usr/local/opt/ricty/share/fonts/Ricty-Regular.ttf
      /usr/local/opt/ricty/share/fonts/Ricty-BoldOblique.ttf
      /usr/local/opt/ricty/share/fonts/RictyDiscord-Bold.ttf
      /usr/local/opt/ricty/share/fonts/RictyDiscord-BoldOblique.ttf
***************************************************
To install Ricty:
  $ cp -f /usr/local/opt/ricty/share/fonts/Ricty*.ttf ~/Library/Fonts/
  $ fc-cache -vf
***************************************************

$ brew options ricty
--with-patch-in-place
    Patch Powerline glyphs directly into Ricty fonts without creating new 'for Powerline' fonts
--with-powerline
    Patch for Powerline
--without-fullwidth
    Disable fullwidth ambiguous characters
--without-visible-space
    Disable visible zenkaku space
(使えるオプションを表示)

$ brew reinstall --with-powerline --with-patch-in-place ricty
==> Reinstalling sanemat/font/ricty --with-powerline --with-patch-in-place
==> Downloading http://yusa.lab.uec.ac.jp/~yusa/ricty/ricty_generator-4.1.1.sh
Already downloaded: /Users/gozu/Library/Caches/Homebrew/downloads/aacf520745eb723ecce41723f843ab10ead03a7323099ce2b7c51123d0c01e77--ricty_generator-4.1.1.sh
==> Downloading https://osdn.jp/frs/redir.php?m=gigenet&f=%2Fmix-mplus-ipa%2F63545%2Fmigu-1m-20150712.zip
Already downloaded: /Users/gozu/Library/Caches/Homebrew/downloads/4e24ddf8bf40fc096f34c12ec91e4469efcded452334dcbefb265ca0343ba455--migu-1m-20150712.zip
==> Downloading https://github.com/google/fonts/raw/f0e90b27b6e567af9378952a37bc8cf29e2d88e9/ofl/inconsolata/Inconsolata-
Already downloaded: /Users/gozu/Library/Caches/Homebrew/downloads/24a8808bea96ca8579bc893547b86241448b2944cca2414aca6d6400986529a3--Inconsolata-Regular.ttf
==> Downloading https://github.com/google/fonts/raw/f0e90b27b6e567af9378952a37bc8cf29e2d88e9/ofl/inconsolata/Inconsolata-
Already downloaded: /Users/gozu/Library/Caches/Homebrew/downloads/0f8e8be9545eb996c487dc08e9d95b408e9b5d0084889938d588d7bf7c98c31f--Inconsolata-Bold.ttf
==> Downloading https://github.com/powerline/fontpatcher/archive/c3488091611757cb02014ed7ed2f11be0208da83.zip
==> Downloading from https://codeload.github.com/powerline/fontpatcher/zip/c3488091611757cb02014ed7ed2f11be0208da83
######################################################################## 100.0%
==> Patching
patching file scripts/powerline-fontpatcher
==> sh ./ricty_generator-4.1.1.sh Inconsolata-Regular.ttf Inconsolata-Bold.ttf migu-1m-regular.ttf migu-1m-bold.ttf
==> fontforge -lang=py -script /private/tmp/ricty-20191104-6196-hotccb/scripts/powerline-fontpatcher --no-rename RictyDis
==> fontforge -lang=py -script /private/tmp/ricty-20191104-6196-hotccb/scripts/powerline-fontpatcher --no-rename Ricty-Ob
==> fontforge -lang=py -script /private/tmp/ricty-20191104-6196-hotccb/scripts/powerline-fontpatcher --no-rename Ricty-Bo
==> fontforge -lang=py -script /private/tmp/ricty-20191104-6196-hotccb/scripts/powerline-fontpatcher --no-rename RictyDis
==> fontforge -lang=py -script /private/tmp/ricty-20191104-6196-hotccb/scripts/powerline-fontpatcher --no-rename Ricty-Re
==> fontforge -lang=py -script /private/tmp/ricty-20191104-6196-hotccb/scripts/powerline-fontpatcher --no-rename Ricty-Bo
==> fontforge -lang=py -script /private/tmp/ricty-20191104-6196-hotccb/scripts/powerline-fontpatcher --no-rename RictyDis
==> fontforge -lang=py -script /private/tmp/ricty-20191104-6196-hotccb/scripts/powerline-fontpatcher --no-rename RictyDis
==> Caveats
***************************************************
Generated files:
  /usr/local/opt/ricty/share/fonts/RictyDiscord-Regular.ttf
      /usr/local/opt/ricty/share/fonts/Ricty-Oblique.ttf
      /usr/local/opt/ricty/share/fonts/Ricty-Bold.ttf
      /usr/local/opt/ricty/share/fonts/RictyDiscord-Oblique.ttf
      /usr/local/opt/ricty/share/fonts/Ricty-Regular.ttf
      /usr/local/opt/ricty/share/fonts/Ricty-BoldOblique.ttf
      /usr/local/opt/ricty/share/fonts/RictyDiscord-Bold.ttf
      /usr/local/opt/ricty/share/fonts/RictyDiscord-BoldOblique.ttf
***************************************************
To install Ricty:
  $ cp -f /usr/local/opt/ricty/share/fonts/Ricty*.ttf ~/Library/Fonts/
  $ fc-cache -vf
***************************************************
==> Summary
🍺  /usr/local/Cellar/ricty/4.1.1: 12 files, 27MB, built in 3 minutes 15 seconds
(PowerLine対応パッチを当てて再インストール。"--with-patch-in-place ricty"は新しいフォントを作らず元のファイルにパッチを当てるということらしい)

$ cp -f /usr/local/opt/ricty/share/fonts/Ricty*.ttf ~/Library/Fonts/
$ fc-cache -vf

iTerm2のフォントにRictyを指定

$ prompt -p
(ちゃんと出たー(≧∇≦)b)

※ 後で気がついたけど、今どきのiTerm2は、 Preferences > Profiles > Text > []Use built-in Powerline glyphs でPowerLine表示できるのね。ゴニョゴニョする必要なかったのか・・・。

  • iTerm2との調整

Preztoのテーマはagnosterで良さそうなのだが、iTerm2の透過を有効にしていると字が暗くて見ずらい。
なのでiTerm2のテーマを変えてみる。
Preferences > Profiles > Colors > Color Presets... から「Pastel(Dark Background)」にする。結構良くなったけど透過率が高めなら見やすいかなという感じ。
透過率低めなら、Visit Online GalleryからHybridを選ぶと良さそう。
※ 透過設定(Preferences > Profiles > Window > Transeparency)をいじったら下にある Keep background colors opaqueにチェックを入れる。PowerLineの三角が綺麗に塗られるようになります。

iterm2colorschemes.com

とりあえず、iTerm2の透過率(Transparency)は10%程度にしてテーマをHybrid、Preztoのテーマをagnosterでやってみることにした。

$ prompt agnoster
(agnosterを試してみる)

$ vi ~/.zpreztorc
#zstyle ':prezto:module:prompt' theme 'sorin'
zstyle ':prezto:module:prompt' theme 'agnoster'

$ source ~/.zpreztorc

ということでこんな感じになりました。

f:id:gozuk16:20191104193012p:plain

AndroidのUSBテザリングでMacを繋ぐ

この間のCROSS Party 2019に行ったときにWi-Fiと電源が無かったので、急遽USBテザリングでしのいだメモ。
きっかけは、Wi-FiテザリングだとAndroidの電池が心もとないのでどうしようと思って、ちょっと充電できないかとMacbook AirAndroid(Xperia XZ2 Compact)をUSB-Cケーブルで繋いでみたことです。
なんか通知を見てたらUSBテザリングできそうだったのでこの方が消費電力が抑えられるかなと思ってやってみました。

officeforest.org

を参考にしました。

Android : Xperia XZ2 Compact (SO-05K)

Macと繋ぐと通知が来るのでONにできますが、設定は以下の通りにしました。
設定 > ネットワークとインターネット > テザリング > USBテザリング > ON

Mac : Macbook Air 2019

ドライバが必要なので以下のサイトからダウンロードしてインストールします。

joshuawise.com

HoRNDIS-9.2.pkg をダウンロードしてインストールしました。
この時ばかりはWi-Fiテザリング使いました。

インストールして再起動すると システム環境設定 > ネットワーク に SO-05K が追加されていました。

困ったこと

いとも簡単にできたのですが問題が一つ・・・

設定 > 機器接続 > USBの設定 で、 接続機器の充電ON にするとAndroidからMacへ充電が行われるのですが、 OFF にすると今度はMacからAndroidの充電が行われます!

両側USB-Cだからなんだろうか?
充電を止めることはできないのか?

Nature Remo miniの室温データをinfluxdbに入れてみる

Nature Remo mini 使って寝ている間に暑すぎればクーラーON、寒すぎればOFFしています。
買ってすぐの頃は温度設定がイマイチでうまく行ってなくて暑いのにONされなかったり、夜中に寒すぎて手動でOFFしたりしてました。

そこで室温データを分析してうまくやりたいと思ってNature Remo Cloud APIを叩いて室温を取得してからGoogle Spreadsheetに書き込むというのを書いたことがありました。
ただ設定を試行錯誤しているうちにいい感じになってきたのでデータを使うことはありませんでした・・・

最近InfluxDBを触っていたのでSpreadsheetの代わりにDBへ入れたほうがいいかなと思って修正してみたらむしろ簡単になったのでこちらを記録に残しておくことにします。

前提としてMacで作業していてGoでプログラム書いてます。
(常時動かすときはLinuxで動かすつもりですけど)

室温データの取得

Nature Remo Cloud API

developer.nature.global

アクセストークンが必要です。トーク無しでAPIを叩くとUnauthorizedになります。
トークンを公開しないように気をつけましょう。

バイスの情報を取りたいので /1/devices というAPIを使ってみます。

swagger.nature.global

Goで書いてるのでまずはJSONが欲しいということでトークンを使って取得してみます。(${Token}を置き換える)

$ curl -X GET "https://api.nature.global/1/devices" -H "accept: application/json" -k --header "Authorization: Bearer ${Token}"
[{"name":"3F_Remo","id":"xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","created_at":"2018-08-06T13:12:11Z","updated_at":"2019-09-30T14:12:13Z","mac_address":"xx:xx:xx:xx:xx:xx","serial_number":"xxxxxxxxx","firmware_version":"Remo-mini/1.0.87-g8b06f0e","temperature_offset":-2,"humidity_offset":0,"users":[{"id":"xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx","nickname":"GOZU Kenichiro","superuser":true}],"newest_events":{"te":{"val":27.2,"created_at":"2019-10-01T00:13:52Z"}}}]

こんな感じで取れました。
見ずらいので整形したものを貼っておきます。

[
    {
        "name": "3F_Remo",
        "id": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "created_at": "2018-08-06T13:12:11Z",
        "updated_at": "2019-09-30T14:12:13Z",
        "mac_address": "xx:xx:xx:xx:xx:xx",
        "serial_number": "xxxxxxxxx",
        "firmware_version": "Remo-mini/1.0.87-g8b06f0e",
        "temperature_offset": -2,
        "humidity_offset": 0,
        "users": [
            {
                "id": "xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx",
                "nickname": "GOZU Kenichiro",
                "superuser": true
            }
        ],
        "newest_events": {
            "te": {
                "val": 27.2,
                "created_at": "2019-10-01T00:13:52Z"
            }
        }
    }
]

newest_events.te.val が室温ですね。27.2度でした。

GoでJSON扱うために struct を書くのが鬱陶しいのでjson2goサイトでサクッと変換します。

mholt.github.io

type RemoDevices []struct {
    Name              string    `json:"name"`
    ID                string    `json:"id"`
    CreatedAt         time.Time `json:"created_at"`
    UpdatedAt         time.Time `json:"updated_at"`
    MacAddress        string    `json:"mac_address"`
    SerialNumber      string    `json:"serial_number"`
    FirmwareVersion   string    `json:"firmware_version"`
    TemperatureOffset int       `json:"temperature_offset"`
    HumidityOffset    int       `json:"humidity_offset"`
    Users             []struct {
        ID        string `json:"id"`
        Nickname  string `json:"nickname"`
        Superuser bool   `json:"superuser"`
    } `json:"users"`
    NewestEvents struct {
        Te struct {
            Val       float64   `json:"val"`
            CreatedAt time.Time `json:"created_at"`
        } `json:"te"`
    } `json:"newest_events"`
}

配列になってます。うちにはRemoは1つしかないから常に1しか返ってこないけどね。。。

あとは API 叩いてレスポンスのJSONからteを取得します。
まずは net/httpを使ってhttp clientの準備。

import (
    "fmt"
    "log"
    "net/http"
    "net/http/httputil"
)

func newRequest(m map[string]string) (*http.Request, error) {
    url := m["url"]

    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return nil, err
    }

    req.Header.Set("Content-Type", "application/json")
    req.Header.Set(m["headerKey"], m["headerValue"])

    dump, err := httputil.DumpRequestOut(req, true)
    fmt.Printf("%s", dump)
    if err != nil {
        log.Fatal("Error requesting dump")
    }

    return req, err
}

func getResponse(m map[string]string) (*http.Response, error) {
    req, err := newRequest(m)

    res, err := http.DefaultClient.Do(req)
    if err != nil {
        return nil, err
    } else if res.StatusCode != 200 {
        return nil, fmt.Errorf("http status %d", res.StatusCode)
    }

    return res, err
}

そんでもってAPIの処理。(実際にはファイル別れてるけど便宜上まとめて書いてます)

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "time"
)

func main() {
    te := Remo("https://api.nature.global/1/devices")
}

func Remo(url string) (te float64) {
    res, err := encodeJson4Remo(url)
    if err != nil {
        log.Fatalf("http error: %v", err)
    }
    for _, r := range res {
        jst := time.FixedZone("Asia/Tokyo", 9*60*60)

        fmt.Println("Name: " + r.Name)
        fmt.Println("ID: " + r.ID)
        fmt.Printf("UpdatedAt: %s\n", r.UpdatedAt.In(jst).Format("2006/01/02 15:04:05"))
        fmt.Printf("TemperatureOffset: %d\n", r.TemperatureOffset)
        fmt.Println("User ID: " + r.Users[0].ID)
        fmt.Println("User Nickname: " + r.Users[0].Nickname)
        fmt.Printf("User Superuser: %t\n", r.Users[0].Superuser)
        fmt.Printf("Temperature val: %f\n", r.NewestEvents.Te.Val)
        te = r.NewestEvents.Te.Val
        fmt.Printf("Temperature CreatedAt: %s\n", r.NewestEvents.Te.CreatedAt.In(jst).Format("2006/01/02 15:04:05"))
    }

    return te
}

func encodeJson4Remo(url string) (RemoDevices, error) {
    token := "Bearer トークン入れてね"
    m := map[string]string{
        "url":         url,
        "headerKey":   "Authorization",
        "headerValue": token}
    res, err := getResponse(m)
    if err != nil {
        return remoDevices, err
    }

    byteArray, err := ioutil.ReadAll(res.Body)
    if err != nil {
        return remoDevices, err
    }
    defer res.Body.Close()

    if err := json.Unmarshal(byteArray, &remoDevices); err != nil {
        log.Fatalf("Error!: %v", err)
    }
    return remoDevices, err
}

結果。

$ go run natureremo_temperature.go remo.go httpclient.go 
GET /1/devices HTTP/1.1
Host: api.nature.global
User-Agent: Go-http-client/1.1
Authorization: Bearer トークン
Content-Type: application/json
Accept-Encoding: gzip

Name: 3F_Remo
ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
UpdatedAt: 2019/09/30 23:12:13
TemperatureOffset: -2
User ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
User Nickname: GOZU Kenichiro
User Superuser: true
Temperature val: 26.000000
Temperature CreatedAt: 2019/09/30 23:37:19
26.000000
success!

室温データの登録

室温は取れたのでInfluxDBに保存します。

環境構築

brewでinfluxdb入れます。

$ brew install influxdb
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> New Formulae
kepubify                                                    tmuxinator
==> Updated Formulae
ammonite-repl       evince              git-secret          jenkins-lts         libomp              squashfs

==> Downloading https://homebrew.bintray.com/bottles/influxdb-1.7.7.mojave.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/aa/aa1cf675fa005f5f5dff6879ca4f5a31886f6d82828037c285656df9786f59c1?__g
######################################################################## 100.0%
==> Pouring influxdb-1.7.7.mojave.bottle.tar.gz
==> Caveats
To have launchd start influxdb now and restart at login:
  brew services start influxdb
Or, if you don't want/need a background service you can just run:
  influxd -config /usr/local/etc/influxdb.conf
==> Summary
🍺  /usr/local/Cellar/influxdb/1.7.7: 9 files, 127.4MB

$ influx
Failed to connect to http://localhost:8086: Get http://localhost:8086/ping: dial tcp [::1]:8086: connect: connection refused
Please check your connection settings and ensure 'influxd' is running.

落ち着け!起動してないとbrewが教えてくれてるじゃないかw

$ influxd -config /usr/local/etc/influxdb.conf

 8888888           .d888 888                   8888888b.  888888b.
   888            d88P"  888                   888  "Y88b 888  "88b
   888            888    888                   888    888 888  .88P
   888   88888b.  888888 888 888  888 888  888 888    888 8888888K.
   888   888 "88b 888    888 888  888  Y8bd8P' 888    888 888  "Y88b
   888   888  888 888    888 888  888   X88K   888    888 888    888
   888   888  888 888    888 Y88b 888 .d8""8b. 888  .d88P 888   d88P
 8888888 888  888 888    888  "Y88888 888  888 8888888P"  8888888P"

2019-09-30T17:50:06.740730Z info    InfluxDB starting   {"log_id": "0ICpYNa0000", "version": "v1.7.7", "branch": "master", "commit": "f8fdf652f348fc9980997fe1c972e2b79ddd13b0"}
2019-09-30T17:50:06.740759Z info    Go runtime  {"log_id": "0ICpYNa0000", "version": "go1.12.6", "maxprocs": 4}
2019-09-30T17:50:06.868211Z info    Using data dir  {"log_id": "0ICpYNa0000", "service": "store", "path": "/usr/local/var/influxdb/data"}
2019-09-30T17:50:06.868314Z info    Compaction settings {"log_id": "0ICpYNa0000", "service": "store", "max_concurrent_compactions": 2, "throughput_bytes_per_second": 50331648, "throughput_bytes_per_second_burst": 50331648}
2019-09-30T17:50:06.868349Z info    Open store (start)  {"log_id": "0ICpYNa0000", "service": "store", "trace_id": "0ICpYO50000", "op_name": "tsdb_open", "op_event": "start"}
2019-09-30T17:50:06.868582Z info    Open store (end)    {"log_id": "0ICpYNa0000", "service": "store", "trace_id": "0ICpYO50000", "op_name": "tsdb_open", "op_event": "end", "op_elapsed": "0.236ms"}
2019-09-30T17:50:06.868937Z info    Registered diagnostics client   {"log_id": "0ICpYNa0000", "service": "monitor", "name": "system"}

DB作ります。

$ influx
Connected to http://localhost:8086 version v1.7.7
InfluxDB shell version: v1.7.7
> show databases
name: databases
name
----
_internal
> create database remo
> show databases
name: databases
name
----
_internal
remo

アクセス用のユーザ作っておくべきなんですがちょいと手抜きで・・・

データ登録

参考にした記事では、"github.com/influxdata/influxdb/client/v2" を使えと書いてあったがgo getでエラーになる。URLが変わっているらしい。

import (
   "github.com/influxdata/influxdb/client/v2"
)

$ go get
package github.com/influxdata/influxdb/client/v2: cannot find package "github.com/influxdata/influxdb/client/v2" in any of:
    /usr/local/Cellar/go/1.13.1/libexec/src/github.com/influxdata/influxdb/client/v2 (from $GOROOT)
    /Users/gozu/go/src/github.com/influxdata/influxdb/client/v2 (from $GOPATH)

"github.com/influxdata/influxdb1-client/v2" に修正する。

Client作って tags と fields を登録する流れ。
値は複数登録できるっぽいけどとりあえず一回起動したら一回データを登録するようにしておいた。(cronで登録すればいいし)

package main

import (
    "fmt"
    "log"
    "time"

    "github.com/influxdata/influxdb1-client/v2"
)

func PushData(te float64) {
    MyDB := "remo"
    username := "root"
    password := "root"
    MyMeasurement := "temperature"

    c, err := client.NewHTTPClient(client.HTTPConfig{
        Addr:     "http://localhost:8086",
        Username: username,
        Password: password,
    })
    if err != nil {
        log.Fatalln("Error: ", err)
    }

    bp, err := client.NewBatchPoints(client.BatchPointsConfig{
        Database:  MyDB,
        Precision: "s",
    })
    if err != nil {
        log.Fatalln("Error: ", err)
    }

    tags := map[string]string{"remo": "3F"}
    fields := map[string]interface{}{
        "temperature": te,
    }

    pt, err := client.NewPoint(MyMeasurement, tags, fields, time.Now())
    if err != nil {
        log.Fatalln("Error: ", err)
    }

    bp.AddPoint(pt)
    err = c.Write(bp)
    if err != nil {
        log.Fatalf("Unable to write value. %v", err)
    }

    fmt.Printf("success!\n")
}

実行してみる。

$ go run remo.go remoget.go httpclient.go influxdb.go

確認。

$ influx
Connected to http://localhost:8086 version v1.7.7
InfluxDB shell version: v1.7.7
> use remo
Using database remo
> show series
key
---
temperature,remo=3F
> select * from temperature;
name: temperature
time                remo temperature
----                ---- -----------
1569869753000000000 3F   26
> precision rfc3339
> select * from temperature;
name: temperature
time                 remo temperature
----                 ---- -----------
2019-09-30T18:55:53Z 3F   26
> 

入ってるね!
それではとりあえずcronで1分に1回実行するようにしてデータ取ってみる。

$ crontab -e
*/1 * * * * /Users/gozu/go/src/github.com/gozuk16/natureremo_temperature/natureremo_temperature > /dev/null 2>&1

まあ取れてる。

> select * from temperature;
name: temperature
time                 remo temperature
----                 ---- -----------
2019-09-30T18:55:53Z 3F   26
2019-09-30T19:25:02Z 3F   26
2019-09-30T19:26:01Z 3F   26
2019-09-30T19:27:02Z 3F   26
2019-09-30T19:28:01Z 3F   26
2019-09-30T19:29:01Z 3F   26
2019-09-30T19:30:02Z 3F   26
2019-09-30T23:09:01Z 3F   26.59
2019-09-30T23:10:01Z 3F   26.59
2019-09-30T23:16:01Z 3F   26.59
2019-09-30T23:17:01Z 3F   26.59
2019-09-30T23:18:01Z 3F   26.59
2019-09-30T23:45:01Z 3F   26.59
2019-09-30T23:46:01Z 3F   27.2
2019-10-01T00:04:02Z 3F   27.79
2019-10-01T00:05:01Z 3F   27.79
2019-10-01T00:06:01Z 3F   27.79
2019-10-01T00:07:01Z 3F   27.79
2019-10-01T00:11:01Z 3F   27.79
2019-10-01T00:13:47Z 3F   27.79
2019-10-01T00:13:48Z 3F   27.79
2019-10-01T00:14:01Z 3F   27.2
2019-10-01T00:15:01Z 3F   27.2
2019-10-01T00:16:01Z 3F   27.2
2019-10-01T00:17:01Z 3F   27.2
2019-10-01T00:18:01Z 3F   27.2
2019-10-01T00:24:01Z 3F   27.2
2019-10-01T00:25:01Z 3F   27.2
2019-10-01T00:26:01Z 3F   27.2
2019-10-01T00:27:01Z 3F   27.2
2019-10-01T00:28:01Z 3F   27.2
2019-10-01T01:05:01Z 3F   27.79
2019-10-01T01:06:01Z 3F   27.79
2019-10-01T01:07:01Z 3F   27.79
2019-10-01T01:11:01Z 3F   27.79
2019-10-01T01:24:01Z 3F   27.79
2019-10-01T01:25:01Z 3F   27.79
2019-10-01T03:17:02Z 3F   29.59
2019-10-01T03:18:01Z 3F   29.59
2019-10-01T03:19:01Z 3F   29.59
2019-10-01T03:20:01Z 3F   29.59
2019-10-01T03:21:01Z 3F   29.59
2019-10-01T03:22:01Z 3F   29.59

貼り付けたデータは適当に間引いてます。

とりあえずLTするために突貫で書いたので後でまとめなおそう・・・

.NET Core のNugetパッケージと中身のDLLのバージョンにGitのコミットIDを含める

だいぶ前に、.NET Framework でAssemblyInfoをいじってファイルバージョンを自動採番するというのをやったのですが、

gozuk16.hatenablog.com

最近は、.NET Coreのプロジェクトが始まってやり方が色々違うし、どうやらJavaでやってたようにGitのコミットIDを入れられそうだというので試してみました。 あと、最近はNexusリポジトリにNugetパッケージをアップしているのですが、開発中にファイル名が同じだとキャッシュが更新されないことがあったのでビルドのたびにファイル名を変えたいというのがあります。 合わせて中身のDllの製品バージョンも一緒にできるといいなーと。

tech.guitarrapc.com

ここのサイトでは、GitVersioningとGitInfoが紹介されていたのでまずはシンプルそうなGitInfoを試してみました。

プロジェクトを新規作成

>dotnet new console -o assemblyInfoTest

cd assemblyInfoTest

>dotnet run
Hello World!

プロジェクトにGitInfoを追加

www.nuget.org

>dotnet add package GitInfo --version 2.0.20

早速Gitの情報を取得してみます。

using System;
using System.Diagnostics;
using System.Reflection;

namespace assemblyInfoTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            Console.WriteLine($"GitBranch: {ThisAssembly.Git.Branch}");
            Console.WriteLine($"GitCommit: {ThisAssembly.Git.Commit}");
            Console.WriteLine($"GitSha: {ThisAssembly.Git.Sha}");
            Console.WriteLine($"GitBaseVersionMajor: {ThisAssembly.Git.BaseVersion.Major}");
            Console.WriteLine($"GitBaseVersionMinor: {ThisAssembly.Git.BaseVersion.Minor}");
            Console.WriteLine($"GitBaseVersionPatch: {ThisAssembly.Git.BaseVersion.Patch}");
            Console.WriteLine($"GitCommits: {ThisAssembly.Git.Commits}");
            Console.WriteLine($"GitTag: {ThisAssembly.Git.Tag}");
            Console.WriteLine($"GitBaseTag: {ThisAssembly.Git.BaseTag}");
            Console.WriteLine($"GitSemVerMajor: {ThisAssembly.Git.SemVer.Major}");
            Console.WriteLine($"GitSemVerMinor: {ThisAssembly.Git.SemVer.Minor}");
            Console.WriteLine($"GitSemVerPatch: {ThisAssembly.Git.SemVer.Patch}");
            Console.WriteLine($"GitSemVerLabel: {ThisAssembly.Git.SemVer.Label}");
            Console.WriteLine($"GitSemVerDashLabel: {ThisAssembly.Git.SemVer.DashLabel}");
            Console.WriteLine($"GitSemVerSource: {ThisAssembly.Git.SemVer.Source}");
            Console.WriteLine($"GitIsDirty: {ThisAssembly.Git.IsDirty}");

            var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version;
            var fileVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion;
            var productVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion;
            Console.WriteLine($"assemblyVersion: {assemblyVersion}");
            Console.WriteLine($"fileVersion: {fileVersion}");
            Console.WriteLine($"productVersion: {productVersion}");
        }
    }
}
C:\home\gozu\projects\assemblyInfoTest>dotnet run
Hello World!
GitBranch: master
GitCommit: 5ac94b0
GitSha: 5ac94b013eef929d3b8a932247966bd5f9a87952
GitBaseVersionMajor: 0
GitBaseVersionMinor: 0
GitBaseVersionPatch: 0
GitCommits: 2
GitTag:
GitBaseTag:
GitSemVerMajor: 0
GitSemVerMinor: 0
GitSemVerPatch: 2
GitSemVerLabel:
GitSemVerDashLabel:
GitSemVerSource: Default
GitIsDirty: True
assemblyVersion: 1.0.0.0
fileVersion: 1.0.0.0
productVersion: 1.0.0

簡単に取れました。

Git情報を埋め込んでみる

以下を追加しました。

[assembly: AssemblyVersion(ThisAssembly.Git.BaseVersion.Major + "." + ThisAssembly.Git.BaseVersion.Minor + ThisAssembly.Git.BaseVersion.Patch)]
[assembly: AssemblyFileVersion(ThisAssembly.Git.SemVer.Major + "." + ThisAssembly.Git.SemVer.Minor + "." + ThisAssembly.Git.SemVer.Patch)]
[assembly: AssemblyInformationalVersion(ThisAssembly.Git.SemVer.Major + "." + ThisAssembly.Git.SemVer.Minor + "." + ThisAssembly.Git.SemVer.Patch + "-" +
    ThisAssembly.Git.Branch + "+" + ThisAssembly.Git.Commit)]
>dotnet run
obj\Debug\netcoreapp2.2\assemblyInfoTest.AssemblyInfo.cs(12,12): error CS0579: System.Reflection.AssemblyFileVersionAttribute' 属性が重複しています。 [C:\home\gozu\projects\assemblyInfoTest\assemblyInfoTest.csproj]
obj\Debug\netcoreapp2.2\assemblyInfoTest.AssemblyInfo.cs(13,12): error CS0579: System.Reflection.AssemblyInformationalVersionAttribute' 属性が重複しています。 [C:\home\gozu\projects\assemblyInfoTest\assemblyInfoTest.csproj]
obj\Debug\netcoreapp2.2\assemblyInfoTest.AssemblyInfo.cs(16,12): error CS0579: System.Reflection.AssemblyVersionAttribute' 属性が重複しています。 [C:\home\gozu\projects\assemblyInfoTest\assemblyInfoTest.csproj]

ビルドに失敗しました。ビルド エラーを修正して、もう一度実行してください。

.NET CoreだとAssemblyInfo.csが生成されるので書き換えたいプロパティの生成を抑制する必要があるらしい。

csprojに以下を追加しました。

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
    <GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
    <GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
  </PropertyGroup>
>dotnet run
Hello World!
GitBranch: master
GitCommit: 37fdbb4
GitSha: 37fdbb48f4c47b29089f6dd0ce36178c21500861
GitBaseVersionMajor: 0
GitBaseVersionMinor: 0
GitBaseVersionPatch: 0
GitCommits: 3
GitTag:
GitBaseTag:
GitSemVerMajor: 0
GitSemVerMinor: 0
GitSemVerPatch: 3
GitSemVerLabel:
GitSemVerDashLabel:
GitSemVerSource: Default
GitIsDirty: False
assemblyVersion: 0.0.0.0
fileVersion: 0.0.3
productVersion: 0.0.3-master+37fdbb4

おー、出来た!

CIで外部から指定できるように

想定ではJenkinsでnupkgのファイル名とDllの製品バージョンをビルドごとに一意なバージョンにするなので、GitのコミットIDを付加する方向で行きます。

外部から指定できるようにcsprojに Version を定義しておきます。 1.0.0としてますが書き換わるので気にしない。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
    <!--GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute-->
    <!--GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute-->
    <Version>1.0.0</Version>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="GitInfo" Version="2.0.20">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
  </ItemGroup>

</Project>

コードの方も調整します。 FileVersionだけは入れておこうかという感じです。

using System;
using System.Diagnostics;
using System.Reflection;

//[assembly: AssemblyVersion(ThisAssembly.Git.BaseVersion.Major + "." + ThisAssembly.Git.BaseVersion.Minor + ThisAssembly.Git.BaseVersion.Patch)]
[assembly: AssemblyFileVersion(ThisAssembly.Git.SemVer.Major + "." + ThisAssembly.Git.SemVer.Minor + "." + ThisAssembly.Git.SemVer.Patch)]
//[assembly: AssemblyInformationalVersion("1.0.0" + "-alpha." + ThisAssembly.Git.Commit)]

namespace assemblyInfoTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            Console.WriteLine($"GitBranch: {ThisAssembly.Git.Branch}");
            Console.WriteLine($"GitCommit: {ThisAssembly.Git.Commit}");
            Console.WriteLine($"GitSha: {ThisAssembly.Git.Sha}");
            Console.WriteLine($"GitBaseVersionMajor: {ThisAssembly.Git.BaseVersion.Major}");
            Console.WriteLine($"GitBaseVersionMinor: {ThisAssembly.Git.BaseVersion.Minor}");
            Console.WriteLine($"GitBaseVersionPatch: {ThisAssembly.Git.BaseVersion.Patch}");
            Console.WriteLine($"GitCommits: {ThisAssembly.Git.Commits}");
            Console.WriteLine($"GitTag: {ThisAssembly.Git.Tag}");
            Console.WriteLine($"GitBaseTag: {ThisAssembly.Git.BaseTag}");
            Console.WriteLine($"GitSemVerMajor: {ThisAssembly.Git.SemVer.Major}");
            Console.WriteLine($"GitSemVerMinor: {ThisAssembly.Git.SemVer.Minor}");
            Console.WriteLine($"GitSemVerPatch: {ThisAssembly.Git.SemVer.Patch}");
            Console.WriteLine($"GitSemVerLabel: {ThisAssembly.Git.SemVer.Label}");
            Console.WriteLine($"GitSemVerDashLabel: {ThisAssembly.Git.SemVer.DashLabel}");
            Console.WriteLine($"GitSemVerSource: {ThisAssembly.Git.SemVer.Source}");
            Console.WriteLine($"GitIsDirty: {ThisAssembly.Git.IsDirty}");

            var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version;
            var fileVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion;
            var productVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion;
            Console.WriteLine($"assemblyVersion: {assemblyVersion}");
            Console.WriteLine($"fileVersion: {fileVersion}");
            Console.WriteLine($"productVersion: {productVersion}");

        }
    }
}

Jenkinsfileで以下のようにdotnetコマンドを実行してビルドとパッケージングをします。

bat """chcp 65001

for /f "usebackq tokens=*" %%a in (`git rev-parse --short HEAD`) do @set GIT_COMMIT=%%a
for /f "usebackq tokens=*" %%a in (`git rev-parse --abbrev-ref HEAD`) do @set GIT_BRANCH=%%a

dotnet build -p:Version="1.0.0-alpha.%GIT_COMMIT%"
dotnet pack --no-build -p:PackageVersion="1.0.0-alpha.%GIT_COMMIT%"
"""

これで、製品バージョンに 1.0.0-alpha.xxxxxxx と埋め込まれたDllを含めた、 assemblyInfoTest.1.0.0-alpha.xxxxxxx.nupkg が出来ました。

1.0.0-aplpha のところはまあどこかで一元的に定義しないといけないですけどね。

Karabiner-ElementsでMavVimだけ特定のキーマップを除外する

MacにHHKBを付けているので、Karabiner-Elementsにいつもお世話になってます。

仕事ではMacWindowsを同時に使うのでMacWindowsキーバインドをある程度あわせたくて、Complex Modificationsに PC-Style Shortcuts の中から PC-Style Copy/Paste/Cut を追加しています。

ところでVimで矩形選択をたまにしたくなるのですが「Ctrl + v」がペーストになってしまいます。
iTerm2の中でVim使ってるときはうまくいくのだからこれはなにかの設定に違いない。。。

ぐぐるfrontmost_application_unless を設定しなさいということらしい。

qiita.com

~/.config/karabiner/assets/complex_modifications/ を探ると 1543454397.jsonPC-Style Shortcuts のようです。
※ このファイル名、別のMacで見てみたら違ってました。

「Ctrl + v」を探すと

        {
          "type": "basic",
          "from": {
            "key_code": "v",
            "modifiers": {
              "mandatory": [
                "control"
              ],
              "optional": [
                "any"
              ]
            }
          },
          "to": [
            {
              "key_code": "v",
              "modifiers": [
                "left_command"
              ]
            }
          ],
          "conditions": [
            {
              "type": "frontmost_application_unless",
              "bundle_identifiers": [
                "^com\\.microsoft\\.rdc$",
                "^com\\.microsoft\\.rdc\\.mac$",
                "^com\\.microsoft\\.rdc\\.macos$",
                "^com\\.microsoft\\.rdc\\.osx\\.beta$",
                "^net\\.sf\\.cord$",
                "^com\\.thinomenon\\.RemoteDesktopConnection$",
                "^com\\.itap-mobile\\.qmote$",
                "^com\\.nulana\\.remotixmac$",
                "^com\\.p5sys\\.jump\\.mac\\.viewer$",
                "^com\\.p5sys\\.jump\\.mac\\.viewer\\.web$",
                "^com\\.teamviewer\\.TeamViewer$",
                "^com\\.vmware\\.horizon$",
                "^com\\.2X\\.Client\\.Mac$",
                "^com\\.vmware\\.fusion$",
                "^com\\.vmware\\.horizon$",
                "^com\\.vmware\\.view$",
                "^com\\.parallels\\.desktop$",
                "^com\\.parallels\\.vm$",
                "^com\\.parallels\\.desktop\\.console$",
                "^org\\.virtualbox\\.app\\.VirtualBoxVM$",
                "^com\\.vmware\\.proxyApp\\.",
                "^com\\.parallels\\.winapp\\.",
                "^com\\.apple\\.Terminal$",
                "^com\\.googlecode\\.iterm2$",
                "^co\\.zeit\\.hyperterm$",
                "^co\\.zeit\\.hyper$",
                "^io\\.alacritty$",
                "^net\\.kovidgoyal\\.kitty$"
              ]
            }

とありました。やっぱり iterm2 設定されてる。

ここにMacVimを追加しよう! Karabiner-ElementsのEvenViewerを立ち上げて、「Frontmost Application」にしてからMacVimを触ると

Bundle Identifier:  org.vim.MacVim
File Path:          /Applications/MacVim.app/Contents/MacOS/MacVim

と出ます。 ということで↑の bundle_identifiers

                "^org\\.vim\\.MacVim$"

を追加します。

これでKarabiner-Elementsを再起動すればいいと思ったのですがどうも反映しない。
Complex Modificationsで PC-Style Copy/Paste/Cut をremoveしてからadd ruleしてみたら反映した!

f:id:gozuk16:20190830184916p:plain

やっと出来たー。

MacからWindowsファイル共有(日本語で濁点あり)をマウントする

ちょっとターミナルでやりたかったので調べたら今はmountコマンドでやるらしい。

$ mount -t smbfs //username:passwd@hostname/hogehoge ~/mnt/hogehoge

↑これは普通にできる。

で実際に、共有したい所を見てみたら日本語じゃないか。嫌な予感・・・。

$ mount -t smbfs //username:passwd@hostname/ほげほげ ~/mnt/hogehoge
mount_smbfs: URL parsing failed, please correct the URL and try again: Invalid argument

やっぱりね。 _| ̄|○
調べてみたら日本語というより濁点がいけないらしい。

qiita.com

URLエンコードしとけばいいとのことなので、

$ mount -t smbfs //username:passwd@hostname/%E3%81%BB%E3%81%92%E3%81%BB%E3%81%92 ~/mnt/hogehoge

できたー。 (^^)