Home Assistant Unofficial Reference 2024.12.1
convert_device_diagnostics_to_fixture.py
Go to the documentation of this file.
1 """Script to convert a device diagnostics file to a fixture."""
2 
3 from __future__ import annotations
4 
5 import argparse
6 import json
7 from pathlib import Path
8 from typing import Any
9 
10 from homeassistant.util import slugify
11 
12 
13 def get_arguments() -> argparse.Namespace:
14  """Get parsed passed in arguments."""
15  parser = argparse.ArgumentParser(description="Z-Wave JS Fixture generator")
16  parser.add_argument(
17  "diagnostics_file", type=Path, help="Device diagnostics file to convert"
18  )
19  parser.add_argument(
20  "--file",
21  action="store_true",
22  help=(
23  "Dump fixture to file in fixtures folder. By default, the fixture will be "
24  "printed to standard output."
25  ),
26  )
27 
28  return parser.parse_args()
29 
30 
31 def get_fixtures_dir_path(data: dict) -> Path:
32  """Get path to fixtures directory."""
33  device_config = data["deviceConfig"]
34  filename = slugify(
35  f"{device_config['manufacturer']}-{device_config['label']}_state"
36  )
37  path = Path(__file__).parents[1]
38  index = path.parts.index("homeassistant")
39  return Path(
40  *path.parts[:index],
41  "tests",
42  *path.parts[index + 1 :],
43  "fixtures",
44  f"{filename}.json",
45  )
46 
47 
48 def load_file(path: Path) -> Any:
49  """Load file from path."""
50  return json.loads(path.read_text("utf8"))
51 
52 
53 def extract_fixture_data(diagnostics_data: Any) -> dict:
54  """Extract fixture data from file."""
55  if (
56  not isinstance(diagnostics_data, dict)
57  or "data" not in diagnostics_data
58  or "state" not in diagnostics_data["data"]
59  ):
60  raise ValueError("Invalid diagnostics file format")
61  state: dict = diagnostics_data["data"]["state"]
62  if not isinstance(state["values"], list):
63  values_dict: dict[str, dict] = state.pop("values")
64  state["values"] = list(values_dict.values())
65  if not isinstance(state["endpoints"], list):
66  endpoints_dict: dict[str, dict] = state.pop("endpoints")
67  state["endpoints"] = list(endpoints_dict.values())
68 
69  return state
70 
71 
72 def create_fixture_file(path: Path, state_text: str) -> None:
73  """Create a file for the state dump in the fixtures directory."""
74  path.write_text(state_text, "utf8")
75 
76 
77 def main() -> None:
78  """Run the main script."""
79  args = get_arguments()
80  diagnostics_path: Path = args.diagnostics_file
81  diagnostics = load_file(diagnostics_path)
82  fixture_data = extract_fixture_data(diagnostics)
83  fixture_text = json.dumps(fixture_data, indent=2)
84  if args.file:
85  fixture_path = get_fixtures_dir_path(fixture_data)
86  create_fixture_file(fixture_path, fixture_text)
87  return
88  print(fixture_text) # noqa: T201
89 
90 
91 if __name__ == "__main__":
92  main()