Vimを毎日自分用にビルドするようにした
Windowsのシリアル通信でBREAK信号を送受信する
https://msdn.microsoft.com/ja-jp/library/cc429842.aspx
https://github.com/bamchoh/go-serial/commit/f74298f65a6834a06357510f1d208ff8df764c11
SetCommMask で EV_BREAK を設定しておくこと。そうしないと、エラーになる。
あと、立ち上がりは検出できるけど、立下りは検出できなさそう。
一応、BREAK信号を送信するのと、受信(?)するののサンプルは以下のような感じで
package main import ( "bufio" "flag" "fmt" "log" "os" "time" "github.com/bamchoh/go-serial" ) type SIO struct { port serial.Port txq chan []byte rxq chan []byte } func (sio *SIO) Start() { go sio.Write() go sio.Read() } func (sio *SIO) Write() { for { q := <-sio.txq log.Printf("send: %q", q) sio.port.Write(q) } } func (sio *SIO) Read() { err := sio.port.SetCommMask(0x0041) if err != nil { fmt.Println(err) } for { buf := make([]byte, 128) n, err := sio.port.Read(buf) if err != nil { fmt.Println(err) time.Sleep(1 * time.Second) continue } sio.rxq <- buf[:n] } } func (s *SIO) SetBreak() { s.port.SetBreak() } func (s *SIO) ClearBreak() { s.port.ClearBreak() } var port = flag.String("p", "COM3", "port name") var baud = flag.Int("b", 9600, "baud rate") func main() { flag.Parse() c := &serial.Mode{BaudRate: *baud} s, err := serial.Open(*port, c) if err != nil { log.Fatal(err) } txq := make(chan []byte, 5) rxq := make(chan []byte, 5) sio := SIO{ s, txq, rxq, } go sio.Start() go func() { scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { text := scanner.Text() s.SetBreak() time.Sleep(10 * time.Millisecond) s.ClearBreak() txq <- []byte(text) } }() for { q := <-rxq if err != nil { log.Fatal(err) } log.Printf("recv: %v", q) } }
余談だけど、LinuxだとBREAK信号の受信が\FF\00\00という3バイトに変換されてしまうみたい。 バイナリデータの送受信だと、このバイト列が来るようなプロトコルを使うようなものだと BREAK信号を送信できないという制限がかかってしまう。回避策ってないのかな?
https://stackoverflow.com/questions/14803434/receive-read-break-condition-on-linux-serial-port
追記(2018/7/17) Linux の BREAK信号の受信方法がなんとなくわかった。
Armadillo460シリアルとTFTP | アットマークテクノ ユーザーズサイト
ここによると、ioctlのTIOCGICOUNTを使うとできるらしい。
ラズパイで、確かにBREAK信号を受信するとカウントアップしていることが確認できた。
カウントが上がってることと、\xFF\x00\x00 のバイト列が来てることをダブルチェックして
BREAK信号を認識できるかもしれない。O_NONBLOCK
なので、ループがすごい回ってしまうのが
どうにかしたいところ。
(追記2018/7/18) 非カノニカルモードにすることでブロッキングしていても、指定のバイト数を受信すれば 処理が戻るようにできた。後、残ってる課題は カウンタのクリアの仕方かなぁ
The Linux Serial Programming HOWTO: $B%W%m%0%i%`Nc(B
以下にサンプルを例示しておく。
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <termios.h> #include <unistd.h> #include <linux/serial.h> #define SERIAL_PORT "/dev/ttyAMA0" int main(int argc, char *argv[]) { unsigned char msg[] = "serial port open...\n"; unsigned char buf[255]; int fd; struct termios tio; int baudRate = B9600; int i; int len; fd = open(SERIAL_PORT, O_RDWR|O_NOCTTY); if (fd < 0) { printf("open error\n"); return -1; } tio.c_cflag += CREAD; tio.c_cflag += CLOCAL; tio.c_cflag += CS8; tio.c_cflag += 0; tio.c_cflag += 0; cfsetispeed(&tio, baudRate); cfsetospeed(&tio, baudRate); // non canonical mode setting tio.c_lflag = 0; tio.c_cc[VTIME] = 0; tio.c_cc[VMIN] = 1; ioctl(fd, TCSETS, &tio); // send break signal for 100 ms(?) tcsendbreak(fd, 100); tcdrain(fd); // write 2 bytes buf[0] = 'A'; buf[1] = 'B'; len = 2; write(fd, buf, len); tcdrain(fd); // waiting for receive any data while (1) { len = read(fd, buf, sizeof(buf)); if (0 < len) { // check break detection count struct serial_icounter_struct icount; ioctl(fd, TIOCGICOUNT, &icount); printf("brk: %d", icount.brk); // print received data for(i = 0; i < len; i++) { if(i != 0) { if((i % 8) == 0) { printf("\n"); } else { printf(":"); } } printf("%02X", buf[i]); } printf("\n"); } } close(fd); return 0; }
【ブロク読書感想文】→ テスト自動化の理論と技術と戦略:LINE Developer Meetup Tokyo #39 - Testing & Engineering
読書したブログ
これを読んでてよくわからない単語があったので、調べてメモ。 後で考えるときの参考にできればいいなという感じ。
違和感のアンドン化
違和感を見える場所に書き出して、リスク的なものをみんなと共有できてイイネ。ということだろうか? リスク共有しても「そうだねー、そういうリスクあるよねー問題だよねー」みたいなので終わりがちなので注意していきたい。
フロントローディング
「初期段階で品質の作りこみを綿密にする」という意味らしい。 でも、品質を作りこむのって時間がかかるし、試作からのブラッシュアップのほうが いいような気もするんだけど、早く品質を作りこむ手法みたいなのあるのだろうか? 気になる。
インダストリー 4.0
「IoTやAIを用いることによる製造業の革新」という意味合いが強そう。 AIというか機械学習による不具合発見の効率化には興味がある。
デジタルツイン
「工場や製品などに関わる物理世界の出来事を、そっくりそのままデジタル上にリアルタイムに再現する」ということらしい。 仮想現実のようなものだろうか?物理的な制約がなくなるので、テストもしやすいよねってことなのかなー?
QAアーキテクチャ
QAアーキテクチャの設計による説明責任の高いテスト・品質保証 Qaアーキテクチャの話 QAアーキテクチャはプロセスアーキテクチャか? by @YasuharuNishi - Togetter
まだちゃんと読んでない。後で読む(ほんとか?)
SaPID
ソフトウェアプロセス改善手法“SaPID”による自律改善実践セミナー| JUSE-SQiPセミナー
アドホックテスト
アドホックテスト(あどほっくてすと) - ITmedia エンタープライズ
俺が探索的テストだと思っていたものはアドホックテストだったのか...
VSTeP
SPLIT
Cookpadエンジニアが解説 “テスト自動化”を実現する「SPLIT」とはなにか? - ログミーTech(テック)
まとめ
こういう発表資料を見ると、なるほどなー。たしかになー。という気分になるんだけど。 じゃぁ、それをどう自分の関わっているプロジェクトに落とし込んでいこうか。ということを考えると まず上司を説得して、プロセスを改善して。。。みたいなことになるので、まず上司を説得するためには どうするればいいのか。みたいなのを学びたい気もする。
友達同士でもくもく会した
要約
友達同士でもくもく会して、意外と捗って良かった
もくもく会とは?
自宅には誘惑がいっぱいあるので、プログラミングとかやろうと思ってもなかなか捗りませんよね。でも周りに人が居るとよく見られようという意識が高まって誘惑に負けずに作業に集中できる。という効果があります。カフェで勉強すると意外と捗ったりするのはそういう理由ですね。でも、カフェだとガヤガヤしてて集中できない。という人も居ると思います。そこで「もくもく会」です。もくもく会では、静かな場所で集中して作業したい人が集まることで、集中力を高めながら、作業を捗らせる。ということを目的としています。また、同じ同志が集まることで、問題解決をみんなで出来るという強みもあり、一人で作業するよりも何倍も効率が上がる!というもくろみがあります。
友達同士でもくもく会
とはいえ、そういう会に参加するのは、結構ハードルが高いものです。私もその一人でした。ですが偶然、友達が「もくもく会」に興味があり、それに賛同したことから、あれよあれよと「友達同士でのもくもく会」が開催されることが決定しました。もくもく会といっても、上で述べたような効率よく作業しよう!という感じではなく、ゆるく集まって作業できたらいいよね。ぐらいの気持ちでした。現に、「もくもく会」ではなく、「もぐもぐ会」という名前になってて、一部のメンバーはお菓子を食べながら雑談をしたりしてましたし(笑)
なんしか、「もくもく会」というものがどういうもので、どれだけ効果があるのか?友達とやっても効果があるのか?という実験的な会だったと思います。
「もぐもぐ会」感想
日曜の13時から始まって、18時に解散でした。はじめは「5時間もするのかー」という気持ちでしたが、意外と集中して作業していたということもあってかすぐに時間が過ぎたなーという感想です。
開始する前に、みんなで今日やることを言い合ってからもくもく会開始、終了の30分前に何をやったかを発表して終わりました。発表といっても大したことではなく、「○○を実装しようと思ったけど、ここまで作って時間切れでした~」ぐらいの軽い感じです。これぐらい軽いほうが参加しやすいかな。とも思いました。
合計8人の参加者がいて、そのうち3人は「もぐもぐ会」を実施、5人は「もくもく会」を実施しました。「もぐもぐ会」メンバーは結構気を使って会話のトーンを落としてしゃべってくれたってのもあって、良いBGM感という感じでした。集中が切れたら、私ももぐもぐ会に10分ほど参加したりして、それなりのリフレッシュも入れられましたし。差し入れもうまかった。
作業自体は集中できたと思います。完全にYoutube/Twitterをシャットアウトできましたし、最初にやることを明確にしていたということもあり、ここまではやりきるぞ!という気持ちで作業ができたので、いつも以上に集中できたと思います。
今後
今回の会場はマンションの一室を借りて実施しました。(借りたのは友達ですが) 作業スペースはきれいでよかったのですが、トイレが普通に1ルームのトイレだったので、音漏れが気になったので、もし次やるならそういうところも気にしないといけないかなーと思いました。
友達同士でやるもくもく会はストレスフリーにもくもく出来ることがわかったので、これからも定期的に実施していけたらなと思います。
それとは別に、外部のもくもく会にも参加していくことで自分のスキル向上もあるのかなと思っています。 とりあえず、まずは、ネット上でもくもく会が開催されているようなので、それに参加しようかなぁ。
JWTを生成/解析するときのsecret keyの生成方法
JWTについて調べてる。golangでちょっと使いたい用途があったので。
golang には JWT生成/解析するライブラリが結構あって、jwt-go
ってのが有名みたい。
func createTokenString(data *User, secretkey string) (string,error) { token := jwt.NewWithClaims(jwt.SigningMethodHS256, data) return token.SignedString([]byte(secretkey)) }
こんな感じでトークンが生成できるんだけど、secretkey
の部分に何を入れたらいいんだろう?ってなってた。
railsの例を見ると、configハッシュのsecret_key_baseキーに入っている値を渡してるみたい。 値はランダムな文字列のようだ。
それはどうやって生成されてるかっていうと、rake secret
みたいなコマンドを打つと生成できるようだ。でも、どういうアルゴリズムで生成されているかわからない。
とおもったら、以下に答えが。というかソースが。
んで、secure random golang とかで検索すると、まんまの答えがqiitaに上がってた。
ということで、これを使わせてもらって、めでたくセキュアにJWTのデータを生成・解析できるようになりました。
めでたし、めでたし。
heroku の golang で http から https へリダイレクト
お名前.comで取得した カスタムドメインを使ってhttps化しようと思ったけど、なんか難しかったので、カスタムドメインはあきらめた。んで、herokuapp.com のサブドメインでSSL化してhttps化完了とす。
でも、httpのほうもアクセスできちゃうので、そっちをどうにか閉じたい。herokuの機能としてhttpからhttpsへのリダイレクトはサポートされていないようなので、自前でリダイレクトしてあげないといけないっぽい。
Can Heroku force an application to use SSL/TLS? - Heroku Help
でも、↑のサンプルには go のサンプルがない... つらたん...
なので、色んなサイトを参考に以下のように作成。
func main() { var err error proto := os.Getenv("PROTO") if proto == "" { proto = "https" } engine := gin.New() engine.Use(func(c *gin.Context) { if proto != "https" { return } header := c.Request.Header isssl := false if params, ok := header["X-Forwarded-Proto"]; ok { if len(params) != 0 && params[0] == "https" { isssl = true } } if !isssl { req := c.Request loc := "https://" + req.Host + req.URL.Path if len(req.URL.RawQuery) > 0 { loc += "?" + req.URL.RawQuery } c.Redirect(http.StatusMovedPermanently, loc) } }) engine.Run(":" + port) }
抜粋なので、これだけではちゃんと動かない。 全体は こちら
ローカルでは http で動かしたかったので、環境変数にPROTO
があるかどうかで判別している。
herokuでは、httpsの場合だと、X-Forwarded-Proto
にhttps
が入ってくるらしいので、それをチェックして
https
じゃない場合はリダイレクトしている。
heroku にデプロイ時に goose up を動かす
Procfile に release: goose up
を足すだけ。