-
-
Couldn't load subscription status.
- Fork 1.1k
SHM: generate stable device ids (BC) #24771
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes - here's some feedback:
- In the stable ID branch you’re mutating s.did in place by XORing it—copy the slice first so subsequent calls aren’t using a permanently altered base ID.
- You’re passing a byte slice to fmt.Sprintf with the sempDeviceId format (which expects an integer), so convert the derived did bytes to the appropriate numeric type before formatting.
- Accessing s.site.Loadpoints()[id] without bounds checking may panic—add validation or a safer lookup for the loadpoint.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In the stable ID branch you’re mutating s.did in place by XORing it—copy the slice first so subsequent calls aren’t using a permanently altered base ID.
- You’re passing a byte slice to fmt.Sprintf with the sempDeviceId format (which expects an integer), so convert the derived did bytes to the appropriate numeric type before formatting.
- Accessing s.site.Loadpoints()[id] without bounds checking may panic—add validation or a safer lookup for the loadpoint.
## Individual Comments
### Comment 1
<location> `hems/shm/shm.go:327` </location>
<code_context>
// deviceID combines base device id with device number
func (s *SEMP) deviceID(id int) string {
- // numerically add device number
- did := append([]byte{0, 0}, s.did...)
</code_context>
<issue_to_address>
**issue (complexity):** Consider extracting the legacy and stable device ID logic into separate helper methods to simplify the main deviceID function.
Extract the two ID‐building branches into small helpers so that `deviceID` just picks one—no in‐place hashing or bit‐math:
```go
func (s *SEMP) deviceID(id int) string {
if s.legacy {
return s.legacyDeviceID(id)
}
return s.stableDeviceID(id)
}
```
Then pull out each implementation:
```go
func (s *SEMP) legacyDeviceID(id int) string {
// old: prepend two zero bytes, add id, mask to 6 bytes
did := append([]byte{0, 0}, s.did...)
raw := binary.BigEndian.Uint64(did) + uint64(id)
masked := ^uint64(0xffff<<48) & raw
return fmt.Sprintf(sempDeviceId, s.vid, masked)
}
```
```go
func (s *SEMP) stableDeviceID(id int) string {
// new: XOR SHA256(chargerRef) into base did
ref := s.site.Loadpoints()[id].GetChargerRef()
hash := sha256.Sum256([]byte(ref))
out := make([]byte, len(s.did))
copy(out, s.did)
for i, b := range hash {
out[i%len(out)] ^= b
}
return fmt.Sprintf(sempDeviceId, s.vid, out)
}
```
This keeps all functionality but moves the bit-fiddling and hashing out of the main path, improving readability and maintainability.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
@sourcery-ai I don't see an expected integer? See https://go.dev/play/p/TIwWPejEmQ5 |
|
To save us the pain we might enable this option automatically internally if and only if there are no loadpoints configured yet. Not sure, where or how we would do this... |
|
Can we maybe add an optional parameter to the lp, e.g sempDeviceId that will be taken, and if not defined we calculate it? There will be ghosts anyways, but at least we could get the mapping back that legacy users used to have? |
|
No. A loadpoint must know nothing about about specific devices. |
|
I'm away this week. @Maschga do you want to implement the UI bit and adjust the tests accordingly? |
Fix #24768
To disable the new behaviour and keep IDs stable, set
legacyId: true.TODO