add simulator

This commit is contained in:
Pedro Pérez 2025-10-09 23:35:31 +02:00
parent fcc0d06f96
commit fb58ce55fb
2 changed files with 94 additions and 1 deletions

View File

@ -21,12 +21,26 @@ const (
type Handlers struct {
service *Service
*iot.IoTDevice
simulator *Simulator
}
func NewHandlers(service *Service, iot *iot.IoTDevice) *Handlers {
simulator := Start(iot.NATS)
activeSensors, err := service.repo.ReadAllSensors()
if err != nil {
slog.Error("reading all sensors", "error", err)
}
for _, sensor := range activeSensors {
go simulator.SimulateSensor(sensor)
slog.Info("started simulator for sensor", "sensor_id", sensor.SensorID)
}
return &Handlers{
service: service,
IoTDevice: iot,
simulator: simulator,
}
}
@ -85,6 +99,8 @@ func (h *Handlers) register() {
return Sensor{}, err
}
go h.simulator.SimulateSensor(req)
return req, nil
})
})

View File

@ -1,3 +1,80 @@
package sensors
type Simulator struct{}
import (
"encoding/json"
"log/slog"
"math/rand"
"nats-app/internal/broker"
"time"
)
type Simulator struct {
*broker.NATS
}
func Start(nats *broker.NATS) *Simulator {
return &Simulator{
NATS: nats,
}
}
func (s *Simulator) SimulateSensor(sensor Sensor) {
ticker := time.NewTicker(*sensor.SamplingInterval * time.Second)
defer ticker.Stop()
for range ticker.C {
data := s.generateData(sensor)
if data.SensorID == "" {
slog.Warn("sensor data generation failed", "sensor_id", sensor.SensorID)
continue
}
payload, err := json.Marshal(data)
if err != nil {
slog.Error("failed to marshal sensor data", "error", err, "sensor_id", sensor.SensorID)
continue
}
subject := subjectSensorsData + sensor.SensorID
if err := s.Publish(subject, payload); err != nil {
slog.Error("failed to publish sensor data", "error", err, "subject", subject)
} else {
slog.Debug("sensor data published", "sensor_id", sensor.SensorID, "value", data.Value)
}
}
}
func (s *Simulator) generateData(sensor Sensor) SensorData {
now := time.Now()
data := SensorData{
SensorID: sensor.SensorID,
Timestamp: &now,
}
if rand.Float64() < 0.05 {
return SensorData{}
}
var value float64
switch sensor.SensorType {
case Temperature:
value = -20 + rand.Float64()*100
case Humidity:
value = 10 + rand.Float64()*90
case CarbonDioxide:
value = 980 + rand.Float64()*60
case Pressure:
value = 950 + rand.Float64()*100
case Proximity:
value = rand.Float64() * 400
case Light:
value = rand.Float64() * 10000
default:
value = rand.Float64() * 100
}
data.Value = &value
return data
}