From e1c8cb365f7ad86537df05d3afb9002408020f6c Mon Sep 17 00:00:00 2001 From: dije07 <71131378+dije07@users.noreply.github.com> Date: Mon, 1 Apr 2024 16:30:32 +0700 Subject: [PATCH] Delete Thesis_Code directory --- .../docker-compose.yaml | 44 -- Thesis_Code/gateway-classification/go.mod | 37 -- Thesis_Code/gateway-classification/go.sum | 69 ---- Thesis_Code/gateway-classification/main.go | 28 -- .../mqtt/config/mosquitto.conf | 7 - Thesis_Code/gateway-classification/readme.md | 44 -- .../src/classify/complex.go | 112 ----- .../src/classify/elmClassifier.go | 1 - .../src/classify/elmModel.go | 96 ----- .../src/classify/hrvFeature.go | 255 ------------ .../src/database/database.go | 111 ----- .../src/entity/entity.go | 76 ---- .../src/handler/handler.go | 353 ---------------- .../gateway-classification/src/mqtt/mqtt.go | 96 ----- Thesis_Code/quantification/go.mod | 17 - Thesis_Code/quantification/go.sum | 32 -- Thesis_Code/quantification/quantification.go | 390 ------------------ 17 files changed, 1768 deletions(-) delete mode 100644 Thesis_Code/gateway-classification/docker-compose.yaml delete mode 100644 Thesis_Code/gateway-classification/go.mod delete mode 100644 Thesis_Code/gateway-classification/go.sum delete mode 100644 Thesis_Code/gateway-classification/main.go delete mode 100644 Thesis_Code/gateway-classification/mqtt/config/mosquitto.conf delete mode 100644 Thesis_Code/gateway-classification/readme.md delete mode 100644 Thesis_Code/gateway-classification/src/classify/complex.go delete mode 100644 Thesis_Code/gateway-classification/src/classify/elmClassifier.go delete mode 100644 Thesis_Code/gateway-classification/src/classify/elmModel.go delete mode 100644 Thesis_Code/gateway-classification/src/classify/hrvFeature.go delete mode 100644 Thesis_Code/gateway-classification/src/database/database.go delete mode 100644 Thesis_Code/gateway-classification/src/entity/entity.go delete mode 100644 Thesis_Code/gateway-classification/src/handler/handler.go delete mode 100644 Thesis_Code/gateway-classification/src/mqtt/mqtt.go delete mode 100644 Thesis_Code/quantification/go.mod delete mode 100644 Thesis_Code/quantification/go.sum delete mode 100644 Thesis_Code/quantification/quantification.go diff --git a/Thesis_Code/gateway-classification/docker-compose.yaml b/Thesis_Code/gateway-classification/docker-compose.yaml deleted file mode 100644 index c23ef5d..0000000 --- a/Thesis_Code/gateway-classification/docker-compose.yaml +++ /dev/null @@ -1,44 +0,0 @@ -## Docker Testing - -version: "3.7" -services: - mqtt-broker: - image: eclipse-mosquitto - container_name: mqtt-broker - ports: - - "1883:1883" #default mqtt port - - "9001:9001" #default mqtt port for websockets - volumes: - - ./mqtt/config:/mosquitto/config - - ./mqtt/data:/mosquitto/data - - ./mqtt/log:/mosquitto/log/mosquitto.log - - mqtt-client: - image: emqx/mqttx-web - container_name: mqtt-client - ports: - - "9000:80" - - db: - container_name: db - image: postgres:14.1-alpine - restart: always - environment: - - POSTGRES_USER=postgres - - POSTGRES_PASSWORD=postgres - ports: - - '5432:5432' - volumes: - - db:/var/lib/postgresql/data - - -volumes: - config: - data: - log: - db: - -networks: - default: - name: mqtt - external: true \ No newline at end of file diff --git a/Thesis_Code/gateway-classification/go.mod b/Thesis_Code/gateway-classification/go.mod deleted file mode 100644 index 1db4231..0000000 --- a/Thesis_Code/gateway-classification/go.mod +++ /dev/null @@ -1,37 +0,0 @@ -module github.com/stanleydv12/gateway-classification - -go 1.21.3 - -require ( - github.com/eclipse/paho.mqtt.golang v1.4.3 - github.com/galeone/tensorflow/tensorflow/go v0.0.0-20221023090153-6b7fa0680c3e - github.com/galeone/tfgo v0.0.0-20230715013254-16113111dc99 - github.com/joho/godotenv v1.5.1 - github.com/mitchellh/mapstructure v1.5.0 -) - -require ( - github.com/chzyer/readline v1.5.1 // indirect - github.com/google/go-cmp v0.5.8 // indirect - github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect - github.com/gorilla/websocket v1.5.1 // indirect - github.com/ianlancetaylor/demangle v0.0.0-20240205174729-1f824a1a9b87 // indirect - github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect - github.com/jackc/pgx/v5 v5.4.3 // indirect - github.com/stretchr/testify v1.8.4 // indirect - github.com/tensorflow/tensorflow v2.15.0+incompatible // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.17.0 // indirect -) - -require ( - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jinzhu/now v1.1.5 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/text v0.14.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect - gorm.io/driver/postgres v1.5.4 - gorm.io/gorm v1.25.5 -) diff --git a/Thesis_Code/gateway-classification/go.sum b/Thesis_Code/gateway-classification/go.sum deleted file mode 100644 index 10c9ea0..0000000 --- a/Thesis_Code/gateway-classification/go.sum +++ /dev/null @@ -1,69 +0,0 @@ -github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= -github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= -github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= -github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik= -github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE= -github.com/galeone/tensorflow/tensorflow/go v0.0.0-20221023090153-6b7fa0680c3e h1:9+2AEFZymTi25FIIcDwuzcOPH04z9+fV6XeLiGORPDI= -github.com/galeone/tensorflow/tensorflow/go v0.0.0-20221023090153-6b7fa0680c3e/go.mod h1:TelZuq26kz2jysARBwOrTv16629hyUsHmIoj54QqyFo= -github.com/galeone/tfgo v0.0.0-20230715013254-16113111dc99 h1:8Bt1P/zy1gb37L4n8CGgp1qmFwBV5729kxVfj0sqhJk= -github.com/galeone/tfgo v0.0.0-20230715013254-16113111dc99/go.mod h1:3YgYBeIX42t83uP27Bd4bSMxTnQhSbxl0pYSkCDB1tc= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= -github.com/ianlancetaylor/demangle v0.0.0-20240205174729-1f824a1a9b87 h1:IG+58MeF0K/wSXknV4FMOABt6B4VZCguRDxYSCJqWb4= -github.com/ianlancetaylor/demangle v0.0.0-20240205174729-1f824a1a9b87/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= -github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= -github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= -github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/tensorflow/tensorflow v2.15.0+incompatible h1:qWaan+jC2rrHctJliI+TSAwLGdCoQdsrwN7YddLv81Y= -github.com/tensorflow/tensorflow v2.15.0+incompatible/go.mod h1:itOSERT4trABok4UOoG+X4BoKds9F3rIsySdn+Lvu90= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/postgres v1.5.4 h1:Iyrp9Meh3GmbSuyIAGyjkN+n9K+GHX9b9MqsTL4EJCo= -gorm.io/driver/postgres v1.5.4/go.mod h1:Bgo89+h0CRcdA33Y6frlaHHVuTdOf87pmyzwW9C/BH0= -gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= -gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= diff --git a/Thesis_Code/gateway-classification/main.go b/Thesis_Code/gateway-classification/main.go deleted file mode 100644 index 170e20d..0000000 --- a/Thesis_Code/gateway-classification/main.go +++ /dev/null @@ -1,28 +0,0 @@ -package main - -import ( - "github.com/stanleydv12/gateway-classification/src/database" - "github.com/stanleydv12/gateway-classification/src/handler" - "github.com/stanleydv12/gateway-classification/src/mqtt" -) - -// main initializes the database and MQTT setup, then starts listening for MQTT messages. -// -// No parameters. -// No return types. -func main() { - // Setup Database - db := database.SetupDatabase() - handler.SetDBInstance(db) - - // Setup Mqtt - mqtt.SetupMqtt() - - // Application set to listen - mqtt.Sub(mqtt.Client) - - handler.StartTimer() - - // Block the main function with a select statement - select {} -} diff --git a/Thesis_Code/gateway-classification/mqtt/config/mosquitto.conf b/Thesis_Code/gateway-classification/mqtt/config/mosquitto.conf deleted file mode 100644 index 7e1ceef..0000000 --- a/Thesis_Code/gateway-classification/mqtt/config/mosquitto.conf +++ /dev/null @@ -1,7 +0,0 @@ -persistence true -persistence_location /mosquitto/data/ -log_dest file /mosquitto/log/mosquitto.log -allow_anonymous true -listener 1883 0.0.0.0 -listener 9001 0.0.0.0 -protocol websockets diff --git a/Thesis_Code/gateway-classification/readme.md b/Thesis_Code/gateway-classification/readme.md deleted file mode 100644 index ac25eba..0000000 --- a/Thesis_Code/gateway-classification/readme.md +++ /dev/null @@ -1,44 +0,0 @@ -# Panduan Setup MQTT - -Berikut adalah langkah-langkah untuk melakukan setup pada MQTT: -1. Buatlah folder mqtt yang didalamnya terdapat 3 folder lain yaitu config, data, dan log. -2. Lalu konfigurasi mqtt sesuai kebutuhan pada folder mqtt -> config -> mosquitto.conf - -# Panduan Menjalankan Dockerfile - -Berikut adalah langkah-langkah untuk menjalankan Dockerfile dan membangun image Docker: - -## Langkah 1: Build Docker Image - -```bash -docker build -t myapp . -``` - -## Langkah 2: Kirim Image ke Registry Cloud -```bash -docker login -docker tag : //: -``` - -# Panduan Instalasi Kubernetes Cluster menggunakan Terraform - -Berikut adalah langkah-langkah untuk menggunakan Terraform untuk menerapkan kluster Kubernetes di lingkungan Anda. - -## Persyaratan Sebelum Instalasi: - -1. Pastikan Anda memiliki akun layanan cloud (seperti AWS, GCP, atau Azure) dan telah mengkonfigurasi kredensial akses yang sesuai. -2. Instalasi Terraform di komputer lokal Anda. Anda dapat mengunduh Terraform dari situs web resmi mereka. Direkomendasikan menggunakan Google Cloud Console dimana sudah terdapat instalasi terraform nya. - -## Langkah-langkah: - -```bash -$ terraform init -$ terraform plan -$ terraform apply -``` - -# Panduan Testing - -Berikut adalah langkah-langkah untuk melakukan testing menggunakan JMeter: -1. Tambahkan plugin MQTT yang terdapat di folder infrastructure pada JMeter. -2. Lalu open file dengan tipe .jmx pada folder infrastructure tersebut. diff --git a/Thesis_Code/gateway-classification/src/classify/complex.go b/Thesis_Code/gateway-classification/src/classify/complex.go deleted file mode 100644 index 95a9552..0000000 --- a/Thesis_Code/gateway-classification/src/classify/complex.go +++ /dev/null @@ -1,112 +0,0 @@ -package classify - -import ( - "fmt" - "math" -) - -type Complex struct { - Re float64 // the real part - Im float64 // the imaginary part -} - -// create a new object with the given real and imaginary parts -func NewComplex(real, imag float64) Complex { - return Complex{Re: real, Im: imag} -} - -// return a string representation of the invoking Complex object -func (c Complex) String() string { - if c.Im == 0 { - return fmt.Sprintf("%g", c.Re) - } - if c.Re == 0 { - return fmt.Sprintf("%gi", c.Im) - } - if c.Im < 0 { - return fmt.Sprintf("%g - %gi", c.Re, -c.Im) - } - return fmt.Sprintf("%g + %gi", c.Re, c.Im) -} - -// return abs/modulus/magnitude -func (c Complex) Abs() float64 { - return math.Hypot(c.Re, c.Im) -} - -// return a new Complex object whose value is (this + b) -func (c Complex) Plus(b Complex) Complex { - return Complex{c.Re + b.Re, c.Im + b.Im} -} - -// return a new Complex object whose value is (this - b) -func (c Complex) Minus(b Complex) Complex { - return Complex{c.Re - b.Re, c.Im - b.Im} -} - -// return a new Complex object whose value is (this * b) -func (c Complex) Times(b Complex) Complex { - return Complex{c.Re*b.Re - c.Im*b.Im, c.Re*b.Im + c.Im*b.Re} -} - -// return a new Complex object whose value is the reciprocal of this -func (c Complex) Reciprocal() Complex { - scale := c.Re*c.Re + c.Im*c.Im - return Complex{c.Re / scale, -c.Im / scale} -} - -// return a / b -func (c Complex) Divides(b Complex) Complex { - return c.Times(b.Reciprocal()) -} - -// return a new Complex object whose value is the complex sine of this -func (c Complex) Sin() Complex { - return Complex{math.Sin(c.Re) * math.Cosh(c.Im), math.Cos(c.Re) * math.Sinh(c.Im)} -} - -// return a new Complex object whose value is the complex cosine of this -func (c Complex) Cos() Complex { - return Complex{math.Cos(c.Re) * math.Cosh(c.Im), -math.Sin(c.Re) * math.Sinh(c.Im)} -} - -// equals returns true if the given Complex object is equal to the receiver -func (c Complex) Equals(x Complex) bool { - return c.Re == x.Re && c.Im == x.Im -} - -// FFT computes the FFT of a complex sequence x[] of length n. -func FFT(x []Complex) []Complex { - n := len(x) - if n == 1 { - return []Complex{x[0]} - } - - if n%2 != 0 { - panic("n is not a power of 2") - } - - // Compute FFT of even terms - even := make([]Complex, n/2) - for k := 0; k < n/2; k++ { - even[k] = x[2*k] - } - q := FFT(even) - - // Compute FFT of odd terms - odd := even // Reuse the array - for k := 0; k < n/2; k++ { - odd[k] = x[2*k+1] - } - r := FFT(odd) - - // Combine - y := make([]Complex, n) - for k := 0; k < n/2; k++ { - kth := -2 * math.Pi * float64(k) / float64(n) - wk := Complex{math.Cos(kth), math.Sin(kth)} - y[k] = q[k].Plus(wk.Times(r[k])) - y[k+n/2] = q[k].Minus(wk.Times(r[k])) - } - return y -} \ No newline at end of file diff --git a/Thesis_Code/gateway-classification/src/classify/elmClassifier.go b/Thesis_Code/gateway-classification/src/classify/elmClassifier.go deleted file mode 100644 index f41f72d..0000000 --- a/Thesis_Code/gateway-classification/src/classify/elmClassifier.go +++ /dev/null @@ -1 +0,0 @@ -package classify \ No newline at end of file diff --git a/Thesis_Code/gateway-classification/src/classify/elmModel.go b/Thesis_Code/gateway-classification/src/classify/elmModel.go deleted file mode 100644 index d938952..0000000 --- a/Thesis_Code/gateway-classification/src/classify/elmModel.go +++ /dev/null @@ -1,96 +0,0 @@ -package classify - -import ( - "errors" - "io/ioutil" - "strconv" - "strings" -) - -type RealMatrix struct { - Rows int - Cols int - Data [][]float64 -} - -type Weight struct { - W RealMatrix - BW RealMatrix -} - -type ELMModel struct { - InputWeight RealMatrix - BiasInputWeight RealMatrix - OutputWeight RealMatrix - Separator string -} - -func NewELMModel(inputWeightFilePath, outputWeightFilePath string) (*ELMModel, error) { - var elmModel ELMModel - - inputWeightFileBytes, err := ioutil.ReadFile(inputWeightFilePath) - if err != nil { - return nil, err - } - - outputWeightFileBytes, err := ioutil.ReadFile(outputWeightFilePath) - if err != nil { - return nil, err - } - - inputWeightFileLines := strings.Split(string(inputWeightFileBytes), "\n") - outputWeightFileLines := strings.Split(string(outputWeightFileBytes), "\n") - - weight, err := convertListCsvTo2dArr(inputWeightFileLines, true) - if err != nil { - return nil, err - } - elmModel.InputWeight = weight.W - elmModel.BiasInputWeight = weight.BW - - weight, err = convertListCsvTo2dArr(outputWeightFileLines, false) - if err != nil { - return nil, err - } - elmModel.OutputWeight = weight.W - - return &elmModel, nil -} - -func convertListCsvTo2dArr(input []string, useBias bool) (Weight, error) { - var weight Weight - - listSize := len(input) - if listSize == 0 { - return weight, errors.New("empty input list") - } - - csvElementSize := len(strings.Split(input[0], ",")) - for _, line := range input { - if len(strings.Split(line, ",")) != csvElementSize { - return weight, errors.New("invalid CSV length") - } - } - - weightData := make([][]float64, listSize) - biasWeightData := make([][]float64, listSize) - - for i, line := range input { - splittedLine := strings.Split(line, ",") - temp := make([]float64, len(splittedLine)) - for j, val := range splittedLine { - temp[j], _ = strconv.ParseFloat(strings.TrimSpace(val), 64) - } - if useBias { - weightData[i] = temp[:len(temp)-1] - biasWeightData[i] = []float64{temp[len(temp)-1]} - } else { - weightData[i] = temp - } - } - - weight.W = RealMatrix{Rows: listSize, Cols: len(weightData[0]), Data: weightData} - weight.BW = RealMatrix{Rows: listSize, Cols: 1, Data: biasWeightData} - - return weight, nil -} diff --git a/Thesis_Code/gateway-classification/src/classify/hrvFeature.go b/Thesis_Code/gateway-classification/src/classify/hrvFeature.go deleted file mode 100644 index ea98e52..0000000 --- a/Thesis_Code/gateway-classification/src/classify/hrvFeature.go +++ /dev/null @@ -1,255 +0,0 @@ -package classify - -import ( - "math" - "sort" -) - -type HRVFeature struct { - F01_AVNN float64 - F02_SDNN float64 - F03_RMSSD float64 - F04_SDSD float64 - F05_NNx float64 - F06_PNNx float64 - F07_HRV_TRIANGULAR_IDX float64 - F08_SD1 float64 - F09_SD2 float64 - F10_SD1_SD2_RATIO float64 - F11_S float64 - F12_TP float64 - F13_pLF float64 - F14_pHF float64 - F15_LFHFratio float64 - F16_VLF float64 - F17_LF float64 - F18_HF float64 -} - -func NewHRVFeature(rrIntervalSet RRIntervalSet) *HRVFeature { - var hrv HRVFeature - - rrIntervalValue := rrIntervalSet.RRIntervalValue - rrIntervalsValueDiff := rrIntervalSet.RRIntervalsValueDiff - - hrv.F01_AVNN = f01_AVNN(rrIntervalValue) - hrv.F02_SDNN = f02_SDNN(rrIntervalValue) - hrv.F03_RMSSD = f03_RMSSD(rrIntervalsValueDiff) - hrv.F04_SDSD = f04_SDSD(rrIntervalsValueDiff) - hrv.F05_NNx = f05_NNx(rrIntervalsValueDiff, 50) - hrv.F06_PNNx = f06_PNNx(rrIntervalValue, hrv.F05_NNx) - hrv.F07_HRV_TRIANGULAR_IDX = f07_HRV_TRIANGULAR_IDX(rrIntervalValue) - hrv.F08_SD1 = f08_SD1(hrv.F04_SDSD) - hrv.F09_SD2 = f09_SD2(hrv.F02_SDNN, hrv.F04_SDSD) - hrv.F10_SD1_SD2_RATIO = f10_SD1_SD2_RATIO(hrv.F08_SD1, hrv.F09_SD2) - hrv.F11_S = f11_S(hrv.F08_SD1, hrv.F09_SD2) - - feature12To18 := f12_18(rrIntervalValue, 2) - hrv.F12_TP = feature12To18.TP - hrv.F13_pLF = feature12To18.pLF - hrv.F14_pHF = feature12To18.pHF - hrv.F15_LFHFratio = feature12To18.LFHFratio - hrv.F16_VLF = feature12To18.VLF - hrv.F17_LF = feature12To18.LF - hrv.F18_HF = feature12To18.HF - - return &hrv -} - -func f01_AVNN(rrIntervalValue []float64) float64 { - return mean(rrIntervalValue) -} - -func f02_SDNN(rrIntervalValue []float64) float64 { - return sampleStandardDeviation(rrIntervalValue) -} - -func f03_RMSSD(rrIntervalsValueDiff []float64) float64 { - return math.Sqrt(mean(powList(rrIntervalsValueDiff, 2))) -} - -func f04_SDSD(rrIntervalsValueDiff []float64) float64 { - return sampleStandardDeviation(rrIntervalsValueDiff) -} - -func f05_NNx(rrIntervalsValueDiff []float64, x float64) float64 { - count := filterCount(mulList(rrIntervalsValueDiff, 1000), func(y float64) bool { - return y > x - }) - return float64(count) -} - -func f06_PNNx(rrIntervalValue []float64, NNx float64) float64 { - return (NNx / (float64(len(rrIntervalValue)) - 1)) * 100 -} - -func f07_HRV_TRIANGULAR_IDX(rrIntervalValue []float64) float64 { - binSize := 7.812 - var tempRr []float64 - for _, val := range rrIntervalValue { - tempRr = append(tempRr, val*1000) - } - - sort.Float64s(tempRr) - maxVal := tempRr[len(tempRr)-1] - minVal := tempRr[0] - - binCount := math.Ceil((maxVal - minVal) / binSize) - edges := make([]float64, int(binCount)+1) - var Nds []float64 - edges[0] = minVal - - for i := 1; i <= int(binCount); i++ { - edges[i] = edges[i-1] + binSize - var d float64 - for _, x := range tempRr { - if x >= edges[i-1] && x < edges[i] { - d++ - } - } - if d != 0 { - Nds = append(Nds, d) - } - } - - return max(Nds) / sum(Nds) -} - -func f08_SD1(sdsd float64) float64 { - return math.Sqrt(math.Pow(sdsd, 2) / 2) -} - -func f09_SD2(sdnn, sdsd float64) float64 { - return math.Sqrt(2*math.Pow(sdnn, 2) - math.Pow(sdsd, 2)/2) -} - -func f10_SD1_SD2_RATIO(sd1, sd2 float64) float64 { - return sd1 / sd2 -} - -func f11_S(sd1, sd2 float64) float64 { - return math.Pi * sd1 * sd2 -} - -func f12_18(rrIntervalValue []float64, Fs float64) Feature12To18 { - var feature Feature12To18 - // Implement the logic for feature calculation - return feature -} - -func filterF(YY []float64, f []float64, predicate func(float64) bool) []float64 { - var result []float64 - for i, val := range f { - if predicate(val) { - result = append(result, YY[i]) - } - } - return result -} - -func nanzscore(input []float64) []float64 { - m := nanmean(input) - s := nanstd(input) - - var z []float64 - for _, val := range input { - z = append(z, (val-m)/s) - } - return z -} - -func nanmean(input []float64) float64 { - return mean(input) -} - -func nanstd(input []float64) float64 { - return populationStandardDeviation(input) -} - -type Feature12To18 struct { - TP float64 - pLF float64 - pHF float64 - LFHFratio float64 - VLF float64 - LF float64 - HF float64 -} - -type RRIntervalSet struct { - RRIntervalValue []float64 - RRIntervalsValueDiff []float64 -} - -func mean(arr []float64) float64 { - sum := 0.0 - for _, val := range arr { - sum += val - } - return sum / float64(len(arr)) -} - -func sampleStandardDeviation(arr []float64) float64 { - mean := mean(arr) - variance := 0.0 - for _, val := range arr { - variance += math.Pow(val-mean, 2) - } - return math.Sqrt(variance / float64(len(arr)-1)) -} - -func powList(arr []float64, exp float64) []float64 { - var result []float64 - for _, val := range arr { - result = append(result, math.Pow(val, exp)) - } - return result -} - -func filterCount(arr []float64, predicate func(float64) bool) int { - count := 0 - for _, val := range arr { - if predicate(val) { - count++ - } - } - return count -} - -func sum(arr []float64) float64 { - total := 0.0 - for _, val := range arr { - total += val - } - return total -} - -func max(arr []float64) float64 { - if len(arr) == 0 { - return 0 - } - max := arr[0] - for _, val := range arr { - if val > max { - max = val - } - } - return max -} - -func populationStandardDeviation(input []float64) float64 { - meanVal := mean(input) - variance := 0.0 - for _, val := range input { - variance += math.Pow(val-meanVal, 2) - } - return math.Sqrt(variance / float64(len(input))) -} - -func mulList(input []float64, multiplier float64) []float64 { - result := make([]float64, len(input)) - for i, val := range input { - result[i] = val * multiplier - } - return result -} diff --git a/Thesis_Code/gateway-classification/src/database/database.go b/Thesis_Code/gateway-classification/src/database/database.go deleted file mode 100644 index 6111134..0000000 --- a/Thesis_Code/gateway-classification/src/database/database.go +++ /dev/null @@ -1,111 +0,0 @@ -package database - -import ( - "fmt" - "log" - "os" - "time" - - "github.com/joho/godotenv" - "github.com/stanleydv12/gateway-classification/src/entity" - "gorm.io/driver/postgres" - "gorm.io/gorm" -) - -// SetupDatabase initializes and returns a *gorm.DB object representing a connection to the database. -// -// It reads the database configuration from the environment variables and establishes a connection to the database using the specified parameters. -// The function automatically migrates the entity.SensorData struct to the database and returns the *gorm.DB object. -func SetupDatabase() *gorm.DB { - - var err error - - errEnv := godotenv.Load(".env") - - if errEnv != nil { - log.Fatal("Error loading .env") - } - - host := os.Getenv("DSN_HOST") - user := os.Getenv("DSN_USER") - password := os.Getenv("DSN_PASSWORD") - dbname := os.Getenv("DSN_DB_NAME") - port := os.Getenv("DSN_PORT") - sslMode := os.Getenv("SSL_MODE") - timeZone := os.Getenv("TIMEZONE") - - dsn := - "host=" + host + - " user=" + user + - " password=" + password + - " dbname=" + dbname + - " port=" + port + - " sslmode=" + sslMode + - " TimeZone=" + timeZone - - db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) - if err != nil { - log.Fatalf("Error connecting to the database: %v", err) - } - - err = AutoMigrateAllEntities(db) - if err != nil { - log.Fatalf("Error migrating entities: %v", err) - } - - // Seeding - InsertTestData(db) - - return db -} - -// AutoMigrateAllEntities migrates all entities to the database. -func AutoMigrateAllEntities(db *gorm.DB) error { - err := db.AutoMigrate( - &entity.Doctor{}, - &entity.ECG{}, - &entity.Patient{}, - &entity.SleepData{}, - &entity.SleepStage{}, - &entity.SleepQuality{}, - ) - if err != nil { - return err - } - return nil -} - -func InsertTestData(db *gorm.DB) { - // Contoh data Doctor - doctorData := entity.Doctor{ - FirstName: "John", - LastName: "Doe", - Gender: "Male", - Email: "john.doe@example.com", - PhoneNumber: "123456789", - BirthRate: time.Date(1980, 1, 1, 0, 0, 0, 0, time.UTC), - RegistrationDate: time.Now(), - Address: "123 Main St, City", - } - - // Contoh data Patient - patientData := entity.Patient{ - FirstName: "Alice", - LastName: "Johnson", - Gender: "Female", - Email: "alice.johnson@example.com", - PhoneNumber: "987654321", - BirthDate: time.Date(1990, 5, 15, 0, 0, 0, 0, time.UTC), - RegistrationDate: time.Now(), - Address: "456 Oak St, Town", - SensorToken: "sensortoken123", - StartSleepTime: time.Now(), - EndSleepTime: time.Now().Add(8 * time.Hour), // Contoh: tidur selama 8 jam - } - - // Sisipkan data ke database - db.Create(&doctorData) - db.Create(&patientData) - - fmt.Println("Data inserted successfully.") -} diff --git a/Thesis_Code/gateway-classification/src/entity/entity.go b/Thesis_Code/gateway-classification/src/entity/entity.go deleted file mode 100644 index 3b8915c..0000000 --- a/Thesis_Code/gateway-classification/src/entity/entity.go +++ /dev/null @@ -1,76 +0,0 @@ -package entity - -import ( - "time" -) - -// Doctor represents the Doctor table -type Doctor struct { - ID uint `gorm:"primaryKey" json:"id"` - FirstName string `json:"first_name,omitempty"` - LastName string `json:"last_name,omitempty"` - Gender string `json:"gender,omitempty"` - Email string `json:"email,omitempty"` - PhoneNumber string `json:"phone_number,omitempty"` - BirthRate time.Time `json:"birth_rate,omitempty"` - RegistrationDate time.Time `json:"registration_date,omitempty"` - Address string `json:"address,omitempty"` -} - -// Patient represents the Patient table -type Patient struct { - ID uint `gorm:"primaryKey" json:"id"` - FirstName string `json:"first_name,omitempty"` - LastName string `json:"last_name,omitempty"` - Gender string `json:"gender,omitempty"` - Email string `json:"email,omitempty"` - PhoneNumber string `json:"phone_number,omitempty"` - BirthDate time.Time `json:"birth_date,omitempty"` - RegistrationDate time.Time `json:"registration_date,omitempty"` - Address string `json:"address,omitempty"` - SensorToken string `json:"sensor_token,omitempty"` - StartSleepTime time.Time `json:"start_sleep_time,omitempty"` - EndSleepTime time.Time `json:"end_sleep_time,omitempty"` -} - -// SleepData represents the Sleep Data table -type SleepData struct { - ID uint `gorm:"primaryKey" json:"id"` - PatientID uint `json:"patient_id,omitempty"` - FirstECGID uint `json:"first_ecg_id,omitempty"` - FirstSleepStageID uint `json:"first_sleep_stage_id,omitempty"` - SleepQualityID uint `json:"sleep_quality_id,omitempty"` - FirstInputTime time.Time `json:"first_input_time,omitempty"` - LastInputTime time.Time `json:"last_input_time,omitempty"` -} - -// ECG represents the ECG table -type ECG struct { - ID uint `gorm:"primaryKey" json:"id"` - ReferenceID uint `json:"reference_id,omitempty"` - Value float64 `json:"value,omitempty"` - InputTime time.Time `json:"input_time,omitempty"` -} - -// SleepStage represents the Sleep Stage table -type SleepStage struct { - ID uint `gorm:"primaryKey" json:"id"` - ReferenceID uint `json:"reference_id,omitempty"` - Value string `json:"value,omitempty"` - Method string `json:"method,omitempty"` -} - -// SleepQuality represents the Sleep Quality table -type SleepQuality struct { - ID uint `gorm:"primaryKey" json:"id"` - Value string `json:"value,omitempty"` - InBedDuration time.Time `json:"in_bed_duration,omitempty"` - BeginToSleepTime time.Time `json:"begin_to_sleep_time,omitempty"` - AwakeFromSleepTime time.Time `json:"awake_from_sleep_time,omitempty"` - SleepEfficiency float64 `json:"sleep_efficiency,omitempty"` - LightSleepDuration time.Time `json:"light_sleep_duration,omitempty"` - DeepSleepDuration time.Time `json:"deep_sleep_duration,omitempty"` - REMDuration time.Time `json:"rem_duration,omitempty"` - AwakeDuration time.Time `json:"awake_duration,omitempty"` - InputTime time.Time `json:"input_time,omitempty"` -} diff --git a/Thesis_Code/gateway-classification/src/handler/handler.go b/Thesis_Code/gateway-classification/src/handler/handler.go deleted file mode 100644 index 25acc29..0000000 --- a/Thesis_Code/gateway-classification/src/handler/handler.go +++ /dev/null @@ -1,353 +0,0 @@ -package handler - -import ( - "bytes" - "encoding/json" - "fmt" - "log" - "net/http" - "os" - "time" - - "github.com/mitchellh/mapstructure" - "github.com/stanleydv12/gateway-classification/src/entity" - "gorm.io/gorm" -) - -var saveTimer *time.Timer - -// HandleEvent handles the given event and data. -// -// Parameters: -// - event: a string representing the event to be handled. -// - data: an interface{} containing the data related to the event. -// -// Returns: None. -func HandleEvent(event string, data interface{}) { - switch event { - case "save-data": - sensorData, ok := convertToSensorData(data) - if !ok { - fmt.Println("HandleEvent: Failed to convert data to SensorData") - return - } - SaveData(sensorData) - default: - fmt.Println("HandleEvent: unknown event") - } -} - -// SaveData saves the provided data to the database if it meets certain conditions. -// -// The function takes in a data interface{} parameter, which should be of type entity.ECG. -// It first checks if the data is of the correct type using type assertion. -// If the data is not of type entity.ECG, the function prints an error message and returns. -// -// The function then parses the input timestamp of the data and checks if it is valid. -// If there is an error in parsing the timestamp, the function prints an error message and returns. -// -// The function calculates the time difference between the current time and the input timestamp. -// If the time difference is greater than 30 seconds, the function prints a message and returns. -// -// If the data is the first ECG for a patient, the function sets the ReferenceID to 0. -// Otherwise, it retrieves the ReferenceID for the patient using the GetReferenceIDForPatient function. -// -// The function creates a new instance of entity.ECG with the updated ReferenceID and other attributes. -// -// The function then attempts to save the newSensorData to the database using the DB.Create function. -// If there is an error in saving the data, the function prints an error message and returns. -// -// Finally, if the data is successfully saved to the database, the function prints a success message. -func SaveData(data interface{}) { - fmt.Println(data) - sensorData, ok := data.(entity.ECG) - if !ok { - fmt.Println("SaveData: Invalid data format") - return - } - - // Note: Inject input time with current time - sensorData.InputTime = time.Now() - currentTime := time.Now() - - diff := currentTime.Sub(sensorData.InputTime) - if diff.Seconds() > 30 { - fmt.Println("SaveData: Data is older than 30 seconds, skipping save to DB") - return - } - - if isFirstEcg := CheckIfFirstECG(sensorData); isFirstEcg { - sensorData.ReferenceID = 0 - - newSensorData := entity.ECG{ - ReferenceID: sensorData.ReferenceID, - Value: sensorData.Value, - InputTime: sensorData.InputTime, - } - - err := DB.Create(&newSensorData).Error - if err != nil { - fmt.Println("SaveData: Failed to save data to DB:", err) - return - } - - firstSensorData := entity.ECG{} - DB.Select("id").First(&firstSensorData) - - sleepData := entity.SleepData{ - ID: 1, - PatientID: 1, - FirstECGID: firstSensorData.ID, - FirstInputTime: firstSensorData.InputTime, - } - - err = DB.Save(&sleepData).Error - if err != nil { - fmt.Println("SaveData: Failed to save sleep data to DB:", err) - return - } - - } else { - sensorData.ReferenceID = GetReferenceIDForPatient(sensorData) - - newSensorData := entity.ECG{ - ReferenceID: sensorData.ReferenceID, - Value: sensorData.Value, - InputTime: sensorData.InputTime, - } - - err := DB.Create(&newSensorData).Error - if err != nil { - fmt.Println("SaveData: Failed to save data to DB:", err) - return - } - - sleepData := entity.SleepData{ - ID: 1, - PatientID: 1, - LastInputTime: sensorData.InputTime, - } - - err = DB.Save(&sleepData).Error - if err != nil { - fmt.Println("SaveData: Failed to save sleep data to DB:", err) - return - } - } - - // Reset the timer to 30 seconds - if saveTimer == nil { - saveTimer = time.NewTimer(30 * time.Second) - } else { - saveTimer.Reset(30 * time.Second) - } - - fmt.Println("SaveData: Data saved to DB") -} - -// convertToSensorData converts the given data to a SensorData object. -// -// data: The data to be converted. -// Returns: The converted SensorData object and a boolean indicating if the conversion was successful. -func convertToSensorData(data interface{}) (entity.ECG, bool) { - var sensorData entity.ECG - err := mapstructure.Decode(data, &sensorData) - if err != nil { - return entity.ECG{}, false - } - return sensorData, true -} - -var DB *gorm.DB - -// SetDBInstance sets the global variable DB to the given *gorm.DB instance. -// -// db: the *gorm.DB instance to be set. -func SetDBInstance(db *gorm.DB) { - DB = db -} - -// CheckIfFirstECG checks if the given ECG sensor data is the first data recorded for a given date. -// -// It takes an ECG object as a parameter and returns a boolean value indicating whether the data is the first for that date. -func CheckIfFirstECG(sensorData entity.ECG) bool { - var count int64 - var lastData entity.ECG - - // Check if data is empty - DB.Model(&entity.ECG{}).Count(&count) - if count == 0 { - return true - } - - // Check if the last data for reference_id is not empty - DB.Order("input_time DESC").Where("reference_id = ?", sensorData.ReferenceID).First(&lastData) - if lastData.ID != 0 { - // Check if input_time is more than 30 seconds from the current time - currentTime := time.Now() - timeDiff := currentTime.Sub(lastData.InputTime) - if timeDiff.Seconds() > 30 { - return true - } - } - - return false -} - -// GetReferenceIDForPatient retrieves the reference ID for a patient based on the given ECG sensor data. -// -// It takes the following parameter: -// - sensorData: an instance of the entity.ECG struct representing the ECG sensor data. -// -// It returns a uint representing the reference ID. -func GetReferenceIDForPatient(sensorData entity.ECG) uint { - var referenceID uint - DB.Model(&entity.ECG{}).Where("DATE(input_time) = ?", sensorData.InputTime.Format("2006-01-02")).Select("id").Order("id ASC").First(&referenceID) - return referenceID -} - -// StartTimer starts the timer for saving data to DB and calling classifyData -func StartTimer() { - saveTimer = time.NewTimer(30 * time.Second) - - go func() { - for { - select { - case <-saveTimer.C: - classifyData() - saveTimer.Reset(30 * time.Second) - } - } - }() -} - -type PredictionResponse struct { - Prediction string `json:"prediction"` -} - -func classifyData() { - - var lastECG entity.ECG - if err := DB.Order("input_time desc").First(&lastECG).Error; err != nil { - if err == gorm.ErrRecordNotFound { - fmt.Println("No ecg data found in the database") - } else { - log.Fatalf("Failed to get last ecg data: %v", err) - } - return - } - - sleepData := entity.SleepData{ - ID: 1, - LastInputTime: lastECG.InputTime, - } - if err := DB.Save(&sleepData).Error; err != nil { - log.Fatalf("Failed to save sleep data: %v", err) - return - } - - - // Mengambil data ECG berdasarkan ID - var ecgByID []entity.ECG - if err := DB.Where("id = ?", lastECG.ReferenceID).Find(&ecgByID).Error; err != nil { - log.Fatalf("Failed to get ECG data by ID: %v", err) - return - } - - // Mengambil semua data ECG berdasarkan reference ID - var ecgByReferenceID []entity.ECG - if err := DB.Where("reference_id = ?", lastECG.ReferenceID).Find(&ecgByReferenceID).Error; err != nil { - log.Fatalf("Failed to get ECG data by reference ID: %v", err) - return - } - - // Combine data retrieved by ID and reference ID - allECG := append(ecgByID, ecgByReferenceID...) - - // Process data in batches of 10 - for i := 0; i < len(allECG); i += 10 { - end := i + 10 - if end > len(allECG) { - end = len(allECG) - } - - batch := allECG[i:end] - - // Call the function to handle the API call for this batch - prediction, err := predict(batch) - if err != nil { - log.Fatalf("Failed to make prediction: %v", err) - return - } - - if i == 0 { - sleepStage := entity.SleepStage{ - ID: 1, - ReferenceID: 0, - Value: prediction.Prediction, - } - - err = DB.Save(&sleepStage).Error - if err != nil { - log.Fatalf("Failed to save sleep stage: %v", err) - return - } - - var sleepData entity.SleepData - err = DB.Find(&sleepData, "id = ?", 1).First(&sleepData).Error - if err != nil { - log.Fatalf("Failed to get sleep data: %v", err) - return - } - - sleepData.FirstSleepStageID = sleepStage.ID - } else { - sleepStage := entity.SleepStage{ - ReferenceID: 1, - Value: prediction.Prediction, - } - - err = DB.Save(&sleepStage).Error - if err != nil { - log.Fatalf("Failed to save sleep stage: %v", err) - return - } - } - } -} - -func predict(data []entity.ECG) (PredictionResponse, error) { - extractedValues := make([]float64, len(data)) - - for i, ecg := range data { - extractedValues[i] = ecg.Value - } - - // Convert the extracted data slice to JSON - jsonData, err := json.Marshal(data) - if err != nil { - return PredictionResponse{}, err - } - - predictURL := os.Getenv("PREDICT_URL") - if predictURL == "" { - return PredictionResponse{}, fmt.Errorf("PREDICT_URL environment variable is not set") - } - - resp, err := http.Post(predictURL, "application/json", bytes.NewBuffer(jsonData)) - if err != nil { - return PredictionResponse{}, err - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return PredictionResponse{}, fmt.Errorf("unexpected status code: %d", resp.StatusCode) - } - - var predictionResponse PredictionResponse - if err := json.NewDecoder(resp.Body).Decode(&predictionResponse); err != nil { - return PredictionResponse{}, err - } - - return predictionResponse, nil -} diff --git a/Thesis_Code/gateway-classification/src/mqtt/mqtt.go b/Thesis_Code/gateway-classification/src/mqtt/mqtt.go deleted file mode 100644 index a103f47..0000000 --- a/Thesis_Code/gateway-classification/src/mqtt/mqtt.go +++ /dev/null @@ -1,96 +0,0 @@ -package mqtt - -import ( - "encoding/json" - "fmt" - "log" - "os" - - mqtt "github.com/eclipse/paho.mqtt.golang" - "github.com/joho/godotenv" - "github.com/stanleydv12/gateway-classification/src/handler" -) - -type Message struct { - Event string `json:"event"` - Data interface{} `json:"data"` -} - -var Client mqtt.Client - -var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { - fmt.Printf("Message Received from [%s] : %s\n", msg.Topic(), msg.Payload()) - - var receivedMessage Message - err := json.Unmarshal(msg.Payload(), &receivedMessage) - if err != nil { - fmt.Println("Error decoding message:", err) - return - } - - handler.HandleEvent(receivedMessage.Event, receivedMessage.Data) -} - -var connectHandler mqtt.OnConnectHandler = func(client mqtt.Client) { - fmt.Println("Connected") - Sub(client) -} - -var onLostHandler mqtt.ConnectionLostHandler = func(client mqtt.Client, err error) { - fmt.Printf("Connection lost : %v", err) -} - -// SetupMqtt sets up the MQTT connection. -// -// It loads the environment variables from the .env file. -// It creates a new MQTT client options object and configures it with the -// MQTT broker host, port, and client ID. -// It sets the default publish handler, on connect handler, and connection lost -// handler for the MQTT client options. -// It creates a new MQTT client with the configured options. -// It connects the MQTT client to the broker. -// If there is an error during the connection, it panics. -func SetupMqtt() { - errEnv := godotenv.Load(".env") - if errEnv != nil { - log.Fatal("Error loading .env") - } - - broker := os.Getenv("MQTT_BROKER_HOST") - port := os.Getenv("MQTT_BROKER_PORT") - clientID := os.Getenv("MQTT_CLIENT_ID") - - opts := mqtt.NewClientOptions() - opts.AddBroker(fmt.Sprintf("ws://%s:%s", broker, port)) - opts.SetClientID(clientID) - opts.SetDefaultPublishHandler(messagePubHandler) - opts.SetOnConnectHandler(connectHandler) - opts.SetConnectionLostHandler(onLostHandler) - - Client = mqtt.NewClient(opts) - - if token := Client.Connect(); token.Wait() && token.Error() != nil { - panic(token.Error()) - } -} - -// Sub is a function that subscribes to an MQTT topic and prints a message. -// -// It takes a client of type mqtt.Client as a parameter. -// It does not return any value. -func Sub(client mqtt.Client) { - topic := os.Getenv("MQTT_TOPIC") - token := client.Subscribe(topic, 1, nil) - token.Wait() - fmt.Printf("Subscribed to topic %s\n", topic) -} - -// Pub publishes the given message to the MQTT topic. -// -// It takes a single parameter, msg, which is of type interface{}. -// The function does not return any value. -func Pub(msg interface{}) { - topic := os.Getenv("MQTT_TOPIC") - token := Client.Publish(topic, 1, false, msg) - token.Wait() -} diff --git a/Thesis_Code/quantification/go.mod b/Thesis_Code/quantification/go.mod deleted file mode 100644 index 0836f80..0000000 --- a/Thesis_Code/quantification/go.mod +++ /dev/null @@ -1,17 +0,0 @@ -module github.com/dije07/sqqs - -go 1.21.3 - -require ( - github.com/eclipse/paho.mqtt.golang v1.4.3 - github.com/go-redis/redis/v8 v8.11.5 - github.com/lib/pq v1.10.9 -) - -require ( - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/gorilla/websocket v1.5.0 // indirect - golang.org/x/net v0.8.0 // indirect - golang.org/x/sync v0.1.0 // indirect -) diff --git a/Thesis_Code/quantification/go.sum b/Thesis_Code/quantification/go.sum deleted file mode 100644 index 3a59eb8..0000000 --- a/Thesis_Code/quantification/go.sum +++ /dev/null @@ -1,32 +0,0 @@ -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik= -github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= -github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= -github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/Thesis_Code/quantification/quantification.go b/Thesis_Code/quantification/quantification.go deleted file mode 100644 index ccecedb..0000000 --- a/Thesis_Code/quantification/quantification.go +++ /dev/null @@ -1,390 +0,0 @@ -package main - -import ( - "database/sql" - "encoding/json" - "fmt" - "log" - "math" - "os" - "time" - - "github.com/go-redis/redis/v8" - _ "github.com/lib/pq" - - MQTT "github.com/eclipse/paho.mqtt.golang" -) - -// Define your MQTT broker address and port -const ( - brokerAddress = "ws://localhost:9001" // Change this to your MQTT broker address - host = "localhost" - port = 5432 - user = "postgres" - password = "postgres" - dbname = "sleep_monitoring" -) - -var DB *sql.DB - -type Message struct { - Event string `json:"event"` - Data interface{} `json:"data"` -} - -type SleepQuality struct { - ID uint `gorm:"primaryKey" json:"id"` - Value string `json:"value,omitempty"` - DeepSleepDuration float64 `json:"deep_sleep_duration,omitempty"` - AwakeDuration float64 `json:"awake_duration,omitempty"` - TotalSleepDuration float64 `json:"total_sleep_duration,omitempty"` - InputTime time.Time `json:"input_time,omitempty"` - UserId uint `json:"user_id,omitempty"` -} - -// FuzzySet represents a fuzzy set with a membership function. -type FuzzySet struct { - Name string - Terms map[string]func(float64) float64 -} - -// Fuzzify function calculates the membership values for each term in the fuzzy set. -func (fs *FuzzySet) Fuzzify(value float64) string { - max := 0.0 - result := "" - - for term, mf := range fs.Terms { - membership := mf(value) - if membership > max { - max = membership - result = term - } - } - - return result -} - -// ApplyRule function evaluates the conditions and returns the corresponding action. -func ApplyRule(conditions map[string]float64) (string, bool) { - // Apply all rules - switch { - case conditions["awakeDuration"] == 1 && conditions["deepSleepTime"] == 1 && conditions["totalSleepTime"] == 1: - return "LEVEL 9", true - case conditions["awakeDuration"] == 1 && conditions["deepSleepTime"] == 1 && conditions["totalSleepTime"] == 0.5: - return "LEVEL 8", true - case conditions["awakeDuration"] == 1 && conditions["deepSleepTime"] == 1 && conditions["totalSleepTime"] == 0: - return "LEVEL 7", true - case conditions["awakeDuration"] == 1 && conditions["deepSleepTime"] == 0.5 && conditions["totalSleepTime"] == 1: - return "LEVEL 7", true - case conditions["awakeDuration"] == 1 && conditions["deepSleepTime"] == 0.5 && conditions["totalSleepTime"] == 0.5: - return "LEVEL 6", true - case conditions["awakeDuration"] == 1 && conditions["deepSleepTime"] == 0.5 && conditions["totalSleepTime"] == 0: - return "LEVEL 5", true - case conditions["awakeDuration"] == 1 && conditions["deepSleepTime"] == 0 && conditions["totalSleepTime"] == 1: - return "LEVEL 5", true - case conditions["awakeDuration"] == 1 && conditions["deepSleepTime"] == 0 && conditions["totalSleepTime"] == 0.5: - return "LEVEL 4", true - case conditions["awakeDuration"] == 1 && conditions["deepSleepTime"] == 0 && conditions["totalSleepTime"] == 0: - return "LEVEL 3", true - case conditions["awakeDuration"] == 0.5 && conditions["deepSleepTime"] == 1 && conditions["totalSleepTime"] == 1: - return "LEVEL 8", true - case conditions["awakeDuration"] == 0.5 && conditions["deepSleepTime"] == 1 && conditions["totalSleepTime"] == 0.5: - return "LEVEL 7", true - case conditions["awakeDuration"] == 0.5 && conditions["deepSleepTime"] == 1 && conditions["totalSleepTime"] == 0: - return "LEVEL 6", true - case conditions["awakeDuration"] == 0.5 && conditions["deepSleepTime"] == 0.5 && conditions["totalSleepTime"] == 1: - return "LEVEL 6", true - case conditions["awakeDuration"] == 0.5 && conditions["deepSleepTime"] == 0.5 && conditions["totalSleepTime"] == 0.5: - return "LEVEL 5", true - case conditions["awakeDuration"] == 0.5 && conditions["deepSleepTime"] == 0.5 && conditions["totalSleepTime"] == 0: - return "LEVEL 4", true - case conditions["awakeDuration"] == 0.5 && conditions["deepSleepTime"] == 0 && conditions["totalSleepTime"] == 1: - return "LEVEL 4", true - case conditions["awakeDuration"] == 0.5 && conditions["deepSleepTime"] == 0 && conditions["totalSleepTime"] == 0.5: - return "LEVEL 3", true - case conditions["awakeDuration"] == 0.5 && conditions["deepSleepTime"] == 0 && conditions["totalSleepTime"] == 0: - return "LEVEL 2", true - case conditions["awakeDuration"] == 0 && conditions["deepSleepTime"] == 1 && conditions["totalSleepTime"] == 1: - return "LEVEL 7", true - case conditions["awakeDuration"] == 0 && conditions["deepSleepTime"] == 1 && conditions["totalSleepTime"] == 0.5: - return "LEVEL 6", true - case conditions["awakeDuration"] == 0 && conditions["deepSleepTime"] == 1 && conditions["totalSleepTime"] == 0: - return "LEVEL 5", true - case conditions["awakeDuration"] == 0 && conditions["deepSleepTime"] == 0.5 && conditions["totalSleepTime"] == 1: - return "LEVEL 5", true - case conditions["awakeDuration"] == 0 && conditions["deepSleepTime"] == 0.5 && conditions["totalSleepTime"] == 0.5: - return "LEVEL 4", true - case conditions["awakeDuration"] == 0 && conditions["deepSleepTime"] == 0.5 && conditions["totalSleepTime"] == 0: - return "LEVEL 3", true - case conditions["awakeDuration"] == 0 && conditions["deepSleepTime"] == 0 && conditions["totalSleepTime"] == 1: - return "LEVEL 3", true - case conditions["awakeDuration"] == 0 && conditions["deepSleepTime"] == 0 && conditions["totalSleepTime"] == 0.5: - return "LEVEL 2", true - case conditions["awakeDuration"] == 0 && conditions["deepSleepTime"] == 0 && conditions["totalSleepTime"] == 0: - return "LEVEL 1", true - } - - // No rule matched - return "", false -} - -var messagePubHandler MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) { - fmt.Printf("Message Received from [%s] : %s\n", msg.Topic(), msg.Payload()) - - if string(msg.Payload()) == "sleepStageReady" { - quantifyData() - } -} - -func setUpDB() *sql.DB { - // Construct the connection string - connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", - os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), - os.Getenv("DB_USER"), os.Getenv("DB_PASSWORD"), - os.Getenv("DB_NAME")) - - // Open a connection to the database - db, err := sql.Open("postgres", connStr) - if err != nil { - log.Fatal("Error connecting to the database: ", err) - } - - // Attempt to ping the database to verify connection - err = db.Ping() - if err != nil { - log.Fatal("Error pinging the database: ", err) - } - - fmt.Println("Successfully connected to the database!") - - return db -} - -var red *redis.Client - -func quantifyData() { - - var awake float64 = 0 - var deepSleep float64 = 0 - var totalSleep float64 = 0 - - db := setUpDB() - DB = db - value, err := red.Get(red.Context(), "sleep-stages").Result() - if value == "" || err != nil { - // Example query - start := time.Now().UnixMilli() - rows, err := DB.Query("SELECT * FROM sleep_stages") - end := time.Now().UnixMilli() - fmt.Println("Start : ", start) - fmt.Println("End : ", end) - fmt.Println("Duration : ", end-start, "ms") - if err != nil { - log.Fatal("Error querying the database: ", err) - } - defer rows.Close() - - // Iterate over the rows - for rows.Next() { - var id int - var reference_id string - var value string - var method any - var timestamp time.Time - err := rows.Scan(&id, &reference_id, &value, &method, ×tamp) - if err != nil { - log.Println("Error scanning row: ", err) - } - if value == "N1" || value == "N2" || value == "REM" { - totalSleep++ - } - if value == "N3" { - totalSleep++ - deepSleep++ - } - if value == "AWAKE" { - awake++ - } - } - if err := rows.Err(); err != nil { - log.Println("Error iterating over rows: ", err) - } - } else { - type SleepStage struct { - ID uint `json:"id"` - ReferenceID uint `json:"reference_id"` - Value string `json:"value"` - Method string `json:"method"` - Timestamp time.Time `json:"timestamp"` - } - - type SleepStages struct { - Stages []SleepStage `json:"sleep-stages"` - } - - // Unmarshal the JSON into a SleepStages struct - var stages SleepStages - err := json.Unmarshal([]byte(value), &stages) - if err != nil { - log.Println(err) - } - - // Loop through the stages and print values - for _, stage := range stages.Stages { - if stage.Value == "N1" || stage.Value == "N2" || stage.Value == "REM" { - totalSleep++ - } - if stage.Value == "N3" { - totalSleep++ - deepSleep++ - } - if stage.Value == "AWAKE" { - awake++ - } - } - } - - // Define fuzzy sets and input values - awakeDurationSet := FuzzySet{ - Name: "awakeDuration", - Terms: map[string]func(float64) float64{ - "low": func(x float64) float64 { return math.Max(0, 1.0-0.5*x) }, - "medium": func(x float64) float64 { return math.Max(0, 1-2*math.Abs(x-0.5)) }, - "high": func(x float64) float64 { return math.Max(0, 2*x-1) }, - }, - } - deepSleepDurationSet := FuzzySet{ - Name: "awakeDuration", - Terms: map[string]func(float64) float64{ - "low": func(x float64) float64 { return math.Max(0, 1.0-0.5*x) }, - "medium": func(x float64) float64 { return math.Max(0, 1-2*math.Abs(x-0.5)) }, - "high": func(x float64) float64 { return math.Max(0, 2*x-1) }, - }, - } - totalSleepDurationSet := FuzzySet{ - Name: "awakeDuration", - Terms: map[string]func(float64) float64{ - "low": func(x float64) float64 { return math.Max(0, 1.0-0.5*x) }, - "medium": func(x float64) float64 { return math.Max(0, 1-2*math.Abs(x-0.5)) }, - "high": func(x float64) float64 { return math.Max(0, 2*x-1) }, - }, - } - - inputValues := map[string]float64{ - "awakeDuration": awake / 60, - "deepSleepTime": deepSleep / 60, - "totalSleepTime": totalSleep / 60, - } - - // Fuzzify the sleep data - awakeTerm := awakeDurationSet.Fuzzify(inputValues["awakeDuration"]) - deepSleepTerm := deepSleepDurationSet.Fuzzify(inputValues["deepSleepTime"]) - totalSleepTerm := totalSleepDurationSet.Fuzzify(inputValues["totalSleepTime"]) - // Fuzzify the other sleep data... - - // Print the intermediate results - fmt.Println("Fuzzy Conditions:") - fmt.Printf("Awake Duration: %s (%f)\n", awakeTerm, inputValues["awakeDuration"]) - fmt.Printf("Deep Sleep Duration: %s (%f)\n", deepSleepTerm, inputValues["deepSleepTime"]) - fmt.Printf("Total Sleep Duration: %s (%f)\n", totalSleepTerm, inputValues["totalSleepTime"]) - // Print the other fuzzy conditions... - - // Map the linguistic terms to their respective numerical values - linguisticValues := map[string]float64{ - "high": 1.0, - "medium": 0.5, - "low": 0.0, - } - - // Create a map for all conditions - allConditions := map[string]float64{ - "awakeDuration": linguisticValues[awakeTerm], - "deepSleepTime": linguisticValues[deepSleepTerm], - "totalSleepTime": linguisticValues[totalSleepTerm], - } - - action, ruleMatched := ApplyRule(allConditions) - - // Print the final results - if ruleMatched { - fmt.Println("\nRule Matched! Action:", action) - } else { - fmt.Println("\nNo Rule Matched.") - } - - sleepQuality := SleepQuality{ - Value: action, - DeepSleepDuration: inputValues["deepSleepTime"], - TotalSleepDuration: inputValues["totalSleepTime"], - AwakeDuration: inputValues["awakeDuration"], - InputTime: time.Now(), - UserId: 1, - } - - sleepQualityJSON, err := json.Marshal(sleepQuality) - if err != nil { - fmt.Println("Error:", err) - return - } - - err = red.Set(red.Context(), "sleep_quality_1", sleepQualityJSON, 0).Err() - if err != nil { - log.Fatalf("Failed to save to redis: %v", err) - } else { - fmt.Println("Saved to redis") - } - - // Prepare the SQL statement for inserting data. - stmt, err := db.Prepare("INSERT INTO sleep_qualities (value, deep_sleep_duration, awake_duration, total_sleep_duration, input_time, user_id) VALUES ($1, $2, $3, $4, $5, $6)") - if err != nil { - log.Fatal(err) - } - defer stmt.Close() - - // Example data to be inserted. - value1 := action - value2 := inputValues["deepSleepTime"] - value3 := inputValues["awakeDuration"] - value4 := inputValues["totalSleepTime"] - value5 := time.Now() - value6 := 1 - - // Execute the SQL statement with the provided values. - _, err = stmt.Exec(value1, value2, value3, value4, value5, value6) - if err != nil { - log.Println(err) - } - -} - -func main() { - red = redis.NewClient(&redis.Options{ - Addr: os.Getenv("REDIS_ADDR"), // Redis server address - Password: "", // no password set - DB: 0, // use default DB - }) - - // Set MQTT client options - - opts := MQTT.NewClientOptions().AddBroker("ws://" + os.Getenv("MQTT_BROKER")) - opts.SetClientID("MQTT_simulator") - opts.SetDefaultPublishHandler(messagePubHandler) - - topic := "sleep_monitoring" - - // Create and start a client using the above options - client := MQTT.NewClient(opts) - if token := client.Connect(); token.Wait() && token.Error() != nil { - fmt.Println("Error connecting to MQTT broker:", token.Error()) - os.Exit(1) - } - - // Subscribe to MQTT topics - if token := client.Subscribe(topic, 0, messagePubHandler); token.Wait() && token.Error() != nil { - fmt.Println("Error subscribing to MQTT topic:", token.Error()) - os.Exit(1) - } - fmt.Printf("Subscribed to topic: %s\n", topic) - // Keep the program running indefinitely - select {} -}