UUUM攻殻機動隊(エンジニアブログ)

UUUMのエンジニアによる技術ブログです

今年も合宿にいきました!

こんにちは。2月入社でシステムユニット所属の井上です。

今日のテーマは合宿です!!

システムユニットでは年に2回、開発旅行合宿があります。

合宿ではテーマが設定されており、テーマに沿って自分の好きなプロジェクトの開発だったり、新技術の勉強などそれぞれが自由に研鑽します。

今回はその一環として2/22(金)~2/23(土)に、UUUM攻殻機動隊のエンジニア達で開発合宿に行ってきました。

今回の合宿場は、神奈川県の箱根にある「COLONY 箱根」でした。

施設紹介

企業の研修用の施設らしく広々としていました。また箱根名物の温泉もありました。

そしてラッキーなことに利用者は他におらず(!!)貸切りのような状態で利用することができました。

簡単に施設紹介をします。

お昼ご飯

f:id:iammyeye1:20190225192101j:plain
お昼ご飯

広間 

f:id:iammyeye1:20190225194458j:plain:h551:w681
広間

温泉

f:id:iammyeye1:20190225193734j:plain:h551:w681
温泉

訪問した施設はこちらです。

colony-hakone.com

開発合宿では何をしたのか?

ここからが本題ですが、今回の開発合宿のテーマは「自由開発」でした。

今回の合宿も前回に引き続き、それぞれが一つのプロダクトを開発しました。

お昼ご飯をいただいて2時ごろから雑談混じりで開発は始まり、次第にそれぞれの開発に集中していきました。

f:id:iammyeye1:20190225193857j:plain:h551:w681
開発風景

みんな自由に開発しています!

夕飯・温泉後

18時半の夕ご飯で一旦休憩。

f:id:iammyeye1:20190225192051j:plain
豪華な夕御飯

温泉に入るなど各自で休憩を挟みつつ開発を続けます。 温泉とマッサージ機は凶器ということも知りました。

f:id:iammyeye1:20190225193907j:plain
開発デスマーチ開発を楽しんでる様子

開発の合間の一枚です!

楽しそうな笑顔〜。

しかし開発が進まず5時ごろまで開発をしていた人も、、、

2日目

朝から豪華な食事をいただき、開発の最終調整と発表資料を作成して10時半から発表開始です。

僕は遅くまで起きていたので寝不足で食欲がなく、ご飯は2杯しか食べれませんでした、、、(美味しかったです)

f:id:iammyeye1:20190225192332j:plain
朝食

発表風景

最後にそれぞれが発表資料をスライドで作り、プロダクトのデモンストレーションなども交えながら発表しました!

f:id:iammyeye1:20190225193929j:plain
個人的に一番好きだったプロダクトを開発されたメルさんの発表

こんな感じで発表会が行われました。

発表では、技術的にはAWS, Rails, Lambda, bulma, dockerなど様々な分野に渡り、開発物も自分が欲しいプロダクト、業務効率改善用プロダクト、日頃の業務で関わることの少ないライブラリを試してみた開発など十人十色でした。

結果として幅広い分野の発表となり、非常に知的好奇心を刺激しあう発表でした。

まとめ

まず2日間に渡り開発に集中できる素晴らしい環境を整えてくださった施設の皆様ありがとうございました。

合宿全体に関してですが、まとまった時間を設けて勉強することのできる非常に貴重な機会でした。

発表を通じてそれぞれの成果や知識の共有をすることで、チーム全体で大きく成長できたのかなと思います。

また2日間一緒に過ごしたことでコミュニケーションが活発になったのも良かったと感じています。

個人的に非常に楽しかった合宿でした。

最後は集合写真でもって締めさせていただきます。

f:id:iammyeye1:20190225192239j:plain

また参加したい〜。

すごいTerminal 楽しく学ぼう!

最近Terminalが楽しい takeokunn です。

社内勉強会の順番が回ってきたので、せっかくだから最近ハマってるterminalについて語っちゃおうかなーと思いスライドを作りました!

インスタ映えしちゃうterminalを創ってスタバでドヤ顔したいですね!

スタバといえば、木下ゆうかさんの動画!

↑チャンネル登録しよう

Vue.jsコミッターのkazuponさんをお招きして社内勉強会をしました

