信頼はずっと、挑戦はもっと。

お問い合わせ
TEL:03-3496-3888

BLOG コアテックの社員ブログ (毎週月曜~金曜更新中)

LIST OF ARTICLES

記事一覧

  • 画像:ブログサムネイル

    テクログ

    【nfcpyでLINE通知】ちょうど目の前にICカードリーダーとNFCチップが転がっていたので

    こんにちはじゅんすです。私は実家暮らしで兄弟がいるのですが、どうも兄が家に帰ってきても手を洗っていないっぽいのです。時期が時期なのでちゃんと手洗いうがいはしてほしいのですが、、。こりゃどうしたもんか、、、と思ったその時、ちょうど目の前にICカードリーダーとNFCチップが転がっていたので「手を洗ったらICカードリーダーにピッてしてLINEのトークルームに通知を送るシステム」を作っちゃいました。Pythonだと参考資料が多かったのでPythonで開発しました。触ったことないですけどね、、資料が多かったもんで、。なのでコードに至らない部分は多くあると思いますがご了承ください。以下にざっくりと処理の流れを記載しておきます。ICカードリーダーでNFCチップのIDm(固有ID)を取得。取得したIDmでDBからユーザー名を取得。「〇〇〇(ユーザー名)は手を洗ったよ」という内容でLINE通知。開発環境■各バージョンWindows 10 Home 64-bitPython 3.8.2libusb 1.0.23Zadig 2.5nfcpy 1.0.3MySQL 8.0.19■DBクライアントMySQL Workbench■USBドライバZadig■ICカードリーダー非接触型ICカードリーダー / ライター RC-S380(SONY製)■NFCチップNTAG213(NXP製)下準備ただICカードリーダー差してコードを書いただけじゃ動かないので以下の準備をしておきます。■libusbのインストール公式サイト(https://libusb.info/)からダウンロードできます(私の時はlibusb-1.0.23.7zでした)。ダウンロードしたファイルを解凍したら以下の操作をします。64ビット版Windowsの場合MS64\dll\libusb-1.0.dllをC:\Windows\System32にコピーMS32\dll\libusb-1.0.dllをC:\Windows\SysWOW64にコピー32ビット版Windowsの場合MS32\dll\libusb-1.0.dllをC:\Windows\System32にコピー■ドライバの適用公式サイト(https://zadig.akeo.ie/)からダウンロードできます(私の時はZadig 2.5でした)。ダウンロードしたらZadigアプリケーションを実行する前にPCにRC-S380を差します。ドライバが自動適用されたらZadigアプリケーションを実行します。表示されたウィンドウの上にあるリストボックスからNFC Port/PaSoRi 100 USBを選択します(ない場合はOptions ⇒ List All Devicesで表示されます)。Driverの項目はWinUSBにします。Replace Driverをクリックしたら完了です。■LINE Notify アクセストークンの発行公式サイト(https://notify-bot.line.me/ja/)にログインして、右上のアカウントからマイページに行きます。マイページの下部にトークンを発行するがあるのでトークン名の入力と通知したいトークルームを選択して発行します。※発行されたトークンは1度しか表示されないので注意。■DBの設定まずhand_washingという名前でDBを作成します。CREATE DATABASE hand_washing  CHARACTER SET utf8  COLLATE utf8_general_ci; 続いてNFCチップのデータを入れるnfc_tipsと、それを使うユーザーのデータを入れるusersテーブルを作成します。CREATE TABLE `hand_washing`.`nfc_tips` (  `id` INT NOT NULL AUTO_INCREMENT,  `idm` VARCHAR(50) NOT NULL COMMENT 'NFCチップの固有ID',  `user_id` INT NOT NULL COMMENT 'NFCチップを使用するユーザーのID',  `created_at` DATETIME NOT NULL,  `updated_at` DATETIME NOT NULL,  PRIMARY KEY (`id`)) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 COMMENT = 'NFCチップデータ用のテーブル'; CREATE TABLE `hand_washing`.`users` (  `id` INT NOT NULL AUTO_INCREMENT,  `name` VARCHAR(10) NOT NULL COMMENT 'ユーザー名',  `created_at` DATETIME NOT NULL,  `updated_at` DATETIME NOT NULL,  PRIMARY KEY (`id`)) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 COMMENT = 'NFCチップを使用するユーザー用テーブル'; テーブル作成も無事終わったらそれぞれのテーブルにデータを登録しておきます。nfc_tipsのidmには後述するnfc_reader.pyで取得したidmを登録します(ちょっと手間ですが、、登録機能を先に作っといた方がよかったなぁ)。動作確認■パッケージのインストールnfcpyとrequestsをpipでインストールします。pip install nfcpy pip install requests ■ファイルの作成以下3つのファイルを全て同階層に作成します。DBに接続してNFCチップのIDmからユーザー名を取得する処理を書いたdb_crud.py。import MySQLdb # データベース接続 connection = MySQLdb.connect(  host = 'ホスト名もしくはIP',  user = 'ユーザー名',  passwd = 'パスワード',  db = 'hand_washing',  charset='utf8' ) # カーソル生成 cursor = connection.cursor() # NFCのIDmからユーザー名を取得 def getUserNameByIdm(idm):  cursor.execute("SELECT users.name FROM nfc_tips JOIN users ON nfc_tips.user_id = users.id WHERE idm = '%s'" % idm.decode())  return cursor.fetchone()[0] LINEに通知を送る処理を書いたline_notify.py。import requests # LINE Notifyの情報 line_notify_token = 'アクセストークン' line_notify_api = 'https://notify-api.line.me/api/notify' # LINEでメッセージを送る def sendMessage(person):  message = str(person) + 'は手を洗ったよ'  payload = {'message': message}  headers = {'Authorization': 'Bearer ' + line_notify_token}  # 送信  requests.post(line_notify_api, data = payload, headers = headers) NFCチップのデータを読み込む処理を書いたnfc_reader.py。import nfc import binascii import time # 外部ファイル import db_crud import line_notify # タッチ待ち受けの1サイクル秒 TIME_CYCLE = 2.0 # タッチ待ち受けの反応インターバル秒 TIME_INTERVAL = 2.0 # タッチされてから次の待ち受けを開始するまで無効化する秒 TIME_WAIT = 5 # NFC接続リクエストのための準備 # NXP製のNFCチップのため106A(通信規格TypeA)で設定(Suicaで試したい人は212F) remoteTarget = nfc.clf.RemoteTarget("106A") print("カードをかざしてください") while True:  # USBに接続されたNFCリーダに接続してインスタンス化  with nfc.ContactlessFrontend("usb") as clf:   # タッチ待ち受け開始   # clf.sense( [リモートターゲット], [検索回数], [検索の間隔] )   target = clf.sense(remoteTarget, iterations = int(TIME_CYCLE//TIME_INTERVAL) + 1, interval = TIME_INTERVAL)   while target:    tag = nfc.tag.activate(clf, target)    if tag != None:     #固有のIDmを取り出す     idm = binascii.hexlify(tag.identifier).upper()     # ユーザー名取得     person = db_crud.getUserNameByIdm(idm)     print("読み込み成功\n")     print("タグ情報:" + str(tag))     print("IDm:" + idm.decode())     print("ユーザー名:" + person + "\n")     print("カードをかざしてください")     # LINEに通知する     line_notify.sendMessage(person)    else:     print("読み込みに失敗しました")    time.sleep(TIME_WAIT)    break 各ファイルが用意出来たらターミナルでnfc_reader.pyのある階層までいきます。以下のコマンドでnfc_reader.pyの処理を実行します。python nfc_reader.py すると以下のように表示されるのでNFCチップをICカードリーダーに2秒ほどかざします。python nfc_reader.py カードをかざしてください NFCチップのデータとユーザー名が表示されると同時にLINEに通知が送られます。python nfc_reader.py カードをかざしてください タグ情報:〇〇〇〇〇〇 IDm:〇〇〇〇〇〇 ユーザー名:〇〇〇〇〇〇 カードをかざしてください とまぁ、こんな感じで通知システムを作ってみたってお話です。ただ、これだけじゃ手を洗ったふりしてICカードリーダーにピッてする不正行為ができてしまうので、手の汚れをブラックライトで可視化してカメラで読み込む機能等と組み合わせるなどしたほうが良いかなとか思ったり思わなかったりって感じですね、、(Raspberry Piが欲しい)。皆さんも目の前に転がっていたら色々作ってみてください!ではでは!
  • 健康

    毎日R-1ヨーグルト生活

    こんにちはじゅんすです。2020年が来てしまいましたね。みなさんは今年の抱負を考えているところでしょうか。私は健康な日々を送りたいなと思って毎日R-1ヨーグルトを食べるようにしています。「強さ引き出す乳酸菌」ですからね、最強を目指そうと思います。R-1ヨーグルトの名前にもなっている「乳酸菌1073R-1株」はインフルエンザワクチンの効果を高める可能性があることがヒトを対象とした研究で確認されたみたいですよ(明治さん公式)。なのでこれからR-1生活をしようと考えている人はインフルエンザの予防接種をちゃんと受けましょう(私は次回ちゃんと受けます、別に怖いわけではありません)。
  • 画像:ブログサムネイル

    テクログ

    Webサイトのパフォーマンスを改善するならクリティカルレンダリングパスを知っておこう

    ご無沙汰してますじゅんすです!最近やっと涼しくなってきましたね。それはさておき皆さんクリティカルレンダリングパス(Critical Rendering Path)ってご存じですか?僕はつい最近知ったばかりなのでちょっと紹介しようかと思います。Webサイトを開発している時になんか重いなぁと思う時が必ずありますよね。重いWebサイトのパフォーマンスを改善する際に、このクリティカルレンダリングパスはかなり重要なものになってきます。クリティカルレンダリングパスというのはブラウザがページを表示する際、サーバーからHTMLのレスポンスを受け取って要素を描画するまでのステップのことです。このステップは以下の通りです。・DOMツリーの構築・CSSOMツリーの構築・レンダリング ツリーの作成・レイアウトの生成・ペインティング(描画)順を追って説明していきますね。DOMツリーの構築Q. DOMツリーって何ですか?A. DOM(Document Object Model)ツリーはパース(文法を元に解析)されたHTMLのドキュメントをツリー構造として表現したものです(下図)。■critical.html<html>     <head>         <link rel="stylesheet" href="style.css">         <title>クリティカルレンダリングパスとは</title>     </head>     <body>         <header>             <h1>クリティカルレンダリングパスとは</h1>         </header>         <main>             <h2>概要</h2>             <p>概要テキスト</p>         </main>         <footer>             <small>Copyright 2019</small>         </footer>     </body> </html> ■DOMツリールート要素の<html>から始ってページ上のあらゆる要素やテキストごとにノード(結び目)が作成されます。他の要素にネスト(入れ子)された要素は子ノードとして表現され、各ノードにはその要素の属性すべてが含まれます。例えば、<a>要素はそのノードに関連づけられたhref属性を持ちます。HTMLは部分的に実行することができ、ページのコンテンツが表示される際もドキュメントを完全に読み込む必要はありません。ですがCSSがページのレンダリングをブロックする可能性があるのです。CSSOMツリーの構築Q. CSSOMツリーも知らないのですが...。A. CSSOM(CSS Object Model)ツリーはDOMに関連付けられたスタイルのオブジェクトを表現したものです(下図)。DOMと似た感じで各ノードのスタイルが関連づけられて表現されます。■style.cssbody { font-size: 18px; } header { color: #ff9bba; } h1 { font-size: 28px; } main { color: #ff7974; } h2 { font-size: 20px; } footer { display: none; } ■CSSOMツリーそういえばさっき「CSSがページのレンダリングをブロックする可能性がある」と言いましたがどういうことかというと、CSSは「レンダーブロッキングリソース(render blocking resource)」とみなされています。というのもHTMLと違って上流で定義されたものが下流へ引き継がれて文書に適用されるため、CSSを部分的に使用することはできません。途中で定義されたものを使ってしまうと間違ったCSSが適用されることがあるため、次の段階(レンダリングツリーの作成)に進む前に完全に読み込む必要があるのです。しかし常にレンダーブロッキングと見なされるわけではなく、現在のデバイスに適用される場合だけみなされます。例として<link>タグを挙げますね。<link>タグはmedia属性を指定することができ、適用されるスタイルのメディアクエリを指定することができます。例えば以下のようにmedia属性に「min-width:480px」を指定した場合、画面サイズが480pxより大きくなったら読み込むため、それ以下の場合はレンダーブロッキングとみなされません。■link要素として指定する場合<link href="URL" rel="リンクタイプ" media="screen and(min-width:480px)" > ■スタイルシートに指定する場合@media screen and (min-width:480px) {   p { color: #ededed; } } レンダリングツリーの作成Q. レンダリングツリー?A. DOMとCSSOMの両方を組み合わせたもので、ページに最終的に表示される内容を表現するツリーのことです(下図)。ただし目に見えるコンテンツのみを取得するため、「display: none;」を使用してCSSで非表示にした要素は含まれません。■レンダリングツリーこれで画面に表示する要素を整理することができました。しかしまだ端末のビューポート内における要素の正確な位置やサイズは決まっていません。それを決めるためには次のステップが必要になります。レイアウトの生成レイアウトはビューポートのサイズを決定するもので、パーセンテージやビューポートの単位に依存するCSSスタイルのコンテキストを提供します。ビューポートのサイズはhead内の<meta name = "viewport">タグによって決まり、タグが指定されていない場合は、デフォルトの980pxが適用されます。一般的な<meta name = "viewport">の値は、デバイスの幅に対応するようにビューポートサイズを設定することです。ペインティング(描画)クリティカルパスの最後の段階で、ページの目に見えるコンテンツをピクセルに変換して画面に表示します。ペインティングにかかる時間はDOMのサイズや適用されるスタイルによって異なりますので時間がかかっている場合はDOMやCSSを見てみるといいかもしれません。改めてコンテンツが表示されるまでのステップを表すとこのようになります。一見シンプルなページでも様々な処理が必要だということがわかりますね。最近サイトが重いなぁと思ったらちょっと考えてみるのもいいかもしれません。クリティカルレンダリングパスを改善するためのツールもちらほらありますので試してみてはいかがでしょうか。下にちょっとだけ貼っておきます。■Critical Path CSS Generatorhttps://www.sitelocity.com/critical-path-css-generatorhttps://jonassebastianohlsson.com/criticalpathcssgenerator/ではではっ!
  • 画像:ブログサムネイル

    レビュー

    世界最初のグミを知っていますか

    実はグミが大好きなじゅんすですこんにちは。皆さんは世界で最初に作られたグミってご存じでしょうか。コンビニやスーパーでよく見かけるあのグミですよ、ほらあれ。一度は見たことがあるかと思います。そう、ハリボー(HARIBO)です!名前や画像を見て「あ~!」と思ったでしょう。今では何十種類もありますよね。片面がマシュマロっぽい生地のタイプや砂糖の粒が塗されているタイプ、「世界一まずい」とよくネタにされているタイヤみたいなタイプ等など。僕の好きなグミの1つでもあるハリボーですが、なぜ「ハリボー(HARIBO)」という名前なのか知ってますか?その昔、ドイツでは歯の病(虫歯や歯周病)が流行っており、その主な原因は咀嚼力の低下でした。噛む力が弱いと咬み合わせが悪くなり、結果として歯の病を患ってしまうのです。それを見かねた「ボン(Bonn)」という町にいた「ハンス・リーゲル(Hans Rigel) 」さんは、「子供のうちから咀嚼力を高めてあげれば解決するだろう」と思い、咀嚼力を高めるキャンディーとしてグミを作ったのです。ここで気づいたと思います。なぜ「ハリボー(HARIBO)」という名前なのか。そう、「Hans Rigel」と「Bonn」の頭の文字から名付けられたのです!ほぇ~~って感じですよね。僕も同じですもん。世の中には作成者の名前から名付けられたものが数多くありますがハリボーもその中の1つなんですよね。とまぁ、ほぇ~っとなるお話でした!因みにハリボー以外で好きなグミは「果汁グミ」「コーラアップ」です。弾力のある固めのグミが好きなのでどれも冷蔵庫で冷やしてから食べてます。(冷やさなくても十分弾力ありますが、さらなる強さを求めているので)
  • レビュー

    今日は注目の日です

    ご無沙汰してますじゅんすです。今日は新元号が発表される日ですね(11時30分頃)。朝からどのニュース番組も新元号について取り上げていましたね。今回も従来通り中国古典から引用されるのかそれとも日本古典から引用されるのかと、どの古典から引用されるのかも話題となっております。聞いた話では従来通り中国古典から引用されるのならばと中国古典の漢字2文字の組み合わせを全てリスト化したという猛者もいるとかいないとか。全ての組み合わせを数えると228万通りもあるとのことです。信じるか信じないかは皆さん次第ですよ。因みに新元号に変わるのは今日ではなく5/1(水)ですのでお間違いのないように(これは本当です)。
  • 画像:ブログサムネイル

    テクログ

    忘れがちなあなたへ【IFTTT】

    こんにちは、じゅんすです!学校、会社で何かの当番を任されたけれど、「あ、そういえば今日は自分が当番だった...。」なんて忘れてしまうことありませんか?意識しているつもりでもつい忘れてしまったことは少なからず1度は経験しているんじゃないでしょうか。そこで僕がちょっと注目している、というか使っているサービスについてご紹介しようと思います!それは「IFTTT」という異なるソーシャルメディアやプラットフォームを連携させるWebサービスです!これで一体何ができるのかというと、例えば、「Gmailに画像が添付されていたら、その画像をDropBoxに保存する」「Twitterで特定のツイートをEverNoteに保存する」「LINE等で特定の人に指定した日時になったら通知を送る」といったことを自動で行ってくれるのです!僕は普段LINEと連携させてこの通知機能を使っています!なので今回は通知機能が使えるまでの手順を簡単に書いていこうと思います。①IFTTTサービスページ(https://ifttt.com/)に行ってアカウントを作成し、ログインする。 ※Google、Facebookのアカウントでもログインすることができます。②画面上部の「My Applets」をクリックする。③画面右上の「New Applet」をクリックする。④大きく表示されている「if +this then that」の「+this」をクリックする。⑤どのサービスを使うのか求められるので、自分が使いたいものを選択する(今回は通知機能についてなので「Date&Time」を選択)。⑥どのタイミングで通知させるのか求められるので、自分の設定したいものを選択する。 ※左上から、以下のようになっています。 「毎日〇〇時〇〇分」 「毎時〇〇分」 「毎週〇曜日の〇〇時〇〇分」 「毎月〇〇日の〇〇時〇〇分」 「毎年〇〇月〇〇日の〇〇時〇〇分」⑦自分で日時を設定し、「Create trigger」をクリックする。⑧すると「if (Date&Time) the +that」という大きな文字が表示されるので、「+that」をクリックする。⑨この通知機能をどのサービスで扱うかを選択する(chatwork、LINE等)。 ※現状、LINEでは「Send message」しかないけれど、画面下の「Suggest a new action」で新たに通知機能の使い道を提案することも可能です。 chatworkでは接続する際にAPIを利用する権限が必要とのことです。 とりあえずLINEで使う体で続けますね!⑩選択したサービス(LINE)で設定した通知機能の詳細を以下のように設定する。 「Recipient」 ⇒ どの部屋で通知を受け取るか 「Message」    ⇒ どういった内容の通知にするか 「Photo URL 」⇒ 通知メッセージに画像を載せる⑪詳細設定が完了したら「Create action」をクリックする。これで完了です!!僕はまだ通知機能しか触っていないので、後々他の機能も試してみようかなと思っています!スケジュール管理のサポートツールとして、皆さんも試してみては如何でしょうか!それではっ!