Skip to content

Commit

Permalink
Init Group meter readings upload
Browse files Browse the repository at this point in the history
  • Loading branch information
haneslinger committed Nov 22, 2024
1 parent 13a8d8a commit 876a5d3
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ angular.module('SEED.controller.inventory_group_detail_meters', [])
'<div class="meters-table-actions" style="display: flex; flex-direction=column">' +
' <button type="button" ng-show="grid.appScope.menu.user.organization.user_role !== \'viewer\'" class="btn-danger" style="border-radius: 4px;" ng-click="grid.appScope.open_meter_deletion_modal(row.entity)" title="Delete Meter"><i class="fa-solid fa-xmark"></i></button>' +
' <button type="button" ng-show="grid.appScope.menu.user.organization.user_role !== \'viewer\'" class="btn-primary" style="border-radius: 4px;" ng-click="grid.appScope.open_meter_connection_edit_modal(row.entity)" title="Edit Meter Connection"><i class="fa-solid fa-pencil"></i></button>' +
' <button type="button" ng-show="grid.appScope.menu.user.organization.user_role !== \'viewer\'" class="btn-primary" style="border-radius: 4px;" ng-click="grid.appScope.open_create_meter_readings_modal(row.entity)" title="Edit Meter Connection"><i class="fa-solid fa-plus"></i></button>' +
'</div>'
);

Expand Down Expand Up @@ -221,6 +222,21 @@ angular.module('SEED.controller.inventory_group_detail_meters', [])
});
};

$scope.open_create_meter_readings_modal = (meter) => {
// get view if property_id
$uibModal.open({
templateUrl: `${urls.static_url}seed/partials/system_meter_readings_upload_modal.html`,
controller: 'system_meter_readings_upload_modal_controller',
resolve: {
organization: () => $scope.organization,
meter: () => meter,
datasets: () => dataset_service.get_datasets().then((result) => result.datasets),
filler_cycle: () => $scope.filler_cycle,
refresh_meters_and_readings: () => $scope.refresh_meters_and_readings
}
});
};

