)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"97b83e6deb4ea13edc36d90b531f615e0874eacf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"d13a8c6b_3ea24a76","updated":"2023-12-27 14:50:54.000000000","message":"IMHO the conversion should be opt-in because this may break existing systems expecting actual rpm. We can probably add an option like ``[ipmi] fan_metric_unit`` which defaults to None and convert the metric only when the option is set to a specific value.\n\n```\ncfg.StrOpt(\u0027fan_metric_unit\u0027,\n           default\u003dNone,\n           choices\u003d[\u0027rpm\u0027, \u0027percent\u0027, None],\n           ...)\n```","commit_id":"cd790b8bf9d3023d2697d3b93980f12b79c771f3"},{"author":{"_account_id":32968,"name":"Juan Larriba","email":"jlarriba@redhat.com","username":"jlarriba"},"change_message_id":"6482d69cb828143e222508ba2f5da92d6cfccf5a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"d3db56dc_2b6e3e49","updated":"2024-10-04 08:51:42.000000000","message":"This metric will be very useful considering how important sustainability is becoming for every cloud operator.","commit_id":"48f2fa23123f56b9dfc1950765c6a9b22b61df09"},{"author":{"_account_id":32240,"name":"Yadnesh Kulkarni","email":"yadnesh_kulkarni@proton.me","username":"ykulkarn"},"change_message_id":"67ab37123b1dbf0c4894722f6956364204006d4d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"5a5117a8_fbc207e0","updated":"2024-12-23 06:33:50.000000000","message":"@kajinamit@oss.nttdata.com what do you think about adding the maximum rpm value in resource_metadata in the metrics, instead of calculating rpm % in ceilometer we could calcuate in the metrics storage like prometheus during visualization ?","commit_id":"2ccc64cf96755d9545953c31f124a4d2171c18eb"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"a3883c5487f58f6c62a665fbf585b7ba18814ea2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"0b9af87c_f70ddf6d","in_reply_to":"14423a7e_931a88e8","updated":"2024-12-23 08:45:01.000000000","message":"That approach sounds better. It does not require config change and users can keep capturing the existing metrics along with the new one.","commit_id":"2ccc64cf96755d9545953c31f124a4d2171c18eb"},{"author":{"_account_id":32240,"name":"Yadnesh Kulkarni","email":"yadnesh_kulkarni@proton.me","username":"ykulkarn"},"change_message_id":"6f19b44d287ff12fe6efcfa57321e97884d4ce9f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"14423a7e_931a88e8","in_reply_to":"5a5117a8_fbc207e0","updated":"2024-12-23 06:38:19.000000000","message":"With this approach end user has the ability to rely on rpm and rpm % both without making any config change to ceilometer.","commit_id":"2ccc64cf96755d9545953c31f124a4d2171c18eb"}],"ceilometer/ipmi/pollsters/__init__.py":[{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"d90305713c0578653e7e05e60f80694f90db9bdb","unresolved":true,"context_lines":[{"line_number":24,"context_line":"               help\u003d\u0027Tolerance of IPMI/NM polling failures \u0027"},{"line_number":25,"context_line":"                    \u0027before disable this pollster. \u0027"},{"line_number":26,"context_line":"                    \u0027Negative indicates retrying forever.\u0027),"},{"line_number":27,"context_line":"    cfg.StrOpt(\u0027fan_metric_unit\u0027,"},{"line_number":28,"context_line":"               default\u003d\u0027RPM\u0027,"},{"line_number":29,"context_line":"               choices\u003d[\u0027RPM\u0027, \u0027percent\u0027],"},{"line_number":30,"context_line":"               help\u003d\u0027Unit in which fan usage metric is to be reported\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5606eb83_0d30117e","line":27,"range":{"start_line":27,"start_character":16,"end_line":27,"end_character":31},"updated":"2024-01-02 12:07:18.000000000","message":"If you intend to implement only RPM -\u003e percent conversion then it may be better to implement a boolean option like `fan_metric_use_percent`.","commit_id":"2149b7655b57f92087cd871d554ff1c0ca7030f1"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"185e7d4a850688ab88533790593e8d85d724334f","unresolved":false,"context_lines":[{"line_number":24,"context_line":"               help\u003d\u0027Tolerance of IPMI/NM polling failures \u0027"},{"line_number":25,"context_line":"                    \u0027before disable this pollster. \u0027"},{"line_number":26,"context_line":"                    \u0027Negative indicates retrying forever.\u0027),"},{"line_number":27,"context_line":"    cfg.StrOpt(\u0027fan_metric_unit\u0027,"},{"line_number":28,"context_line":"               default\u003d\u0027RPM\u0027,"},{"line_number":29,"context_line":"               choices\u003d[\u0027RPM\u0027, \u0027percent\u0027],"},{"line_number":30,"context_line":"               help\u003d\u0027Unit in which fan usage metric is to be reported\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"e5f0c241_1dba6b0f","line":27,"range":{"start_line":27,"start_character":16,"end_line":27,"end_character":31},"in_reply_to":"0c405ebb_dc7838b4","updated":"2024-11-06 11:23:21.000000000","message":"Done","commit_id":"2149b7655b57f92087cd871d554ff1c0ca7030f1"},{"author":{"_account_id":32240,"name":"Yadnesh Kulkarni","email":"yadnesh_kulkarni@proton.me","username":"ykulkarn"},"change_message_id":"edd225ff12a416cee592420e8132ae6229f46af0","unresolved":true,"context_lines":[{"line_number":24,"context_line":"               help\u003d\u0027Tolerance of IPMI/NM polling failures \u0027"},{"line_number":25,"context_line":"                    \u0027before disable this pollster. \u0027"},{"line_number":26,"context_line":"                    \u0027Negative indicates retrying forever.\u0027),"},{"line_number":27,"context_line":"    cfg.StrOpt(\u0027fan_metric_unit\u0027,"},{"line_number":28,"context_line":"               default\u003d\u0027RPM\u0027,"},{"line_number":29,"context_line":"               choices\u003d[\u0027RPM\u0027, \u0027percent\u0027],"},{"line_number":30,"context_line":"               help\u003d\u0027Unit in which fan usage metric is to be reported\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"0c405ebb_dc7838b4","line":27,"range":{"start_line":27,"start_character":16,"end_line":27,"end_character":31},"in_reply_to":"0faab885_00fedead","updated":"2024-01-03 13:06:17.000000000","message":"I\u0027ve noticed output of ipmitool cmd in some systems return fan metric usage in percent instead of RPM. I don\u0027t think fan metrics would be measured in units other than RPM and percent. So we could very well have it as a boolean option like you suggested.","commit_id":"2149b7655b57f92087cd871d554ff1c0ca7030f1"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"a7815b5cd46159a5c75f593519c2d2c1d7e9b787","unresolved":true,"context_lines":[{"line_number":24,"context_line":"               help\u003d\u0027Tolerance of IPMI/NM polling failures \u0027"},{"line_number":25,"context_line":"                    \u0027before disable this pollster. \u0027"},{"line_number":26,"context_line":"                    \u0027Negative indicates retrying forever.\u0027),"},{"line_number":27,"context_line":"    cfg.StrOpt(\u0027fan_metric_unit\u0027,"},{"line_number":28,"context_line":"               default\u003d\u0027RPM\u0027,"},{"line_number":29,"context_line":"               choices\u003d[\u0027RPM\u0027, \u0027percent\u0027],"},{"line_number":30,"context_line":"               help\u003d\u0027Unit in which fan usage metric is to be reported\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"0faab885_00fedead","line":27,"range":{"start_line":27,"start_character":16,"end_line":27,"end_character":31},"in_reply_to":"5606eb83_0d30117e","updated":"2024-01-02 12:10:44.000000000","message":"NOTE: ignore this in case fan sensors always return value in RPM.","commit_id":"2149b7655b57f92087cd871d554ff1c0ca7030f1"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"40975e9064feaca18337d9bcff427e497fcd5216","unresolved":true,"context_lines":[{"line_number":24,"context_line":"               help\u003d\u0027Tolerance of IPMI/NM polling failures \u0027"},{"line_number":25,"context_line":"                    \u0027before disable this pollster. \u0027"},{"line_number":26,"context_line":"                    \u0027Negative indicates retrying forever.\u0027),"},{"line_number":27,"context_line":"    cfg.BoolOpt(\u0027fan_metric_unit_percent\u0027,"},{"line_number":28,"context_line":"                default\u003dFalse,"},{"line_number":29,"context_line":"                help\u003d\u0027Report Fan metrics in percent\u0027)"},{"line_number":30,"context_line":"]"}],"source_content_type":"text/x-python","patch_set":15,"id":"7453eb4f_d26085dc","line":27,"range":{"start_line":27,"start_character":17,"end_line":27,"end_character":40},"updated":"2025-01-08 09:37:03.000000000","message":"Can this be removed now ?","commit_id":"20830bbe583af717cd4428675138b3003e6215e8"}],"ceilometer/ipmi/pollsters/sensor.py":[{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"d90305713c0578653e7e05e60f80694f90db9bdb","unresolved":true,"context_lines":[{"line_number":86,"context_line":""},{"line_number":87,"context_line":"            try:"},{"line_number":88,"context_line":"                volume, unit \u003d parser.parse_reading(sensor_reading)"},{"line_number":89,"context_line":"                if ("},{"line_number":90,"context_line":"                    unit \u003d\u003d \u0027RPM\u0027 and"},{"line_number":91,"context_line":"                    self.conf.ipmi.fan_metric_unit \u003d\u003d \u0027percent\u0027"},{"line_number":92,"context_line":"                ):"},{"line_number":93,"context_line":"                    volume \u003d self.fan_rpm_percent("},{"line_number":94,"context_line":"                        volume, float(sensor_data[\u0027Normal Maximum\u0027])"},{"line_number":95,"context_line":"                    )"},{"line_number":96,"context_line":"                    unit \u003d \u0027percent\u0027"},{"line_number":97,"context_line":"            except parser.InvalidSensorData:"},{"line_number":98,"context_line":"                continue"},{"line_number":99,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"7fc68a50_72e29031","line":96,"range":{"start_line":89,"start_character":0,"end_line":96,"end_character":36},"updated":"2024-01-02 12:07:18.000000000","message":"this logic is specific to FanSensorPollster and adding this to the SensorPollster class breaks the other classes inheriting the base class.\n\nWhat you can do is to create a parse_reading method to SensorPollster, which returns parser.parse_reading and override it in FanSensorPollster","commit_id":"2149b7655b57f92087cd871d554ff1c0ca7030f1"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"c94b728c9c46b8aa4de02a9152e26724ee956dee","unresolved":true,"context_lines":[{"line_number":86,"context_line":""},{"line_number":87,"context_line":"            try:"},{"line_number":88,"context_line":"                volume, unit \u003d parser.parse_reading(sensor_reading)"},{"line_number":89,"context_line":"                if ("},{"line_number":90,"context_line":"                    unit \u003d\u003d \u0027RPM\u0027 and"},{"line_number":91,"context_line":"                    self.conf.ipmi.fan_metric_unit \u003d\u003d \u0027percent\u0027"},{"line_number":92,"context_line":"                ):"},{"line_number":93,"context_line":"                    volume \u003d self.fan_rpm_percent("},{"line_number":94,"context_line":"                        volume, float(sensor_data[\u0027Normal Maximum\u0027])"},{"line_number":95,"context_line":"                    )"},{"line_number":96,"context_line":"                    unit \u003d \u0027percent\u0027"},{"line_number":97,"context_line":"            except parser.InvalidSensorData:"},{"line_number":98,"context_line":"                continue"},{"line_number":99,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"8330d871_447fb985","line":96,"range":{"start_line":89,"start_character":0,"end_line":96,"end_character":36},"in_reply_to":"7fc68a50_72e29031","updated":"2024-01-02 12:08:22.000000000","message":"\u003e adding this to the SensorPollster class breaks the other classes inheriting the base class.\nIt may not cause direct breakage as long as the other metric do not return RPM unit but because this is very specific to FanSensorPollSter the logic still needs to be in that class, IMO.","commit_id":"2149b7655b57f92087cd871d554ff1c0ca7030f1"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"185e7d4a850688ab88533790593e8d85d724334f","unresolved":false,"context_lines":[{"line_number":86,"context_line":""},{"line_number":87,"context_line":"            try:"},{"line_number":88,"context_line":"                volume, unit \u003d parser.parse_reading(sensor_reading)"},{"line_number":89,"context_line":"                if ("},{"line_number":90,"context_line":"                    unit \u003d\u003d \u0027RPM\u0027 and"},{"line_number":91,"context_line":"                    self.conf.ipmi.fan_metric_unit \u003d\u003d \u0027percent\u0027"},{"line_number":92,"context_line":"                ):"},{"line_number":93,"context_line":"                    volume \u003d self.fan_rpm_percent("},{"line_number":94,"context_line":"                        volume, float(sensor_data[\u0027Normal Maximum\u0027])"},{"line_number":95,"context_line":"                    )"},{"line_number":96,"context_line":"                    unit \u003d \u0027percent\u0027"},{"line_number":97,"context_line":"            except parser.InvalidSensorData:"},{"line_number":98,"context_line":"                continue"},{"line_number":99,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"68399e95_d2005f40","line":96,"range":{"start_line":89,"start_character":0,"end_line":96,"end_character":36},"in_reply_to":"8330d871_447fb985","updated":"2024-11-06 11:23:21.000000000","message":"Done","commit_id":"2149b7655b57f92087cd871d554ff1c0ca7030f1"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"185e7d4a850688ab88533790593e8d85d724334f","unresolved":true,"context_lines":[{"line_number":87,"context_line":"            if not parser.validate_reading(sensor_reading):"},{"line_number":88,"context_line":"                continue"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"            self.sensor_data \u003d sensor_data"},{"line_number":91,"context_line":"            try:"},{"line_number":92,"context_line":"                volume, unit \u003d self.parse_reading(sensor_reading)"},{"line_number":93,"context_line":"            except parser.InvalidSensorData:"}],"source_content_type":"text/x-python","patch_set":12,"id":"10203338_fec41fc0","line":90,"range":{"start_line":90,"start_character":17,"end_line":90,"end_character":28},"updated":"2024-11-06 11:23:21.000000000","message":"sensor data should not be associated with the core pollster instance. I\u0027d suggest passing sensor_data as an argument of parse_reading.","commit_id":"2ccc64cf96755d9545953c31f124a4d2171c18eb"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"185e7d4a850688ab88533790593e8d85d724334f","unresolved":true,"context_lines":[{"line_number":125,"context_line":"    METRIC \u003d \u0027Fan\u0027"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"    def fan_rpm_percent(self, volume, normal_maximum):"},{"line_number":128,"context_line":"        return float(f\u0027{volume * 100 /normal_maximum:.2f}\u0027)"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"    def parse_reading(self, sensor_reading):"},{"line_number":131,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":12,"id":"59c372b7_ebc98b91","line":128,"range":{"start_line":128,"start_character":15,"end_line":128,"end_character":59},"updated":"2024-11-06 11:23:21.000000000","message":"Can we use round instead of dumping it as a string.","commit_id":"2ccc64cf96755d9545953c31f124a4d2171c18eb"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"185e7d4a850688ab88533790593e8d85d724334f","unresolved":true,"context_lines":[{"line_number":139,"context_line":"                    float(volume), float(self.sensor_data[\u0027Normal Maximum\u0027])"},{"line_number":140,"context_line":"                )"},{"line_number":141,"context_line":"                unit \u003d \u0027percent\u0027"},{"line_number":142,"context_line":"            return float(volume), parser.UNIT_MAP.get(unit, unit)"},{"line_number":143,"context_line":"        except ValueError:"},{"line_number":144,"context_line":"            raise parser.InvalidSensorData("},{"line_number":145,"context_line":"                \u0027unable to parse sensor reading: %s\u0027 % sensor_reading"}],"source_content_type":"text/x-python","patch_set":12,"id":"c9c48898_7196ebc4","line":142,"range":{"start_line":142,"start_character":41,"end_line":142,"end_character":49},"updated":"2024-11-06 11:23:21.000000000","message":"It seems this does not exist ?","commit_id":"2ccc64cf96755d9545953c31f124a4d2171c18eb"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"40975e9064feaca18337d9bcff427e497fcd5216","unresolved":true,"context_lines":[{"line_number":122,"context_line":"                resource_id\u003dresource_id,"},{"line_number":123,"context_line":"                resource_metadata\u003dmetadata)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def extra_sensor_metadata(self):"},{"line_number":126,"context_line":"        # override extra_sensor_metadata to add specific metrics for"},{"line_number":127,"context_line":"        # each sensor"},{"line_number":128,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":15,"id":"1d44cd04_79b00320","line":125,"range":{"start_line":125,"start_character":8,"end_line":125,"end_character":29},"updated":"2025-01-08 09:37:03.000000000","message":"If this is a method then get_extra_sensor_metadata would be better, or make this property.","commit_id":"20830bbe583af717cd4428675138b3003e6215e8"},{"author":{"_account_id":32240,"name":"Yadnesh Kulkarni","email":"yadnesh_kulkarni@proton.me","username":"ykulkarn"},"change_message_id":"b3b9b92b29465c8b2966212cfcc3a447000cd5bb","unresolved":true,"context_lines":[{"line_number":122,"context_line":"                resource_id\u003dresource_id,"},{"line_number":123,"context_line":"                resource_metadata\u003dmetadata)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def extra_sensor_metadata(self):"},{"line_number":126,"context_line":"        # override extra_sensor_metadata to add specific metrics for"},{"line_number":127,"context_line":"        # each sensor"},{"line_number":128,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":15,"id":"d46fb1ce_05bf576d","line":125,"range":{"start_line":125,"start_character":8,"end_line":125,"end_character":29},"in_reply_to":"1d44cd04_79b00320","updated":"2025-01-08 09:55:26.000000000","message":"I meant that to be a method, I\u0027ve made the changes accordingly.","commit_id":"20830bbe583af717cd4428675138b3003e6215e8"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"40975e9064feaca18337d9bcff427e497fcd5216","unresolved":true,"context_lines":[{"line_number":125,"context_line":"    def extra_sensor_metadata(self):"},{"line_number":126,"context_line":"        # override extra_sensor_metadata to add specific metrics for"},{"line_number":127,"context_line":"        # each sensor"},{"line_number":128,"context_line":"        pass"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"class TemperatureSensorPollster(SensorPollster):"}],"source_content_type":"text/x-python","patch_set":15,"id":"363ad81e_c3c92db0","line":128,"range":{"start_line":128,"start_character":8,"end_line":128,"end_character":12},"updated":"2025-01-08 09:37:03.000000000","message":"You can return {} then you use dict.update to merge extra metadata into the metadata. This allows you to simplify the logic.","commit_id":"20830bbe583af717cd4428675138b3003e6215e8"},{"author":{"_account_id":32240,"name":"Yadnesh Kulkarni","email":"yadnesh_kulkarni@proton.me","username":"ykulkarn"},"change_message_id":"b3b9b92b29465c8b2966212cfcc3a447000cd5bb","unresolved":false,"context_lines":[{"line_number":125,"context_line":"    def extra_sensor_metadata(self):"},{"line_number":126,"context_line":"        # override extra_sensor_metadata to add specific metrics for"},{"line_number":127,"context_line":"        # each sensor"},{"line_number":128,"context_line":"        pass"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"class TemperatureSensorPollster(SensorPollster):"}],"source_content_type":"text/x-python","patch_set":15,"id":"37573238_c4c1e0f1","line":128,"range":{"start_line":128,"start_character":8,"end_line":128,"end_character":12},"in_reply_to":"363ad81e_c3c92db0","updated":"2025-01-08 09:55:26.000000000","message":"Done","commit_id":"20830bbe583af717cd4428675138b3003e6215e8"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"40975e9064feaca18337d9bcff427e497fcd5216","unresolved":true,"context_lines":[{"line_number":147,"context_line":"        except KeyError:"},{"line_number":148,"context_line":"            # Maximum rpm might not be reported when usage"},{"line_number":149,"context_line":"            # is reported as percent"},{"line_number":150,"context_line":"            pass"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"class VoltageSensorPollster(SensorPollster):"}],"source_content_type":"text/x-python","patch_set":15,"id":"1f8eb322_dd449796","line":150,"range":{"start_line":150,"start_character":12,"end_line":150,"end_character":16},"updated":"2025-01-08 09:37:03.000000000","message":"ditto. Use {}","commit_id":"20830bbe583af717cd4428675138b3003e6215e8"},{"author":{"_account_id":32240,"name":"Yadnesh Kulkarni","email":"yadnesh_kulkarni@proton.me","username":"ykulkarn"},"change_message_id":"b3b9b92b29465c8b2966212cfcc3a447000cd5bb","unresolved":false,"context_lines":[{"line_number":147,"context_line":"        except KeyError:"},{"line_number":148,"context_line":"            # Maximum rpm might not be reported when usage"},{"line_number":149,"context_line":"            # is reported as percent"},{"line_number":150,"context_line":"            pass"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"class VoltageSensorPollster(SensorPollster):"}],"source_content_type":"text/x-python","patch_set":15,"id":"e9a3a944_da6eee4a","line":150,"range":{"start_line":150,"start_character":12,"end_line":150,"end_character":16},"in_reply_to":"1f8eb322_dd449796","updated":"2025-01-08 09:55:26.000000000","message":"Done","commit_id":"20830bbe583af717cd4428675138b3003e6215e8"}]}
