Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/docker-build-develop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Test and Build Python Image to ECR

on:
pull_request:
branches:
- main

jobs:
test-and-deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Run Streamlit sanity check
run: |
streamlit --version
python -m pytest || echo "Tests not configured, skipping..."

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-2

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

- name: Build, tag, and push image to ECR
env:
ECR_REGISTRY: ${{ secrets.AWS_ECR_REGISTRY }}
ECR_REPOSITORY: streamlit-app
IMAGE_TAG: streamlit-latest
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ referencing==0.36.2
requests==2.32.3
rpds-py==0.24.0
s3transfer==0.12.0
scipy==1.15.3
six==1.17.0
smmap==5.0.2
streamlit==1.45.0
Expand Down
14 changes: 11 additions & 3 deletions service/simulation/CurrentSimulator.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .SimulatorInterface2 import SimulatorInterface2
from simulate_type.simulate_list import generate_current_data
import random
from scipy.stats import truncnorm

class CurrentSimulator(SimulatorInterface2):
def __init__(self, idx: int, zone_id:str, equip_id:str, interval:int = 5, msg_count:int = 10, conn=None):
Expand All @@ -20,15 +20,23 @@ def __init__(self, idx: int, zone_id:str, equip_id:str, interval:int = 5, msg_co
self.shadow_desired_topic_name = f"$aws/things/Sensor/shadow/name/{self.sensor_id}/update/desired"
self.topic_name = f"sensor/{zone_id}/{equip_id}/{self.sensor_id}/{self.type}"
self.target_current = None # ์ดˆ๊ธฐ๊ฐ’ ์„ค์ •(shadow ์šฉ)

self.mu = 62.51
self.sigma = 33.76
lower = 0
upper = self.mu + 3 * self.sigma
self.a = (lower - self.mu) / self.sigma
self.b = (upper - self.mu) / self.sigma


# ๋ฐ์ดํ„ฐ ์ƒ์„ฑ ๋กœ์ง ์ •์˜
def _generate_data(self) -> dict:
return {
"zoneId": self.zone_id,
"equipId": self.equip_id,
"sensorId": self.sensor_id,
"sensorType": self.type,
"val": round(random.uniform(0.1 + self.idx, 10.0 + self.idx), 2)
# "val": round(random.uniform(0.1 + self.idx, 10.0 + self.idx), 2)
"val": round(truncnorm.rvs(self.a, self.b, loc=self.mu, scale=self.sigma), 2) # 0: 7, 1: 7์ด์ƒ, 2: 30 ์ด์ƒ ์ตœ์†Œ๊ฐ’์€ 0
}

################################################
Expand Down
11 changes: 10 additions & 1 deletion service/simulation/DustSimulator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .SimulatorInterface2 import SimulatorInterface2
import random
from scipy.stats import truncnorm

class DustSimulator(SimulatorInterface2):
def __init__(self, idx: int, zone_id:str, equip_id:str, interval:int = 5, msg_count:int = 10, conn=None):
Expand All @@ -19,6 +20,14 @@ def __init__(self, idx: int, zone_id:str, equip_id:str, interval:int = 5, msg_co
self.shadow_desired_topic_name = f"$aws/things/Sensor/shadow/name/{self.sensor_id}/update/desired"
self.topic_name = f"sensor/{zone_id}/{equip_id}/{self.sensor_id}/{self.type}"
self.target_current = None # ์ดˆ๊ธฐ๊ฐ’ ์„ค์ •(shadow ์šฉ)

self.mu = 180 # ํ‰๊ท  ๋ฏธ์„ธ๋จผ์ง€ ์ˆ˜์น˜
self.sigma = 60 # ํ‘œ์ค€ํŽธ์ฐจ
self.lower = 0
self.upper = self.mu + 3 * self.sigma

self.a = (self.lower - self.mu) / self.sigma
self.b = (self.upper - self.mu) / self.sigma

# ๋ฐ์ดํ„ฐ ์ƒ์„ฑ ๋กœ์ง ์ •์˜
def _generate_data(self) -> dict:
Expand All @@ -27,7 +36,7 @@ def _generate_data(self) -> dict:
"equipId": self.equip_id,
"sensorId": self.sensor_id,
"sensorType": self.type,
"val": round(random.uniform(5.0 + self.idx, 50.0 + self.idx), 2)
"val": round(truncnorm.rvs(self.a, self.b, loc=self.mu, scale=self.sigma), 2)
}

################################################
Expand Down
2 changes: 1 addition & 1 deletion service/simulation/HumiditySimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def _generate_data(self) -> dict:
"equipId": self.equip_id,
"sensorId": self.sensor_id,
"sensorType": self.type,
"val": round(random.uniform(20.0 + self.idx, 80.0 + self.idx), 2)
"val": round(random.gauss(mu = 11.68, sigma = 29.38), 2) # 0: 60์ดํ•˜,1: 60์ดˆ๊ณผ, 2: 80 ์ดˆ๊ณผ๊ณผ
}

