11import logging
2+ import re
23import voluptuous as vol
34from typing import Any , Dict , Optional
45
1415
1516_LOGGER = logging .getLogger (__name__ )
1617
18+ # --- Custom validator for train number ---
19+ def validate_train_number (value : str | None ) -> str | None :
20+ """Validate that train number is 2–4 alphanumeric characters or empty."""
21+ if value in ("" , None ):
22+ return None # normalize empty
23+ value = str (value ).strip ().upper ()
24+ if not re .fullmatch (r"[A-Z0-9]{2,4}" , value ):
25+ raise vol .Invalid ("Train number must be 2–4 letters/numbers or empty" )
26+ return value
27+
1728
1829def get_user_schema (default_api_key : str = "" ) -> vol .Schema :
1930 return vol .Schema ({
2031 vol .Required ("depart_from" , default = "" ): str ,
2132 vol .Required ("arrive_at" , default = "" ): str ,
2233 vol .Required ("api_key" , default = default_api_key ): vol .All (str , vol .Length (min = 32 , max = 32 )),
2334 vol .Optional ("max_trips" , default = 2 ): int ,
24- vol .Optional ("train" , default = "" ): vol .Any (
25- vol .All (str , vol .Length (min = 3 , max = 3 )),
26- ""
27- )
35+ vol .Optional ("train" , default = "" ): validate_train_number ,
2836 })
2937
3038
@@ -45,6 +53,10 @@ async def async_step_user(
4553 arrive_at = user_input .get ("arrive_at" )
4654 api_key = user_input .get ("api_key" , "" ).strip ()
4755 train = user_input .get ("train" , "" )
56+ # Normalize empty train to None
57+ if train in ("" , None ):
58+ train = None
59+ user_input ["train" ] = None
4860
4961 if not api_key :
5062 errors ["api_key" ] = "required"
0 commit comments