Procházet zdrojové kódy

chore: move relevant types to app context, create new health types

master
Blaz Smehov před 1 týdnem
rodič
revize
7f10683483
23 změnil soubory, kde provedl 242 přidání a 170 odebrání
  1. binární
      bridge
  2. binární
      decoder
  3. +2
    -2
      internal/app/decoder/app.go
  4. +2
    -2
      internal/app/location/app.go
  5. +3
    -3
      internal/app/server/app.go
  6. +1
    -1
      internal/pkg/apiclient/updatedb.go
  7. +2
    -1
      internal/pkg/bridge/handler.go
  8. +20
    -21
      internal/pkg/common/appcontext/context.go
  9. +1
    -1
      internal/pkg/common/appcontext/type_methods.go
  10. +100
    -0
      internal/pkg/common/appcontext/types.go
  11. +3
    -2
      internal/pkg/common/utils/beacons.go
  12. +2
    -2
      internal/pkg/common/utils/distance.go
  13. +3
    -3
      internal/pkg/controller/settings_controller.go
  14. +2
    -1
      internal/pkg/database/database.go
  15. +2
    -2
      internal/pkg/decoder/process.go
  16. +20
    -0
      internal/pkg/kafkaclient/manager.go
  17. +4
    -5
      internal/pkg/location/assign.go
  18. +71
    -0
      internal/pkg/model/health.go
  19. +4
    -2
      internal/pkg/model/parser.go
  20. +0
    -13
      internal/pkg/model/settings.go
  21. +0
    -109
      internal/pkg/model/types.go
  22. binární
      location
  23. binární
      server

binární
bridge Zobrazit soubor


binární
decoder Zobrazit soubor


+ 2
- 2
internal/app/decoder/app.go Zobrazit soubor