こんにちは!エンジニア(仮)のめる(@c5meru)です。
最近、弊社のフロントエンドエンジニアごーさんが、社内勉強会に立て続けにスーパーゲストを呼んでくださっています(第1回第2回 )。
上記に続いて今回はなんと、なんと、Vue.jsコミッターのkazuponさんこと、川口和也さんをお招きしました!🎉✨

続きを読む

Webの技術でYoutube Viewer作った

はじめに

この記事は、UUUM Advent Calendar 2018 20日目です。

12月から新入社員の takeokunn です。普段は LMND の開発をやっております。

UUUMに入った初日(9/18)、 クリエイター(youtuber)のことを全く知らず他の人と会話が合わずに詰みました。 そこでこの会社でこの先生きのこるには効率よくキャッチアップする方法が必要だと思ってUUUM Creatorの動画viewerを作りました。

木下ゆうか さん、ごはん美味しそうに食べるから好き

Effective Youtube Viewer

f:id:bararararatty:20181217152621p:plain

Electronは配布してないので自前でbuildしてください

使ってる技術

  • electron
  • webpack/babel
  • react
  • redux/redux-saga
  • service worker
  • CSS Grid
  • csscomb/eslint
  • CircleCI

よくあるweb frontendの構成です。

redux-saga 楽しい

サービスの質を決めるのはエラーハンドリングだと思っています。 web frontendにおいて、非同期処理、特にAjax周りのハンドリングは非常に面倒ですが、redux-sagaを使えば体感すっきり書くことができます。

この辺がわかりやすいです。 redux-sagaで非同期処理と戦う f:id:bararararatty:20181217160209p:plain

以下はyoutube channelを取得する action/reducer/saga の例です。

抜粋: src/actions/youtube.action.js

export const fetchChannelVideo = {
    request: channel_id => action(YOUTUBE.FETCH_CHANNEL_VIDEO_REQUEST, { channel_id: channel_id }),
    success: data => action(YOUTUBE.FETCH_CHANNEL_VIDEO_SUCCESS, { data: data }),
    failure: () => action(YOUTUBE.FETCH_CHANNEL_VIDEO_FAILURE)
};

抜粋: src/reducers/youtube.reducer.js

const channel_video = (state, action) => {
    switch (action.type) {
    case YOUTUBE.FETCH_CHANNEL_VIDEO_REQUEST:
        return { ...state, is_fetching: true };
    case YOUTUBE.FETCH_CHANNEL_VIDEO_SUCCESS:
        return {
            ...state,
            is_fetching: false,
            search_videos: action.payload.data.items.map(item => ({
                title: item.snippet.title,
                description: item.snippet.description,
                thumbnail_url: item.snippet.thumbnails.medium.url,
                video_id: item.id.videoId,
                comments: [],
                comment_count: null,
                dislike_count: null,
                favorite_count: null,
                like_count: null,
                view_count: null,
            }))
        };
    case YOUTUBE.FETCH_CHANNEL_VIDEO_FAILURE:
        return { ...state, is_fetching: false };
    }
};

抜粋: src/sagas/youtube.saga.js

function* handleFetchChannelVideo() {
    for(;;) {
        const action = yield take(YOUTUBE.FETCH_CHANNEL_VIDEO_REQUEST);
        const response = yield call(ajax.searchChannelId, action.payload.channel_id);
        switch (response.status) {
        case 200:
            yield put(youtube.fetchChannelVideo.success(response.data));
            break;
        default:
            yield toastr.error('失敗', '通信失敗');
            yield put(youtube.fetchChannelVideo.failure());
        }
    }
}

今後の展望

弊社ではクリエイター分析ツールの開発などもやっているのでそれと連携して拡張できたら良いなぁと思います。

また、新着のsubscribe(webpush)やそのクリエイターの詳細情報など載せられるともっともっと良くなるだろうなぁと

今はクリエイターの管理がjsonで手書きで書いていて雑なのでなんとかしたいのと、あまりテストを書けてないので充実させたいなぁと src/options/youtuber.json

最後に

木下ゆうか さんの動画をデバッグに使い始めてから体感開発効率は上がるわ、体感javascript力も上がるわ、体感リロード時間も早くなるわで良いことづくめでした。本当にありがとうございました。 ← チャンネル登録しよう

UUUMでは (任意の文字列)エンジニアを募集しているそうです。 www.wantedly.com www.wantedly.com

CSS3のkeyframesで はじめしゃちょーを走らせてみました

こんにちは!エンジニア(仮)のめる(@c5meru)です。
こちらの記事は、UUUM Advent Calendar 2018 19日目の記事です!

