fix: devicecheck biznis logika
This commit is contained in:
@@ -48,6 +48,9 @@ func New(db *sql.DB, mq *mqtt.Client, topic string, interval, timeout time.Durat
|
||||
|
||||
// Start launches the periodic checker until the context is canceled.
|
||||
func (c *Checker) Start(ctx context.Context) {
|
||||
if c != nil {
|
||||
log.Printf("devicecheck: starting (topic=%s interval=%s timeout=%s)", c.Topic, c.Interval, c.Timeout)
|
||||
}
|
||||
go c.loop(ctx)
|
||||
}
|
||||
|
||||
@@ -76,7 +79,12 @@ func (c *Checker) HandleMessage(payload []byte) {
|
||||
return
|
||||
}
|
||||
|
||||
// Notify waiter if present
|
||||
msgType := strings.ToLower(strings.TrimSpace(msg.Type))
|
||||
if msgType != "device_check_response" && msgType != "device_state" && !strings.EqualFold(msg.Status, "ok") {
|
||||
return
|
||||
}
|
||||
|
||||
// Notify waiter if present for valid response/state
|
||||
c.mu.Lock()
|
||||
ch := c.waiters[id]
|
||||
c.mu.Unlock()
|
||||
@@ -87,10 +95,8 @@ func (c *Checker) HandleMessage(payload []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
// Update status to ok on explicit ok or check response
|
||||
if msg.Type == "device_check_response" || msg.Type == "device_state" || strings.EqualFold(msg.Status, "ok") {
|
||||
_ = c.updateStatus(id, 1) // 1 = ok
|
||||
}
|
||||
// Update status to ok on explicit ok or check response/state
|
||||
_ = c.updateStatus(id, 1) // 1 = ok
|
||||
}
|
||||
|
||||
func (c *Checker) loop(ctx context.Context) {
|
||||
@@ -115,7 +121,7 @@ func (c *Checker) runOnce() {
|
||||
return
|
||||
}
|
||||
|
||||
rows, err := c.DB.Query("SELECT BIN_TO_UUID(id) FROM devices WHERE status_id != 4") // skip disabled
|
||||
rows, err := c.DB.Query("SELECT BIN_TO_UUID(id) FROM devices WHERE status_id NOT IN (3, 4)") // skip lost/disabled
|
||||
if err != nil {
|
||||
log.Printf("devicecheck: query devices failed: %v", err)
|
||||
return
|
||||
@@ -131,6 +137,14 @@ func (c *Checker) runOnce() {
|
||||
}
|
||||
ids = append(ids, strings.ToLower(id))
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
log.Printf("devicecheck: rows error: %v", err)
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
log.Printf("devicecheck: no devices found to check")
|
||||
return
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for _, id := range ids {
|
||||
@@ -148,10 +162,6 @@ func (c *Checker) checkDevice(deviceID string) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.updateStatus(deviceID, 2); err != nil { // 2 = pending
|
||||
log.Printf("devicecheck: set pending failed for %s: %v", deviceID, err)
|
||||
}
|
||||
|
||||
ch := make(chan struct{}, 1)
|
||||
c.mu.Lock()
|
||||
c.waiters[deviceID] = ch
|
||||
@@ -169,17 +179,22 @@ func (c *Checker) checkDevice(deviceID string) {
|
||||
|
||||
body, err := json.Marshal(payload)
|
||||
if err == nil {
|
||||
log.Printf("devicecheck: publish request for %s", deviceID)
|
||||
if err := c.MQTT.Publish(c.Topic, body); err != nil {
|
||||
log.Printf("devicecheck: publish failed for %s: %v", deviceID, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.updateStatus(deviceID, 2); err != nil { // 2 = pending
|
||||
log.Printf("devicecheck: set pending failed for %s: %v", deviceID, err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ch:
|
||||
if err := c.updateStatus(deviceID, 1); err != nil { // ok
|
||||
log.Printf("devicecheck: set ok failed for %s: %v", deviceID, err)
|
||||
}
|
||||
case <-time.After(c.Timeout):
|
||||
case <-time.After(c.Interval):
|
||||
if err := c.updateStatus(deviceID, 3); err != nil { // lost
|
||||
log.Printf("devicecheck: set lost failed for %s: %v", deviceID, err)
|
||||
}
|
||||
@@ -194,6 +209,19 @@ func (c *Checker) updateStatus(deviceID string, statusID int) error {
|
||||
if c == nil || c.DB == nil {
|
||||
return nil
|
||||
}
|
||||
_, err := c.DB.Exec("UPDATE devices SET status_id = ?, updated_at = NOW(6) WHERE id = UUID_TO_BIN(?)", statusID, deviceID)
|
||||
return err
|
||||
log.Printf("devicecheck: update status request %s -> %d", deviceID, statusID)
|
||||
res, err := c.DB.Exec("UPDATE devices SET status_id = ?, updated_at = NOW(6) WHERE id = UUID_TO_BIN(?)", statusID, deviceID)
|
||||
if err != nil {
|
||||
log.Printf("devicecheck: update status failed for %s -> %d: %v", deviceID, statusID, err)
|
||||
return err
|
||||
}
|
||||
rows, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
log.Printf("devicecheck: rows affected failed for %s -> %d: %v", deviceID, statusID, err)
|
||||
return err
|
||||
}
|
||||
if rows == 0 {
|
||||
log.Printf("devicecheck: no rows updated for %s -> %d", deviceID, statusID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user