#include <string.h>  // 必要なヘッダーファイルをインクルード | Include necessary header files
#include "DHT.h"     // DHTセンサー用のライブラリをインクルード | Include library for DHT sensor

// ピン設定 | Pin assignments
#define GT_DTR 4 //DTR
#define GT_DSR 6 //DSR
#define GT_TRDY 7 //TRDY <--未使用 | Disused

#define DHT_SENSOR_PIN 10   // DHTセンサーのデータピン | Data pin for DHT sensor
#define DHT_SENSOR_TYPE DHT11  // 使用するDHTセンサーの型 | Type of DHT sensor being used

//変数 | Variable
float temperature;   //温度 | Temperature
float humidity;      //湿度 | Humidity

DHT dht(DHT_SENSOR_PIN, DHT_SENSOR_TYPE);  // DHTセンサーオブジェクトを作成 | Create DHT sensor object

////////////////////////////////////////////////////
// setup
////////////////////////////////////////////////////
void setup() {
  // ピン初期設定 | Pin settings
  pinMode(GT_DTR, INPUT);
  pinMode(GT_DSR, OUTPUT);
  pinMode(GT_TRDY, INPUT);
  digitalWrite(GT_TRDY, LOW);

  // シリアル通信設定 | Serial communication settings
  Serial.begin(38400);       // 38400bps Baud rate
  Serial.setTimeout(100);    // シリアルタイムアウト | Serial timeout
  dht.begin();               // DHTセンサーの初期化 | Initialize DHT sensor
}

////////////////////////////////////////////////////
// loop
////////////////////////////////////////////////////
void loop() {

  //温度と湿度の取得 | Get temperature and humidity
  temperature = dht.readTemperature(false); // trueならば華氏 それ以外は摂氏 | Fahrenheit if true, Celsius otherwise
  humidity = dht.readHumidity();

  if (isnan(humidity) || isnan(temperature)) {
    // センサーからの読み取りエラー時のメッセージ出力 | Output error message for sensor read failure
    gtsp_ObjPrpSet_string(1, 0x40, "Error");  //Object No.1 / 0x40 = Text0
    gtsp_ObjPrpSet_string(3, 0x40, "Error");  //Object No.3 / 0x40 = Text0
  }
  else{
    //温度と湿度の出力 | Output temperature and humidity
    gtsp_ObjPrpSet_string(1, 0x40, String(temperature,1) + " deg C");   //Object No.1 / 0x40 = Text0
    gtsp_ObjPrpSet_string(3, 0x40, String(humidity,0) + " %");          //Object No.3 / 0x40 = Text0
    
    if (temperature >= 21.0) { // 温度が21度以上の場合 | if temperature is 21 degrees Celsius or higher
      gtsp_ObjPrpSet_val(1, 0x50, 4, 0x00FF0000); // オブジェクト1の色を赤に設定 (例: RGBAで 0xFF0000FF = 赤) | Set object 1 color to red (e.g. 0xFF0000FF = red in RGBA)
    } else { // デフォルトの色を設定 | Set default color)
      gtsp_ObjPrpSet_val(1, 0x50, 4, 0x0000FF00); // オブジェクト1の色を緑に設定 | Set object 1 color to green
    }

    if (humidity < 36) { // 湿度が36未満場合 | If humidity is less than 36
      gtsp_ObjPrpSet_val(3, 0x50, 4, 0x00FF0000); // オブジェクト3の色を赤に設定 | Set object 3 color to red
    } else { // デフォルトの色を設定 | Set default color)
      gtsp_ObjPrpSet_val(3, 0x50, 4, 0x0000FF00); // オブジェクト3の色を緑に設定 | Set object 3 color to green
    }

    int tempbar = map(temperature, 0, 30, 0, 100); // 温度を0から30度を0から100の範囲にマッピング | Mapping temperature from 0 to 30 degrees Celsius in the range 0 to 100
    gtsp_ObjPrpSet_val(4, 0x10, 4, tempbar); // Object No.4 / 0x10 = Bar0
      
    int humbar = map(humidity, 0, 100, 0, 100); // 湿度を0から100%を0から100の範囲にマッピング | Mapping humidity from 0 to 100% in the range 0 to 100
    gtsp_ObjPrpSet_val(5, 0x10, 4, humbar); // Object No.5 / 0x10 = Bar1
  }

  delay(2000);
}




