<JavaScript>来場者カウンター作ってみたPart.3

ようやく書ける
//今まで書いてなかっただけ
ということでこれの第三段です
poolbooyer.hatenablog.jp
poolbooyer.hatenablog.jp

ということでまずは目次から確認

  • 制作物の目的(前々回)
  • 制作物の概要(前々回)
  • 制作物の完成形(前々回)
  • 制作したコード(html)(前々回)
  • 制作したコード(JavaScript)
    • 機能1:人数カウント機能(前回)
    • 機能2:トータル人数算出機能(前回)
    • 機能3:時間ごと人数統計表示機能(今回)

ということで本編レッツゴー

時間ごと人数統計表示機能

機能の概要

  • 1時間に一度来場者を集計
  • 集計結果を表示
  • 表示数を抑制(2つまで)

機能のために利用したもの

今回はbootstrapのcardコンポーネントを利用しました
くわしくは以下参照です
getbootstrap.com
これだとサンプルでは画像を使ってるんですが今回は画像なしで単体の要素をまとめて表示したいっていう意図もありこれを画像なしで使用しました。

実際のソースコード

var cardmaker = function (card_id) {
    //時間情報を取得
    DD = new Date();
    Hours = DD.getHours();
    Minutes = DD.getMinutes();
    //毎時00分のときに処理を実行
    if (Minutes == 0) {
        //カードを作る場所を指定
        var card = document.createElement("div");
        //その時点でのトータルの値を取得
        var total_p = document.getElementById('parent_total').innerHTML;
        var total_s = document.getElementById('student_total').innerHTML;
        //カード表示を行うために必要な要素を生成
        var card_head = "<div class=\"card\" id=\"" + card_id + "\"><div class=\"card-body\"><h3 class=\"card-title\">";
        //作る場所に指定
        var parent_object = document.getElementById("card");
        var cards = document.getElementsByClassName("card");
        //過去にカードを生成したときのカード情報生成
        if (card_id > 0) {
            var ob = parent_object.getElementsByClassName("num");
            var length = ob.length;
            //pane属性に保存されている前回の集計値を取得
            var num_p = ob[length - 2].getAttribute("pane");
            var num_s = ob[length - 1].getAttribute("pane");
            //totalの増分の取得
            var p_add = total_p - num_p;
            var s_add = total_s - num_s;
            card_id = card_id + 1;
            card_head = card_head + Hours;
            card_head = card_head + "時</h3>";
            var card_body = "<ul class=\"card-text\">";
            //pane属性と表示する情報に集計値を書き込む
            //前回の集計値との差を書き込む
            var p_data = "<li class=\"num\" pane=\"" + total_p + "\">中学生以外:  " + total_p + "(前回比 " + p_add + ")</li>";
            var s_data = "<li class=\"num\"pane=\"" + total_s + "\" pane=\"" + total_p + "\">中学生:  " + total_s + "(前回比 " + s_add + ")</li>";
            card_body = card_body + p_data + s_data + "</li></ul></div>";
            card.innerHTML = card_head + card_body;
            //1つ目のカードを生成
        } else {
            card_id = card_id + 1;
            //時刻情報を作る
            card_head = card_head + Hours;
            card_head = card_head + "時</h3>";

            //集計情報を生成
            var card_body = "<ul class=\"card-text\">";
            //pane属性と表示する情報に集計値を書き込む
            var p_data = "<li class=\"num\" pane=\"" + total_p + "\">中学生以外:  " + total_p + "</li>";
            var s_data = "<li class=\"num\"pane=\"" + total_s + "\" pane=\"" + total_p + "\">中学生:  " + total_s + "</li>";
            card_body = card_body + p_data + s_data + "</li></ul></div>";
            //カードを表示
            card.innerHTML = card_head + card_body;
        }
        parent_object.appendChild(card);
        //1分後に関数を再度呼び出す
        setTimeout(function () {
            cardmaker(card_id);
        }, 60000);
        //カードの数が2つを超えたときに一番古いものを非表示する
        if (card_id > 2) {
            cards[card_id - 3].setAttribute("style", "display:none");
        }
    //時間が00分でないとき1分後に再度実行する
    }else {
        //cardmaker関数を1分後に呼び出す
        setTimeout(function () {
            cardmaker(card_id);
        }, 60000);
    }
    return card_id;
}

