Commit e10ee9b2 authored by Theis's avatar Theis
Browse files

The prototype now supports the use of assistive aids and loan period

parent c0731574
Pipeline #99925 failed with stage
in 59 seconds
......@@ -8,46 +8,45 @@ generator client {
}
model Citizen {
id Int @id @default(autoincrement())
first_name String @db.VarChar(255)
last_name String @db.VarChar(255)
age Int @db.Int
gender String @db.VarChar(255)
ssn String @unique @db.VarChar(255)
Training_Plans Training_Plans[]
Registered_Falls Registered_Falls[]
Home_Care Home_Care[]
id Int @id @default(autoincrement())
first_name String @db.VarChar(255)
last_name String @db.VarChar(255)
age Int @db.Int
gender String @db.VarChar(255)
ssn String @unique @db.VarChar(255)
Assistive_Aids Assistive_Aids[]
Training_Plans Training_Plans[]
Home_Care Home_Care[]
}
model Training_Plans {
id Int @id @default(autoincrement())
citizen_Id Int @db.Int
agreement_date String @db.VarChar(255)
name String @db.VarChar(255)
type String @db.VarChar(255)
start_date String @db.VarChar(255)
end_date String @db.VarChar(255)
status String @db.VarChar(255)
time_slot Float @db.Float
Citizen Citizen @relation(fields: [citizen_Id], references: [id])
id Int @id @default(autoincrement())
citizen_Id Int @db.Int
name String @db.VarChar(255)
start_date String @db.VarChar(255)
end_date String @db.VarChar(255)
status String @db.VarChar(255)
time_slot Float @db.Float
Citizen Citizen @relation(fields: [citizen_Id], references: [id])
}
model Home_Care {
id Int @id @default(autoincrement())
citizen_Id Int @db.Int
date String @db.VarChar(255)
type String @db.VarChar(255)
name String @db.VarChar(255)
time_slot Float @db.Float
Citizen Citizen @relation(fields: [citizen_Id], references: [id])
id Int @id @default(autoincrement())
citizen_Id Int @db.Int
date String @db.VarChar(255)
type String @db.VarChar(255)
name String @db.VarChar(255)
time_slot Float @db.Float
Citizen Citizen @relation(fields: [citizen_Id], references: [id])
}
model Registered_Falls {
id Int @id @default(autoincrement())
citizen_Id Int @db.Int
date_fall String @db.VarChar(255)
organisation_name String @db.VarChar(255)
observation_name String @db.VarChar(255)
number_of_affected_citizens Int @db.Int
Citizen Citizen @relation(fields: [citizen_Id], references: [id])
model Assistive_Aids {
id Int @id @default(autoincrement())
citizen_Id Int @db.Int
name String @db.VarChar(255)
iso String @db.VarChar(255)
initiative_name String @db.VarChar(255)
paragraph String @db.VarChar(255)
lend_date String @db.VarChar(255)
Citizen Citizen @relation(fields: [citizen_Id], references: [id])
}
......@@ -27,7 +27,7 @@ app.use(express.urlencoded({ extended: true }));
const log = bunyan.createLogger({ name: "AIR_UI_Backend: " });
const predictionURL_training_fall = 'https://air-fastapi.azurewebsites.net/predict_training'
function deleteVariable(variablesMarkedForDeletion) {
async function deleteVariable(variablesMarkedForDeletion) {
variablesMarkedForDeletion.forEach(element => {
element = undefined;
delete(element);
......@@ -39,12 +39,11 @@ function convertDataSizeToKb(logMessage, data) {
console.log(logMessage, datasizeInKb)
}
function dataPreparationForML(age, gender /*, assistiveAids*/) {
function dataPreparationForML(age, gender, assistiveAids, loanPeriod) {
const Gender = gender == 'Mand' ? 1 : 0
const BirthYear = (new Date().getFullYear() - age)
const LoanPeriod = 180
const Ats = "222718,093307,181210,120606,222718,093307,181210"
//Use real assistive aids and loan period when possible
const LoanPeriod = loanPeriod
const Ats = assistiveAids
return {
"Gender": Gender,
......@@ -54,16 +53,16 @@ function dataPreparationForML(age, gender /*, assistiveAids*/) {
}
}
function getPrediction(inputForMLPrediction) {
async function getMLPrediction(inputForMLPrediction) {
predictionResult = axios.post(predictionURL_training_fall, inputForMLPrediction).then(result => {
return result.data;
}).catch(error => {
log.error("getPrediction() threw an exception: ", error)
log.error("getMLPrediction() threw an exception: ", error)
})
return predictionResult
}
function getCitizenInformation(citizenSSN) {
async function getCitizenInformation(citizenSSN) {
const citizen = prisma.citizen.findUnique({
where: {
ssn: citizenSSN
......@@ -74,14 +73,22 @@ function getCitizenInformation(citizenSSN) {
age: true,
ssn: true,
gender: true,
Assistive_Aids: {
select: {
name: true,
iso: true,
initiative_name: true,
paragraph: true,
lend_date: true,
},
},
Training_Plans: {
select: {
agreement_date: true,
name: true,
type: true,
start_date: true,
end_date: true,
status: true,
time_slot: true,
},
},
Home_Care: {
......@@ -92,14 +99,6 @@ function getCitizenInformation(citizenSSN) {
time_slot: true,
},
},
Registered_Falls: {
select: {
date_fall: true,
organisation_name: true,
observation_name: true,
number_of_affected_citizens: true,
},
},
},
})
return citizen
......@@ -111,19 +110,87 @@ app.get('/', function (req, res) {
app.post("/home/:ssn", async (req, res) => {
var citizenData = await getCitizenInformation(req.body.citizenSSN);
if (!citizenData) {
deleteVariable([citizenData])
if (!citizenData || citizenData.Assistive_Aids.length == 0) {
await deleteVariable([citizenData])
res.send(false)
} else {
const inputDataForMLPrediction = dataPreparationForML(citizenData.age, citizenData.gender /*, */);
var citizenPrediction = await getPrediction(inputDataForMLPrediction);
//Send HMI to ATS Endpoint
//console.log("CITIZEN DATA: ", citizenData)
var assistiveAidsWithCorrectDateFormat = changeLendDateFormat(citizenData.Assistive_Aids)
var sortedAssistiveAids = sortAssistiveAidsByDate(assistiveAidsWithCorrectDateFormat)
//console.log("SORTED AIDS BY DATE: ", sortedAssistiveAids)
//console.log("SORTED AIDS BY DATE LENGTH: ", sortedAssistiveAids.length);
var assistiveAids = appendAssistiveAidsISO(sortedAssistiveAids);
//console.log("APPENDED AIDS: ", assistiveAids);
var loanPeriod = calculateMeanLoanPeriod(sortedAssistiveAids);
var inputDataForMLPrediction = dataPreparationForML(citizenData.age, citizenData.gender, assistiveAids, loanPeriod);
var citizenPrediction = await getMLPrediction(inputDataForMLPrediction);
convertDataSizeToKb("Combined datasize from both the ML Model and Database in Kb: ", { citizenData, citizenPrediction })
res.json({ citizenData, citizenPrediction })
deleteVariable([citizenData, citizenPrediction])
}
await deleteVariable([citizenData, assistiveAidsWithCorrectDateFormat, sortedAssistiveAids, assistiveAids, loanPeriod, inputDataForMLPrediction, citizenPrediction])
}
});
function changeLendDateFormat(assistiveAids) {
assistiveAids.forEach(function(assistiveAid) {
assistiveAid.lend_date = rearrangeDateFormat(assistiveAid.lend_date)
});
return assistiveAids
}
function rearrangeDateFormat(date) {
var dateInArray = date.split('/');
var day = dateInArray[0]
var month = dateInArray[1]
var year = dateInArray[2]
var rearrangedDateFormat = month + '/' + day + '/' + '20' + year
return rearrangedDateFormat
}
function sortAssistiveAidsByDate(assistiveAids){
if(assistiveAids.length == 1) {
return sortedAssistiveAids;
} else {
var sortedAssistiveAids = assistiveAids.sort((a, b) => new Date(b.lend_date) - new Date(a.lend_date))
sortedAssistiveAids.reverse()
return sortedAssistiveAids;
}
}
function appendAssistiveAidsISO(assistiveAids) {
var assistiveAidsISOString = "";
for (var i = 0; i < assistiveAids.length; i++) {
if(i === assistiveAids.length - 1 || i === 9) {
assistiveAidsISOString += assistiveAids[i].iso;
break;
}
else {
assistiveAidsISOString += assistiveAids[i].iso + ",";
}
}
return assistiveAidsISOString;
}
function calculateMeanLoanPeriod(assistiveAids){
var assistiveAidsLoanPeriod = 0;
assistiveAids.forEach(function(assistiveAid) {
assistiveAidsLoanPeriod += dateDifferenceInDays(assistiveAid.lend_date)
});
var assistiveAidsMeanLoanPeriod = (assistiveAidsLoanPeriod / assistiveAids.length)
return Math.round(assistiveAidsMeanLoanPeriod);
}
function dateDifferenceInDays(assistiveAidLendDate) {
var nowDate = new Date();
var lendDate = new Date(assistiveAidLendDate);
var differenceInTime = nowDate.getTime() - lendDate.getTime()
var oneDayInMilliseconds = 1000*3600*24
return Math.round(((differenceInTime))/(oneDayInMilliseconds) - 1);
}
//http.createServer(app).listen(80);
//https.createServer(app).listen(443);
//log.info(`Server is listening on port ${80} and ${443}.`);
......
<template>
<v-data-table
:headers="headers"
:items="aidsList"
:items="assistiveAidsList"
class="elevation-1"
:items-per-page="5"
:items-per-page="10"
:fixed-header="true"
>
<template v-slot:[`item.dateReceived`]="{ item }">
<span>
{{ item.formattedReceivedDate }}
</span>
</template>
<template v-slot:[`item.grantType`]="{ item }">
<span>{{ $_formatGrantType(item) }}</span>
</template>
</v-data-table>
</template>
</template>
<script lang="ts">
import Vue from "vue";
......@@ -29,35 +21,30 @@ export default Vue.extend({
text: "Hjælpemiddel",
align: "start",
sortable: true,
value: "aidName",
value: "name",
width: 1,
},
{
text: "Leveringsdato",
value: "dateReceived",
text: "Bevilling",
value: "initiative_name",
width: 1,
},
{
text: "Bevillingstype",
value: "grantType",
text: "Paragraf",
value: "paragraph",
width: 1,
},
{
text: "Bevillingsbegrundelse",
value: "grantReason",
text: "Udlånsdato",
value: "lend_date",
width: 1,
},
],
};
},
computed: {
aidsList: function () {
return this.$store.getters.activeAids;
},
},
methods: {
$_formatGrantType: function (item: { grantType: string }) {
return item.grantType === "APV" ? item.grantType : "§" + item.grantType;
assistiveAidsList: function () {
return this.$store.getters.assistive_Aids;
},
},
});
......
......@@ -3,7 +3,7 @@
<v-tab>Hjælpemidler</v-tab>
<v-tab-item>
<aid-table class="card-margin" />
<aid-graph class="card-margin" />
<!-- <aid-graph class="card-margin" /> -->
</v-tab-item>
<template>
......@@ -20,21 +20,21 @@
</v-tab-item>
</template>
<template v-if="fall">
<!-- <template v-if="fall">
<v-tab>Registreret fald</v-tab>
<v-tab-item>
<registered-fall-table class="card-margin" />
</v-tab-item>
</template>
</template> -->
</v-tabs>
</template>
<script lang="ts">
import Vue from "vue";
import AidGraph from "@/components/AidGraph.vue";
import AidTable from "@/components/AidTable.vue";
//import AidGraph from "@/components/AidGraph.vue";
import TrainingPlanTable from "@/components/TrainingplanTable.vue";
import RegisteredFallTable from "@/components/RegisteredFallTable.vue";
//import RegisteredFallTable from "@/components/RegisteredFallTable.vue";
import HomeCareTable from "@/components/HomeCareTable.vue";
export default Vue.extend({
......@@ -47,9 +47,9 @@ export default Vue.extend({
},
},
components: {
RegisteredFallTable,
AidGraph,
//RegisteredFallTable,
AidTable,
//AidGraph,
TrainingPlanTable,
HomeCareTable,
},
......
......@@ -13,13 +13,13 @@ export default Vue.extend({
data() {
return {
headers: [
{
text: "Aftaledato",
align: "start",
sortable: true,
value: "agreement_date",
width: "1%",
},
// {
// text: "Aftaledato",
// align: "start",
// sortable: true,
// value: "agreement_date",
// width: "1%",
// },
{
text: "Navn",
align: "start",
......@@ -27,13 +27,13 @@ export default Vue.extend({
value: "name",
width: "1%",
},
{
text: "Paragraf",
align: "start",
sortable: true,
value: "type",
width: "1%",
},
// {
// text: "Paragraf",
// align: "start",
// sortable: true,
// value: "type",
// width: "1%",
// },
{
text: "Start dato",
value: "start_date",
......@@ -49,6 +49,11 @@ export default Vue.extend({
value: "status",
width: "1%",
},
{
text: "Bestilt tid (Minutter)",
value: "time_slot",
width: "1%",
},
],
};
},
......
import {Hmi} from "@/model/Hmi";
import {DateFormat} from "@/model/DateFormat";
export class Aid extends DateFormat {
private $_aidName: any;
private $_hmiNumber: Hmi;
private $_dateReceived: Date;
private $_handInDate: Date;
private $_grantType: any;
private $_grantReason: any;
constructor(hmiNumber: string, dateReceived: string, handInDate: string, grantType: string, grantReason: string) {
super()
this.$_hmiNumber = new Hmi(hmiNumber)
this.$_dateReceived = new Date(dateReceived)
this.$_handInDate = new Date(handInDate)
this.$_grantType = grantType
this.$_grantReason = grantReason
this.$_aidName = this.$_hmiNumber.HmiName
}
get formattedReceivedDate(): string {
return this.formatDate(this.dateReceived)
}
get formattedHandInDate(): string {
return this.formatDate(this.handInDate)
}
get aidName(): any {
return this.$_aidName;
}
get hmiNumber(): Hmi {
return this.$_hmiNumber;
}
get dateReceived(): Date {
return this.$_dateReceived;
}
get handInDate(): Date {
return this.$_handInDate;
}
get grantType(): any {
return this.$_grantType;
}
get grantReason(): any {
return this.$_grantReason;
}
}
export abstract class DateFormat {
formatDate(date: Date): string {
if (date.toString() == 'Invalid Date')
return ''
return new Intl.DateTimeFormat("default", {
year: 'numeric',
month: '2-digit',
day: '2-digit'
}).format(date)
}
formatTime(time: Date): string {
if (time.toString() == 'Invalid Date')
return ''
return new Intl.DateTimeFormat("default", {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
}).format(time)
}
}
export class Hmi {
private $_first: string
private $_second: string
private $_third: string
private $_fourth: string
private $_fith: string
private $_name: string
constructor(hmiNumber: string) {
this.$_first = hmiNumber.substring(0, 2)
this.$_second = hmiNumber.substring(2, 4)
this.$_third = hmiNumber.substring(4, 6)
this.$_fourth = hmiNumber.substring(6, 8)
this.$_fith = hmiNumber.substring(8, 10)
this.$_name = this.nameMapper()
}
get HmiNumber(): string {
return `${this.$_first}${this.$_second}${this.$_third}${this.$_fourth}${this.$_fith}`;
}
get HmiClassification() {
return `${this.$_first}${this.$_second}${this.$_third}`
}
get HmiName(): string {
return this.$_name;
}
private nameMapper() {
switch (this.$_first) {
case '22':
switch (this.$_second) {
case '27':
switch (this.$_third) {
case '18':
switch (this.$_fourth) {
case '10':
break
default:
return 'Personlige nødalarmsystemer'
}
break
default:
return 'Hjælpemidler til signalering, identificering, varsling, overvågning, tidsangivelse, planlægning og erindring'
}
break
default:
return 'Hjælpemidler til håndtering af kommunikation og information'
}
break
case '12':
switch (this.$_second) {
case '03':
switch (this.$_third) {
case '06':
return 'Albuestokke'
break
default:
return 'Ganghjælpemidler, som håndteres med en arm'
}
break
case '06':
switch (this.$_third) {
case '06':
return 'Rollatorer'
break
default:
return 'Ganghjælpemidler, som håndteres med begge arme'
}
break
case '31':
switch (this.$_third) {
case '03':
return 'Glide- og vendehjælpemidler'
break
default:
return 'Hjælpemidler til at skifte stilling'
}
break
default:
return 'Hjælpemidler til personlig mobilitet og transport'
}
break
case '09':
switch (this.$_second) {
case '12':
switch (this.$_third) {
case '18':
return 'Toiletforhøjere, fastmonterede'
break
default:
return 'jælpemidler til toiletbesøg'
}
break