################################################
Expand Down
15 changes: 14 additions & 1 deletion service/simulation/SimulatorInterface2.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import threading
from mqtt_util.publish import AwsMQTT
import time
from scipy.stats import truncnorm

class SimulatorInterface2(ABC):
def __init__(self, idx: int, zone_id: str, equip_id: str, interval: int, msg_count: int, conn:AwsMQTT=None): # ์„ผ์„œ idx๋ฅผ ๋ฐ›๊ธฐ
Expand Down Expand Up @@ -120,4 +121,16 @@ def start_publishing(self):
# self.thread.join()

def stop(self):
self.stop_event.set() # ์Šค๋ ˆ๋“œ ์ข…๋ฃŒ ์ด๋ฒคํŠธ ์„ค์ •
self.stop_event.set() # ์Šค๋ ˆ๋“œ ์ข…๋ฃŒ ์ด๋ฒคํŠธ ์„ค์ •

def generate_truncated_normal(self, mu: float, sigma: float, lower: float = None, upper: float = None) -> float:
# ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •: ํ‰๊ท  ์ด์ƒ์˜ ๊ฐ’๋งŒ ์ƒ์„ฑ
if lower is None:
lower = mu
if upper is None:
upper = mu + 3 * sigma # ๊ฑฐ์˜ ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ’ ํฌํ•จ (ํ•„์š”์‹œ ์กฐ์ •)

# truncnorm์€ ์ •๊ทœํ™”๋œ ๊ตฌ๊ฐ„ [a, b]๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ๋ณ€ํ™˜ ํ•„์š”
a, b = (lower - mu) / sigma, (upper - mu) / sigma
value = truncnorm.rvs(a, b, loc=mu, scale=sigma)
return round(value, 2)
15 changes: 14 additions & 1 deletion service/simulation/TempSimulator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from .SimulatorInterface2 import SimulatorInterface2
import random
from scipy.stats import truncnorm


