@@ -38,6 +38,7 @@ func NewConfigurableFromConfig(ctx context.Context, other map[string]any) (api.C
3838 Soc * plugin.Config
3939 LimitSoc * plugin.Config
4040 Tos bool
41+ measurement.Temperature `mapstructure:",squash"` // optional, for heating devices
4142 measurement.Energy `mapstructure:",squash"` // optional
4243 meter.Phases `mapstructure:",squash"` // optional
4344 }
@@ -114,18 +115,31 @@ func NewConfigurableFromConfig(ctx context.Context, other map[string]any) (api.C
114115 }
115116 }
116117
117- // decorate soc
118+ // decorate soc; for heating devices (api.Heating feature), the soc slot holds
119+ // temperature in °C — fall back to temp getter when no soc getter is configured.
118120 soc , err := cc .Soc .FloatGetter (ctx )
119121 if err != nil {
120122 return nil , fmt .Errorf ("soc: %w" , err )
121123 }
122124
123- // decorate limitsoc
125+ // decorate limitsoc; similarly, fall back to limittemp getter when no limitsoc is configured.
124126 limitsoc , err := cc .LimitSoc .IntGetter (ctx )
125127 if err != nil {
126128 return nil , fmt .Errorf ("limitsoc: %w" , err )
127129 }
128130
131+ // heating fallbacks
132+ temp , limitTemp , err := cc .Temperature .Configure (ctx )
133+ if err != nil {
134+ return nil , err
135+ }
136+ if soc == nil && temp != nil {
137+ soc = temp
138+ }
139+ if limitsoc == nil && limitTemp != nil {
140+ limitsoc = limitTemp
141+ }
142+
129143 // decorate measurements
130144 powerG , energyG , err := cc .Energy .Configure (ctx )
131145 if err != nil {
0 commit comments