File size: 6,215 Bytes
dcf1b21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/usr/bin/env python3
"""Discover Nova API configuration - simple version without dependencies."""

import json
import os
import sys
import urllib.request
from pathlib import Path


def load_env_file(filepath):
    """Simple .env file loader."""
    env_vars = {}
    if not filepath.exists():
        return env_vars

    with open(filepath, 'r') as f:
        for line in f:
            line = line.strip()
            if line and not line.startswith('#') and '=' in line:
                key, value = line.split('=', 1)
                env_vars[key.strip()] = value.strip()
    return env_vars


def request_json(url, access_token):
    """Make a GET request to the Nova API."""
    request = urllib.request.Request(url)
    request.add_header("Authorization", f"Bearer {access_token}")
    request.add_header("Content-Type", "application/json")
    try:
        with urllib.request.urlopen(request, timeout=10) as response:
            body = response.read().decode("utf-8")
            return json.loads(body) if body else {}
    except urllib.error.HTTPError as exc:
        body = exc.read().decode("utf-8") if exc.fp else ""
        print(f"Error: Nova API returned status {exc.code}")
        print(f"Response: {body}")
        return None
    except Exception as exc:
        print(f"Error: {exc}")
        return None


def main():
    # Try to load from .env.local first, then .env
    env_local = Path("nova-sim/.env.local")
    env_file = Path("nova-sim/.env")

    env_vars = {}
    if env_local.exists():
        env_vars = load_env_file(env_local)
        print(f"Loaded configuration from {env_local}")
    elif env_file.exists():
        env_vars = load_env_file(env_file)
        print(f"Loaded configuration from {env_file}")
    else:
        print("Error: No .env or .env.local file found")
        print("Create one with at least NOVA_INSTANCE_URL and NOVA_ACCESS_TOKEN")
        return 1

    # Get configuration
    instance_url = env_vars.get("NOVA_INSTANCE_URL") or env_vars.get("NOVA_API")
    access_token = env_vars.get("NOVA_ACCESS_TOKEN")
    cell_id = env_vars.get("NOVA_CELL_ID", "cell")

    if not instance_url:
        print("Error: NOVA_INSTANCE_URL (or NOVA_API) not set in .env file")
        return 1

    if not access_token:
        print("Error: NOVA_ACCESS_TOKEN not set in .env file")
        return 1

    print(f"\nConnecting to Nova instance: {instance_url}")
    print(f"Cell ID: {cell_id}")
    print()

    # Fetch controllers
    print("Fetching controllers...")
    controllers_url = f"{instance_url}/api/v2/cells/{cell_id}/controllers"
    controllers_data = request_json(controllers_url, access_token)

    if not controllers_data:
        return 1

    # Handle both list and dict responses
    if isinstance(controllers_data, list):
        controllers = controllers_data
    else:
        controllers = controllers_data.get("instances", [])

    if not controllers:
        print("No controllers found")
        return 1

    print(f"Found {len(controllers)} controller(s):")
    print()

    for controller in controllers:
        # Handle both string and dict controller responses
        if isinstance(controller, str):
            controller_id = controller
        else:
            controller_id = controller.get("controller", "unknown")
        print(f"Controller ID: {controller_id}")

        # Fetch motion groups - try cell-level endpoint first
        motion_groups_url = f"{instance_url}/api/v2/cells/{cell_id}/motion-groups"
        motion_groups_data = request_json(motion_groups_url, access_token)

        if not motion_groups_data:
            # Try controller-specific endpoint
            motion_groups_url = f"{instance_url}/api/v2/cells/{cell_id}/controllers/{controller_id}/motion-groups"
            motion_groups_data = request_json(motion_groups_url, access_token)

        if not motion_groups_data:
            print("  Motion groups: Could not fetch")
            continue

        motion_groups = motion_groups_data.get("motion_groups", [])
        print(f"  Motion groups: {len(motion_groups)}")

        for mg in motion_groups:
            mg_id = mg.get("motion_group", "unknown")
            model = mg.get("model_from_controller", "unknown")
            name = mg.get("name_from_controller", "")

            print(f"    - ID: {mg_id}")
            print(f"      Model: {model}")
            if name:
                print(f"      Name: {name}")

            # Fetch motion group description
            desc_url = f"{instance_url}/api/v2/cells/{cell_id}/controllers/{controller_id}/motion-groups/{mg_id}/description"
            desc_data = request_json(desc_url, access_token)

            if desc_data:
                tcps = desc_data.get("tcps", {})
                if tcps:
                    print(f"      Available TCPs: {', '.join(tcps.keys())}")
            print()

    # Generate recommended .env configuration
    print("\n" + "=" * 60)
    print("RECOMMENDED CONFIGURATION")
    print("=" * 60)

    if controllers:
        # Handle both string and dict controller responses
        controller = controllers[0]
        if isinstance(controller, str):
            controller_id = controller
        else:
            controller_id = controller.get("controller", "unknown")

        # Get motion groups for first controller
        motion_groups_url = f"{instance_url}/api/v2/cells/{cell_id}/controllers/{controller_id}/motion-groups"
        motion_groups_data = request_json(motion_groups_url, access_token)

        if motion_groups_data:
            motion_groups = motion_groups_data.get("motion_groups", [])
            if motion_groups:
                mg = motion_groups[0]
                mg_id = mg.get("motion_group", "unknown")
                model = mg.get("model_from_controller", "unknown")

                print("\nAdd/update these in your .env.local file:")
                print(f"""
NOVA_INSTANCE_URL={instance_url}
NOVA_ACCESS_TOKEN={access_token}
NOVA_CELL_ID={cell_id}
NOVA_CONTROLLER_ID={controller_id}
NOVA_MOTION_GROUP_ID={mg_id}
NOVA_MOTION_GROUP_MODEL={model}
NOVA_TCP_NAME=Flange
NOVA_RESPONSE_RATE_MS=200
""")

    return 0


if __name__ == "__main__":
    sys.exit(main())