Skip to content

Conversation

@andig
Copy link
Member

@andig andig commented Oct 26, 2025

Fix #24768

To disable the new behaviour and keep IDs stable, set legacyId: true.

TODO

  • UI option @naltatis
  • backend "stable" setting
  • use backend "stable" setting in UI @naltatis

@andig andig added devices Specific device support needs decision Unsure if we should really do this labels Oct 26, 2025
@andig andig requested a review from premultiply October 26, 2025 18:58
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a 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>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@andig
Copy link
Member Author

andig commented Oct 26, 2025

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.

@sourcery-ai I don't see an expected integer? See https://go.dev/play/p/TIwWPejEmQ5

@andig
Copy link
Member Author

andig commented Oct 26, 2025

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...

@paschdan
Copy link
Contributor

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?

@andig
Copy link
Member Author

andig commented Oct 26, 2025

No. A loadpoint must know nothing about about specific devices.

@naltatis
Copy link
Member

I'm away this week. @Maschga do you want to implement the UI bit and adjust the tests accordingly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

devices Specific device support needs decision Unsure if we should really do this

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Semp devices Id mixed up due device deletion and addition of new

5 participants