ということでこれまで2回で公開した公開したソースコードとこれを組み合わせることで以下のリンクのように使うことができます。
counter

今回は使いたい機能に組み上げることが目的だったのでもっといい感じに書きたかったのですがとりあえずこれにてこのシリーズは終了

<arduino>熱中症警報装置作ってみた

なんか最近proにしませんか広告出てくるのでちょっとしてみるか迷い中

はじめに

poolbooyer.hatenablog.jp
poolbooyer.hatenablog.jp
これの続きですが、明日上げます。
コードのブラッシュアップに時間がかかってしまいました。

ということで本編

arduino熱中症警報装置

最近バカ暑いじゃないですか。(なお,今日の仙台の最高気温は24℃の予想)
暑い中生きる中で何に気をつけなきゃいけないのかって熱中症ですよ
熱中症はホントやばいっすよ
ただただ辛いっすよ
もうなりたくないです
そこで、温度の上昇に合わせて警報をするものがあればいいんじゃないかと思いました。

"思いました"
じゃあ作りましょうってことで作りました

目次

  • 制作物の概要
  • 動作の条件
  • 制作したコード
  • 利用しての感想

制作物の概要

こんな感じの動作をします

  • センサから温度を取得
  • 取得した温度に応じてランプが点灯

今回はランプ(LED)を使って簡易表示をするようにしました。
というかこういうタイプのものに正確な数値の表示は不要じゃないかなと思っています。最近の気温が日常的に危険な温度なので数値にしても危機感が生じないのかなと考えています。
ということで今回の表示方法は信号機のような形にしました。

動作の条件

今回の危険度の判定については以下のサイトを参考に基準を設けました。
環境省熱中症予防情報サイト
ここを基準に

警戒する必要がない
緑(青)
警戒
厳重警戒
黄(点滅)
危険
超危険((オリジナル)35℃を超えたとき)
赤(点滅)

という条件で動作を分岐させました。

制作したコード

ということで今回作成したコードは以下のようになってます。