5日目の前回は、CSSでHIKAKINをかきました
HIKAKINときたので、今回もUUUMのクリエイターである、はじめしゃちょーを題材にしたいと思います!

続きを読む

日頃あまり使っていないAWSのサービスを使う!〜AWS IoT編〜

はじめに

こちらは UUUM Advent Calendar 2018 18日目の記事です。

こんにちは、エンジニアのいぐちです。 WEBアプリケーションを開発していくうえで、AWSと触れ合うことが多い今日この頃ですが、ものすごい数のサービスを提供しているAWSの一部のサービスしか利用できておらず、少し寂しい・・・ そこで、日頃仕事で使ったことのないAWSのサービスを使ってみようということで AWS IoT を使ってみることにしました。

今回はRaspberry Pi2台とAWS IoTのセキュアなメッセージブローカーの機能を利用して簡単なおうちハック的なことをしたのでそちらをつらつらと書いていきます。

AWS IoT

AWS IoTというのはその名の通りちゃんとしたIoTでの開発をおこなっていくうえで必要になってくる様々な機能をまとめたサービス群になります。

詳しくはAWSのドキュメントをご覧ください。

AWS IoT とは - AWS IoT

今回利用したメッセージブローカー機能というのは、 MQTT等のプロトコルで各IoTデバイス(今回はRaspberry Pi)同士のメッセージのやり取りをpub/subモデルで行うものです。 MQTTなどがよく分からない方は以下のリンクをご覧ください。

MQTT の基本知識

やったこと

AWS IoTを使って、 目覚まし時計 を作りました。

え?目覚まし時計にAWS IoTって何言ってるの?ん? と思われるかもしれないですがちょっと説明させてください。

今回AWS IoTを使って作った目覚まし時計は、 スピーカーとスイッチが分離された目覚まし時計 です。

スピーカー側を寝室に置いてスイッチを遠く離れた別の部屋に置くことで、うるさいアラームを止めるのに歩いてスイッチを押しにいかなければならず嫌でも起床することになるという朝が弱い我が家の 最終兵器 です。

構成

  • Raspberry Pi A
    • スピーカーのみ接続
    • 特定の時間になるとアラームが鳴る
    • AWS IoTでTopicをsubscribeしており、別のデバイスからメッセージがpublishされたらアラームが止まる
  • Raspberry Pi B
    • タクトスイッチのみ接続
    • タクトスイッチを押すとメッセージをpublishする。
  • ソースコード
    • それぞれのRaspberry PiにはPython3系で書かれた簡単なコードが配置されています。

f:id:rinjin5th:20181217121317j:plain

AWS IoTの設定

まず以下のとおりモノを作成していきます。 (2台のデバイスを使用していますがとりあえず今回は1つのモノを使いまわします。)

f:id:rinjin5th:20181217010750p:plain

f:id:rinjin5th:20181217010841p:plain

今回は必須項目のモノの名前だけ適当に設定します。 f:id:rinjin5th:20181217010927p:plain

誰でも簡単にメッセージを送受信できては困るので、証明書による認証でセキュリティを担保します。 証明書もコンソール上からすぐに作成できます。

f:id:rinjin5th:20181217011138p:plain

作成できたら、モノの証明書、プライベートキー、ルートCAの証明書をダウンロードしておきます。 また証明書を有効化しとりあえず完了をクリックします。

f:id:rinjin5th:20181217011155p:plain

次にポリシーを作成し、先ほど作成した証明書にアタッチします。 今回はAWSIoT以外操作しないのでiot:*を指定することでAWSIoTの全操作が可能なように設定しておきます。

f:id:rinjin5th:20181217011214p:plain

f:id:rinjin5th:20181217011234p:plain

f:id:rinjin5th:20181217011250p:plain

これだけで設定は完了です。

ソースコード

一部抜粋してソースコードを掲載し説明します。 フルバージョンはこちらで公開しておりますので、気になる方はご確認ください。

https://github.com/rinjin5th/remote-alarm/

ライブラリとして以下を使用しています。

  • AWSIoTPythonSDK
  • PyAudio

AWSIoTMQTTClientの初期設定

スピーカー側、スイッチ側両方共にAWSIoTMQTTClientの設定を行う必要があります。 重要な部分は以下の通りです。

  • ClientIDの設定
  • エンドポイントの設定
  • AWSのルートCA証明書、モノの証明書、プライベートキーの設定