$scope.apply_column_settings = () => {
_.forEach($scope.meterReadGridOptions.columnDefs, (column) => {
column.enableHiding = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* SEED Platform (TM), Copyright (c) Alliance for Sustainable Energy, LLC, and other contributors.
* See also https://github.com/SEED-platform/seed/blob/main/LICENSE.md
*/
angular.module('SEED.controller.system_meter_readings_upload_modal', []).controller('system_meter_readings_upload_modal_controller', [
'$scope',
'$stateParams',
'$uibModalInstance',
'inventory_group_service',
'inventory_service',
'meter_service',
'uploader_service',
'spinner_utility',
'organization',
'meter',
'datasets',
'filler_cycle',
'refresh_meters_and_readings',
// eslint-disable-next-line func-names
function (
$scope,
$stateParams,
$uibModalInstance,
inventory_group_service,
inventory_service,
meter_service,
uploader_service,
spinner_utility,
organization,
meter,
datasets,
filler_cycle,
refresh_meters_and_readings
) {
$scope.state = "upload";
$scope.meter = meter;
$scope.organization = organization;
$scope.organization_id = organization.id;
$scope.datasets = datasets;
$scope.selectedDataset = datasets[0];
$scope.selectedCycle = filler_cycle;


$scope.uploader = {
invalid_file_contents: false,
invalid_csv_extension_alert: false,
invalid_xlsx_extension_alert: false,
progress: 0,
status_message: ''
};

$scope.uploaderfunc = (event_message, file /* , progress */) => {
switch (event_message) {
case 'invalid_extension':
$scope.$apply(() => {
$scope.uploader.invalid_csv_extension_alert = true;
$scope.uploader.invalid_xlsx_extension_alert = true;
$scope.uploader.invalid_file_contents = false;
});
break;

case 'upload_complete':
$scope.state = "processing";
uploader_service
.system_meter_upload(file.file_id, $scope.organization.org_id, meter.id)
.then((data) => {
console.log(data)
$scope.state = "confirmation";
$scope.confirmation_message = data.message

})
.catch((err) => present_meter_import_error(err));
break;
}
};

$scope.dismiss = () => {
refresh_meters_and_readings();
spinner_utility.show();
$uibModalInstance.dismiss('cancel');
};
}
]);
1 change: 1 addition & 0 deletions seed/static/seed/js/seed.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
'SEED.controller.merge_modal',
'SEED.controller.meter_deletion_modal',
'SEED.controller.meter_edit_modal',
'SEED.controller.system_meter_readings_upload_modal',
'SEED.controller.group_meter_creation_modal',
'SEED.controller.modified_modal',
'SEED.controller.move_inventory_modal',
Expand Down
8 changes: 8 additions & 0 deletions seed/static/seed/js/services/uploader_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,14 @@ angular.module('SEED.service.uploader', []).factory('uploader_service', [
});
};

uploader_factory.system_meter_upload = (file_id, org_id, meter_id) => {
return $http.post(`/api/v3/import_files/${file_id}/system_meter_upload/`,
{ meter_id },
{ params: { organization_id: org_id } },
)
.then((response) => response.data)
};

uploader_factory.pm_meters_preview = (file_id, org_id) => $http.get(`/api/v3/import_files/${file_id}/pm_meters_preview/`, { params: { organization_id: org_id } }).then((response) => response.data);

uploader_factory.greenbutton_meters_preview = (file_id, org_id, view_id, system_id) => $http.get(`/api/v3/import_files/${file_id}/greenbutton_meters_preview/`, { params: { organization_id: org_id, view_id, system_id } }).then((response) => response.data);
Expand Down
33 changes: 33 additions & 0 deletions seed/static/seed/partials/system_meter_readings_upload_modal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<div class="modal-header">
<h4>Add readings to {$ meter.alias $}</h4>
</div>

<div ng-switch="state">
<div class="modal-body" ng-switch-when="upload">
<div class="data_upload_steps container-fluid">
<div class="alert alert-danger" ng-show="uploader.invalid_csv_extension_alert" style="margin-bottom: 18px"
translate="INVALID_CSV_EXTENSION_ALERT"></div>
<div class="alert alert-danger" ng-show="uploader.invalid_file_contents" style="margin-bottom: 18px" translate>
An error occurred while processing the file. Please ensure that your file meets the required specifications.
</div>
</div>

<div class="row text-center">
<button type="button" class="btn btn-primary col-sm-6 center-block" sd-uploader organization-id="organization_id"
sourcetype="MetersReadings" sourceprog="" sourcever="" importrecord="selectedDataset.id"
eventfunc="uploaderfunc(message, file, progress)">
<span translate>UPLOAD_FILE</span>
</button>
</div>
</div>

<div class="modal-body" ng-switch-when="processing">
<uib-progressbar class="progress-striped active" value="100" type="info"></uib-progressbar>
</div>

<div class="modal-body" ng-switch-when="confirmation">
{$ confirmation_message $}
<button type="button" class="btn btn-default" ng-click="dismiss()" translate>Dismiss</button>
</div>

</div>
1 change: 1 addition & 0 deletions seed/templates/seed/_scripts.html
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
<script src="{{ STATIC_URL }}seed/js/controllers/merge_modal_controller.js"></script>
<script src="{{ STATIC_URL }}seed/js/controllers/meter_deletion_modal_controller.js"></script>
<script src="{{ STATIC_URL }}seed/js/controllers/meter_edit_modal_controller.js"></script>
<script src="{{ STATIC_URL }}seed/js/controllers/system_meter_readings_upload_modal_controller.js"></script>
<script src="{{ STATIC_URL }}seed/js/controllers/group_meter_creation_modal_controller.js"></script>
<script src="{{ STATIC_URL }}seed/js/controllers/modified_modal_controller.js"></script>
<script src="{{ STATIC_URL }}seed/js/controllers/move_inventory_modal_controller.js"></script>
Expand Down
Binary file added seed/tests/data/system_meter_readings.xlsx
Binary file not shown.
48 changes: 48 additions & 0 deletions seed/views/v3/import_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from seed.data_importer.tasks import do_checks, geocode_and_match_buildings_task, map_data
from seed.data_importer.tasks import save_raw_data as task_save_raw
from seed.data_importer.tasks import validate_use_cases as task_validate_use_cases
from seed.data_importer.utils import kbtu_thermal_conversion_factors, kgal_water_conversion_factors
from seed.decorators import ajax_request_class
from seed.lib.mappings import mapper as simple_mapper
from seed.lib.mcm import mapper, reader
Expand All @@ -38,6 +39,7 @@
Cycle,
ImportFile,
Meter,
MeterReading,
Organization,
PropertyAuditLog,
PropertyState,
Expand Down Expand Up @@ -1074,3 +1076,49 @@ def pm_meters_preview(self, request, pk):
result["unlinkable_pm_ids"] = meters_parser.unlinkable_pm_ids

return result

@swagger_auto_schema(manual_parameters=[AutoSchemaHelper.query_org_id_field()])
@ajax_request_class
@has_perm_class("requires_member")
@has_hierarchy_access(import_file_id_kwarg="pk")
@action(detail=True, methods=["POST"])
def system_meter_upload(self, request, pk):
org_id = self.get_organization(request)
org = Organization.objects.get(pk=org_id)
meter_id = request.data.get("meter_id")
meter = Meter.objects.get(pk=meter_id)

import_file = ImportFile.objects.get(pk=pk, import_record__super_organization_id=org_id)
parser = reader.MCMParser(import_file.local_file)

_kbtu_thermal_conversion_factors = kbtu_thermal_conversion_factors(org.get_thermal_conversion_assumption_display())
_kgal_water_conversion_factors = kgal_water_conversion_factors(org.get_thermal_conversion_assumption_display())

for raw_reading in parser.data:
conversion_factor = get_conversion_factor(
Meter.ENERGY_TYPE_BY_METER_TYPE[meter.type],
raw_reading["Usage Units"],
_kbtu_thermal_conversion_factors,
_kgal_water_conversion_factors,
)

MeterReading.objects.update_or_create(
start_time=raw_reading["Start Date"],
end_time=raw_reading["End Date"],
reading=float(raw_reading["Reading"]) * conversion_factor,
meter_id=meter.id,
conversion_factor=conversion_factor,
)

return JsonResponse({"status": "success", "message": f"{len(raw_reading)} readings created"}, status=status.HTTP_200_OK)


def get_conversion_factor(type_name, unit, _kbtu_thermal_conversion_factors, _kgal_water_conversion_factors):
_log.error(type_name + ", " + unit)

thermal_conversion_factor = _kbtu_thermal_conversion_factors.get(type_name, {}).get(unit, None)
water_conversion_factor = _kgal_water_conversion_factors.get(type_name, {}).get(unit, None)
if thermal_conversion_factor is None and water_conversion_factor is None:
raise Exception

return thermal_conversion_factor or water_conversion_factor

0 comments on commit 876a5d3

Please sign in to comment.