@@ -7530,8 +7530,18 @@ def _test_get_max_inverter_rate_from_model(my_predbat):
75307530 ("GIV-AIO-GW2" , 2600 , 2600 , "GIV-AIO-GW2 => fallback, GW2 is not a rating" ),
75317531 ("GIV-3HY-G3" , 9984 , 9984 , "GIV-3HY-G3 => fallback, G3 is not a rating" ),
75327532 ("GIV-3HY-110" , 9984 , 9984 , "GIV-3HY-110 => fallback, three digits is not a plausible rating" ),
7533- # Decimal pass still wins over the 3HY integer pass
7533+ # Non-3HY hybrids still use the decimal pass
75347534 ("ALPS HY-6.0-GL" , 3600 , 6000 , "ALPS HY-6.0-GL => 6kW" ),
7535+ # The explicit 3HY segment wins over a later decimal segment
7536+ ("GIV-3HY-11-9.5" , 9984 , 11000 , "GIV-3HY-11-9.5 => 11kW, later decimal does not hide the 3HY rating" ),
7537+ # A 3HY decimal rating is not a whole integer segment and falls through to the decimal pass
7538+ ("GIV-3HY-10.0" , 9984 , 10000 , "GIV-3HY-10.0 => 10kW via the decimal pass" ),
7539+ # Trailing punctuation or whitespace does not defeat the segment anchors
7540+ ("GIV-3HY-11." , 9984 , 11000 , "GIV-3HY-11. => 11kW (trailing period)" ),
7541+ ("GIV-3HY-11 " , 9984 , 11000 , "GIV-3HY-11<space> => 11kW (trailing space)" ),
7542+ ("GIV-HY-8.0-G3-HV." , None , 8000 , "GIV-HY-8.0-G3-HV. => 8kW (trailing period)" ),
7543+ # An explicit null model from GE Cloud falls back rather than raising TypeError
7544+ (None , 3600 , 3600 , "None model => fallback to max_charge_rate" ),
75357545 ]
75367546
75377547 failed = 0
@@ -7558,6 +7568,40 @@ def _test_get_max_inverter_rate_from_model(my_predbat):
75587568 else :
75597569 print ("OK unparsed hybrid model warns once" )
75607570
7571+ # With no max_charge_rate the warning must not print "NoneW"
7572+ ge_cloud .model_rate_warned = set ()
7573+ ge_cloud .log_messages = []
7574+ ge_cloud .get_max_inverter_rate_from_model ("GIV-HYZ" , None )
7575+ warnings = [message for message in ge_cloud .log_messages if "Unable to determine inverter rating" in message ]
7576+ if len (warnings ) != 1 or "NoneW" in warnings [0 ]:
7577+ print ("ERROR expected one fallback warning without 'NoneW', got {}" .format (warnings ))
7578+ failed += 1
7579+ else :
7580+ print ("OK fallback warning with no max_charge_rate is readable" )
7581+
7582+ # End to end through publish_info: the 3-phase hybrid publishes its 11kW rating, not the fluctuating battery rate (GH#5136)
7583+ ge_cloud .config_args ["prefix" ] = "predbat"
7584+ ge_cloud .dashboard_items .clear ()
7585+ info_3hy = {"info" : {"battery" : {"nominal_capacity" : 186 , "nominal_voltage" : 51.2 }, "model" : "GIV-3HY-11" , "max_charge_rate" : 9984 }}
7586+ run_async (ge_cloud .publish_info ("dev3hy" , info_3hy ))
7587+ rate = ge_cloud .dashboard_items .get ("sensor.predbat_gecloud_dev3hy_max_inverter_rate" , {}).get ("state" )
7588+ if rate != 11000 :
7589+ print ("ERROR publish_info GIV-3HY-11 expected max_inverter_rate 11000, got {}" .format (rate ))
7590+ failed += 1
7591+ else :
7592+ print ("OK publish_info GIV-3HY-11 publishes 11000" )
7593+
7594+ # An explicit null model in the payload publishes the fallback instead of crashing the refresh
7595+ ge_cloud .dashboard_items .clear ()
7596+ info_null_model = {"info" : {"battery" : {"nominal_capacity" : 186 , "nominal_voltage" : 51.2 }, "model" : None , "max_charge_rate" : 3600 }}
7597+ run_async (ge_cloud .publish_info ("devnull" , info_null_model ))
7598+ rate = ge_cloud .dashboard_items .get ("sensor.predbat_gecloud_devnull_max_inverter_rate" , {}).get ("state" )
7599+ if rate != 3600 :
7600+ print ("ERROR publish_info null model expected max_inverter_rate 3600, got {}" .format (rate ))
7601+ failed += 1
7602+ else :
7603+ print ("OK publish_info null model publishes the fallback" )
7604+
75617605 return 1 if failed else 0
75627606
75637607
0 commit comments