misc: codebase path cleanup
This commit is contained in:
+49
-7
@@ -40,6 +40,23 @@ def parse_actor_value(value):
|
||||
return 0
|
||||
|
||||
|
||||
def parse_actor_float(value):
|
||||
if isinstance(value, bool):
|
||||
return 1.0 if value else 0.0
|
||||
if isinstance(value, (int, float)):
|
||||
return float(value)
|
||||
if isinstance(value, str):
|
||||
if value.strip().lower() in {"true", "on"}:
|
||||
return 1.0
|
||||
if value.strip().lower() in {"false", "off"}:
|
||||
return 0.0
|
||||
try:
|
||||
return float(value)
|
||||
except ValueError:
|
||||
return 0.0
|
||||
return 0.0
|
||||
|
||||
|
||||
def load_env_file(path: str) -> dict:
|
||||
env = {}
|
||||
try:
|
||||
@@ -60,10 +77,14 @@ class DeviceEmulator:
|
||||
self.mac_address = generate_mac()
|
||||
self.device_id = mac_to_device_uuid(self.mac_address)
|
||||
self.sensor_id = uuid.uuid5(self.device_id, "sensor-0")
|
||||
self.sensor_bool_id = uuid.uuid5(self.device_id, "sensor-1")
|
||||
self.actor_id = uuid.uuid5(self.device_id, "actor-0")
|
||||
self.actor_float_id = uuid.uuid5(self.device_id, "actor-1")
|
||||
|
||||
self.actor_value = 0
|
||||
self.actor_float_value = 0.0
|
||||
self.temperature = 22.5
|
||||
self.switch_state = False
|
||||
self.publish_interval = 5
|
||||
|
||||
env_path = os.path.join(os.path.dirname(__file__), ".env")
|
||||
@@ -93,6 +114,12 @@ class DeviceEmulator:
|
||||
"name": "Temperature",
|
||||
"type": "DHT22",
|
||||
"data_type_id": 2,
|
||||
},
|
||||
{
|
||||
"id": str(self.sensor_bool_id),
|
||||
"name": "Presence",
|
||||
"type": "PIR",
|
||||
"data_type_id": 1,
|
||||
}
|
||||
],
|
||||
"actors": [
|
||||
@@ -101,6 +128,12 @@ class DeviceEmulator:
|
||||
"name": "Binary Switch",
|
||||
"type": "Relay",
|
||||
"data_type_id": 1,
|
||||
},
|
||||
{
|
||||
"id": str(self.actor_float_id),
|
||||
"name": "Dimmer",
|
||||
"type": "PWM",
|
||||
"data_type_id": 2,
|
||||
}
|
||||
],
|
||||
}
|
||||
@@ -121,15 +154,16 @@ class DeviceEmulator:
|
||||
self.client.publish(TOPIC, json.dumps(payload), qos=0)
|
||||
print(f"sensor_reading published: {self.temperature}C")
|
||||
|
||||
def publish_actor_state(self):
|
||||
def publish_bool_sensor_reading(self):
|
||||
self.switch_state = not self.switch_state
|
||||
payload = {
|
||||
"type": "actor_state",
|
||||
"actor_id": str(self.actor_id),
|
||||
"value": self.actor_value,
|
||||
"updated_at": now_rfc3339(),
|
||||
"type": "sensor_reading",
|
||||
"sensor_id": str(self.sensor_bool_id),
|
||||
"value": self.switch_state,
|
||||
"value_at": now_rfc3339(),
|
||||
}
|
||||
self.client.publish(TOPIC, json.dumps(payload), qos=0)
|
||||
print(f"actor_state published: {self.actor_value}")
|
||||
print(f"sensor_reading published: presence={self.switch_state}")
|
||||
|
||||
def publish_device_state(self):
|
||||
payload = {
|
||||
@@ -164,11 +198,18 @@ class DeviceEmulator:
|
||||
if payload.get("sensor_id") == str(self.sensor_id):
|
||||
self.publish_sensor_reading()
|
||||
return
|
||||
if payload.get("sensor_id") == str(self.sensor_bool_id):
|
||||
self.publish_bool_sensor_reading()
|
||||
return
|
||||
|
||||
if msg_type == "actor_command":
|
||||
if payload.get("actor_id") == str(self.actor_id):
|
||||
self.actor_value = parse_actor_value(payload.get("value"))
|
||||
self.publish_actor_state()
|
||||
print(f"actor_command received; state={self.actor_value}")
|
||||
return
|
||||
if payload.get("actor_id") == str(self.actor_float_id):
|
||||
self.actor_float_value = parse_actor_float(payload.get("value"))
|
||||
print(f"actor_command received; dimmer={self.actor_float_value}")
|
||||
return
|
||||
|
||||
def run(self):
|
||||
@@ -178,6 +219,7 @@ class DeviceEmulator:
|
||||
while True:
|
||||
time.sleep(self.publish_interval)
|
||||
self.publish_sensor_reading()
|
||||
self.publish_bool_sensor_reading()
|
||||
finally:
|
||||
self.client.loop_stop()
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ services:
|
||||
- MYSQL_ROOT_PASSWORD=rootpass
|
||||
- MYSQL_DATABASE=lambdaiot
|
||||
volumes:
|
||||
- ../ai-improved.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
- ./sql-template.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-prootpass"]
|
||||
interval: 2s
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
-- Devices
|
||||
CREATE TABLE devices (
|
||||
id BINARY(16) NOT NULL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
location VARCHAR(255) NOT NULL,
|
||||
status_id SMALLINT UNSIGNED NOT NULL,
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE device_statuses (
|
||||
id SMALLINT UNSIGNED PRIMARY KEY,
|
||||
name VARCHAR(20) NOT NULL UNIQUE
|
||||
);
|
||||
|
||||
INSERT INTO device_statuses (id, name) VALUES
|
||||
(1,'ok'),(2,'pending'),(3,'lost'),(4,'disabled');
|
||||
|
||||
CREATE TABLE data_types (
|
||||
id SMALLINT UNSIGNED PRIMARY KEY,
|
||||
name VARCHAR(20) NOT NULL UNIQUE
|
||||
);
|
||||
INSERT INTO data_types (id, name) VALUES (1,'bool'),(2,'float');
|
||||
|
||||
-- Sensors
|
||||
CREATE TABLE sensors (
|
||||
id BINARY(16) NOT NULL PRIMARY KEY,
|
||||
device_id BINARY(16) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
type VARCHAR(255) NOT NULL,
|
||||
data_type_id SMALLINT UNSIGNED NOT NULL,
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
FOREIGN KEY (device_id) REFERENCES devices(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (data_type_id) REFERENCES data_types(id)
|
||||
);
|
||||
|
||||
|
||||
-- Sensor readings
|
||||
CREATE TABLE sensor_readings (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
sensor_id BINARY(16) NOT NULL,
|
||||
value DOUBLE NOT NULL,
|
||||
value_at DATETIME(6) NOT NULL,
|
||||
INDEX idx_sensor_time (sensor_id, value_at),
|
||||
FOREIGN KEY (sensor_id) REFERENCES sensors(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
-- Actors (actuators)
|
||||
CREATE TABLE actors (
|
||||
id BINARY(16) NOT NULL PRIMARY KEY,
|
||||
device_id BINARY(16) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
type VARCHAR(255) NOT NULL,
|
||||
data_type_id SMALLINT UNSIGNED NOT NULL,
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
FOREIGN KEY (device_id) REFERENCES devices(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (data_type_id) REFERENCES data_types(id)
|
||||
);
|
||||
|
||||
-- Users table for authentication
|
||||
CREATE TABLE users (
|
||||
id BINARY(16) NOT NULL PRIMARY KEY,
|
||||
username VARCHAR(50) NOT NULL UNIQUE,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
email VARCHAR(255),
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- Create index on username for faster lookups
|
||||
CREATE INDEX idx_username ON users(username);
|
||||
|
||||
-- Insert default admin user (password: password)
|
||||
-- bcrypt hash of "password"
|
||||
INSERT INTO users (id, username, password_hash, email)
|
||||
VALUES (
|
||||
UUID_TO_BIN(UUID()),
|
||||
'admin',
|
||||
'$2a$10$y5R/aLl7Ah9GbdcR57f4ze0lX12suTJQvPyJwLE0RJXqWpg7lStAC',
|
||||
'admin@example.com'
|
||||
);
|
||||
Reference in New Issue
Block a user