irie 0.0.35__py3-none-any.whl → 0.0.37__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of irie might be problematic. Click here for more details.
- irie/apps/context_processors.py +8 -0
- irie/apps/inventory/admin.py +4 -1
- irie/apps/inventory/forms.py +30 -1
- irie/apps/inventory/migrations/0004_datum_sensorgroup_sensor.py +43 -0
- irie/apps/inventory/migrations/0005_alter_sensor_group.py +19 -0
- irie/apps/inventory/migrations/0006_datum_asset_datum_locate_x_datum_locate_y_and_more.py +56 -0
- irie/apps/inventory/migrations/0007_sensor_name.py +19 -0
- irie/apps/inventory/migrations/0008_alter_sensor_dx_alter_sensor_dy_alter_sensor_dz_and_more.py +43 -0
- irie/apps/inventory/models.py +47 -17
- irie/apps/inventory/urls.py +4 -2
- irie/apps/inventory/views.py +55 -2
- irie/apps/templates/includes/sidebar.html +29 -10
- irie/apps/templates/inventory/asset-event-summary.html +17 -7
- irie/apps/templates/inventory/asset-profile.html +10 -2
- irie/apps/templates/inventory/asset-sensors.html +69 -0
- irie/apps/templates/inventory/sensor-upload.html +452 -0
- irie/apps/templates/layouts/base-fullscreen.html +3 -4
- irie/apps/templates/site/index.html +2 -2
- irie/core/settings.py +1 -0
- irie/init/data/nbi_definitions.json +1 -0
- irie/init/getNBIData.py +12 -0
- irie/init/management/commands/init_assets.py +11 -7
- irie/init/management/commands/init_cesmd.py +11 -8
- {irie-0.0.35.dist-info → irie-0.0.37.dist-info}/METADATA +1 -1
- {irie-0.0.35.dist-info → irie-0.0.37.dist-info}/RECORD +28 -20
- {irie-0.0.35.dist-info → irie-0.0.37.dist-info}/WHEEL +1 -1
- {irie-0.0.35.dist-info → irie-0.0.37.dist-info}/entry_points.txt +0 -0
- {irie-0.0.35.dist-info → irie-0.0.37.dist-info}/top_level.txt +0 -0
irie/apps/context_processors.py
CHANGED
|
@@ -3,3 +3,11 @@ from django.conf import settings
|
|
|
3
3
|
|
|
4
4
|
def cfg_assets_root(request):
|
|
5
5
|
return {"ASSETS_ROOT": settings.ASSETS_ROOT}
|
|
6
|
+
|
|
7
|
+
def irie_apps(request):
|
|
8
|
+
return {
|
|
9
|
+
'irie_apps': settings.IRIE_APPS,
|
|
10
|
+
'irie_app_name': request.resolver_match.app_name,
|
|
11
|
+
'namespace': request.resolver_match.namespace,
|
|
12
|
+
'irie_url_name': request.resolver_match.url_name
|
|
13
|
+
}
|
irie/apps/inventory/admin.py
CHANGED
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
#
|
|
5
5
|
#===----------------------------------------------------------------------===#
|
|
6
6
|
from django.contrib import admin
|
|
7
|
-
from .models import Asset, Corridor
|
|
7
|
+
from .models import Asset, Corridor, SensorGroup, Sensor, Datum
|
|
8
8
|
|
|
9
9
|
admin.site.register(Corridor)
|
|
10
10
|
admin.site.register(Asset)
|
|
11
|
+
admin.site.register(SensorGroup)
|
|
12
|
+
admin.site.register(Sensor)
|
|
13
|
+
admin.site.register(Datum)
|
irie/apps/inventory/forms.py
CHANGED
|
@@ -4,9 +4,38 @@
|
|
|
4
4
|
#
|
|
5
5
|
#===----------------------------------------------------------------------===#
|
|
6
6
|
from django import forms
|
|
7
|
-
from
|
|
7
|
+
from django.forms import formset_factory
|
|
8
|
+
from irie.apps.inventory.models import Asset, SensorGroup, Sensor, Datum
|
|
8
9
|
|
|
9
10
|
class AssetForm(forms.ModelForm):
|
|
10
11
|
class Meta:
|
|
11
12
|
model = Asset
|
|
12
13
|
fields = '__all__'
|
|
14
|
+
|
|
15
|
+
class SensorGroupForm(forms.ModelForm):
|
|
16
|
+
class Meta:
|
|
17
|
+
model = SensorGroup
|
|
18
|
+
fields = ['name', 'datum']
|
|
19
|
+
|
|
20
|
+
def __init__(self, *args, asset=None, **kwargs):
|
|
21
|
+
super().__init__(*args, **kwargs)
|
|
22
|
+
if asset:
|
|
23
|
+
self.fields['datum'].queryset = Datum.objects.filter(asset=asset)
|
|
24
|
+
|
|
25
|
+
class SensorForm(forms.ModelForm):
|
|
26
|
+
class Meta:
|
|
27
|
+
model = Sensor
|
|
28
|
+
fields = ['name', 'x', 'y', 'z', 'dx', 'dy', 'dz']
|
|
29
|
+
labels = {
|
|
30
|
+
'name': 'Name',
|
|
31
|
+
'x': 'x',
|
|
32
|
+
'y': 'y',
|
|
33
|
+
'z': 'z',
|
|
34
|
+
'dx': 'dx',
|
|
35
|
+
'dy': 'dy',
|
|
36
|
+
'dz': 'dz',
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# Create a formset for multiple sensors
|
|
41
|
+
SensorFormSet = formset_factory(SensorForm, extra=3) # Default to 3 empty sensor forms
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Generated by Django 5.1.2 on 2025-02-24 00:30
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
('irie_apps_inventory', '0003_asset_notes'),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.CreateModel(
|
|
15
|
+
name='Datum',
|
|
16
|
+
fields=[
|
|
17
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
18
|
+
('name', models.CharField(max_length=100)),
|
|
19
|
+
],
|
|
20
|
+
),
|
|
21
|
+
migrations.CreateModel(
|
|
22
|
+
name='SensorGroup',
|
|
23
|
+
fields=[
|
|
24
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
25
|
+
('name', models.CharField(max_length=100)),
|
|
26
|
+
('asset', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='irie_apps_inventory.asset')),
|
|
27
|
+
('datum', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='irie_apps_inventory.datum')),
|
|
28
|
+
],
|
|
29
|
+
),
|
|
30
|
+
migrations.CreateModel(
|
|
31
|
+
name='Sensor',
|
|
32
|
+
fields=[
|
|
33
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
34
|
+
('x', models.FloatField()),
|
|
35
|
+
('y', models.FloatField()),
|
|
36
|
+
('z', models.FloatField()),
|
|
37
|
+
('dx', models.FloatField()),
|
|
38
|
+
('dy', models.FloatField()),
|
|
39
|
+
('dz', models.FloatField()),
|
|
40
|
+
('group', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='irie_apps_inventory.sensorgroup')),
|
|
41
|
+
],
|
|
42
|
+
),
|
|
43
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Generated by Django 5.1.2 on 2025-02-25 04:49
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
('irie_apps_inventory', '0004_datum_sensorgroup_sensor'),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AlterField(
|
|
15
|
+
model_name='sensor',
|
|
16
|
+
name='group',
|
|
17
|
+
field=models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='sensors', to='irie_apps_inventory.sensorgroup'),
|
|
18
|
+
),
|
|
19
|
+
]
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Generated by Django 5.1.2 on 2025-02-25 05:07
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
('irie_apps_inventory', '0005_alter_sensor_group'),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AddField(
|
|
15
|
+
model_name='datum',
|
|
16
|
+
name='asset',
|
|
17
|
+
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.RESTRICT, to='irie_apps_inventory.asset'),
|
|
18
|
+
preserve_default=False,
|
|
19
|
+
),
|
|
20
|
+
migrations.AddField(
|
|
21
|
+
model_name='datum',
|
|
22
|
+
name='locate_x',
|
|
23
|
+
field=models.CharField(default=0, max_length=240),
|
|
24
|
+
preserve_default=False,
|
|
25
|
+
),
|
|
26
|
+
migrations.AddField(
|
|
27
|
+
model_name='datum',
|
|
28
|
+
name='locate_y',
|
|
29
|
+
field=models.CharField(default=0, max_length=240),
|
|
30
|
+
preserve_default=False,
|
|
31
|
+
),
|
|
32
|
+
migrations.AddField(
|
|
33
|
+
model_name='datum',
|
|
34
|
+
name='locate_z',
|
|
35
|
+
field=models.CharField(default=0, max_length=240),
|
|
36
|
+
preserve_default=False,
|
|
37
|
+
),
|
|
38
|
+
migrations.AddField(
|
|
39
|
+
model_name='datum',
|
|
40
|
+
name='orient_x',
|
|
41
|
+
field=models.CharField(default=0, max_length=240),
|
|
42
|
+
preserve_default=False,
|
|
43
|
+
),
|
|
44
|
+
migrations.AddField(
|
|
45
|
+
model_name='datum',
|
|
46
|
+
name='orient_y',
|
|
47
|
+
field=models.CharField(default=0, max_length=240),
|
|
48
|
+
preserve_default=False,
|
|
49
|
+
),
|
|
50
|
+
migrations.AddField(
|
|
51
|
+
model_name='datum',
|
|
52
|
+
name='orient_z',
|
|
53
|
+
field=models.CharField(default=0, max_length=240),
|
|
54
|
+
preserve_default=False,
|
|
55
|
+
),
|
|
56
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Generated by Django 5.1.2 on 2025-02-26 03:21
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('irie_apps_inventory', '0006_datum_asset_datum_locate_x_datum_locate_y_and_more'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name='sensor',
|
|
15
|
+
name='name',
|
|
16
|
+
field=models.CharField(default=1, max_length=100),
|
|
17
|
+
preserve_default=False,
|
|
18
|
+
),
|
|
19
|
+
]
|
irie/apps/inventory/migrations/0008_alter_sensor_dx_alter_sensor_dy_alter_sensor_dz_and_more.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Generated by Django 5.1.2 on 2025-02-26 07:05
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('irie_apps_inventory', '0007_sensor_name'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterField(
|
|
14
|
+
model_name='sensor',
|
|
15
|
+
name='dx',
|
|
16
|
+
field=models.DecimalField(decimal_places=2, max_digits=10),
|
|
17
|
+
),
|
|
18
|
+
migrations.AlterField(
|
|
19
|
+
model_name='sensor',
|
|
20
|
+
name='dy',
|
|
21
|
+
field=models.DecimalField(decimal_places=2, max_digits=10),
|
|
22
|
+
),
|
|
23
|
+
migrations.AlterField(
|
|
24
|
+
model_name='sensor',
|
|
25
|
+
name='dz',
|
|
26
|
+
field=models.DecimalField(decimal_places=2, max_digits=10),
|
|
27
|
+
),
|
|
28
|
+
migrations.AlterField(
|
|
29
|
+
model_name='sensor',
|
|
30
|
+
name='x',
|
|
31
|
+
field=models.DecimalField(decimal_places=2, max_digits=10),
|
|
32
|
+
),
|
|
33
|
+
migrations.AlterField(
|
|
34
|
+
model_name='sensor',
|
|
35
|
+
name='y',
|
|
36
|
+
field=models.DecimalField(decimal_places=2, max_digits=10),
|
|
37
|
+
),
|
|
38
|
+
migrations.AlterField(
|
|
39
|
+
model_name='sensor',
|
|
40
|
+
name='z',
|
|
41
|
+
field=models.DecimalField(decimal_places=2, max_digits=10),
|
|
42
|
+
),
|
|
43
|
+
]
|
irie/apps/inventory/models.py
CHANGED
|
@@ -22,23 +22,6 @@ class Corridor(models.Model):
|
|
|
22
22
|
return f"{self.name} ({self.assets.count()})"
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
class _Sensor: # (models.Model):
|
|
26
|
-
class Status:
|
|
27
|
-
active: bool
|
|
28
|
-
|
|
29
|
-
status = None
|
|
30
|
-
|
|
31
|
-
class Station: # (models.Model):
|
|
32
|
-
sensors = None
|
|
33
|
-
assets = None
|
|
34
|
-
network = None
|
|
35
|
-
events = None
|
|
36
|
-
|
|
37
|
-
class Vulnerability: # (models.Model):
|
|
38
|
-
type = None
|
|
39
|
-
asset = None
|
|
40
|
-
notes = models.CharField(max_length=1024, blank=True, null=True)
|
|
41
|
-
|
|
42
25
|
class Asset(models.Model):
|
|
43
26
|
id = models.BigAutoField(primary_key=True)
|
|
44
27
|
cesmd = models.CharField(max_length=7, blank=True, null=True)
|
|
@@ -112,3 +95,50 @@ class Asset(models.Model):
|
|
|
112
95
|
class Meta:
|
|
113
96
|
ordering = ["-id"]
|
|
114
97
|
|
|
98
|
+
|
|
99
|
+
class Vulnerability: # (models.Model):
|
|
100
|
+
type = None
|
|
101
|
+
asset = None
|
|
102
|
+
notes = models.CharField(max_length=1024, blank=True, null=True)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class Datum(models.Model):
|
|
106
|
+
name = models.CharField(max_length=100)
|
|
107
|
+
orient_x = models.CharField(max_length=240) # eg, longitudinal axis of the deck from west to east
|
|
108
|
+
locate_x = models.CharField(max_length=240) # eg, east abutment-to-deck interface
|
|
109
|
+
orient_y = models.CharField(max_length=240) # eg, transverse axis of the deck from north to south
|
|
110
|
+
locate_y = models.CharField(max_length=240) # eg, center of deck
|
|
111
|
+
orient_z = models.CharField(max_length=240) # eg, vertical upwards
|
|
112
|
+
locate_z = models.CharField(max_length=240) # eg, deck surface
|
|
113
|
+
asset = models.ForeignKey(Asset, on_delete=models.RESTRICT)
|
|
114
|
+
|
|
115
|
+
def __str__(self):
|
|
116
|
+
return f"{self.name}"
|
|
117
|
+
|
|
118
|
+
class SensorGroup(models.Model):
|
|
119
|
+
name = models.CharField(max_length=100)
|
|
120
|
+
# sensors; access with .sensor_set.all()
|
|
121
|
+
asset = models.ForeignKey(Asset, on_delete=models.RESTRICT)
|
|
122
|
+
datum = models.ForeignKey(Datum, on_delete=models.RESTRICT)
|
|
123
|
+
# network = models.CharField(max_length=100)
|
|
124
|
+
# events = None
|
|
125
|
+
def __str__(self):
|
|
126
|
+
return f"{self.name} - {self.datum}"
|
|
127
|
+
|
|
128
|
+
class Sensor(models.Model):
|
|
129
|
+
# class Status:
|
|
130
|
+
# active: bool
|
|
131
|
+
|
|
132
|
+
name = models.CharField(max_length=100)
|
|
133
|
+
x = models.DecimalField(decimal_places=2, max_digits=10)
|
|
134
|
+
y = models.DecimalField(decimal_places=2, max_digits=10)
|
|
135
|
+
z = models.DecimalField(decimal_places=2, max_digits=10)
|
|
136
|
+
|
|
137
|
+
dx = models.DecimalField(decimal_places=2, max_digits=10)
|
|
138
|
+
dy = models.DecimalField(decimal_places=2, max_digits=10)
|
|
139
|
+
dz = models.DecimalField(decimal_places=2, max_digits=10)
|
|
140
|
+
|
|
141
|
+
group = models.ForeignKey(SensorGroup, related_name="sensors", on_delete=models.RESTRICT)
|
|
142
|
+
|
|
143
|
+
def __str__(self):
|
|
144
|
+
return f"{self.name} ({self.group.name})"
|
irie/apps/inventory/urls.py
CHANGED
|
@@ -23,6 +23,8 @@ urlpatterns = [
|
|
|
23
23
|
"^evaluations/(?P<event>[0-9 A-Z-]*)/(?P<cesmd>[0-9 A-Z-]*)/.*", views.asset_event_summary,
|
|
24
24
|
name="asset_event_summary"
|
|
25
25
|
),
|
|
26
|
-
re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/evaluations/$",
|
|
27
|
-
re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/$",
|
|
26
|
+
re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/evaluations/$", views.asset_evals, name="asset_evals"),
|
|
27
|
+
re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/$", views.asset_profile, name="asset_profile"),
|
|
28
|
+
re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/sensors/$", views.asset_sensors, name="asset_sensors"),
|
|
29
|
+
re_path("^inventory/(?P<calid>[0-9 A-Z-]*)/sensor_upload", views.sensor_upload, name="sensor_upload"),
|
|
28
30
|
]
|
irie/apps/inventory/views.py
CHANGED
|
@@ -17,10 +17,13 @@ from django.core.paginator import Paginator
|
|
|
17
17
|
from django.template import loader
|
|
18
18
|
from django.http import HttpResponse
|
|
19
19
|
from django.contrib.auth.decorators import login_required
|
|
20
|
+
from django.shortcuts import render, redirect, get_object_or_404
|
|
21
|
+
from django.forms import formset_factory
|
|
20
22
|
|
|
21
23
|
from irie.apps.events.models import EventRecord
|
|
22
24
|
from irie.apps.site.view_utils import raise404
|
|
23
|
-
from irie.apps.inventory.models import Asset
|
|
25
|
+
from irie.apps.inventory.models import Asset, SensorGroup, Sensor, Datum
|
|
26
|
+
from irie.apps.inventory.forms import SensorGroupForm, SensorForm, SensorFormSet
|
|
24
27
|
from .filters import AssetFilter
|
|
25
28
|
# Predictors
|
|
26
29
|
from irie.apps.prediction.runners.hazus import hazus_fragility
|
|
@@ -315,7 +318,10 @@ def _make_tables(asset):
|
|
|
315
318
|
} for group in asset.nbi_data.values()
|
|
316
319
|
]
|
|
317
320
|
tables.extend(nbi_data)
|
|
318
|
-
|
|
321
|
+
try:
|
|
322
|
+
tables = [tables[2], *tables[:2], *tables[3:]]
|
|
323
|
+
except:
|
|
324
|
+
pass
|
|
319
325
|
condition = {}
|
|
320
326
|
for table in tables:
|
|
321
327
|
keys = set()
|
|
@@ -339,6 +345,53 @@ def _make_tables(asset):
|
|
|
339
345
|
return tables
|
|
340
346
|
|
|
341
347
|
|
|
348
|
+
@login_required(login_url="/login/")
|
|
349
|
+
def asset_sensors(request, calid):
|
|
350
|
+
asset = Asset.objects.get(calid=calid)
|
|
351
|
+
context = {
|
|
352
|
+
"asset": asset,
|
|
353
|
+
"groups": SensorGroup.objects.filter(asset=asset)
|
|
354
|
+
}
|
|
355
|
+
html_template = loader.get_template("inventory/asset-sensors.html")
|
|
356
|
+
return HttpResponse(html_template.render(context, request))
|
|
357
|
+
|
|
358
|
+
@login_required(login_url="/login/")
|
|
359
|
+
def sensor_upload(request, calid):
|
|
360
|
+
asset = get_object_or_404(Asset, calid=calid) # Fetch the asset using calid
|
|
361
|
+
datums = Datum.objects.filter(asset=asset).values(
|
|
362
|
+
'id', 'orient_x', 'locate_x', 'orient_y', 'locate_y', 'orient_z', 'locate_z'
|
|
363
|
+
)
|
|
364
|
+
SensorFormSet = formset_factory(SensorForm, extra=1, can_delete=False)
|
|
365
|
+
|
|
366
|
+
if request.method == "POST":
|
|
367
|
+
group_form = SensorGroupForm(request.POST, asset=asset)
|
|
368
|
+
formset = SensorFormSet(request.POST)
|
|
369
|
+
|
|
370
|
+
if group_form.is_valid() and formset.is_valid():
|
|
371
|
+
sensor_group = group_form.save(commit=False)
|
|
372
|
+
sensor_group.asset = asset # Assign the asset
|
|
373
|
+
sensor_group.save()
|
|
374
|
+
|
|
375
|
+
for form in formset:
|
|
376
|
+
if form.cleaned_data and not form.cleaned_data.get('DELETE', False):
|
|
377
|
+
sensor = form.save(commit=False)
|
|
378
|
+
sensor.group = sensor_group
|
|
379
|
+
sensor.save()
|
|
380
|
+
|
|
381
|
+
return redirect('asset_sensors', calid=calid) # Redirect after successful submission
|
|
382
|
+
|
|
383
|
+
else:
|
|
384
|
+
group_form = SensorGroupForm(asset=asset)
|
|
385
|
+
formset = SensorFormSet()
|
|
386
|
+
|
|
387
|
+
return render(request, "inventory/sensor-upload.html", {
|
|
388
|
+
"group_form": group_form,
|
|
389
|
+
"formset": formset,
|
|
390
|
+
"asset": asset,
|
|
391
|
+
"datums": list(datums)
|
|
392
|
+
})
|
|
393
|
+
|
|
394
|
+
|
|
342
395
|
def _filter_asset_table(request):
|
|
343
396
|
# Copy the GET parameters and remove the 'page' parameter
|
|
344
397
|
page_query = request.GET.copy()
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
<li class="nav-item {% if 'events' in segment %} active {% endif %}">
|
|
66
66
|
<span
|
|
67
67
|
class="nav-link collapsed d-flex justify-content-between align-items-center"
|
|
68
|
-
data-bs-toggle="collapse" data-bs-target="#submenu-
|
|
68
|
+
data-bs-toggle="collapse" data-bs-target="#submenu-events">
|
|
69
69
|
<span>
|
|
70
70
|
<span class="sidebar-icon">
|
|
71
71
|
<svg class="icon icon-xs me-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M5 4a3 3 0 00-3 3v6a3 3 0 003 3h10a3 3 0 003-3V7a3 3 0 00-3-3H5zm-1 9v-1h5v2H5a1 1 0 01-1-1zm7 1h4a1 1 0 001-1v-1h-5v2zm0-4h5V8h-5v2zM9 8H4v2h5V8z" clip-rule="evenodd"></path></svg>
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
</span>
|
|
79
79
|
</span>
|
|
80
80
|
<div class="multi-level collapse {% if 'events' in segment %} show {% endif %}"
|
|
81
|
-
role="list" id="submenu-
|
|
81
|
+
role="list" id="submenu-events" aria-expanded="false">
|
|
82
82
|
<ul class="flex-column nav">
|
|
83
83
|
<li class="nav-item {% if 'cgs' in segment %} active {% endif %}">
|
|
84
84
|
<a class="nav-link" href="{% url 'event_table' %}">
|
|
@@ -99,15 +99,34 @@
|
|
|
99
99
|
</a>
|
|
100
100
|
</li>
|
|
101
101
|
|
|
102
|
-
<li class="nav-item {% if '
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
<li class="nav-item {% if 'applications' in segment %} active {% endif %}">
|
|
103
|
+
<span
|
|
104
|
+
class="nav-link collapsed d-flex justify-content-between align-items-center"
|
|
105
|
+
data-bs-toggle="collapse" data-bs-target="#submenu-apps">
|
|
106
|
+
<span>
|
|
107
|
+
<span class="sidebar-icon">
|
|
108
|
+
<svg class="icon icon-xs me-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M5 4a3 3 0 00-3 3v6a3 3 0 003 3h10a3 3 0 003-3V7a3 3 0 00-3-3H5zm-1 9v-1h5v2H5a1 1 0 01-1-1zm7 1h4a1 1 0 001-1v-1h-5v2zm0-4h5V8h-5v2zM9 8H4v2h5V8z" clip-rule="evenodd"></path></svg>
|
|
109
|
+
</span>
|
|
110
|
+
<span title="Listing of processed events"
|
|
111
|
+
class="sidebar-text">Applications</span>
|
|
112
|
+
</span>
|
|
113
|
+
<span class="link-arrow">
|
|
114
|
+
<svg class="icon icon-sm" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>
|
|
115
|
+
</span>
|
|
116
|
+
</span>
|
|
117
|
+
<div class="multi-level collapse {% if app.url in irie_url_name %} show {% endif %}"
|
|
118
|
+
role="list" id="submenu-apps" aria-expanded="false">
|
|
119
|
+
<ul class="flex-column nav">
|
|
120
|
+
{% for app in irie_apps %}
|
|
121
|
+
<li class="nav-item {% if app.url in irie_url_name %} active {% endif %}">
|
|
122
|
+
<a class="nav-link" href="{% url app.url %}">
|
|
123
|
+
<span class="sidebar-text">{{ app.name }}</span>
|
|
124
|
+
</a>
|
|
125
|
+
</li>
|
|
126
|
+
{% endfor %}
|
|
127
|
+
</ul>
|
|
128
|
+
</div>
|
|
109
129
|
</li>
|
|
110
|
-
|
|
111
130
|
<li role="separator" class="dropdown-divider mt-4 mb-3 border-gray-700"></li>
|
|
112
131
|
|
|
113
132
|
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
{% endblock %}
|
|
7
7
|
|
|
8
8
|
{% block stylesheets %}
|
|
9
|
+
{% if asset.rendering %}
|
|
10
|
+
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
|
|
11
|
+
<script type="module" src="https://ajax.googleapis.com/ajax/libs/model-viewer/4.0.0/model-viewer.min.js"></script>
|
|
12
|
+
{% endif %}
|
|
9
13
|
<style>
|
|
10
14
|
.ct-series-a .ct-point, .ct-series-a .ct-line, .ct-series-a .ct-bar, .ct-series-a .ct-slice-donut{
|
|
11
15
|
stroke: #506690;
|
|
@@ -60,15 +64,21 @@
|
|
|
60
64
|
<div class="tab-content" id="pills-tabContent">
|
|
61
65
|
<div class="tab-pane fade show active"
|
|
62
66
|
id="pills-rendering" role="tabpanel">
|
|
63
|
-
{% if asset.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
{% if asset.rendering %}
|
|
68
|
+
<model-viewer
|
|
69
|
+
id="viewer"
|
|
70
|
+
src="{{ asset.rendering }}"
|
|
71
|
+
alt="3D Model"
|
|
72
|
+
auto-rotate
|
|
73
|
+
camera-controls
|
|
74
|
+
interaction-prompt="none"
|
|
75
|
+
camera-orbit="0deg 75deg 2m"
|
|
76
|
+
field-of-view="30deg"
|
|
77
|
+
style="width: 100%; height: 400px;">
|
|
78
|
+
</model-viewer>
|
|
69
79
|
{% endif %}
|
|
70
80
|
</div>
|
|
71
|
-
<div class="tab-pane fade show {% if not asset.
|
|
81
|
+
<div class="tab-pane fade show {% if not asset.rendering %}active{% endif %}"
|
|
72
82
|
id="pills-sensors" role="tabpanel">
|
|
73
83
|
<img src="{{ ASSETS_ROOT }}/inventory/ll{{ asset.cesmd|slice:"2:" }}.svg">
|
|
74
84
|
</div>
|
|
@@ -129,15 +129,23 @@
|
|
|
129
129
|
<div class="btn-toolbar mb-2 mb-md-0">
|
|
130
130
|
<a role="button"
|
|
131
131
|
href="/inventory/{{ asset.calid }}/predictors/"
|
|
132
|
-
class="btn btn-sm btn-outline-primary d-inline-flex align-items-center">
|
|
132
|
+
class="btn btn-sm btn-outline-primary d-inline-flex align-items-center mx-1">
|
|
133
133
|
<svg class="icon icon-xs me-2" fill="none"
|
|
134
134
|
stroke="currentColor" viewBox="0 0 24 24"
|
|
135
135
|
xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path></svg>
|
|
136
136
|
Predictors
|
|
137
137
|
</a>
|
|
138
|
+
<a role="button"
|
|
139
|
+
href="{% url 'asset_sensors' calid=asset.calid %}"
|
|
140
|
+
class="btn btn-sm btn-outline-primary d-inline-flex align-items-center mx-1">
|
|
141
|
+
<svg class="icon icon-xs me-2" fill="none"
|
|
142
|
+
stroke="currentColor" viewBox="0 0 24 24"
|
|
143
|
+
xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path></svg>
|
|
144
|
+
Sensors
|
|
145
|
+
</a>
|
|
138
146
|
</div>
|
|
139
147
|
</div>
|
|
140
|
-
{% if
|
|
148
|
+
{% if asset.nbi_data.NBI_BRIDGE %}
|
|
141
149
|
<div class="col-10">
|
|
142
150
|
<p>
|
|
143
151
|
{% if asset.id|divisibleby:3 %}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
===----------------------------------------------------------------------===#
|
|
3
|
+
|
|
4
|
+
STAIRLab -- STructural Artificial Intelligence Laboratory
|
|
5
|
+
|
|
6
|
+
===----------------------------------------------------------------------===#
|
|
7
|
+
|
|
8
|
+
Claudio Perez, Summer 2023
|
|
9
|
+
Chrystal Chern, Spring 2025
|
|
10
|
+
|
|
11
|
+
-->
|
|
12
|
+
|
|
13
|
+
{% extends "layouts/base.html" %}
|
|
14
|
+
{% block title %} {{ asset.calid }} Sensors {% endblock %}
|
|
15
|
+
|
|
16
|
+
{% block content %}
|
|
17
|
+
<h1><code>{{ asset.calid }}</code> Sensors</h1>
|
|
18
|
+
<div class="py-4 align-right">
|
|
19
|
+
<a role="button" class="button btn btn-outline-white btn-gray-600 text-white"
|
|
20
|
+
href="{% url 'asset_profile' calid=asset.calid %}" class="me-1">Back to Structure</a>
|
|
21
|
+
<a role="button" class="button btn btn-outline-white btn-gray-600 text-white"
|
|
22
|
+
href="{% url 'sensor_upload' calid=asset.calid %}" class="me-1">Add SensorGroup</a>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="col-lg-10">
|
|
26
|
+
{% for group in groups %}
|
|
27
|
+
<div class="card shadow-lg mb-4">
|
|
28
|
+
<div class="card-header bg-dark text-white fw-bold d-flex justify-content-between align-items-center">
|
|
29
|
+
<span>{{ group.name }}</span>
|
|
30
|
+
<span class="badge bg-gray text-white px-2 py-1 fs-6">Datum: {{ group.datum.name }}</span>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="card-body">
|
|
33
|
+
<table class="table table-striped table-hover table-bordered">
|
|
34
|
+
<thead class="table-dark">
|
|
35
|
+
<tr>
|
|
36
|
+
<th>Sensor</th>
|
|
37
|
+
<th>x</th>
|
|
38
|
+
<th>y</th>
|
|
39
|
+
<th>z</th>
|
|
40
|
+
<th>dx</th>
|
|
41
|
+
<th>dy</th>
|
|
42
|
+
<th>dz</th>
|
|
43
|
+
</tr>
|
|
44
|
+
</thead>
|
|
45
|
+
<tbody>
|
|
46
|
+
{% for sensor in group.sensors.all %}
|
|
47
|
+
<tr>
|
|
48
|
+
<td class="fw-bold">{{ sensor.name }}</td>
|
|
49
|
+
<td>{{ sensor.x }}</td>
|
|
50
|
+
<td>{{ sensor.y }}</td>
|
|
51
|
+
<td>{{ sensor.z }}</td>
|
|
52
|
+
<td>{{ sensor.dx }}</td>
|
|
53
|
+
<td>{{ sensor.dy }}</td>
|
|
54
|
+
<td>{{ sensor.dz }}</td>
|
|
55
|
+
</tr>
|
|
56
|
+
{% endfor %}
|
|
57
|
+
</tbody>
|
|
58
|
+
</table>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
{% endfor %}
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
{% endblock %}
|
|
65
|
+
|
|
66
|
+
{% block javascripts %}
|
|
67
|
+
|
|
68
|
+
{% endblock %}
|
|
69
|
+
|