class MQTTClient:
    def __init__(self, client_id, host, root_ca, cert, key):
        # client_idはスピーカー側とスイッチ側で別の値にする必要がある
        self._client = AWSIoTMQTTClient(client_id)
        # AWSコンソール上で確認できるエンドポイント
        # ex)xxxxx..iot.ap-northeast-1.amazonaws.com
        self._client.configureEndpoint(host, 8883)
        # ルートCA証明書、モノの証明書、プライベートキーファイルのパスを設定
        self._client.configureCredentials(root_ca, key, cert)

parser = argparse.ArgumentParser()
parser.add_argument("-e", "--endpoint", action="store", required=True, dest="host", help="Your AWS IoT custom endpoint")
parser.add_argument("-r", "--rootCA", action="store", required=True, dest="rootCAPath", help="Root CA file path")
parser.add_argument("-c", "--cert", action="store", required=True, dest="certificatePath", help="Certificate file path")
parser.add_argument("-k", "--key", action="store", required=True, dest="privateKeyPath", help="Private key file path")
parser.add_argument("-m", "--mode", action="store", dest="mode", default="alarm" ,help="Operation modes: %s"%str(ALLOWED_MODES))

args = parser.parse_args()
host = args.host
rootCAPath = args.rootCAPath
certificatePath = args.certificatePath
privateKeyPath = args.privateKeyPath

clientId = "client_" + args.mode
mqtt_client = iotclient.MQTTClient(clientId, host, rootCAPath, certificatePath, privateKeyPath)

スピーカー側

大まかな流れは以下の通りです。

  1. トピックをsubscribeする。メッセージ受信時に実行されるcallback処理(アラーム停止)を設定しておく。
  2. アラームをループして再生しつづける。
class Alarm:
    playing = False
    
    def __init__(self):
        self._audio = pyaudio.PyAudio()

    def play(self, filename):
        self.playing = True
        while True:
            if not self.playing :
                break
            with wave.open(filename, 'rb') as wf:
                stream = self._audio.open(format=self._audio.get_format_from_width(wf.getsampwidth()),
                                 channels=wf.getnchannels(),
                                 rate=wf.getframerate(),
                                 output=True)
                 
                data = wf.readframes(1024)

                while data != b'':
                    stream.write(data)
                    data = wf.readframes(1024)

                stream.stop_stream()
                stream.close()

    def stop(self, client, userdata, message):
        self.playing = False

class MQTTClient:
    def subscribe(self, topic, callback):
        self._client.connect()
        self._client.subscribe(topic, 1, callback)

alarm_obj = alarm.Alarm()
# アラームの停止処理をメッセージ受信時のcallbackメソッドとして設定する
mqtt_client.subscribe("remote/alarm", alarm_obj.stop)
alarm_obj.play(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'alarm.wav'))

今回はあまり複雑な作りにはしたくなかったため、こちらのプログラムを起床時間にcronで実行しております。

スイッチ側

大まかな流れは以下の通りです。

  1. スイッチの状態を監視する。
  2. スイッチが押されたらメッセージをpublishする。
class MQTTClient:
    def publish(self, topic, message):
        self._client.connect()
        message_d = {}
        message_d['message'] = message
        self._client.publish(topic, json.dumps(message_d), 1)
        self._client.disconnect()

def watch():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(24, GPIO.IN) 
    
    try:
        while True:
            # タクトスイッチが押されたらループを抜けて後続の処理を実行
            if GPIO.input(24) == GPIO.HIGH:
                break 
            time.sleep(0.1)
    
    except KeyboardInterrupt:
        pass
    
    GPIO.cleanup() 

watch()
mqtt_client.publish("remote/alarm", "stop")

こちらもまた複雑な作りにはしたくなかったため、こちらのプログラムを起床時間にcronで実行しております。

まとめ

今回は目覚まし時計という軽いモノだったため、AWS IoTのほんの一部の機能しか利用しておりません。 今後はもっと色々なものを作ってAWS IoTを極めていきたいなと思います。

さいごに

UUUMではAWSのサービス(IoTは多分使わないけど・・)を使ったWEBアプリケーション開発ができる方を募集しております! とりあえずお気軽にお話だけでもどうぞ!

www.wantedly.com

www.wantedly.com

全く技術がわからない人にプログラミングを説明してみた

おはこんばんちは!! 尾藤 a.k.a. BTO です

