Expand hints. Add RadioStatistics struct. Add new Order, DataAge and DataAgeMs.
This commit is contained in:
		
							parent
							
								
									163e3672ef
								
							
						
					
					
						commit
						851c6d01ec
					
				
					 2 changed files with 49 additions and 21 deletions
				
			
		
							
								
								
									
										61
									
								
								main.go
									
										
									
									
									
								
							
							
						
						
									
										61
									
								
								main.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -72,20 +72,34 @@ type InverterINV struct {
 | 
			
		|||
	YieldTotal  VUD `json:"YieldTotal"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RadioStatistics contains radio communication statistics
 | 
			
		||||
type RadioStatistics struct {
 | 
			
		||||
	TxRequest     int     `json:"tx_request"`
 | 
			
		||||
	TxReRequest   int     `json:"tx_re_request"`
 | 
			
		||||
	RxSuccess     int     `json:"rx_success"`
 | 
			
		||||
	RxFailNothing int     `json:"rx_fail_nothing"`
 | 
			
		||||
	RxFailPartial int     `json:"rx_fail_partial"`
 | 
			
		||||
	RxFailCorrupt int     `json:"rx_fail_corrupt"`
 | 
			
		||||
	RSSI          float64 `json:"rssi"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Inverter struct
 | 
			
		||||
type Inverter struct {
 | 
			
		||||
	Serial        string                 `json:"serial"`
 | 
			
		||||
	Name          string                 `json:"name"`
 | 
			
		||||
	Order         int                    `json:"order"`
 | 
			
		||||
	DataAge       int                    `json:"data_age"`
 | 
			
		||||
	DataAgeMs     int                    `json:"data_age_ms"`
 | 
			
		||||
	Producing     bool                   `json:"producing"`
 | 
			
		||||
	LimitRelative float64                `json:"limit_relative"`
 | 
			
		||||
	LimitAbsolute float64                `json:"limit_absolute"`
 | 
			
		||||
	AC            map[string]InverterAC  `json:"AC"`
 | 
			
		||||
	DC            map[string]InverterDC  `json:"DC"`
 | 
			
		||||
	Events        int                    `json:"events"`
 | 
			
		||||
	PollEnabled   bool                   `json:"poll_enabled"`
 | 
			
		||||
	Reachable     bool                   `json:"reachable"`
 | 
			
		||||
	DataAge       int                    `json:"data_age"`
 | 
			
		||||
	Events        int                    `json:"events"`
 | 
			
		||||
	AC            map[string]InverterAC  `json:"AC"`
 | 
			
		||||
	DC            map[string]InverterDC  `json:"DC"`
 | 
			
		||||
	INV           map[string]InverterINV `json:"INV"`
 | 
			
		||||
	RadioStats    RadioStatistics        `json:"radio_stats"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Total struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -98,6 +112,7 @@ type Hints struct {
 | 
			
		|||
	TimeSync        bool `json:"time_sync"`
 | 
			
		||||
	RadioProblem    bool `json:"radio_problem"`
 | 
			
		||||
	DefaultPassword bool `json:"default_password"`
 | 
			
		||||
	PinMappingIssue bool `json:"pin_mapping_issue"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type LiveData struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -165,7 +180,7 @@ var config Config
 | 
			
		|||
 | 
			
		||||
// LoadConfig attempts to read the configuration from options.json
 | 
			
		||||
// If it fails, it falls back to using environment variables
 | 
			
		||||
func loadConfig() Config {
 | 
			
		||||
func loadConfig() (Config, error) {
 | 
			
		||||
	configFilePath := os.Getenv("CONFIG_FILE")
 | 
			
		||||
	if configFilePath == "" {
 | 
			
		||||
		configFilePath = "/data/options.json"
 | 
			
		||||
| 
						 | 
				
			
			@ -176,20 +191,20 @@ func loadConfig() Config {
 | 
			
		|||
		// Successfully read the file, parse the JSON
 | 
			
		||||
		err = json.Unmarshal(data, &config)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatalf("Error parsing config file: %v", err)
 | 
			
		||||
			return Config{}, fmt.Errorf("error parsing config file: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
		if config.DB == "" {
 | 
			
		||||
			log.Fatal("db connection settings are not set")
 | 
			
		||||
			return Config{}, fmt.Errorf("db connection settings are not set")
 | 
			
		||||
		}
 | 
			
		||||
		if config.OpenDTUAddress == "" {
 | 
			
		||||
			log.Fatal("opendtu_address is not set")
 | 
			
		||||
			return Config{}, fmt.Errorf("opendtu_address is not set")
 | 
			
		||||
		}
 | 
			
		||||
		if config.OpenDTUAuth {
 | 
			
		||||
			if config.OpenDTUUser == "" {
 | 
			
		||||
				log.Fatal("opendtu_username is not set, while opendtu_auth is set to enabled. Set opendtu_auth to false or set username")
 | 
			
		||||
				return Config{}, fmt.Errorf("opendtu_username is not set, while opendtu_auth is set to enabled. Set opendtu_auth to false or set username")
 | 
			
		||||
			}
 | 
			
		||||
			if config.OpenDTUPassword == "" {
 | 
			
		||||
				log.Fatal("opendtu_password is not set, while opendtu_auth is set to enabled. Set opendtu_auth to false or set password")
 | 
			
		||||
				return Config{}, fmt.Errorf("opendtu_password is not set, while opendtu_auth is set to enabled. Set opendtu_auth to false or set password")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -197,29 +212,29 @@ func loadConfig() Config {
 | 
			
		|||
		// Fallback to environment variables
 | 
			
		||||
		config.DB = os.Getenv("DB_URL")
 | 
			
		||||
		if config.DB == "" {
 | 
			
		||||
			log.Fatal("DB_URL environment variable is not set.")
 | 
			
		||||
			return Config{}, fmt.Errorf("DB_URL environment variable is not set")
 | 
			
		||||
		}
 | 
			
		||||
		config.OpenDTUAddress = os.Getenv("OPENDTU_ADDRESS")
 | 
			
		||||
		if config.OpenDTUAddress == "" {
 | 
			
		||||
			log.Fatal("OPENDTU_ADDRESS environment variable is not set.")
 | 
			
		||||
			return Config{}, fmt.Errorf("OPENDTU_ADDRESS environment variable is not set")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		openDTUAuthStr := os.Getenv("OPENDTU_AUTH")
 | 
			
		||||
		if openDTUAuthStr != "" {
 | 
			
		||||
			openDTUAuth, err := strconv.ParseBool(openDTUAuthStr)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Fatalf("Error parsing OPENDTU_AUTH: %v", err)
 | 
			
		||||
				return Config{}, fmt.Errorf("error parsing OPENDTU_AUTH: %w", err)
 | 
			
		||||
			}
 | 
			
		||||
			config.OpenDTUAuth = openDTUAuth
 | 
			
		||||
		}
 | 
			
		||||
		if config.OpenDTUAuth {
 | 
			
		||||
			config.OpenDTUUser = os.Getenv("OPENDTU_USERNAME")
 | 
			
		||||
			if config.OpenDTUUser == "" {
 | 
			
		||||
				log.Fatal("OPENDTU_USERNAME environment variable is not set.")
 | 
			
		||||
				return Config{}, fmt.Errorf("OPENDTU_USERNAME environment variable is not set")
 | 
			
		||||
			}
 | 
			
		||||
			config.OpenDTUPassword = os.Getenv("OPENDTU_PASSWORD")
 | 
			
		||||
			if config.OpenDTUPassword == "" {
 | 
			
		||||
				log.Fatal("OPENDTU_PASSWORD environment variable is not set.")
 | 
			
		||||
				return Config{}, fmt.Errorf("OPENDTU_PASSWORD environment variable is not set")
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -228,7 +243,7 @@ func loadConfig() Config {
 | 
			
		|||
		if timescaleDBStr != "" {
 | 
			
		||||
			timescaleDB, err := strconv.ParseBool(timescaleDBStr)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Fatalf("Error parsing TIMESCALEDB_ENABLED: %v", err)
 | 
			
		||||
				return Config{}, fmt.Errorf("error parsing TIMESCALEDB_ENABLED: %w", err)
 | 
			
		||||
			}
 | 
			
		||||
			config.TimescaleDB = timescaleDB
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -240,7 +255,7 @@ func loadConfig() Config {
 | 
			
		|||
		logger.Warn("invalid timezone")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return config
 | 
			
		||||
	return config, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Helper function to map environment variable to slog.Level
 | 
			
		||||
| 
						 | 
				
			
			@ -273,7 +288,11 @@ func main() {
 | 
			
		|||
	slog.SetDefault(logger)
 | 
			
		||||
 | 
			
		||||
	// Load the configuration
 | 
			
		||||
	config := loadConfig()
 | 
			
		||||
	var err error
 | 
			
		||||
	config, err = loadConfig()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Set the logLevel
 | 
			
		||||
	logLevel := getLogLevel(slog.LevelInfo) // Default to info level
 | 
			
		||||
| 
						 | 
				
			
			@ -468,9 +487,9 @@ func insertLiveData(db *sql.DB, inverter Inverter, total Total, hints Hints) {
 | 
			
		|||
	}
 | 
			
		||||
	// Insert data into hints table
 | 
			
		||||
	_, err = db.Exec(`
 | 
			
		||||
		INSERT INTO opendtu_hints (timestamp, time_sync, radio_problem, default_password)
 | 
			
		||||
		VALUES ($1, $2, $3, $4);
 | 
			
		||||
		`, timestamp, hints.TimeSync, hints.RadioProblem, hints.DefaultPassword)
 | 
			
		||||
		INSERT INTO opendtu_hints (timestamp, time_sync, radio_problem, default_password, pin_mapping_issue)
 | 
			
		||||
		VALUES ($1, $2, $3, $4, $5);
 | 
			
		||||
		`, timestamp, hints.TimeSync, hints.RadioProblem, hints.DefaultPassword, hints.PinMappingIssue)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Error("Error inserting into log table", "error", err)
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										9
									
								
								migrations/00009_hints_pin_mapping.sql
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								migrations/00009_hints_pin_mapping.sql
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
-- +goose Up
 | 
			
		||||
-- +goose StatementBegin
 | 
			
		||||
ALTER TABLE opendtu_hints ADD COLUMN IF NOT EXISTS pin_mapping_issue BOOLEAN NOT NULL DEFAULT FALSE;
 | 
			
		||||
-- +goose StatementEnd
 | 
			
		||||
 | 
			
		||||
-- +goose Down
 | 
			
		||||
-- +goose StatementBegin
 | 
			
		||||
ALTER TABLE opendtu_hints DROP COLUMN IF EXISTS pin_mapping_issue;
 | 
			
		||||
-- +goose StatementEnd
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue