code: async def get_attached_modules(request):
      
      hw = hw_from_req(request)
      if ff.use_protocol_api_v2():
          hw_mods = await hw.discover_modules()
          module_data = [
              {
                  'name': mod.name(),
                  'displayName': mod.display_name(),
                  'port': mod.port,
                  'serial': mod.device_info.get('serial'),
                  'model': mod.device_info.get('model'),
                  'fwVersion': mod.device_info.get('version'),
                  **mod.live_data
              }
              for mod in hw_mods
          ]
      else:
          hw.discover_modules()
          hw_mods = hw.attached_modules.values()
          module_data = [
              {
                  'name': mod.name(),
                  'displayName': mod.display_name(),
                  'port': mod.port,
                  'serial': mod.device_info and mod.device_info.get('serial'),
                  'model': mod.device_info and mod.device_info.get('model'),
                  'fwVersion': mod.device_info
                  and mod.device_info.get('version'),
                  **mod.live_data
              }
              for mod in hw_mods
          ]
      return web.json_response(data={"modules": module_data},
                               status=200)
docs: On success (including an empty "modules" list if no modules are detected):
      // status: 200
      {
          "modules": [
              {
                  /** name of module */
                  "name": "string",
                  /** model identifier (i.e. part number) */
                  "model": "string",
                  /** unique serial number */
                  "serial": "string",
                  /** current firmware version */
                  "fwVersion": "string",
                  /** human readable status */
                  "status": "string",
                  /** human readable display name */
                  "displayName": "string",
              },
              // ...
          ],
      }
  
      On failure:
      // status: 500
      {
          "message": "..."
      }