//ピンの定義
int TEMP=5;
//センサの値を格納する変数
int temp_value=0;
//気温条件の定義
int NOMAL=25;
int LEVEL1=28;
int LEVEL2=31;
int LEVEL3=35;
//繰り返しの制御を行う変数
int i=0;
//温度に応じてLEDを変化させる関数
int LED_switch(int *);
int LED_switch(int temp_value){
  //25℃以下のとき
  if(temp_value<NOMAL){
    //緑のLEDを接続したピンをHIGHに
    digitalWrite(9,HIGH);
  //警戒が必要なとき
  }else if(temp_value<LEVEL1){
    //黄のLEDを接続したピンをHIGHに
    digitalWrite(10,HIGH);
  //厳重警戒のとき
  }else if(temp_value<LEVEL2){
    //黄のLEDを点滅させる
    digitalWrite(10,HIGH);
    delay(100);
    digitalWrite(10,LOW);
  //危険なとき
  }else if(temp_value<LEVEL3){
    //赤のLEDを接続したピンをHIGHに
    digitalWrite(11,HIGH);
  //超危険なとき
  }else{
    //赤のLEDを点滅させる
    digitalWrite(11,HIGH);
    delay(50);
    digitalWrite(11,LOW);
  }
  return 0;
}
void setup() {
  //各ピンの設定
  pinMode(TEMP,INPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
  //シリアル通信の準備
  Serial.begin(9600);
}

void loop() {
  //温度を取得
  temp_value=analogRead(TEMP);
  //取得した温度から125引くと実際の温度として扱うことができる
  temp_value=temp_value-125;
  //シリアルに温度を送信
  Serial.println(temp_value) ;
  //シリアル通信用待機
  delay(400);
  //1分間同じ温度で扱う
  for(i=0;i<60;i++){
    //LEDを一度すべて消す
    digitalWrite(9,LOW);
    digitalWrite(10,LOW);
    digitalWrite(11,LOW);
    //LED制御部に温度を渡す
    LED_switch(temp_value);
    delay(1000);
  }
}

温度求める式のところはググってみたやつだと74℃とかになってて入ってくるデータをそのままで見て部屋の温度を測るのに使っている温度計との差を求めて使いました。

使っての感想

やっぱぱっと見でわかるの楽でした。
あくまでメイン作業が別である以上見てすぐ状態がつかめるのいいかも知んない

<python>設定情報を別ファイルで管理

はじめに

poolbooyer.hatenablog.jp
poolbooyer.hatenablog.jp
これのpart3はコードのブラッシュアップを勧めているのでもうちょっとかかるかもしれないです。多分今週中には書きます(フラグ)


今回はpythonについてです
ソフトウェアとか作るときにパラメータがその時によって変化したりおんなじコードで複数の条件を使ってやりたいときあるじゃないですか

そういうときに色んな方法で管理することができると思います。
独自の形式作って読み込むところから作るのも有りだとは思うのですが、設定情報について扱う形式にiniけ形式があります。
pythonだとそれを簡単に扱えるんでそれについてメモ

そもそもiniとは

INIファイルは構造の単純なテキストファイルであり、設定ファイルのフォーマットとしてよく使われている。
(参照元:wikipedia
INIファイル - Wikipedia )

くわしいことはwikipediaみてください。
windowsを中心に設定情報の管理に使われてるみたいです。

なぜiniを使うの

そこにConfigParserがあったから

っていう単純な理由です。
というかini形式での記述をやるとセクションなども用いて考えることでとても記述が簡単になるからです。(自分比)

ConfigParserって

pythonで標準で使えるモジュールです。
これで簡単にiniから情報を取得できます。

実際に使ってみよう

下準備

今回は何かを見るviewerアプリの設定ファイルを読み込むっていう設定でやっていきます。
まずは設定ファイルを記述します。
設定ファイルには使用するユーザの名前,IDとviewerを使うときにスケールを調整(拡大表示)したときの倍率情報とwindowの場所の情報が入っているという仮定で行こないます
以下のような記述を行います。
#iniファイルのハイライト表示は非対応でした、する必要もないだろうけど

#ファイル名はtest.ini
#設定ファイル
#USERセクション
[USER]
name=okapi
id=poolbooyer

#viewerセクション
[VIEWER]
scale=1.0
position=center

この設定情報を今回は読み込んでいきます。

pythonで読み込むスクリプトを記述

実際に読み込むスクリプトを書いていきます。
まずはクラスを読み込みます

import ConfigParser

その後はオブジェクトを作ります。

inifile=ConfigParser.SafeConfigParser()

その後には読み込むファイルの場所を記述します。(アスタリスク内に記述)

inifile.read('******')

その後は実際に読み込んでいきます。section nameにはセクション名,data nameにはデータの名前を記述します。

hoge=inifile.get('section name','data name')

こんな流れでデータが取れます。

実際に取得してみよう

先述の設定ファイルの情報を取得するスクリプトを書いてみました
以下のようになります。

#coding:utf-8
import ConfigParser

#設定読み込むオブジェクトを生成
inifile=ConfigParser.SafeConfigParser()

#読み込むファイルを記述
inifile.read('./test.ini')

#USERセクションの情報を読み込んで変数に代入
user_name=inifile.get('USER','name')
user_id=inifile.get('USER','id')

#VIEWERセクションの情報を読み込んで変数に代入
view_scale=inifile.get('VIEWER','scale')
view_position=inifile.get('VIEWER','position')

print("USER data\n")
print("USER NAME:"+user_name+"\n")
print("USER ID:"+user_id+"\n")
print("VIEWER data\n")
print("VIEWER SCALE:"+view_scale+"\n")
print("VIEWER POSITION:"+view_position+"\n")

これを実行すると
f:id:poolbooyer:20180802132537p:plain
こんな感じで取得できます。

まとめ

これを使うことで設定情報をわかり易く管理できるようになります。
書き換えなんかはファイル操作使えばできるんでそれでやればいいのかなとぼんやり考えています。
#基本変更する必要のないものを記述する予定なのであんまり関係ないのですが
configparser便利です。標準で使えるのがとても使いやすくていいなぁと思いました。