Skip to content

Commit

Permalink
Fix errors trying to parse temperatures from switched off thermostat
Browse files Browse the repository at this point in the history
FritzOS 7.29 and Comet DECT devices send the special state values in
Thermostat.Goal where ad FritzOS 7.31 and Fritz!DECT 301 devices send
the state in Thermostat.Saving.

Parsing has been fixed in https://github.com/jayme-github/fritzctl:
8f69fe815d3fdfbc9f36131fe5e29bad70645445

Don't try to parse goal, comfort or saving temparature if thermostat is
not in ON state.

Fixes: #11
  • Loading branch information
jayme-github committed Jun 9, 2022
1 parent 2664bd7 commit cd9095f
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
*.swp
vendor/*
dist/
fritzbox_smarthome_exporter
14 changes: 7 additions & 7 deletions collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,17 +196,17 @@ func (fc *fritzCollector) Collect(ch chan<- prometheus.Metric) {
dev.Productname,
dev.Name,
)
// Don't try to update goal temperature if thermostat is OFF (or in unknown state)
// Update goal, comfort and saving temperatures only if thermostat is ON
if state == 1 {
if err := mustStringToFloatMetric(ch, fc.ThermostatTempGoal, dev.Thermostat.FmtGoalTemperature(), &dev); err != nil {
log.Printf("Unable to parse goal temperature of \"%s\" : %v\n", dev.Name, err)
}
}
if err := mustStringToFloatMetric(ch, fc.ThermostatTempComfort, dev.Thermostat.FmtComfortTemperature(), &dev); err != nil {
log.Printf("Unable to parse comfort temperature of \"%s\" : %v\n", dev.Name, err)
}
if err := mustStringToFloatMetric(ch, fc.ThermostatTempSaving, dev.Thermostat.FmtSavingTemperature(), &dev); err != nil {
log.Printf("Unable to parse saving temperature of \"%s\" : %v\n", dev.Name, err)
if err := mustStringToFloatMetric(ch, fc.ThermostatTempComfort, dev.Thermostat.FmtComfortTemperature(), &dev); err != nil {
log.Printf("Unable to parse comfort temperature of \"%s\" : %v\n", dev.Name, err)
}
if err := mustStringToFloatMetric(ch, fc.ThermostatTempSaving, dev.Thermostat.FmtSavingTemperature(), &dev); err != nil {
log.Printf("Unable to parse saving temperature of \"%s\" : %v\n", dev.Name, err)
}
}

// Window Open is optional, earlier FritzOS versions don't export that
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
)

replace github.com/bpicode/fritzctl => github.com/jayme-github/fritzctl v1.4.23-0.20220424111445-826538a7c038
replace github.com/bpicode/fritzctl => github.com/jayme-github/fritzctl v1.4.23-0.20220609211037-25a9f8556e3b
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jayme-github/fritzctl v1.4.23-0.20220424111445-826538a7c038 h1:QhPu2bo814Kss65tEu6s30PBbkAueJb8wNCkwa/JD9M=
github.com/jayme-github/fritzctl v1.4.23-0.20220424111445-826538a7c038/go.mod h1:8bJv/qlxE0sdIAwjSLyuc+NeQ4kz77bMCdCCZOKJQjc=
github.com/jayme-github/fritzctl v1.4.23-0.20220609211037-25a9f8556e3b h1:pHFq8M4744vLEdj0HfuZS26fO0H0Guw3nI8y8bywJyw=
github.com/jayme-github/fritzctl v1.4.23-0.20220609211037-25a9f8556e3b/go.mod h1:+YZYkLlmX2lFKkzUMljoRM63T6RK83fIChL1IHjo5Aw=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
Expand Down
4 changes: 0 additions & 4 deletions test/devicelist.metrics
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ fritzbox_thermostat_batterylow{device_id="55555 2777777",device_name="HKR_2",dev
fritzbox_thermostat_batterylow{device_id="55555 2777777",device_name="HKR_3",device_type="Comet DECT"} 1
# HELP fritzbox_thermostat_comfort Comfort temperature configured in units of 0.1 °C
# TYPE fritzbox_thermostat_comfort gauge
fritzbox_thermostat_comfort{device_id="44363 2777777",device_name="HKR_1",device_type="Comet DECT"} 20
fritzbox_thermostat_comfort{device_id="55555 2777777",device_name="HKR_2",device_type="Comet DECT"} 20
fritzbox_thermostat_comfort{device_id="55555 2777777",device_name="HKR_3",device_type="Comet DECT"} 23
# HELP fritzbox_thermostat_errorcode Thermostat error code (0 = OK), see https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AHA-HTTP-Interface.pdf
# TYPE fritzbox_thermostat_errorcode gauge
Expand All @@ -88,8 +86,6 @@ fritzbox_thermostat_errorcode{device_id="55555 2777777",device_name="HKR_3",devi
fritzbox_thermostat_goal{device_id="55555 2777777",device_name="HKR_3",device_type="Comet DECT"} 20
# HELP fritzbox_thermostat_saving Configured energy saving temperature in units of 0.1 °C
# TYPE fritzbox_thermostat_saving gauge
fritzbox_thermostat_saving{device_id="44363 2777777",device_name="HKR_1",device_type="Comet DECT"} 18
fritzbox_thermostat_saving{device_id="55555 2777777",device_name="HKR_2",device_type="Comet DECT"} 18
fritzbox_thermostat_saving{device_id="55555 2777777",device_name="HKR_3",device_type="Comet DECT"} 17
# HELP fritzbox_thermostat_state Thermostat state 1/0 (on/off), -1 if unknown or error
# TYPE fritzbox_thermostat_state gauge
Expand Down
2 changes: 0 additions & 2 deletions test/devicelist_729.metrics
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ fritzbox_thermostat_comfort{device_id="12345 0000002",device_name="HKR_1",device
fritzbox_thermostat_comfort{device_id="12345 0000003",device_name="HKR_2",device_type="Comet DECT"} 20
fritzbox_thermostat_comfort{device_id="12345 0000004",device_name="HKR_3",device_type="Comet DECT"} 18.5
fritzbox_thermostat_comfort{device_id="12345 0000005",device_name="HKR_4",device_type="Comet DECT"} 17
fritzbox_thermostat_comfort{device_id="12345 0000006",device_name="HKR_5",device_type="Comet DECT"} 17
# HELP fritzbox_thermostat_errorcode Thermostat error code (0 = OK), see https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AHA-HTTP-Interface.pdf
# TYPE fritzbox_thermostat_errorcode gauge
fritzbox_thermostat_errorcode{device_id="12345 0000002",device_name="HKR_1",device_type="Comet DECT"} 0
Expand All @@ -123,7 +122,6 @@ fritzbox_thermostat_saving{device_id="12345 0000002",device_name="HKR_1",device_
fritzbox_thermostat_saving{device_id="12345 0000003",device_name="HKR_2",device_type="Comet DECT"} 16
fritzbox_thermostat_saving{device_id="12345 0000004",device_name="HKR_3",device_type="Comet DECT"} 16
fritzbox_thermostat_saving{device_id="12345 0000005",device_name="HKR_4",device_type="Comet DECT"} 16
fritzbox_thermostat_saving{device_id="12345 0000006",device_name="HKR_5",device_type="Comet DECT"} 16
# HELP fritzbox_thermostat_state Thermostat state 1/0 (on/off), -1 if unknown or error
# TYPE fritzbox_thermostat_state gauge
fritzbox_thermostat_state{device_id="12345 0000002",device_name="HKR_1",device_type="Comet DECT"} 1
Expand Down
67 changes: 67 additions & 0 deletions test/devicelist_731.metrics
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# HELP fritzbox_battery_charge_level Battery charge level in percent
# TYPE fritzbox_battery_charge_level gauge
fritzbox_battery_charge_level{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301"} 100
fritzbox_battery_charge_level{device_id="09995 0182040",device_name="Thermostat Schlafzimmer",device_type="FRITZ!DECT 301"} 60
fritzbox_battery_charge_level{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301"} 60
# HELP fritzbox_batterylow 0 if the battery is OK, 1 if it is running low on capacity (this seems to be very unreliable)
# TYPE fritzbox_batterylow gauge
fritzbox_batterylow{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301"} 0
fritzbox_batterylow{device_id="09995 0182040",device_name="Thermostat Schlafzimmer",device_type="FRITZ!DECT 301"} 0
fritzbox_batterylow{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301"} 0
# HELP fritzbox_device_info Device information
# TYPE fritzbox_device_info gauge
fritzbox_device_info{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301",functionbitmask="320",fw_version="05.02",internal_id="16",manufacturer="AVM"} 1
fritzbox_device_info{device_id="09995 0182040",device_name="Thermostat Schlafzimmer",device_type="FRITZ!DECT 301",functionbitmask="320",fw_version="05.02",internal_id="18",manufacturer="AVM"} 1
fritzbox_device_info{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301",functionbitmask="320",fw_version="05.02",internal_id="17",manufacturer="AVM"} 1
# HELP fritzbox_device_present Device connected (1) or not (0)
# TYPE fritzbox_device_present gauge
fritzbox_device_present{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301"} 1
fritzbox_device_present{device_id="09995 0182040",device_name="Thermostat Schlafzimmer",device_type="FRITZ!DECT 301"} 1
fritzbox_device_present{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301"} 1
# HELP fritzbox_temperature Temperature measured at the device sensor in units of 0.1 °C
# TYPE fritzbox_temperature gauge
fritzbox_temperature{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301"} 22.5
fritzbox_temperature{device_id="09995 0182040",device_name="Thermostat Schlafzimmer",device_type="FRITZ!DECT 301"} 23
fritzbox_temperature{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301"} 24.5
# HELP fritzbox_temperature_offset Temperature offset (set by the user) in units of 0.1 °C
# TYPE fritzbox_temperature_offset gauge
fritzbox_temperature_offset{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301"} 0
fritzbox_temperature_offset{device_id="09995 0182040",device_name="Thermostat Schlafzimmer",device_type="FRITZ!DECT 301"} 0
fritzbox_temperature_offset{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301"} 0
# HELP fritzbox_thermostat_battery_charge_level Battery charge level in percent
# TYPE fritzbox_thermostat_battery_charge_level gauge
fritzbox_thermostat_battery_charge_level{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301"} 100
fritzbox_thermostat_battery_charge_level{device_id="09995 0182040",device_name="Thermostat Schlafzimmer",device_type="FRITZ!DECT 301"} 60
fritzbox_thermostat_battery_charge_level{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301"} 60
# HELP fritzbox_thermostat_batterylow 0 if the battery is OK, 1 if it is running low on capacity (this seems to be very unreliable)
# TYPE fritzbox_thermostat_batterylow gauge
fritzbox_thermostat_batterylow{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301"} 0
fritzbox_thermostat_batterylow{device_id="09995 0182040",device_name="Thermostat Schlafzimmer",device_type="FRITZ!DECT 301"} 0
fritzbox_thermostat_batterylow{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301"} 0
# HELP fritzbox_thermostat_comfort Comfort temperature configured in units of 0.1 °C
# TYPE fritzbox_thermostat_comfort gauge
fritzbox_thermostat_comfort{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301"} 10
fritzbox_thermostat_comfort{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301"} 12
# HELP fritzbox_thermostat_errorcode Thermostat error code (0 = OK), see https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AHA-HTTP-Interface.pdf
# TYPE fritzbox_thermostat_errorcode gauge
fritzbox_thermostat_errorcode{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301"} 0
fritzbox_thermostat_errorcode{device_id="09995 0182040",device_name="Thermostat Schlafzimmer",device_type="FRITZ!DECT 301"} 0
fritzbox_thermostat_errorcode{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301"} 0
# HELP fritzbox_thermostat_goal Desired temperature (user controlled) in units of 0.1 °C
# TYPE fritzbox_thermostat_goal gauge
fritzbox_thermostat_goal{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301"} 10
fritzbox_thermostat_goal{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301"} 12
# HELP fritzbox_thermostat_saving Configured energy saving temperature in units of 0.1 °C
# TYPE fritzbox_thermostat_saving gauge
fritzbox_thermostat_saving{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301"} 10
fritzbox_thermostat_saving{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301"} 8
# HELP fritzbox_thermostat_state Thermostat state 1/0 (on/off), -1 if unknown or error
# TYPE fritzbox_thermostat_state gauge
fritzbox_thermostat_state{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301"} 1
fritzbox_thermostat_state{device_id="09995 0182040",device_name="Thermostat Schlafzimmer",device_type="FRITZ!DECT 301"} 0
fritzbox_thermostat_state{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301"} 1
# HELP fritzbox_thermostat_window_open 1 if detected an open window (usually turns off heating), 0 if not.
# TYPE fritzbox_thermostat_window_open gauge
fritzbox_thermostat_window_open{device_id="09995 0003386",device_name="Thermostat Wohnzimmer",device_type="FRITZ!DECT 301"} 0
fritzbox_thermostat_window_open{device_id="09995 0182040",device_name="Thermostat Schlafzimmer",device_type="FRITZ!DECT 301"} 0
fritzbox_thermostat_window_open{device_id="09995 0182300",device_name="Thermostat Bad",device_type="FRITZ!DECT 301"} 0
182 changes: 182 additions & 0 deletions test/devicelist_731.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<devicelist version="1" fwversion="7.31">
<device identifier="09995 0003386" id="16" functionbitmask="320" fwversion="05.02" manufacturer="AVM" productname="FRITZ!DECT 301">
<present>1</present>
<txbusy>0</txbusy>
<name>Thermostat Wohnzimmer</name>
<battery>100</battery>
<batterylow>0</batterylow>
<temperature>
<celsius>225</celsius>
<offset>0</offset>
</temperature>
<hkr>
<tist>45</tist>
<tsoll>20</tsoll>
<absenk>20</absenk>
<komfort>20</komfort>
<lock>0</lock>
<devicelock>0</devicelock>
<errorcode>0</errorcode>
<windowopenactiv>0</windowopenactiv>
<windowopenactiveendtime>0</windowopenactiveendtime>
<boostactive>0</boostactive>
<boostactiveendtime>0</boostactiveendtime>
<batterylow>0</batterylow>
<battery>100</battery>
<nextchange>
<endperiod>0</endperiod>
<tchange>20</tchange>
</nextchange>
<summeractive>0</summeractive>
<holidayactive>0</holidayactive>
</hkr>
</device>
<device identifier="09995 0182300" id="17" functionbitmask="320" fwversion="05.02" manufacturer="AVM" productname="FRITZ!DECT 301">
<present>1</present>
<txbusy>0</txbusy>
<name>Thermostat Bad</name>
<battery>60</battery>
<batterylow>0</batterylow>
<temperature>
<celsius>245</celsius>
<offset>0</offset>
</temperature>
<hkr>
<tist>49</tist>
<tsoll>24</tsoll>
<absenk>16</absenk>
<komfort>24</komfort>
<lock>0</lock>
<devicelock>0</devicelock>
<errorcode>0</errorcode>
<windowopenactiv>0</windowopenactiv>
<windowopenactiveendtime>0</windowopenactiveendtime>
<boostactive>0</boostactive>
<boostactiveendtime>0</boostactiveendtime>
<batterylow>0</batterylow>
<battery>60</battery>
<nextchange>
<endperiod>0</endperiod>
<tchange>24</tchange>
</nextchange>
<summeractive>0</summeractive>
<holidayactive>0</holidayactive>
</hkr>
</device>
<device identifier="09995 0182040" id="18" functionbitmask="320" fwversion="05.02" manufacturer="AVM" productname="FRITZ!DECT 301">
<present>1</present>
<txbusy>0</txbusy>
<name>Thermostat Schlafzimmer</name>
<battery>60</battery>
<batterylow>0</batterylow>
<temperature>
<celsius>230</celsius>
<offset>0</offset>
</temperature>
<hkr>
<tist>46</tist>
<tsoll>16</tsoll>
<absenk>253</absenk>
<komfort>40</komfort>
<lock>0</lock>
<devicelock>0</devicelock>
<errorcode>0</errorcode>
<windowopenactiv>0</windowopenactiv>
<windowopenactiveendtime>0</windowopenactiveendtime>
<boostactive>0</boostactive>
<boostactiveendtime>0</boostactiveendtime>
<batterylow>0</batterylow>
<battery>60</battery>
<nextchange>
<endperiod>0</endperiod>
<tchange>40</tchange>
</nextchange>
<summeractive>0</summeractive>
<holidayactive>0</holidayactive>
</hkr>
</device>
<group synchronized="1" identifier="7A:A5:7A-900" id="900" functionbitmask="4160" fwversion="1.0" manufacturer="AVM" productname="">
<present>1</present>
<txbusy>0</txbusy>
<name>Heizung Wohnzimmer</name>
<hkr>
<tist></tist>
<tsoll>20</tsoll>
<absenk>20</absenk>
<komfort>20</komfort>
<lock>0</lock>
<devicelock>0</devicelock>
<errorcode>0</errorcode>
<windowopenactiv>0</windowopenactiv>
<windowopenactiveendtime>0</windowopenactiveendtime>
<boostactive>0</boostactive>
<boostactiveendtime>0</boostactiveendtime>
<nextchange>
<endperiod>0</endperiod>
<tchange>20</tchange>
</nextchange>
<summeractive>0</summeractive>
<holidayactive>0</holidayactive>
</hkr>
<groupinfo>
<masterdeviceid>0</masterdeviceid>
<members>16</members>
</groupinfo>
</group>
<group synchronized="1" identifier="grp7AA57A-3A3E703C3" id="902" functionbitmask="4160" fwversion="1.0" manufacturer="AVM" productname="">
<present>1</present>
<txbusy>0</txbusy>
<name>Heizung Bad</name>
<hkr>
<tist></tist>
<tsoll>24</tsoll>
<absenk>16</absenk>
<komfort>24</komfort>
<lock>0</lock>
<devicelock>0</devicelock>
<errorcode>0</errorcode>
<windowopenactiv>0</windowopenactiv>
<windowopenactiveendtime>0</windowopenactiveendtime>
<boostactive>0</boostactive>
<boostactiveendtime>0</boostactiveendtime>
<nextchange>
<endperiod>0</endperiod>
<tchange>24</tchange>
</nextchange>
<summeractive>0</summeractive>
<holidayactive>0</holidayactive>
</hkr>
<groupinfo>
<masterdeviceid>0</masterdeviceid>
<members>17</members>
</groupinfo>
</group>
<group synchronized="1" identifier="grp7AA57A-3A8AFA86F" id="901" functionbitmask="4160" fwversion="1.0" manufacturer="AVM" productname="">
<present>1</present>
<txbusy>0</txbusy>
<name>Heizung Schlafzimmer</name>
<hkr>
<tist></tist>
<tsoll>16</tsoll>
<absenk>253</absenk>
<komfort>40</komfort>
<lock>0</lock>
<devicelock>0</devicelock>
<errorcode>0</errorcode>
<windowopenactiv>0</windowopenactiv>
<windowopenactiveendtime>0</windowopenactiveendtime>
<boostactive>0</boostactive>
<boostactiveendtime>0</boostactiveendtime>
<nextchange>
<endperiod>0</endperiod>
<tchange>40</tchange>
</nextchange>
<summeractive>0</summeractive>
<holidayactive>0</holidayactive>
</hkr>
<groupinfo>
<masterdeviceid>0</masterdeviceid>
<members>18</members>
</groupinfo>
</group>
</devicelist>

0 comments on commit cd9095f

Please sign in to comment.