class TempSimulator(SimulatorInterface2):
def __init__(self, idx: int, zone_id:str, equip_id:str, interval:int = 5, msg_count:int = 10, conn=None):
Expand Down Expand Up @@ -32,6 +34,17 @@ def __init__(self, idx: int, zone_id:str, equip_id:str, interval:int = 5, msg_co

self.target_temperature = None # ์ดˆ๊ธฐ๊ฐ’ ์„ค์ •(shadow ์šฉ)

self.mu = 25 # ํ‰๊ท  ์˜จ๋„ (์ •์ƒ ๋ฒ”์œ„: 18~21โ„ƒ)
self.sigma = 10 # ํ‘œ์ค€ํŽธ์ฐจ (์˜จ๋„์˜ ๋ณ€๋™ํญ)

# ์ ˆ๋‹จ ๋ฒ”์œ„ ์„ค์ • (์ตœ์†Œ๊ฐ’ -35โ„ƒ, ์ตœ๋Œ€๊ฐ’ 50โ„ƒ๋กœ ์„ค์ •)
self.lower = -35
self.upper = 50

# ์ •๊ทœ๋ถ„ํฌ ๋ฒ”์œ„์˜ a, b ๊ฐ’ ๊ณ„์‚ฐ
self.a = (self.lower - self.mu) / self.sigma
self.b = (self.upper - self.mu) / self.sigma

################################################z
# ๋ฐ์ดํ„ฐ ์ƒ์„ฑ ๋กœ์ง์„ ์ •์˜ (์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ๋งˆ๋‹ค ๋‹ค๋ฅด๊ฒŒ ๊ตฌํ˜„)
# ์˜ˆ) ์˜จ๋„, ์Šต๋„, ์ง„๋™, ์ „๋ฅ˜ ๋“ฑ๋“ฑ
Expand All @@ -43,7 +56,7 @@ def _generate_data(self) -> dict:
"equipId": self.equip_id,
"sensorId": self.sensor_id,
"sensorType": self.type,
"val": round(random.uniform(20.0 + self.idx, 80.0 + self.idx), 2)
"val": round(truncnorm.rvs(self.a, self.b, loc=self.mu, scale=self.sigma), 2)
}

################################################
Expand Down
15 changes: 13 additions & 2 deletions service/simulation/VibrationSimulator.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .SimulatorInterface2 import SimulatorInterface2
from simulate_type.simulate_list import generate_vibration_data
import random
from scipy.stats import truncnorm

class VibrationSimulator(SimulatorInterface2):
def __init__(self, idx: int, zone_id:str, equip_id:str, interval:int = 5, msg_count:int = 10, conn=None):
Expand All @@ -20,15 +21,25 @@ def __init__(self, idx: int, zone_id:str, equip_id:str, interval:int = 5, msg_co
self.shadow_desired_topic_name = f"$aws/things/Sensor/shadow/name/{self.sensor_id}/update/desired"
self.topic_name = f"sensor/{zone_id}/{equip_id}/{self.sensor_id}/{self.type}"
self.target_vibration = None # Initial value for shadow)

self.mu = 3.5 # ํ‰๊ท  ์ง„๋™๊ฐ’
self.sigma = 2 # ํ‘œ์ค€ํŽธ์ฐจ (์ง„๋™์˜ ๋ณ€๋™ํญ)

# ์ ˆ๋‹จ ๋ฒ”์œ„ ์„ค์ • (์ตœ์†Œ๊ฐ’ 0, ์ตœ๋Œ€๊ฐ’ 10์œผ๋กœ ์„ค์ •)
self.lower = 0
self.upper = 10

# ์ •๊ทœ๋ถ„ํฌ ๋ฒ”์œ„์˜ a, b ๊ฐ’ ๊ณ„์‚ฐ
self.a = (self.lower - self.mu) / self.sigma
self.b = (self.upper - self.mu) / self.sigma

# ๋ฐ์ดํ„ฐ ์ƒ์„ฑ ๋กœ์ง์„ ์ •์˜ (์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ๋งˆ๋‹ค ๋‹ค๋ฅด๊ฒŒ ๊ตฌํ˜„)
def _generate_data(self) -> dict:
return {
"zoneId": self.zone_id,
"equipId": self.equip_id,
"sensorId": self.sensor_id,
"sensorType": self.type,
"val": round(random.uniform(0.1 + self.idx, 10.0 + self.idx), 2)
"val": round(truncnorm.rvs(self.a, self.b, loc=self.mu, scale=self.sigma), 2)
}


Expand Down
2 changes: 1 addition & 1 deletion service/simulation/simulateTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,5 @@ def run_simulation_from_json(json_file_path):

if __name__ == "__main__":
# JSON ํŒŒ์ผ ๊ฒฝ๋กœ
json_file_path = "service/simulation/simulation_cconfig.json"
json_file_path = "simulation_cconfig.json"
run_simulation_from_json(json_file_path)
Loading