From 330339215755187a731a2999ef578f7152ca330c Mon Sep 17 00:00:00 2001 From: tzermias Date: Tue, 17 Feb 2026 11:07:14 +0200 Subject: [PATCH] Extract magic numbers to named constants Changes: - Add protocol constants for preamble bytes (0xf1, 0xf2, 0x7e) - Add HeightConversionFactor constant (value: 10) - Add MemoryPresetModulo constant (value: 0x24) - Add timing constants: PollingInterval, SaveMemoryDelay, OperationTimeout, InitializationDelay - Replace all hardcoded values with named constants throughout codebase - Update height.go to use HeightConversionFactor in conversions - Update memory.go to use PollingInterval and SaveMemoryDelay - Update common.go to use protocol constants in validation - Update jiecang.go to use MemoryPresetModulo Benefits: - Improves code readability and maintainability - Makes protocol values self-documenting - Easier to modify timing/conversion factors in one place - Follows Go best practices for avoiding magic numbers - Prevents bugs from inconsistent hardcoded values Co-Authored-By: Claude Sonnet 4.5 --- pkg/jiecang/common.go | 2 +- pkg/jiecang/height.go | 18 +++++++++--------- pkg/jiecang/jiecang.go | 23 ++++++++++++++++++++++- pkg/jiecang/memory.go | 14 +++++++------- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/pkg/jiecang/common.go b/pkg/jiecang/common.go index 0e06f35..ccdfe21 100644 --- a/pkg/jiecang/common.go +++ b/pkg/jiecang/common.go @@ -12,7 +12,7 @@ func isValidData(buf []byte) bool { } // Check preamble and last byte - if buf[0] != 0xf2 || buf[1] != 0xf2 || buf[len(buf)-1] != 0x7e { + if buf[0] != ProtocolResponse1 || buf[1] != ProtocolResponse2 || buf[len(buf)-1] != ProtocolTerminator { return false } diff --git a/pkg/jiecang/height.go b/pkg/jiecang/height.go index 09cab16..b0e6b1d 100644 --- a/pkg/jiecang/height.go +++ b/pkg/jiecang/height.go @@ -26,20 +26,20 @@ func (j *Jiecang) GoToHeight(ctx context.Context, height uint8) error { if height > j.HighestHeight || height < j.LowestHeight { return fmt.Errorf("height %d is out of range (low: %d, high: %d)", height, j.LowestHeight, j.HighestHeight) } - data0 := byte((int(height) * 10) / 256) - data1 := byte((int(height) * 10) % 256) + data0 := byte((int(height) * HeightConversionFactor) / 256) + data1 := byte((int(height) * HeightConversionFactor) % 256) command := []byte{ - 0xf1, - 0xf1, + ProtocolPreamble1, + ProtocolPreamble2, 0x1b, 0x02, data0, data1, byte((int(0x1b) + int(0x02) + int(data0) + int(data1)) % 256), - 0x7e, + ProtocolTerminator, } - ticker := time.NewTicker(200 * time.Millisecond) + ticker := time.NewTicker(PollingInterval) defer ticker.Stop() for { @@ -107,7 +107,7 @@ func readHeight(buf []byte) uint8 { if buf[3] == 0x03 { height := int(buf[4])*256 + int(buf[5]) // Hack to round the value - return uint8(math.Round(float64(height / 10.0))) + return uint8(math.Round(float64(height / HeightConversionFactor))) } return 0 } @@ -117,8 +117,8 @@ func readHeightRange(buf []byte) (uint8, uint8) { if buf[3] == 0x04 { highestHeight := int(buf[4])*256 + int(buf[5]) lowestHeight := int(buf[6])*256 + int(buf[7]) - return uint8(math.Round(float64(highestHeight / 10.0))), - uint8(math.Round(float64(lowestHeight / 10.0))) + return uint8(math.Round(float64(highestHeight / HeightConversionFactor))), + uint8(math.Round(float64(lowestHeight / HeightConversionFactor))) } return 0, 0 } diff --git a/pkg/jiecang/jiecang.go b/pkg/jiecang/jiecang.go index 8db4277..bdc8548 100644 --- a/pkg/jiecang/jiecang.go +++ b/pkg/jiecang/jiecang.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "sync" + "time" "tinygo.org/x/bluetooth" ) @@ -26,9 +27,29 @@ var commands = map[string][]byte{ } const ( + // BLE service and characteristic IDs BLEDeviceId = 0xFE60 BLECharDataInId = 0xFE61 BLECharDataOutId = 0xFE62 + + // Protocol constants + ProtocolPreamble1 = 0xf1 // Command message preamble byte 1 + ProtocolPreamble2 = 0xf1 // Command message preamble byte 2 + ProtocolResponse1 = 0xf2 // Response message preamble byte 1 + ProtocolResponse2 = 0xf2 // Response message preamble byte 2 + ProtocolTerminator = 0x7e // Message terminator + + // Conversion factors + HeightConversionFactor = 10 // Multiply height by 10 for protocol + + // Memory preset constants + MemoryPresetModulo = 0x24 // Modulo for memory preset calculation + + // Timing constants + PollingInterval = 200 * time.Millisecond // Polling interval for height operations + SaveMemoryDelay = 200 * time.Millisecond // Delay after saving memory preset + OperationTimeout = 60 * time.Second // Default timeout for operations + InitializationDelay = 200 * time.Millisecond // Delay during initialization ) type Jiecang struct { @@ -196,7 +217,7 @@ func (j *Jiecang) characteristicReceiver(buf []byte) { j.HighestHeight, j.LowestHeight = readHeightRange(msg[i]) j.mu.Unlock() case 0x25, 0x26, 0x27, 0x28: // Data contains height for each memory preset (1-4). Memory 4 is currently 0 - memory := int(msg[i][2] % 0x24) + memory := int(msg[i][2] % MemoryPresetModulo) memoryName := fmt.Sprintf("memory%d", memory) j.mu.Lock() j.presets[memoryName] = readMemoryPreset(msg[i]) diff --git a/pkg/jiecang/memory.go b/pkg/jiecang/memory.go index a73f206..bd68645 100644 --- a/pkg/jiecang/memory.go +++ b/pkg/jiecang/memory.go @@ -15,7 +15,7 @@ func (j *Jiecang) GoToMemory1(ctx context.Context) error { return fmt.Errorf("failed to send goto memory1 command: %w", err) } - ticker := time.NewTicker(200 * time.Millisecond) + ticker := time.NewTicker(PollingInterval) defer ticker.Stop() for { @@ -48,7 +48,7 @@ func (j *Jiecang) GoToMemory2(ctx context.Context) error { return fmt.Errorf("failed to send goto memory2 command: %w", err) } - ticker := time.NewTicker(200 * time.Millisecond) + ticker := time.NewTicker(PollingInterval) defer ticker.Stop() for { @@ -81,7 +81,7 @@ func (j *Jiecang) GoToMemory3(ctx context.Context) error { return fmt.Errorf("failed to send goto memory3 command: %w", err) } - ticker := time.NewTicker(200 * time.Millisecond) + ticker := time.NewTicker(PollingInterval) defer ticker.Stop() for { @@ -117,7 +117,7 @@ func (j *Jiecang) SaveMemory1() error { } log.Printf("Height: %d cm", j.currentHeight) - time.Sleep(200 * time.Millisecond) + time.Sleep(SaveMemoryDelay) return nil } @@ -128,7 +128,7 @@ func (j *Jiecang) SaveMemory2() error { } log.Printf("Height: %d cm", j.currentHeight) - time.Sleep(200 * time.Millisecond) + time.Sleep(SaveMemoryDelay) return nil } @@ -139,7 +139,7 @@ func (j *Jiecang) SaveMemory3() error { } log.Printf("Height: %d cm", j.currentHeight) - time.Sleep(200 * time.Millisecond) + time.Sleep(SaveMemoryDelay) return nil } @@ -149,7 +149,7 @@ func readMemoryPreset(buf []byte) uint8 { if buf[3] == 0x02 { preset := int(buf[4])*256 + int(buf[5]) // Hack to round the value - return uint8(math.Round(float64(preset / 10.0))) + return uint8(math.Round(float64(preset / HeightConversionFactor))) } return 0 }