/********************** 関数 | Function **********************/
////////////////////////////////////////////////////
//  オブジェクト制御コマンド-プロパティ設定（数値用） | Object Control Command -Property Setting (for Value)
//  (バイト長4バイトまで | Byte length is up to 4 byte)
////////////////////////////////////////////////////
void gtsp_ObjPrpSet_val(int obj, int prp, int ln, unsigned long val )
{
  gt_print("CMD");        //コマンドヘッダ | Command header
  gt_put(0xd3);           //オブジェクト-プロパティ設定コマンド | Object-Property Setting
  gt_put(obj >> 0);    //オブジェクトNo. 下位バイト | Object No. Lower byte
  gt_put(obj >> 8);    //オブジェクトNo. 上位バイト| Object No. Upper byte
  gt_put(prp >> 0 );    //プロパティNo. 下位バイト | Property No. Lower byte 
  gt_put(prp >> 8);    //プロパティNo. 上位バイト| Property No. Upper byte 
  gt_put(ln >> 0);             //データ長 最下位バイト | Data length Least significant byte
  gt_put(ln >> 8);     //データ長 下位バイト | Data length second byte
  gt_put(ln >> 16);   //データ長 上位バイト | Data length third byte
  gt_put(ln >> 24);         //データ長 最上位バイト| Data length Most significant byte        
 if (ln >=1){ gt_put(val >> 0); }             //データ 最下位バイト | Data Least significant byte
  if (ln >=2){ gt_put(val >> 8); }     //データ 下位バイト | Data second byte
  if (ln >=3){ gt_put(val >> 16); }   //データ 上位バイト | Data third byte
  if (ln >=4){ gt_put(val >> 24); }         //データ 最上位バイト| Data Most significant byte
}


////////////////////////////////////////////////////
//  オブジェクト制御コマンド - プロパティ設定 (文字列用) | Object Control Command -Property Setting (for String)
////////////////////////////////////////////////////
void gtsp_ObjPrpSet_string(int obj, int prp, String val )
{
  gt_print("CMD");     //コマンドヘッダ | Command header
  gt_put(0xd3);        //オブジェクト-プロパティ設定コマンド | Object-Property Setting
  gt_put(obj >> 0);    //オブジェクトNo. 下位バイト | Object No. Lower byte
  gt_put(obj >> 8);    //オブジェクトNo. 上位バイト| Object No. Upper byte
  gt_put(prp >> 0);    //プロパティNo. 下位バイト | Property No. Lower byte 
  gt_put(prp >> 8);    //プロパティNo. 上位バイト| Property No. Upper byte 
  gt_put(val.length() >> 0);    //データ長 最下位バイト | Data length Least significant byte
  gt_put(val.length() >> 8);    //データ長 下位バイト | Data length second byte
  gt_put(val.length() >> 16);   //データ長 上位バイト | Data length third byte
  gt_put(val.length() >> 24);   //データ長 最上位バイト| Data length Most significant byte
  gt_print(val);       //文字列送信 | Send String
}

////////////////////////////////////////////////////
//  1byte送信 | Send byte to GT-SP
////////////////////////////////////////////////////
void gt_put(unsigned char onebyte)
{
  while ( digitalRead(GT_DTR) == HIGH ) {}  //busycheck
  Serial.write(onebyte);
}

////////////////////////////////////////////////////
//  文字列送信 | Send String to GT-SP
////////////////////////////////////////////////////
void gt_print(String val)
{
  int val_i;
  //文字列を1文字ずつ送信 | Send string per one byte
  for (val_i = 0; val_i < val.length(); val_i++)
  {
    while ( digitalRead(GT_DTR) == HIGH ) {}  //busycheck
    Serial.print(val.substring(val_i, val_i+1));
  }
}
