サポーターズ主催の技育CAMPに参加しての感想(企業賞受賞！) ③

---
<font color="orange">サポーターズ</font>主催の技育CAMPに参加しての感想 ③
---

**ダース・ベイダーサイド**

正直スターウォーズは見たことがない。

見ようとは思っているが時間がない。

だがダース・ベイダーは知っている。

なんか黒いやつだ。

多分、ラスボスだ。

なんとなくデータベースと語感が似ている。

多分なんか保管してくれるんだろう。

あとアース・ネイチャーにも似ている。

多分蚊を亡きモノにしてくれるんだろう。

あとナイスネイチャにも似ている。

多分可愛いんだろう。

まとめると

ダース・ベイダーは
黒くて、なんか保管する、蚊をやっつける可愛いラスボスなのです。多分。
<br>

**目次**
- [1. ハードサイド](#1-ハードサイド)
- [2. データベースサイド](#2-データベースサイド)
- [3. おわりに](#3-おわりに)

## 1. ハードサイド

<font color="banana">**ラズベリーパイを使用した傾斜検知システムの開発**</font>

<font color="low blue">**はじめに**</font>
　この記事では、ラズベリーパイと傾斜スイッチを使用して傾斜を検知し、その情報を`AWS` `S3`バケットに保存するシステムの開発過程について詳しく解説します。

この記事は[前々回](https://qiita.com/come/items/40f778f59081118cd6f0)と[前回](https://qiita.com/come/items/af94dff3c6764e54abee)の続きです。

<font color="low blue">**ハードウェアの設計とチャレンジ**</font>

　プロジェクトのハードウェア部分では、ラズベリーパイと傾斜スイッチを中心に設計を行いました。
 
 　傾斜スイッチは、その傾きによってON/OFFが切り替わる装置で、傾斜を検知するためのシンプルで効果的な方法を提供します。

　チームメンバーからのフィードバックによると、最適な傾斜センサーを見つける過程はやや挑戦的であったものの、ラズベリーパイに関する大きな問題は発生しなかったとのことです。
 
 　しかし、最終調整時にディスプレイやマウスが利用できない状況は困難でした。


<font color="low blue">**ソフトウェアの実装
ジ**</font>

　プロジェクトのソフトウェア部分では、`Go言語`を使用して`AWS` `S3`バケットにデータを保存する機能を実装しました。
 
 　このコードは、傾斜スイッチの状態に応じて`LED`の色を変更し、傾斜が検知された際にはその情報を`S3`バケットにアップロードします。
  
  　このプロセスにより、データのクラウド上での管理とアクセスが容易になります。


ハードサイドのコードはこちらです。
[ハードサイドのGithub](https://github.com/kknowk/SDK)


<font color="low blue">**学んだことと結論**</font>

　このプロジェクトを通じて、チームはラズベリーパイと傾斜スイッチを用いたハードウェアの設計、`Go言語`と`AWS` `S3`の統合、そして`Gin`フレームワークを活用した開発に関する貴重な経験を得ました。
 
 　ハードウェアとソフトウェアの両面で遭遇した課題を乗り越えることで、物理的なデバイスとクラウドサービスを組み合わせたアプリケーションの開発における実践的な知識とスキルを深めることができました。

## 2. データベースサイド
<font color="banana">**AWSバケットを利用したデータベース設計の挑戦と解決策**</font>

<font color="low blue">**AWSとGo言語の組み合わせ**</font>

　このプロジェクトでは、`AWS`のバケットをデータベースとして利用しました。
 
 　`Go言語`で提供される`AWS` `SDK`を使用することで、初期設定を簡単かつ迅速に行うことができました。`Go言語`のシンプルさと`AWS` `SDK`の使いやすさが相まって、クラウドストレージの設定とデータ管理が効率的に実施できました。


<font color="low blue">**認証情報の設定における挑戦**</font>

　しかし、プロジェクトを進める過程でいくつかの課題に直面しました。
 
 　特に、`AWS`アカウントの登録と、アクセスキー及びシークレットアクセスキーを環境変数として設定する方法の理解までが大変でした。
  
  　これらの認証情報の正しい設定は、`AWS`リソースへの安全なアクセスを確保するために不可欠です。

　適切な方法を学んだ後は、プロセスがずっと簡単になりましたが、その学習曲線は初心者にとってはやや険しいものでした。

<font color="low blue">**従量課金制度に対する懸念**</font>

　また、`AWS`の従量課金制度に関する懸念もありました。
 
 　無料枠を超えると追加料金が発生するため、`GET`や`POST`のリクエスト数を慎重に管理しながらプロジェクトを進める必要がありました。
  
  　この制度は、コスト管理に対する意識を高めるとともに、リソースの利用効率を最適化する動機付けとなりました。

<font color="low blue">**データ保存方法の工夫**</font>

　データ構造に関しては、`LINE`のユーザー`ID`とラズパイの`ID`、さらに鍵の開閉状態とその時間を保存するための工夫が施されました。

　これらの情報はキーとバリューの形式で保存され、ラズパイから送信されたデータを適切なユーザーに割り当てることが可能になりました。
 
 　この方法により、データの整理とアクセスの効率化が実現しました。

<font color="low blue">**コード例**</font>

　以下は今回使用した、」バケットへの保存と取得の実装コードです。
 
```go

// ユーザーIDとMACアドレスの紐付けをS3に保存
func AssociateUserWithMacAddress(userID, macAddress string) {
	client := initS3Client()

	bucket := "magickeybucket"                       // 適切なバケット名に設定
	key := fmt.Sprintf("UserDevices/%s.txt", "testUserID") // ファイル名（ここではuserIDを使用）
	body := fmt.Sprintf("UserID: %s, MacAddress: %s", userID, macAddress)

	_, err := client.PutObject(context.TODO(), &s3.PutObjectInput{
		Bucket: aws.String(bucket),
		Key:    aws.String(key),
		Body:   strings.NewReader(body),
	})
	if err != nil {
		fmt.Println("Failed to upload to S3:", err)
	} else {
		fmt.Println("Successfully uploaded to S3")
	}
}

// 指定されたMACアドレスに対応するユーザーIDをS3バケットから取得
func FindUserIDByMacAddress(macAddress string) (string, error) {
	client := initS3Client()
	if client == nil {
		return "", fmt.Errorf("Failed to initialize S3 client")
	}

	bucket := "magickeybucket"                             // バケット名を設定
	key := fmt.Sprintf("UserDevices/%s.txt", "testUserID") // MACアドレスに基づくファイルパス

	// S3からファイルを取得
	output, err := client.GetObject(context.TODO(), &s3.GetObjectInput{
		Bucket: aws.String(bucket),
		Key:    aws.String(key),
	})
	if err != nil {
		return "", fmt.Errorf("Failed to get object from S3: %v", err)
	}
	defer output.Body.Close()

	// ファイルの内容を読み込む
	body, err := io.ReadAll(output.Body)
	if err != nil {
		return "", fmt.Errorf("Failed to read object body: %v", err)
	}

	// ファイルの内容を文字列に変換
	content := string(body)

	// 文字列を解析してUserIDを取得
	var userID string
	parts := strings.Split(content, ",")
	for _, part := range parts {
		// "UserID: "で始まる部分を探す
		if strings.HasPrefix(part, "UserID: ") {
			userID = strings.TrimSpace(strings.TrimPrefix(part, "UserID: "))
			break
		}
	}

	if userID == "" {
		return "", fmt.Errorf("UserID not found in object body")
	}

	return userID, nil
}
```

　このコードは、`AWS`の`S3`サービスを使ってユーザー`ID`と`MAC`アドレスを紐付けて保存し、後でそれを検索する機能を提供します。具体的には:

- 保存: ユーザー`ID`と`MA`Cアドレスを組み合わせた情報を`S3`の特定のファイルに保存します。

- 検索: 指定した`MAC`アドレスに基づいて、対応するユーザー`ID`を`S3`から探し出します。


<font color="low blue">**結論**</font>

　`AWS`のバケットを使用したデータベース設計は、多くの学びとともにいくつかの挑戦を提供しました。

　`Go言語`と`AWS` `SDK`の組み合わせは初期設定を容易にし、データ保存方法の工夫により効率的なデータ管理を実現しました。
 
　しかし、認証情報の設定と従量課金制度は、特に注意を要する領域でした。
 
　このプロジェクトを通じて、クラウドベースのアプリケーション開発における重要な側面について深い理解を得ることができました。

## 3. おわりに

　このハッカソンを通じて、多岐にわたる学びを得ることができました。
 
 　特に、これまで学んできた知識の応用により、実用的なサービスを開発する経験は大きな喜びをもたらしました。
  
  　今後もこのようなプロジェクトに取り組むことで、さらなる成長と発展を目指したいと思います。