[卒業計画-2]Dummy Data Serverの作成

35535 ワード

現在進行中の卒業プロジェクトGithub組織住所.
https://github.com/smu-graduation-project
私の卒業プロジェクトの名前は「センサデータ収集に基づく監視システムの開発」です.

進捗


LoRaセンサのデータ処理は思ったより時間がかかり,タスクの割り当てができない.
したがって、Lora Dataではなくコードを記述してスタックデータをデータベースに格納することで、サーバの正常な稼働を推進したいと考えています.
バックエンドとフロントエンドは、これらのデータに基づいています.
lora gatewayからのデータを受信し、スタックデータのフォーマットに変換し、データベースを開発する順序で行います.
我々のプロジェクトはリアルタイムデータモニタリングシステムであるため,データベース内のデータを秒単位で更新することが重要であるため,テストのために他のフレームワークを用いずにJDBCベースで簡単な開発を行った.

データ構造


AUTO INCREMENTプロパティをdatatypedataname説明LongidPrimary Keyに追加しました.これはintportEndノードを区別するデータ、すなわちデータを区別するタイプと見なすことができる.intsequenceデータの順序.タイムスタンプデータ作成日.doubledata sensing data(dummy).
コードは次のとおりです.

Dummy Data Class


DBに送信するデータを整理するためのデータ構造.
自動生成されたidとdateのほかに、3つのデータがあります.
public class DummyData {

    /** id, port, sequence, date, data
     * port 별로 전압, 전류, 온도, 위치 값이 다르다.
     * sequence는 순서대로 1씩 증가한다.( sequence가 중간에 없는 경우는 sensor node에서 값을 제대로 보내지 못한 것이다.)
     * date는 이후에 날짜별로 데이터를 보여줘야 하는 경우 사용하면 좋을 것 같다.
     **/
	
    // DATA
	private int port;
    private int sequence;
    private double data; // 일단 double로 설정, 실제 데이터는 다를 수 있음.
    
    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public int getSequence() {
        return sequence;
    }

    public void setSequence(int sequence) {
        this.sequence = sequence;
    }

    public double getData() {
        return data;
    }

    public void setData(double data) {
        this.data = data;
    }
}

Random Dummy Data Class


仮想データの一部を作成します.
プロジェクトの目標は,計4つのセンサを用いてデータを感知することである.
データごとに適切な値を作成する必要があります.
そこで,int配列を用いて次のように処理する.
public class RandomDummyData {

    DummyData dummy = new DummyData(); // dummy data의 구조를 가지는 객체
    Random random = new Random();
   
   private int[] ports = {10,11,12,13}; // 총 4개의 data를 의미
    private int[] sequences = {1,1,1,1};

    public DummyData makeDummyData(int index) {
        dummy.setPort(ports[index]);
        dummy.setSequence(sequences[index]++);
        dummy.setData(random.nextDouble()*100);
        return dummy;
    }
    
    // table 초기화 진행시, sequence도 초기화 진행
    public void resetSequence() {
    	sequences = {1,1,1,1};
   	}
    // 데이터 누락 발생시, 테스트용
    public void addSequence(int index) {
    	sequences[index]++;
    }
    
    // 테이블 초기화시, sequence도 초기화
    public void resetData() {
    	sequences = int[] new {1,1,1,1};
    }
}

Main Class


以上のコードに基づいて生成するDummyデータは、
Main関数では、無限反復文を使用してデータをデータベースに永続的に格納するように構成します.
public class Main {
    public static int DELAYTIME = 1; //데이터 전송 주기

    public static void main(String[] args) throws Exception {

        JDBCController jdbcController = new JDBCController();
        RandomDummyData randomDummyData = new RandomDummyData();

        Reader reader = new FileReader(Main.class.getResource("").getPath()+"settingJDBC.json");
        JSONParser parser = new JSONParser();
        Object obj = parser.parse(reader);

        JSONObject settingJDBC = (JSONObject)obj;

        Random random = new Random();

        Connection conn = null;

        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection((String)settingJDBC.get("JDBCURL"), (String)settingJDBC.get("MYSQLID"), (String)settingJDBC.get("MYSQLPASSWORD"));
            Statement stmt = conn.createStatement();

        } catch (SQLException | ClassNotFoundException e) {
            e.printStackTrace();
        }

        Long id = Long.valueOf(0); // 이후 시간을 유동적으로 변경하기 위해 Long type으로 설정

        while(true) {
            // 참고 : 하루 = 86,400초
            while(id.longValue() < 100000) {
            	// 1/10000확률로 데이터를 넘기지 않는다.(sequence 문제 발생)
                int rand = random.nextInt(10000);
                // index를 기반으로 sequence, prot 설정
                if (rand != 1) {
         			jdbcController.pushDummyData(randomDummyData.makeDummyData(0), conn);			
                }               
                else {
                	randomDummyData.addSequence(0); 	
                }
                if (rand != 2) {
                	jdbcController.pushDummyData(randomDummyData.makeDummyData(1), conn);	
 				}
                else {
                	randomDummyData.addSequence(1); 	
                }
 				if (rand != 3) {
 					jdbcController.pushDummyData(randomDummyData.makeDummyData(2), conn);	
                }
                else {
                	randomDummyData.addSequence(2); 	
                }
				if (rand != 4) {
                	jdbcController.pushDummyData(randomDummyData.makeDummyData(3), conn);
                }
                else {
                	randomDummyData.addSequence(3); 	
                }
                id++;

                try {
                    // 딜레이 시간
                    TimeUnit.SECONDS.sleep(DELAYTIME);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            // 데이터의 지속적인 누적을 막기위해 테이블을 reset.
            System.out.println("reset table");
            randomDummyData.resetData();
            jdbcController.remakeTable(conn);
            id = Long.valueOf(0);
        }
    }
}

JDBC Controller Class


JDBC Controlは、各クエリーを関数としてDBに送信します.
dummyDataをparameterとして受信し、オブジェクトとしてDBにフォーマットでデータを送信します.
public class JDBCController {

    private Statement stmt;
    public void pushDummyData(DummyData dummyData, Connection conn) {
        // data 입력
        try {
            stmt = conn.createStatement();
            stmt.executeUpdate("INSERT INTO dummyData (" +
                    "port, sequence, date, data)" +
                    "values ("+dummyData.getPort()+", "+dummyData.getSequence()+", now(), "+String.format("%.3f", dummyData.getData())+");");

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // Table 제거 및 재생성
    public void remakeTable(Connection conn) {
        dropTable(conn);
        makeTable(conn);
    }

    private void makeTable(Connection conn) {
        // 테이블 만들기 (기준은 dummyData)
        try {
            stmt = conn.createStatement();
            stmt.executeUpdate(" CREATE TABLE dummyData ( " +
                    "id INT NOT NULL AUTO_INCREMENT," +
                    "port INT NOT NULL, " +
                    "sequence  INT NOT NULL," +
                    "date TIMESTAMP NOT NULL," +
                    "data DOUBLE," +
                    "PRIMARY KEY(id));");

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private void dropTable(Connection conn) {
        // 테이블 drop
        try {
            stmt = conn.createStatement();
            stmt.executeUpdate("DROP TABLE dummyData;");

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

実行結果


データベースのデータが正常に保存されているかどうかをリアルタイムで確認できます。