@@ -19,7 +19,7 @@ type DecoderApp struct {
KafkaManager *kafkaclient.KafkaManager
AppState *appcontext.AppState
ParserRegistry *model.ParserRegistry
ChRaw chan model.BeaconAdvertisement
ChRaw chan appcontext.BeaconAdvertisement
ChParser chan model.KafkaParser
Cleanup func()
wg sync.WaitGroup
@@ -48,7 +48,7 @@ func New(cfg *config.Config) (*DecoderApp, error) {
KafkaManager: kafkaManager,
AppState: appState,
ParserRegistry: registry,
ChRaw: make(chan model.BeaconAdvertisement, config.LARGE_CHANNEL_SIZE),
ChRaw: make(chan appcontext.BeaconAdvertisement, config.LARGE_CHANNEL_SIZE),
ChParser: make(chan model.KafkaParser, config.SMALL_CHANNEL_SIZE),
Cleanup: cleanup,
}, nil


+ 2
- 2
internal/app/location/app.go Zobrazit soubor

@@ -22,7 +22,7 @@ type LocationApp struct {
KafkaManager *kafkaclient.KafkaManager
AppState *appcontext.AppState
Inferencer pkglocation.Inferencer
ChRaw chan model.BeaconAdvertisement
ChRaw chan appcontext.BeaconAdvertisement
ChSettings chan map[string]any
Cleanup func()
wg sync.WaitGroup
@@ -47,7 +47,7 @@ func New(cfg *config.Config) (*LocationApp, error) {
KafkaManager: kafkaManager,
AppState: appState,
Inferencer: pkglocation.NewDefaultInferencer(cfg.TLSInsecureSkipVerify),
ChRaw: make(chan model.BeaconAdvertisement, config.LARGE_CHANNEL_SIZE),
ChRaw: make(chan appcontext.BeaconAdvertisement, config.LARGE_CHANNEL_SIZE),
ChSettings: make(chan map[string]any, config.SMALL_CHANNEL_SIZE),
Cleanup: cleanup,
}, nil


+ 3
- 3
internal/app/server/app.go Zobrazit soubor

@@ -28,7 +28,7 @@ type ServerApp struct {
KafkaManager *kafkaclient.KafkaManager
AppState *appcontext.AppState
ChLoc chan model.HTTPLocation
ChEvents chan model.BeaconEvent
ChEvents chan appcontext.BeaconEvent
ctx context.Context
Server *http.Server
Cleanup func()
@@ -98,12 +98,12 @@ func (a *ServerApp) Init(ctx context.Context) error {
slog.Error("UpdateDB", "err", err)
}

readerTopics := []string{"locevents", "alertbeacons"}
readerTopics := []string{"locevents", "alertbeacons", "health"}
a.KafkaManager.PopulateKafkaManager(a.Cfg.KafkaURL, "server", readerTopics)
slog.Info("Kafka readers initialized", "topics", readerTopics)

a.ChLoc = make(chan model.HTTPLocation, config.SMALL_CHANNEL_SIZE)
a.ChEvents = make(chan model.BeaconEvent, config.MEDIUM_CHANNEL_SIZE)
a.ChEvents = make(chan appcontext.BeaconEvent, config.MEDIUM_CHANNEL_SIZE)

a.wg.Add(2)
go kafkaclient.Consume(a.KafkaManager.GetReader("locevents"), a.ChLoc, ctx, &a.wg)


+ 1
- 1
internal/pkg/apiclient/updatedb.go Zobrazit soubor

@@ -70,7 +70,7 @@ func UpdateDB(db *gorm.DB, ctx context.Context, cfg *config.Config, writer *kafk
}
}

var settings model.Settings
var settings appcontext.Settings
db.First(&settings)
if settings.ID == 0 {
msg := "settings are empty"


+ 2
- 1
internal/pkg/bridge/handler.go Zobrazit soubor

@@ -7,6 +7,7 @@ import (
"strings"
"time"

"github.com/AFASystems/presence/internal/pkg/common/appcontext"
"github.com/AFASystems/presence/internal/pkg/kafkaclient"
"github.com/AFASystems/presence/internal/pkg/model"
"github.com/segmentio/kafka-go"
@@ -42,7 +43,7 @@ func HandleMQTTMessage(topic string, payload []byte, lookup BeaconLookup, writer
if !ok {
continue
}
adv := model.BeaconAdvertisement{
adv := appcontext.BeaconAdvertisement{
ID: id,
Hostname: hostname,
MAC: reading.MAC,


+ 20
- 21
internal/pkg/common/appcontext/context.go Zobrazit soubor

@@ -5,16 +5,15 @@ import (
"log/slog"
"os"

"github.com/AFASystems/presence/internal/pkg/model"
"github.com/mitchellh/mapstructure"
)

// AppState provides centralized access to application state
type AppState struct {
beacons model.BeaconsList
settings model.Settings
beaconEvents model.BeaconEventList
beaconsLookup model.BeaconsLookup
beacons BeaconsList
settings Settings
beaconEvents BeaconEventList
beaconsLookup BeaconsLookup
}

func getEnv(key, def string) string {
@@ -27,10 +26,10 @@ func getEnv(key, def string) string {
// NewAppState creates a new application context AppState with default values
func NewAppState() *AppState {
return &AppState{
beacons: model.BeaconsList{
Beacons: make(map[string]model.Beacon),
beacons: BeaconsList{
Beacons: make(map[string]Beacon),
},
settings: model.Settings{
settings: Settings{
ID: 1,
CurrentAlgorithm: getEnv("ALGORITHM", "filter"),
LocationConfidence: 4,
@@ -41,29 +40,29 @@ func NewAppState() *AppState {
RSSIEnforceThreshold: false,
RSSIMinThreshold: 100,
},
beaconEvents: model.BeaconEventList{
Beacons: make(map[string]model.BeaconEvent),
beaconEvents: BeaconEventList{
Beacons: make(map[string]BeaconEvent),
},
beaconsLookup: model.BeaconsLookup{
beaconsLookup: BeaconsLookup{
Lookup: make(map[string]string),
},
}
}

// GetBeacons returns thread-safe access to beacons list
func (m *AppState) GetBeacons() *model.BeaconsList {
func (m *AppState) GetBeacons() *BeaconsList {
m.beacons.Lock.RLock()
defer m.beacons.Lock.RUnlock()
return &m.beacons
}

// GetSettings returns thread-safe access to settings
func (m *AppState) GetSettings() *model.Settings {
func (m *AppState) GetSettings() *Settings {
return &m.settings
}

// GetBeaconEvents returns thread-safe access to beacon events
func (m *AppState) GetBeaconEvents() *model.BeaconEventList {
func (m *AppState) GetBeaconEvents() *BeaconEventList {
m.beaconEvents.Lock.RLock()
defer m.beaconEvents.Lock.RUnlock()
return &m.beaconEvents
@@ -98,7 +97,7 @@ func (m *AppState) BeaconExists(id string) (string, bool) {
}

// GetBeacon returns a beacon by ID (thread-safe)
func (m *AppState) GetBeacon(id string) (model.Beacon, bool) {
func (m *AppState) GetBeacon(id string) (Beacon, bool) {
m.beacons.Lock.RLock()
defer m.beacons.Lock.RUnlock()

@@ -107,7 +106,7 @@ func (m *AppState) GetBeacon(id string) (model.Beacon, bool) {
}

// UpdateBeacon updates a beacon in the list (thread-safe)
func (m *AppState) UpdateBeacon(id string, beacon model.Beacon) {
func (m *AppState) UpdateBeacon(id string, beacon Beacon) {
m.beacons.Lock.Lock()
defer m.beacons.Lock.Unlock()

@@ -115,7 +114,7 @@ func (m *AppState) UpdateBeacon(id string, beacon model.Beacon) {
}

// GetBeaconEvent returns a beacon event by ID (thread-safe)
func (m *AppState) GetBeaconEvent(id string) (model.BeaconEvent, bool) {
func (m *AppState) GetBeaconEvent(id string) (BeaconEvent, bool) {
m.beaconEvents.Lock.RLock()
defer m.beaconEvents.Lock.RUnlock()

@@ -124,7 +123,7 @@ func (m *AppState) GetBeaconEvent(id string) (model.BeaconEvent, bool) {
}

// UpdateBeaconEvent updates a beacon event in the list (thread-safe)
func (m *AppState) UpdateBeaconEvent(id string, event model.BeaconEvent) {
func (m *AppState) UpdateBeaconEvent(id string, event BeaconEvent) {
m.beaconEvents.Lock.Lock()
defer m.beaconEvents.Lock.Unlock()

@@ -132,11 +131,11 @@ func (m *AppState) UpdateBeaconEvent(id string, event model.BeaconEvent) {
}

// GetAllBeacons returns a copy of all beacons
func (m *AppState) GetAllBeacons() map[string]model.Beacon {
func (m *AppState) GetAllBeacons() map[string]Beacon {
m.beacons.Lock.RLock()
defer m.beacons.Lock.RUnlock()

beacons := make(map[string]model.Beacon)
beacons := make(map[string]Beacon)
for id, beacon := range m.beacons.Beacons {
beacons[id] = beacon
}
@@ -152,7 +151,7 @@ func (m *AppState) GetBeaconCount() int {
}

// GetSettingsValue returns current settings as a value
func (m *AppState) GetSettingsValue() model.Settings {
func (m *AppState) GetSettingsValue() Settings {
return m.settings
}



internal/pkg/model/type_methods.go → internal/pkg/common/appcontext/type_methods.go Zobrazit soubor

@@ -1,4 +1,4 @@
package model
package appcontext

import (
"crypto/sha256"

+ 100
- 0
internal/pkg/common/appcontext/types.go Zobrazit soubor

@@ -0,0 +1,100 @@
package appcontext

import "sync"

// BeaconAdvertisement represents the JSON payload received from beacon advertisements.
type BeaconAdvertisement struct {
ID string
Hostname string `json:"hostname"`
MAC string `json:"mac"`
RSSI int64 `json:"rssi"`
ScanResponse string `json:"is_scan_response"`
Type string `json:"type"`
Data string `json:"data"`
BeaconType string `json:"beacon_type"`
UUID string `json:"uuid"`
Major string `json:"major"`
Minor string `json:"minor"`
TXPower string `json:"tx_power"`
NamespaceID string `json:"namespace"`
InstanceID string `json:"instance_id"`
HSButtonCounter int64 `json:"hb_button_counter"`
HSButtonPrev int64 `json:"hb_button_counter_prev"`
HSBatteryLevel int64 `json:"hb_button_battery"`
HSRandomNonce string `json:"hb_button_random"`
HSButtonMode string `json:"hb_button_mode"`
}

// BeaconMetric stores signal and distance data for a beacon.
type BeaconMetric struct {
Location string
Distance float64
RSSI int64
Timestamp int64
}

// Beacon holds all relevant information about a tracked beacon device.
type Beacon struct {
Name string `json:"name"`
ID string `json:"beacon_id"`
BeaconType string `json:"beacon_type"`
BeaconLocation string `json:"beacon_location"`
LastSeen int64 `json:"last_seen"`
IncomingJSON BeaconAdvertisement `json:"incoming_json"`
Distance float64 `json:"distance"`
PreviousLocation string
PreviousConfidentLocation string
ExpiredLocation string
LocationConfidence int64
LocationHistory []string
BeaconMetrics []BeaconMetric
Location string `json:"location"`
HSButtonCounter int64 `json:"hs_button_counter"`
HSButtonPrev int64 `json:"hs_button_counter_prev"`
HSBattery int64 `json:"hs_button_battery"`
HSRandomNonce string `json:"hs_button_random"`
HSButtonMode string `json:"hs_button_mode"`
Event int `json:"beacon_event"`
}

type Settings struct {
ID int `gorm:"primaryKey"` // this is always 1
CurrentAlgorithm string `json:"current_algorithm" mapstructure:"current_algorithm"`
LocationConfidence int64 `json:"location_confidence" mapstructure:"location_confidence"`
LastSeenThreshold int64 `json:"last_seen_threshold" mapstructure:"last_seen_threshold"`
BeaconMetricSize int `json:"beacon_metric_size" mapstructure:"beacon_metric_size"`
HASendInterval int `json:"HA_send_interval" mapstructure:"HA_send_interval"`
HASendChangesOnly bool `json:"HA_send_changes_only" mapstructure:"HA_send_changes_only"`
RSSIEnforceThreshold bool `json:"RSSI_enforce_threshold" mapstructure:"RSSI_enforce_threshold"`
RSSIMinThreshold int64 `json:"RSSI_min_threshold" mapstructure:"RSSI_min_threshold"`
}

type BeaconEvent struct {
Name string
ID string
Type string
Battery uint32
Event int
AccX int16
AccY int16
AccZ int16
Temperature uint16
Heart int16
BtnPressed bool
}

// BeaconsList holds all known beacons and their synchronization lock.
type BeaconsList struct {
Beacons map[string]Beacon `json:"beacons"`
Lock sync.RWMutex
}

type BeaconEventList struct {
Beacons map[string]BeaconEvent
Lock sync.RWMutex
}

type BeaconsLookup struct {
Lookup map[string]string
Lock sync.RWMutex
}

+ 3
- 2
internal/pkg/common/utils/beacons.go Zobrazit soubor

@@ -1,6 +1,7 @@
package utils

import (
"github.com/AFASystems/presence/internal/pkg/common/appcontext"
"github.com/AFASystems/presence/internal/pkg/model"
)

@@ -37,8 +38,8 @@ func RemoveFlagBytes(b []byte) []byte {
}

// Generate event based on the Beacon type
func LoopADStructures(b []byte, i [][2]int, id string, parserRegistry *model.ParserRegistry) model.BeaconEvent {
be := model.BeaconEvent{}
func LoopADStructures(b []byte, i [][2]int, id string, parserRegistry *model.ParserRegistry) appcontext.BeaconEvent {
be := appcontext.BeaconEvent{}
for _, r := range i {
ad := b[r[0]:r[1]]
if !isValidADStructure(ad) {


+ 2
- 2
internal/pkg/common/utils/distance.go Zobrazit soubor

@@ -4,10 +4,10 @@ import (
"math"
"strconv"

"github.com/AFASystems/presence/internal/pkg/model"
"github.com/AFASystems/presence/internal/pkg/common/appcontext"
)

func CalculateDistance(adv model.BeaconAdvertisement) float64 {
func CalculateDistance(adv appcontext.BeaconAdvertisement) float64 {
rssi := adv.RSSI
power := adv.TXPower
ratio := float64(rssi) * (1.0 / float64(twosComp(power)))


+ 3
- 3
internal/pkg/controller/settings_controller.go Zobrazit soubor

@@ -7,15 +7,15 @@ import (
"net/http"

"github.com/AFASystems/presence/internal/pkg/api/response"
"github.com/AFASystems/presence/internal/pkg/common/appcontext"
"github.com/AFASystems/presence/internal/pkg/kafkaclient"
"github.com/AFASystems/presence/internal/pkg/model"
"github.com/segmentio/kafka-go"
"gorm.io/gorm"
)

func SettingsListController(db *gorm.DB, context context.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var settings []model.Settings
var settings []appcontext.Settings
if err := db.WithContext(context).Find(&settings).Error; err != nil {
response.InternalError(w, "failed to list settings", err)
return
@@ -34,7 +34,7 @@ func SettingsUpdateController(db *gorm.DB, writer *kafka.Writer, context context

slog.Info("updating settings", "updates", updates)

if err := db.WithContext(context).Model(&model.Settings{}).Where("id = ?", 1).Updates(updates).Error; err != nil {
if err := db.WithContext(context).Model(&appcontext.Settings{}).Where("id = ?", 1).Updates(updates).Error; err != nil {
response.InternalError(w, "failed to update settings", err)
return
}


+ 2
- 1
internal/pkg/database/database.go Zobrazit soubor

@@ -4,6 +4,7 @@ import (
"fmt"
"log/slog"

"github.com/AFASystems/presence/internal/pkg/common/appcontext"
"github.com/AFASystems/presence/internal/pkg/config"
"github.com/AFASystems/presence/internal/pkg/model"
"gorm.io/driver/postgres"
@@ -25,7 +26,7 @@ func Connect(cfg *config.Config) (*gorm.DB, error) {
return nil, err
}

if err := db.AutoMigrate(&model.Gateway{}, model.Zone{}, model.TrackerZones{}, model.Tracker{}, model.Config{}, model.Settings{}, model.Tracks{}, &model.Alert{}); err != nil {
if err := db.AutoMigrate(&model.Gateway{}, model.Zone{}, model.TrackerZones{}, model.Tracker{}, model.Config{}, appcontext.Settings{}, model.Tracks{}, &model.Alert{}); err != nil {
return nil, err
}



+ 2
- 2
internal/pkg/decoder/process.go Zobrazit soubor

@@ -16,14 +16,14 @@ import (
)

// ProcessIncoming decodes a beacon advertisement and writes the event to the writer if it changed.
func ProcessIncoming(adv model.BeaconAdvertisement, appState *appcontext.AppState, writer *kafka.Writer, registry *model.ParserRegistry) {
func ProcessIncoming(adv appcontext.BeaconAdvertisement, appState *appcontext.AppState, writer *kafka.Writer, registry *model.ParserRegistry) {
if err := DecodeBeacon(adv, appState, writer, registry); err != nil {
slog.Error("decoding beacon", "err", err, "id", adv.ID)
}
}

// DecodeBeacon hex-decodes the payload, runs the parser registry, dedupes by event hash, and writes to writer.
func DecodeBeacon(adv model.BeaconAdvertisement, appState *appcontext.AppState, writer *kafka.Writer, registry *model.ParserRegistry) error {
func DecodeBeacon(adv appcontext.BeaconAdvertisement, appState *appcontext.AppState, writer *kafka.Writer, registry *model.ParserRegistry) error {
beacon := strings.TrimSpace(adv.Data)
id := adv.ID
if beacon == "" {


+ 20
- 0
internal/pkg/kafkaclient/manager.go Zobrazit soubor

@@ -121,3 +121,23 @@ func (m *KafkaManager) GetWriter(topic string) *kafka.Writer {
defer m.kafkaWritersMap.KafkaWritersLock.RUnlock()
return m.kafkaWritersMap.KafkaWriters[topic]
}

func (m *KafkaManager) GetReaders() []string {
m.kafkaReadersMap.KafkaReadersLock.RLock()
var readers []string
for key := range m.kafkaReadersMap.KafkaReaders {
readers = append(readers, key)
}
m.kafkaReadersMap.KafkaReadersLock.RUnlock()
return readers
}

func (m *KafkaManager) GetWriters() []string {
m.kafkaWritersMap.KafkaWritersLock.RLock()
var writers []string
for key := range m.kafkaWritersMap.KafkaWriters {
writers = append(writers, key)
}
m.kafkaWritersMap.KafkaWritersLock.RUnlock()
return writers
}

+ 4
- 5
internal/pkg/location/assign.go Zobrazit soubor

@@ -6,12 +6,11 @@ import (

"github.com/AFASystems/presence/internal/pkg/common/appcontext"
"github.com/AFASystems/presence/internal/pkg/common/utils"
"github.com/AFASystems/presence/internal/pkg/model"
)

// AssignBeaconToList updates app state with a new beacon advertisement: appends a metric
// to the beacon's sliding window and updates last seen.
func AssignBeaconToList(adv model.BeaconAdvertisement, appState *appcontext.AppState) {
func AssignBeaconToList(adv appcontext.BeaconAdvertisement, appState *appcontext.AppState) {
id := adv.ID
now := time.Now().Unix()
settings := appState.GetSettingsValue()
@@ -23,17 +22,17 @@ func AssignBeaconToList(adv model.BeaconAdvertisement, appState *appcontext.AppS

beacon, ok := appState.GetBeacon(id)
if !ok {
beacon = model.Beacon{ID: id}
beacon = appcontext.Beacon{ID: id}
}

beacon.IncomingJSON = adv
beacon.LastSeen = now

if beacon.BeaconMetrics == nil {
beacon.BeaconMetrics = make([]model.BeaconMetric, 0, settings.BeaconMetricSize)
beacon.BeaconMetrics = make([]appcontext.BeaconMetric, 0, settings.BeaconMetricSize)
}

metric := model.BeaconMetric{
metric := appcontext.BeaconMetric{
Distance: utils.CalculateDistance(adv),
Timestamp: now,
RSSI: int64(adv.RSSI),


+ 71
- 0
internal/pkg/model/health.go Zobrazit soubor

@@ -0,0 +1,71 @@
package model

import (
"encoding/json"
"sync"
"time"

"github.com/AFASystems/presence/internal/pkg/common/appcontext"
"github.com/AFASystems/presence/internal/pkg/kafkaclient"
)

type BaseHealth struct {
Lock sync.RWMutex
Uptime time.Duration `json:"uptime"`
ActiveReaders []string `json:"activeReaders"`
ActiveWriters []string `json:"activeWriters"`
ActiveBeacons []string `json:"activeBeacons"`
}

type DecoderHealth struct {
BaseHealth
// current active configs ? dont know yet how
}

type LocationHealth struct {
BaseHealth
ActiveSettings []appcontext.Settings `json:"activeSettings"`
}

type BridgeHealth struct {
BaseHealth
}

func (b *BaseHealth) GetUptime(startTime time.Time) {
b.Lock.Lock()
b.Uptime = time.Since(startTime)
b.Lock.Unlock()
}

func (b *BaseHealth) GetActiveReaders(m *kafkaclient.KafkaManager) {
b.Lock.Lock()
b.ActiveReaders = m.GetReaders()
b.Lock.Unlock()
}

func (b *BaseHealth) GetActiveWriters(m *kafkaclient.KafkaManager) {
b.Lock.Lock()
b.ActiveWriters = m.GetWriters()
b.Lock.Unlock()
}

func (b *BaseHealth) GetActiveBeacons(m *appcontext.AppState) {
b.Lock.Lock()
beacons := m.GetAllBeacons()
for beacon := range beacons {
b.ActiveBeacons = append(b.ActiveBeacons, beacon)
}
b.Lock.Unlock()
}

func (d *DecoderHealth) Marshal() ([]byte, error) {
return json.Marshal(d)
}

func (l *LocationHealth) Marshal() ([]byte, error) {
return json.Marshal(l)
}

func (b *BridgeHealth) Marshal() ([]byte, error) {
return json.Marshal(b)
}

+ 4
- 2
internal/pkg/model/parser.go Zobrazit soubor

@@ -6,6 +6,8 @@ import (
"fmt"
"log/slog"
"sync"

"github.com/AFASystems/presence/internal/pkg/common/appcontext"
)

type ParserConfig struct {
@@ -77,9 +79,9 @@ func (p *ParserRegistry) Unregister(name string) {
// TODO: change this to be dynamic, maybe event is interface with no predefined properties
// or types

func (b *BeaconParser) Parse(name string, ad []byte) (BeaconEvent, bool) {
func (b *BeaconParser) Parse(name string, ad []byte) (appcontext.BeaconEvent, bool) {
flag := false
event := BeaconEvent{Type: name}
event := appcontext.BeaconEvent{Type: name}
if cfg, ok := b.configs["battery"]; ok {
event.Battery = uint32(b.extract(ad, cfg).(uint16))
flag = true


+ 0
- 13
internal/pkg/model/settings.go Zobrazit soubor

@@ -1,13 +0,0 @@
package model

type Settings struct {
ID int `gorm:"primaryKey"` // this is always 1
CurrentAlgorithm string `json:"current_algorithm" mapstructure:"current_algorithm"`
LocationConfidence int64 `json:"location_confidence" mapstructure:"location_confidence"`
LastSeenThreshold int64 `json:"last_seen_threshold" mapstructure:"last_seen_threshold"`
BeaconMetricSize int `json:"beacon_metric_size" mapstructure:"beacon_metric_size"`
HASendInterval int `json:"HA_send_interval" mapstructure:"HA_send_interval"`
HASendChangesOnly bool `json:"HA_send_changes_only" mapstructure:"HA_send_changes_only"`
RSSIEnforceThreshold bool `json:"RSSI_enforce_threshold" mapstructure:"RSSI_enforce_threshold"`
RSSIMinThreshold int64 `json:"RSSI_min_threshold" mapstructure:"RSSI_min_threshold"`
}

+ 0
- 109
internal/pkg/model/types.go Zobrazit soubor

@@ -1,40 +1,5 @@
package model

import (
"sync"
)

// BeaconAdvertisement represents the JSON payload received from beacon advertisements.
type BeaconAdvertisement struct {
ID string
Hostname string `json:"hostname"`
MAC string `json:"mac"`
RSSI int64 `json:"rssi"`
ScanResponse string `json:"is_scan_response"`
Type string `json:"type"`
Data string `json:"data"`
BeaconType string `json:"beacon_type"`
UUID string `json:"uuid"`
Major string `json:"major"`
Minor string `json:"minor"`
TXPower string `json:"tx_power"`
NamespaceID string `json:"namespace"`
InstanceID string `json:"instance_id"`
HSButtonCounter int64 `json:"hb_button_counter"`
HSButtonPrev int64 `json:"hb_button_counter_prev"`
HSBatteryLevel int64 `json:"hb_button_battery"`
HSRandomNonce string `json:"hb_button_random"`
HSButtonMode string `json:"hb_button_mode"`
}

// BeaconMetric stores signal and distance data for a beacon.
type BeaconMetric struct {
Location string
Distance float64
RSSI int64
Timestamp int64
}

// HTTPLocation describes a beacon's state as served over HTTP.
type HTTPLocation struct {
Method string `json:"method"`
@@ -50,80 +15,6 @@ type HTTPLocation struct {
MAC string `json:"mac"`
}

// Beacon holds all relevant information about a tracked beacon device.
type Beacon struct {
Name string `json:"name"`
ID string `json:"beacon_id"`
BeaconType string `json:"beacon_type"`
BeaconLocation string `json:"beacon_location"`
LastSeen int64 `json:"last_seen"`
IncomingJSON BeaconAdvertisement `json:"incoming_json"`
Distance float64 `json:"distance"`
PreviousLocation string
PreviousConfidentLocation string
ExpiredLocation string
LocationConfidence int64
LocationHistory []string
BeaconMetrics []BeaconMetric
Location string `json:"location"`
HSButtonCounter int64 `json:"hs_button_counter"`
HSButtonPrev int64 `json:"hs_button_counter_prev"`
HSBattery int64 `json:"hs_button_battery"`
HSRandomNonce string `json:"hs_button_random"`
HSButtonMode string `json:"hs_button_mode"`
Event int `json:"beacon_event"`
}

type BeaconEvent struct {
Name string
ID string
Type string
Battery uint32
Event int
AccX int16
AccY int16
AccZ int16
Temperature uint16
Heart int16
BtnPressed bool
}

type HTTPResult struct {
BeaconId string `json:"id"`
Name string `json:"name"`
ID string `json:"MAC"`
Status string `json:"status"`
Model string `json:"model"`
Position string `json:"position"`
Notes string `json:"notes"`
X float32 `json:"x"`
Y float32 `json:"y"`
Zone string `json:"zone"`
Building string `json:"building"`
BeaconType string `json:"type"`
Battery int64 `json:"battery"`
Event int `json:"event"`
Distance float64 `json:"distance"`
LastSeen int64 `json:"timestamp"`
PreviousConfidentLocation string `json:"previous_confident_location"`
}

// BeaconsList holds all known beacons and their synchronization lock.
type BeaconsList struct {
Beacons map[string]Beacon `json:"beacons"`
Lock sync.RWMutex
}

type BeaconEventList struct {
Beacons map[string]BeaconEvent
Lock sync.RWMutex
}

type BeaconsLookup struct {
Lookup map[string]string
Lock sync.RWMutex
}

// RawReading represents an incoming raw sensor reading.
type RawReading struct {
Timestamp string `json:"timestamp"`


binární
location Zobrazit soubor


binární
server Zobrazit soubor


Načítá se…
Zrušit
Uložit