この記事は、UUUM Advent Calendar 2018 12日目の記事です。 (だけど遅れて13日目に公開しました。ごめんなさいごめんなさい)

UUUMでは新入社員に会社の事業を理解してもらうために、各ユニット長が自分たちが何をやっているのか新入社員に説明する事業説明会というのがあります。 そこでシステムユニットの説明をするのですが、1時間という限られた時間の中で技術のわからない人たちに僕ら開発部隊がやっていることを理解してもらうのには無理があります。そうすると結局開発しているツールの説明になってしまうのですが、会社の状況がよくわかってない新入社員にいきなりツールの説明しても理解できませんし、自分の職種に関係のないツールの説明を聞いてもわかりません。で、結局何もわからずに終わってしまいます。

せっかく新入社員の人に時間をとってもらっている貴重な機会なので有意義なものにしたいです。どうせツールの説明は業務を進めれば自ずと理解が進むんだし、事業説明会でもやらなくても大丈夫です。システムユニットは周りから何の仕事をしているのかわからないとよく言われます。じゃあ、技術のわからない人たちに少しでも僕らシステムユニットがどういう仕事をしているのかを理解してもらう試みをしてみようと考えました。僕らがやっているのはプログラミングです。なので技術がわからない人たちにプログラミングはどういうものなのか、なんとなく理解できるように説明してみました。

プレゼン資料

こちらがプレゼン資料です。ドドーン!!! プログラミングの説明のところだけ抜粋してます。

いくつかのポイントを説明していきます。

ゴール設定

ゴールは

  • プログラムを分かった気になる
  • システムユニットの仕事を分かった気になる

の2つです。プログラムを書くのがなんで大変なのか、なんでそんなに時間がかかるのか、といったことがなんとなくわかってもらえるようになることを目指します。

プログラミングに一番必要な科目は?

英国数理社の5教科のうち、プログラミングに一番必要なのはどの教科か? 僕はこれは 国語 だと思います(異論は認める)。

この質問をするとプログラム書いたことない人からの一番多い回答は 数学 です。知らない人からすると、プログラマはさぞかし難しそうな計算式を扱っているように思われているんでしょうね。でも実際にプログラムを書く時に使うのはせいぜい四則演算ぐらいです。もちろんそういった分野もありますが、僕らが開発しているようなアプリケーションはライブラリを使うことがほとんどなので、自分たちで難しい数式を扱うことはほとんどありません。

次に多い回答は 英語 です。でもプログラムを書くのにレベルの高い英語は必要ないですよね。せいぜいいくつかの英単語を扱うぐらいです。英語の文書を読むというのもありますが、なくてもなんとかなります。

この質問で回答が 国語 だというと、かなり意外な顔をされます。これで外から見たプログラミングのイメージもだいぶ変わるのではないかなと思っています。

コンピュータを小人に例える

コンピュータがよくわからない鉄の塊なので、もっと身近な存在として小人に例えます(小人が身近じゃないというツッコミは置いといて)。 小人は次のような特徴を持ってます。

  • 真面目
  • 作業が正確・高速
  • 24時間365日休み無し
  • 賃金が安い
  • いきなり死ぬ
  • 言われたことしかできない
  • 言われた通りにしかできない

だいたいコンピュータの特徴とあってるのではないでしょうか。

こういう特徴を持った小人さんにちゃんと働いてもらうためにはしっかりとしたマニュアルが必要です。マニュアルを書くには時間もかかるし、正確に記述するには国語力が必要です。逆にしっかりとしたマニュアルを書くことができれば、小人さんにいっぱい働いてもらってその恩恵を受けることができます。プログラミングはマニュアルを書くのに似ています。だから一見簡単そうに見えることでも書くのに時間がかかるのです。

実際に小人用のマニュアルを書いてみます

例として小人に水を飲んでもらうというタスクを設定しました。人間なら一言で済むことが、小人さんにやってもらうと随分面倒なマニュアルを書く必要があります。彼らは融通がきかず言われたことしかできないので当然ですね。これでなんとなく面倒臭さがわかるのではないかなと思います。

アンケート結果

気になるアンケート結果はこちら

満足度

満足度
満足度

理解度

理解度
理解度

ということで満足度も理解度もかなり高い結果になりました。一安心です。

結論

2018年 YouTube 国内トップトレンドに選ばれた動画は全て UUUM クリエイターによる動画でした!!!!

www.buzzfeed.com