Skip to content

Commit 668907e

Browse files
committed
feat: support setting the MQTT client ID separately
1 parent a4c3758 commit 668907e

6 files changed

Lines changed: 76 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22

33
Starting from v2.2.5, all notable changes to this project will be documented in this file.
44

5+
## v4.3.4
6+
7+
### Release Notes
8+
9+
This release focuses on **MQTT connectivity robustness and operational convenience**, introducing **configurable MQTT Client ID support** and **in-app restart capability**.
10+
11+
By allowing explicit control over the **MQTT Client ID**, AnyShake Observer can now avoid client collisions and better integrate with managed brokers and shared infrastructures. In addition, the new **in-app restart mechanism** improves maintainability by enabling controlled restarts without external process management.
12+
13+
### New Features
14+
15+
- Added support for **configurable MQTT Client ID**, allowing users to explicitly define the client identifier used when connecting to the MQTT broker.
16+
- Added support for **in-app restart**, enabling the service to restart itself without external supervisors or manual intervention.
17+
518
## v4.3.3
619

720
### Release Notes

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CURRENT_VERSION_MAJOR = 4
22
CURRENT_VERSION_MINOR = 3
3-
CURRENT_VERSION_PATCH = 3
3+
CURRENT_VERSION_PATCH = 4
44

55
REQUIRED_VERSION_MAJOR = 4
66
REQUIRED_VERSION_MINOR = 3

internal/service/quakesense/config.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,59 @@ func (s *quakeSenseConfigMqttPasswordImpl) Restore(handler *action.Handler) erro
253253
return nil
254254
}
255255

256+
type quakeSenseConfigMqttClientIdImpl struct{}
257+
258+
func (s *quakeSenseConfigMqttClientIdImpl) GetName() string { return "MQTT Client ID" }
259+
func (s *quakeSenseConfigMqttClientIdImpl) GetNamespace() string { return ID }
260+
func (s *quakeSenseConfigMqttClientIdImpl) GetKey() string { return "mqtt_client_id" }
261+
func (s *quakeSenseConfigMqttClientIdImpl) GetType() action.SettingType { return action.String }
262+
func (s *quakeSenseConfigMqttClientIdImpl) IsRequired() bool { return true }
263+
func (s *quakeSenseConfigMqttClientIdImpl) GetVersion() int { return 0 }
264+
func (s *quakeSenseConfigMqttClientIdImpl) GetOptions() map[string]any { return nil }
265+
func (s *quakeSenseConfigMqttClientIdImpl) GetDefaultValue() any {
266+
b := make([]byte, 4)
267+
if _, err := crypto_rand.Read(b); err != nil {
268+
return fmt.Sprintf("anyshake-observer-%x", uint32(time.Now().UnixNano()))
269+
}
270+
return fmt.Sprintf("anyshake-observer-%x", b)
271+
}
272+
func (s *quakeSenseConfigMqttClientIdImpl) GetDescription() string {
273+
return "MQTT Client ID uniquely identifies a client when connecting to the broker. By default, it is anyshake-observer-<random string>."
274+
}
275+
func (s *quakeSenseConfigMqttClientIdImpl) Init(handler *action.Handler) error {
276+
if _, err := handler.SettingsInit(s.GetNamespace(), s.GetKey(), s.GetType(), s.GetVersion(), s.GetDefaultValue()); err != nil {
277+
return fmt.Errorf("failed to set default MQTT client ID: %w", err)
278+
}
279+
return nil
280+
}
281+
func (s *quakeSenseConfigMqttClientIdImpl) Set(handler *action.Handler, newVal any) error {
282+
topic, err := config.GetConfigValString(newVal)
283+
if err != nil {
284+
return err
285+
}
286+
if err := handler.SettingsSet(s.GetNamespace(), s.GetKey(), s.GetType(), s.GetVersion(), topic); err != nil {
287+
return fmt.Errorf("failed to set MQTT client ID: %w", err)
288+
}
289+
return nil
290+
}
291+
func (s *quakeSenseConfigMqttClientIdImpl) Get(handler *action.Handler) (any, error) {
292+
val, _, _, err := handler.SettingsGet(s.GetNamespace(), s.GetKey())
293+
if err != nil {
294+
return nil, fmt.Errorf("failed to get MQTT client ID: %w", err)
295+
}
296+
id, ok := val.(string)
297+
if !ok {
298+
return nil, errors.New("string expected")
299+
}
300+
return id, nil
301+
}
302+
func (s *quakeSenseConfigMqttClientIdImpl) Restore(handler *action.Handler) error {
303+
if err := handler.SettingsSet(s.GetNamespace(), s.GetKey(), s.GetType(), s.GetVersion(), s.GetDefaultValue()); err != nil {
304+
return fmt.Errorf("failed to reset MQTT client ID: %w", err)
305+
}
306+
return nil
307+
}
308+
256309
type quakeSenseConfigMonitorChannelImpl struct{}
257310

258311
func (s *quakeSenseConfigMonitorChannelImpl) GetName() string { return "Monitor Channel" }
@@ -787,6 +840,7 @@ func (s *QuakeSenseServiceImpl) GetConfigConstraint() []config.IConstraint {
787840
&quakeSenseConfigMqttTopicImpl{},
788841
&quakeSenseConfigMqttUsernameImpl{},
789842
&quakeSenseConfigMqttPasswordImpl{},
843+
&quakeSenseConfigMqttClientIdImpl{},
790844
&quakeSenseConfigMonitorChannelImpl{},
791845
&quakeSenseConfigFilterTypeImpl{},
792846
&quakeSenseConfigMinFreqImpl{},

internal/service/quakesense/init.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ func (s *QuakeSenseServiceImpl) Init() error {
4040
}
4141
s.mqttPassword = mqttPassword.(string)
4242

43+
mqttClientId, err := (&quakeSenseConfigMqttClientIdImpl{}).Get(s.actionHandler)
44+
if err != nil {
45+
return fmt.Errorf("failed to get quakeSense MQTT client ID: %w", err)
46+
}
47+
s.mqttClientId = mqttClientId.(string)
48+
4349
stationName, err := (&config.StationNameConfigConstraintImpl{}).Get(s.actionHandler)
4450
if err != nil {
4551
return fmt.Errorf("failed to get quakeSense station name: %w", err)

internal/service/quakesense/start.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func (s *QuakeSenseServiceImpl) Start() error {
3232
mqttClientOptions.AddBroker(s.mqttBroker)
3333
mqttClientOptions.SetAutoReconnect(true)
3434
mqttClientOptions.SetKeepAlive(30 * time.Second)
35-
mqttClientOptions.SetClientID("anyshake-observer")
35+
mqttClientOptions.SetClientID(s.mqttClientId)
3636
mqttClientOptions.SetConnectTimeout(10 * time.Second)
3737
if s.mqttUsername != "" && s.mqttPassword != "" {
3838
mqttClientOptions.SetUsername(s.mqttUsername)

internal/service/quakesense/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ type QuakeSenseServiceImpl struct {
4949
mqttTopic string
5050
mqttUsername string
5151
mqttPassword string
52+
mqttClientId string
5253
mqttClient mqtt.Client
5354

5455
stationName string

0 commit comments

Comments
 (0)