diff --git a/device/models.py b/device/models.py
index 3bd5eeb..2aaa470 100644
--- a/device/models.py
+++ b/device/models.py
@@ -25,6 +25,7 @@ class Device:
def __init__(self, *args, **kwargs):
# the id is the chid of the device
self.id = kwargs["id"]
+ self.uuid = kwargs.get("uuid")
self.pk = self.id
self.shortid = self.pk[:6].upper()
self.algorithm = None
@@ -103,6 +104,14 @@ class Device:
self.evidences = [Evidence(u) for u in self.uuids]
def get_last_evidence(self):
+ if self.last_evidence:
+ return
+
+ if self.uuid:
+ import pdb; pdb.set_trace()
+ self.last_evidence = Evidence(self.uuid)
+ return
+
annotations = self.get_annotations()
if not annotations.count():
return
@@ -126,6 +135,8 @@ class Device:
return False
def last_uuid(self):
+ if self.uuid:
+ return self.uuid
return self.uuids[0]
def get_lots(self):
@@ -263,41 +274,35 @@ class Device:
@property
def is_websnapshot(self):
- if not self.last_evidence:
- self.get_last_evidence()
+ self.get_last_evidence()
return self.last_evidence.doc['type'] == "WebSnapshot"
@property
def last_user_evidence(self):
- if not self.last_evidence:
- self.get_last_evidence()
+ self.get_last_evidence()
return self.last_evidence.doc['kv'].items()
@property
def manufacturer(self):
- if not self.last_evidence:
- self.get_last_evidence()
+ self.get_last_evidence()
return self.last_evidence.get_manufacturer()
@property
def serial_number(self):
- if not self.last_evidence:
- self.get_last_evidence()
+ self.get_last_evidence()
return self.last_evidence.get_serial_number()
@property
def type(self):
+ self.get_last_evidence()
if self.last_evidence.doc['type'] == "WebSnapshot":
return self.last_evidence.doc.get("device", {}).get("type", "")
- if not self.last_evidence:
- self.get_last_evidence()
return self.last_evidence.get_chassis()
@property
def model(self):
- if not self.last_evidence:
- self.get_last_evidence()
+ self.get_last_evidence()
return self.last_evidence.get_model()
@property
@@ -308,6 +313,5 @@ class Device:
@property
def components(self):
- if not self.last_evidence:
- self.get_last_evidence()
+ self.get_last_evidence()
return self.last_evidence.get_components()
diff --git a/device/views.py b/device/views.py
index 3c7118c..c7c2b1f 100644
--- a/device/views.py
+++ b/device/views.py
@@ -1,4 +1,3 @@
-import json
from django.http import JsonResponse
from django.http import Http404
@@ -15,6 +14,7 @@ from dashboard.mixins import DashboardView, Http403
from evidence.models import Annotation
from lot.models import LotTag
from dpp.models import Proof
+from dpp.api_dlt import PROOF_TYPE
from device.models import Device
from device.forms import DeviceFormSet
@@ -104,7 +104,10 @@ class DetailsView(DashboardView, TemplateView):
context = super().get_context_data(**kwargs)
self.object.initial()
lot_tags = LotTag.objects.filter(owner=self.request.user.institution)
- dpps = Proof.objects.filter(uuid__in=self.object.uuids)
+ dpps = Proof.objects.filter(
+ uuid__in=self.object.uuids,
+ type=PROOF_TYPE["IssueDPP"]
+ )
context.update({
'object': self.object,
'snapshot': self.object.get_last_evidence(),
diff --git a/did/templates/device_did.html b/did/templates/device_did.html
new file mode 100644
index 0000000..d3a0e2a
--- /dev/null
+++ b/did/templates/device_did.html
@@ -0,0 +1,497 @@
+
+
+
+
+
+
+
{{ object.manufacturer }} {{ object.type }} {{ object.model }}
+
+
+
+ {% if manuals.details.logo %}
+
+ {% endif %}
+
+
+ {% if manuals.details.image %}
+
+ {% endif %}
+
+
+
+
+
Details
+
+
+
Type
+
{{ object.type }}
+
+
+ {% if object.is_websnapshot %}
+ {% for snapshot_key, snapshot_value in object.last_user_evidence %}
+
+
{{ snapshot_key }}
+
{{ snapshot_value|default:'' }}
+
+ {% endfor %}
+ {% else %}
+
+
Manufacturer
+
{{ object.manufacturer|default:'' }}
+
+
+
Model
+
{{ object.model|default:'' }}
+
+ {% if user.is_authenticated %}
+
+
Serial Number
+
{{ object.serial_number|default:'' }}
+
+ {% endif %}
+ {% endif %}
+
+
+
+
Identifiers
+ {% for chid in object.hids %}
+
+
{{ chid|default:'' }}
+
+ {% endfor %}
+
+
+
Components
+
+ {% for component in object.components %}
+
+
+
+
{{ component.type }}
+
+ {% for component_key, component_value in component.items %}
+ {% if component_key not in 'actions,type' %}
+ {% if component_key != 'serialNumber' or user.is_authenticated %}
+ {{ component_key }}: {{ component_value }}
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+
+
+
+
+ {% endfor %}
+
+ {% if manuals.icecat %}
+
Icecat data sheet
+
+
+ {% if manuals.details.logo %}
+
+ {% endif %}
+ {% if manuals.details.image %}
+
+ {% endif %}
+ {% if manuals.details.pdf %}
+
{{ manuals.details.title }}
+ {% else %}
+ {{ manuals.details.title }}
+ {% endif %}
+
+
+
+
+
+ {% for m in manuals.icecat %}
+
+ {% if m.logo %}
+
+ {% endif %}
+ {% if m.pdf %}
+
{{ m.title }}
+ {% else %}
+ {{ m.title }}
+ {% endif %}
+
+ {% endfor %}
+
+
+
+
+ {% endif %}
+ {% if manuals.laer %}
+
+
+
Recycled Content
+
+
+
+ Metal
+
+
+
+
+
{{ manuals.laer.0.metal }}%
+
+
+
+
+
+
+ Plastic post Consumer
+
+
+
+
{{ manuals.laer.0.plastic_post_consumer }}%
+
+
+
+
+
+
+ Plastic post Industry
+
+
+
+
{{ manuals.laer.0.plastic_post_industry }}%
+
+
+
+
+
+
+ {% endif %}
+
+ {% if manuals.energystar %}
+
+
+
Energy spent
+
+ {% if manuals.energystar.long_idle_watts %}
+
+
+ Consumption when inactivity power function is activated (watts)
+
+
+ {{ manuals.energystar.long_idle_watts }}
+
+
+ {% endif %}
+
+ {% if manuals.energystar.short_idle_watts %}
+
+
+ Consumption when inactivity power function is not activated (watts)
+
+
+ {{ manuals.energystar.short_idle_watts }}
+
+
+ {% endif %}
+
+ {% if manuals.energystar.sleep_mode_watts %}
+
+
+ sleep_mode_watts
+ Consumption when computer goes into sleep mode (watts)
+
+
+ {{ manuals.energystar.sleep_mode_watts }}
+
+
+ {% endif %}
+
+ {% if manuals.energystar.off_mode_watts %}
+
+
+ Consumption when the computer is off (watts)
+
+
+ {{ manuals.energystar.off_mode_watts }}
+
+
+ {% endif %}
+
+ {% if manuals.energystar.tec_allowance_kwh %}
+
+
+ Power allocation for normal operation (kwh)
+
+
+ {{ manuals.energystar.tec_allowance_kwh }}
+
+
+ {% endif %}
+
+ {% if manuals.energystar.tec_of_model_kwh %}
+
+
+ Consumption of the model configuration (kwh)
+
+
+ {{ manuals.energystar.tec_of_model_kwh }}
+
+
+ {% endif %}
+
+ {% if manuals.energystar.tec_requirement_kwh %}
+
+
+ Energy allowance provided (kwh)
+
+
+ {{ manuals.energystar.tec_requirement_kwh }}
+
+
+ {% endif %}
+
+ {% if manuals.energystar.work_off_mode_watts %}
+
+
+ The lowest power mode which cannot be switched off (watts)
+
+
+ {{ manuals.energystar.work_off_mode_watts }}
+
+
+ {% endif %}
+
+ {% if manuals.energystar.work_weighted_power_of_model_watts %}
+
+
+ Weighted energy consumption from all its states (watts)
+
+
+ {{ manuals.energystar.work_weighted_power_of_model_watts }}
+
+
+ {% endif %}
+
+
+
+ {% endif %}
+
+
+ {% if manuals.ifixit %}
+
+
+
+
+
+ {% for m in manuals.ifixit %}
+
+ {% if m.image %}
+
+ {% endif %}
+ {% if m.url %}
+
{{ m.title }}
+ {% else %}
+ {{ m.title }}
+ {% endif %}
+
+ {% endfor %}
+
+
+
+
+ {% endif %}
+
+{% if user.is_anonymous and not roles %}
+
+{% else %}
+
+{% endif %}
+
+
+
+
diff --git a/did/templates/device_web.html b/did/templates/device_web.html
deleted file mode 100644
index 8c607d3..0000000
--- a/did/templates/device_web.html
+++ /dev/null
@@ -1,171 +0,0 @@
-
-
-
-
-
-
{{ object.type }}
-
-
-
-
-
-
-
{{ object.manufacturer }} {{ object.type }} {{ object.model }}
-
-
-
-
Details
-
-
-
Type
-
{{ object.type }}
-
-
- {% if object.is_websnapshot %}
- {% for snapshot_key, snapshot_value in object.last_user_evidence %}
-
-
{{ snapshot_key }}
-
{{ snapshot_value|default:'' }}
-
- {% endfor %}
- {% else %}
-
-
Manufacturer
-
{{ object.manufacturer|default:'' }}
-
-
-
Model
-
{{ object.model|default:'' }}
-
- {% if user.is_authenticated %}
-
-
Serial Number
-
{{ object.serial_number|default:'' }}
-
- {% endif %}
- {% endif %}
-
-
-
-
Identifiers
- {% for chid in object.hids %}
-
-
{{ chid|default:'' }}
-
- {% endfor %}
-
-
-
Components
-
- {% for component in object.components %}
-
-
-
-
{{ component.type }}
-
- {% for component_key, component_value in component.items %}
- {% if component_key not in 'actions,type' %}
- {% if component_key != 'serialNumber' or user.is_authenticated %}
- {{ component_key }}: {{ component_value }}
- {% endif %}
- {% endif %}
- {% endfor %}
-
-
-
-
- {% endfor %}
-
-
-
-
-
-
-
diff --git a/did/views.py b/did/views.py
index 1caa081..e8ad5cd 100644
--- a/did/views.py
+++ b/did/views.py
@@ -1,14 +1,26 @@
+import json
+import logging
+
from django.http import JsonResponse, Http404
from django.views.generic.base import TemplateView
from device.models import Device
+from dpp.models import Proof
+
+
+logger = logging.getLogger('django')
class PublicDeviceWebView(TemplateView):
- template_name = "device_web.html"
+ template_name = "device_did.html"
def get(self, request, *args, **kwargs):
self.pk = kwargs['pk']
- self.object = Device(id=self.pk)
+ chid = self.pk.split(":")[0]
+ proof = Proof.objects.filter(signature=self.pk).first()
+ if proof:
+ self.object = Device(id=chid, uuid=proof.uuid)
+ else:
+ self.object = Device(id=chid)
if not self.object.last_evidence:
raise Http404
@@ -18,12 +30,24 @@ class PublicDeviceWebView(TemplateView):
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
- context = super().get_context_data(**kwargs)
+ self.context = super().get_context_data(**kwargs)
self.object.initial()
- context.update({
- 'object': self.object
+ roles = [("Operator", "Operator")]
+ role = "Operator"
+ if self.request.user.is_anonymous:
+ roles = []
+ role = None
+ self.context.update({
+ 'object': self.object,
+ 'role': role,
+ 'roles': roles,
+ 'path': self.request.path,
+ 'last_dpp': "",
+ 'before_dpp': "",
})
- return context
+ if not self.request.user.is_anonymous:
+ self.get_manuals()
+ return self.context
@property
def public_fields(self):
@@ -58,3 +82,107 @@ class PublicDeviceWebView(TemplateView):
device_data = self.get_device_data()
return JsonResponse(device_data)
+ def get_manuals(self):
+ manuals = {
+ 'ifixit': [],
+ 'icecat': [],
+ 'details': {},
+ 'laer': [],
+ 'energystar': {},
+ }
+ try:
+ params = {
+ "manufacturer": self.object.manufacturer,
+ "model": self.object.model,
+ }
+ self.params = json.dumps(params)
+ manuals['ifixit'] = self.request_manuals('ifixit')
+ manuals['icecat'] = self.request_manuals('icecat')
+ manuals['laer'] = self.request_manuals('laer')
+ manuals['energystar'] = self.request_manuals('energystar') or {}
+ if manuals['icecat']:
+ manuals['details'] = manuals['icecat'][0]
+ except Exception as err:
+ logger.error("Error: {}".format(err))
+
+ self.context['manuals'] = manuals
+ self.parse_energystar()
+
+ def parse_energystar(self):
+ if not self.context.get('manuals', {}).get('energystar'):
+ return
+
+ # Defined in:
+ # https://dev.socrata.com/foundry/data.energystar.gov/j7nq-iepp
+
+ energy_types = [
+ 'functional_adder_allowances_kwh',
+ 'tec_allowance_kwh',
+ 'long_idle_watts',
+ 'short_idle_watts',
+ 'off_mode_watts',
+ 'sleep_mode_watts',
+ 'tec_of_model_kwh',
+ 'tec_requirement_kwh',
+ 'work_off_mode_watts',
+ 'work_weighted_power_of_model_watts',
+ ]
+ energy = {}
+ for field in energy_types:
+ energy[field] = []
+
+ for e in self.context['manuals']['energystar']:
+ for field in energy_types:
+ for k, v in e.items():
+ if not v:
+ continue
+ if field in k:
+ energy[field].append(v)
+
+ for k, v in energy.items():
+ if not v:
+ energy[k] = 0
+ continue
+ tt = sum([float(i) for i in v])
+ energy[k] = round(tt / len(v), 2)
+
+ self.context['manuals']['energystar'] = energy
+
+ def request_manuals(self, prefix):
+ #TODO reimplement manuals service
+ response = {
+ "laer": [{"metal": 40, "plastic_post_consumer": 27, "plastic_post_industry": 34}],
+ "energystar": [{
+ 'functional_adder_allowances_kwh': 180,
+ "long_idle_watts": 240,
+ "short_idle_watts": 120,
+ "sleep_mode_watts": 30,
+ "off_mode_watts": 3,
+ "tec_allowance_kwh": 180,
+ "tec_of_model_kwh": 150,
+ "tec_requirement_kwh": 220,
+ "work_off_mode_watts": 70,
+ "work_weighted_power_of_model_watts": 240
+ }],
+ "ifixit": [
+ {
+ "image": "https://guide-images.cdn.ifixit.com/igi/156EpI4YdQeVfVPa.medium",
+ "url": "https://es.ifixit.com/Gu%C3%ADa/HP+ProBook+450+G4+Back+Panel+Replacement/171196?lang=en",
+ "title": "HP ProBook 450 G4 Back Panel Replacement"
+ },
+ {
+ "image": "https://guide-images.cdn.ifixit.com/igi/usTIqCKpuxVWC3Ix.140x105",
+ "url": "https://es.ifixit.com/Gu%C3%ADa/HP+ProBook+450+G4+Display+Assembly+Replacement/171101?lang=en",
+ "title": "Display Assembly Replacement"
+ }
+ ],
+ "icecat": [
+ {
+ "logo": "https://images.icecat.biz/img/brand/thumb/1_cf8603f6de7b4c4d8ac4f5f0ef439a05.jpg",
+ "image": "https://guide-images.cdn.ifixit.com/igi/Q2nYjTIQfG6GaI5B.standard",
+ "pdf": "https://icecat.biz/rest/product-pdf?productId=32951710&lang=en",
+ "title": "HP ProBook 450 G3"
+ }
+ ]
+ }
+ return response.get(prefix, {})