Skip to content

Commit

Permalink
Merge pull request #27 from ubuntu-robotics/dev/device_view
Browse files Browse the repository at this point in the history
feat(device_view): adapt the view to list all dashboards and layouts
  • Loading branch information
Guillaumebeuzeboc committed Mar 25, 2024
2 parents 95c135d + fce2a9c commit 30ffc84
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 17 deletions.
8 changes: 6 additions & 2 deletions cos_registration_server/devices/templates/devices/device.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<p>Device {{device.uid}} with ip {{device.address}}, was created on the {{device.creation_date}}</p>
<ul>
{% for name, link in links_dict.items %}
<li><a href="{{request.scheme}}://{{link}}">{{ name }}</a></li>
{% for application_link in links_list%}
<li><a href="{{request.scheme}}://{{application_link.main_link}}">{{ application_link.name }}</a>
{% for name, link in application_link.additional_links.items %}
<ul><a href="{{request.scheme}}://{{link}}">{{ name }}</a></ul>
{% endfor %}
</li>
{% endfor %}
</ul>
47 changes: 45 additions & 2 deletions cos_registration_server/devices/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,56 @@ def test_listed_device(self) -> None:
f" {device.creation_date.strftime('%B %d, %Y, %-I')}",
)
self.assertContains(
response, self.base_url + "/cos-grafana/f/" + device.uid + "/"
response,
self.base_url + "/cos-grafana/dashboards/?query=" + device.uid,
)
self.assertContains(
response,
self.base_url
+ "/cos-foxglove-studio/"
+ escape("?ds=foxglove-websocket&ds.url=ws%3A%2F%2F")
+ device.address
+ "%3A8765/",
+ "%3A8765",
)

self.assertContains(
response, self.base_url + "/cos-ros2bag-fileserver/" + device.uid
)

def test_listed_device_additional_links(self) -> None:
grafana_dashboard = GrafanaDashboard(
uid="dashboard-1", dashboard=SIMPLE_GRAFANA_DASHBOARD
)
grafana_dashboard.save()
foxglove_dashboard = FoxgloveDashboard(
uid="layout-1", dashboard=SIMPLE_FOXGLOVE_DASHBOARD
)
foxglove_dashboard.save()
device = Device(
uid="hello-123",
creation_date=timezone.now(),
address="127.0.0.1",
)
device.save()
device.grafana_dashboards.add(grafana_dashboard)
device.foxglove_dashboards.add(foxglove_dashboard)
url = reverse("devices:device", args=(device.uid,))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(
response,
self.base_url
+ "/cos-foxglove-studio/"
+ escape("?ds=foxglove-websocket&ds.url=ws%3A%2F%2F")
+ device.address
+ "%3A8765"
+ escape("&layoutUrl=")
+ f"127.0.0.1%3A8080%2Fcos-cos-registration-server%2Fapi%2Fv1%2F"
+ "applications%2Ffoxglove%2Fdashboards%2Flayout-1",
)

self.assertContains(
response,
self.base_url
+ "/cos-grafana/dashboards/dashboard-1/?instance=hello-123",
)
80 changes: 67 additions & 13 deletions cos_registration_server/devices/views.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""Devices views."""

from typing import Any
from typing import Any, Dict

from django.http import HttpRequest, HttpResponse
from django.shortcuts import render
from django.utils.http import urlencode
from django.views import generic

from .models import Device
Expand Down Expand Up @@ -32,22 +33,75 @@ def device(request: HttpRequest, uid: str) -> HttpResponse:
device = Device.objects.get(uid=uid)
except Device.DoesNotExist:
return HttpResponse(f"device {uid} not found")

class ApplicationLinks:
"""Application links structure.
This class is holding the links of an application
so it can be passed to the html template.
params:
name: Name of the application.
main_link: Main link of the application.
additional_links: Additional links of the application
(dashboards etc).
"""

def __init__(
self,
name: str,
main_link: str,
additional_links: Dict[str, str] = {},
) -> None:
self.name = name
self.main_link = main_link
self.additional_links = additional_links

base_url = request.META["HTTP_HOST"]
grafana_folder = base_url + "/cos-grafana/f/" + uid + "/"
foxglove = (
base_url
+ "/cos-foxglove-studio/?ds=foxglove-websocket&ds.url=ws%3A%2F%2F"
+ device.address
+ "%3A8765/"

grafana_param = {"query": uid}
grafana_main_link = (
f"{base_url}/cos-grafana/dashboards/?{urlencode(grafana_param)}/"
)
bag_files = base_url + "/cos-ros2bag-fileserver/" + uid + "/"
links = {
"grafana folder": grafana_folder,
"foxglove": foxglove,
"bag_files": bag_files,
grafana_dashboards = {}
grafana_param = {"instance": uid}
for grafana_dashboard in device.grafana_dashboards.all():
grafana_dashboards[grafana_dashboard.uid] = (
base_url + "/cos-grafana/dashboards/" + grafana_dashboard.uid + "/"
f"?{urlencode(grafana_param)}/"
)

foxglove_params = {
"ds": "foxglove-websocket",
"ds.url": f"ws://{device.address}:8765",
}
foxglove_main_link = (
f"{base_url}/cos-foxglove-studio/?{urlencode(foxglove_params)}"
)
foxglove_layouts = {}
for foxglove_dashboard in device.foxglove_dashboards.all():
foxglove_params["layoutUrl"] = (
f"{base_url}/cos-cos-registration-server/api/v1/"
f"applications/foxglove/dashboards/{foxglove_dashboard.uid}"
)
foxglove_layouts[foxglove_dashboard.uid] = (
f"{base_url}/cos-foxglove-studio/?{urlencode(foxglove_params)}"
)

bag_files = f"{base_url}/cos-ros2bag-fileserver/{uid}/"

links = []
links.append(
ApplicationLinks(
"Foxglove studio", foxglove_main_link, foxglove_layouts
)
)
links.append(
ApplicationLinks("Grafana", grafana_main_link, grafana_dashboards)
)
links.append(ApplicationLinks("Bag files", bag_files))
context = {
"device": device,
"links_dict": links,
"links_list": links,
}
return render(request, "devices/device.html", context)

0 comments on commit 30ffc84

Please sign in to comment.