This commit is contained in:
Samuele Locatelli
2020-07-10 16:57:21 +02:00
12 changed files with 133 additions and 56 deletions
@@ -298,6 +298,9 @@
.recipe {
height: 97px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
&::before {
content: "";
@@ -314,6 +317,11 @@
background-image: url(/assets/svg/dashboard-top-right.svg);
}
label {
font-size: 36px;
z-index: 1;
}
}
.piece_time {
@@ -4371,6 +4371,9 @@ article .box .body {
.dashboard .third_col .recipe {
height: 97px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.dashboard .third_col .recipe::before {
content: "";
@@ -4386,6 +4389,10 @@ article .box .body {
z-index: 0;
background-image: url(/assets/svg/dashboard-top-right.svg);
}
.dashboard .third_col .recipe label {
font-size: 36px;
z-index: 1;
}
.dashboard .third_col .piece_time {
display: grid;
grid-template-rows: repeat(2, auto);
@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1156"
height="800"
viewBox="0 0 1156 800"
@@ -54,7 +53,7 @@
id="layer1"
transform="translate(0,503)">
<path
style="fill:#4d85ff;fill-opacity:0.5018587;stroke:#0000a9;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
style="fill:#99cfff;stroke:#002680;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 850.19123,-221.17487 c 0,0 122.26692,-1.97359 180.30647,0.24275 l -35.60462,147.001143 -111.4927,0.65955 -7.07924,-30.572513 -27.17361,-117.34132 1.04341,0.0577"
id="path54-0"
inkscape:connector-curvature="0"
@@ -62,7 +61,7 @@
inkscape:export-xdpi="96"
inkscape:export-ydpi="96" />
<path
style="fill:none;stroke:#0000d1;stroke-width:4.21029854;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
style="fill:none;stroke:#002680;stroke-width:4.21029854;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 762.66311,-224.80453 355.98669,-0.0872"
id="path4569-2"
inkscape:connector-curvature="0"
@@ -74,7 +73,7 @@
id="path857"
inkscape:connector-curvature="0" />
<path
style="fill:#4d85ff;fill-opacity:0.5018587;stroke:#0000a9;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
style="fill:#99cfff;stroke:#002680;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 220.17481,-466.8417 c 0,0 122.26692,-1.97359 180.30648,0.24275 l -35.60463,147.00114 -111.4927,0.65955 -7.07924,-30.57251 -27.17361,-117.34132 1.04341,0.0577"
id="path54"
inkscape:connector-curvature="0"
@@ -82,7 +81,7 @@
inkscape:export-xdpi="96"
inkscape:export-ydpi="96" />
<path
style="fill:none;stroke:#0000d1;stroke-width:4.21029854;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
style="fill:none;stroke:#002680;stroke-width:4.21029854;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 132.64669,-470.47136 355.9867,-0.0872"
id="path4569"
inkscape:connector-curvature="0"

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

@@ -2,7 +2,7 @@
"env": "development",
"api": {
"enabled": true,
"apiServerUrl": "http://localhost:9000/"
"apiServerUrl": "http://seriate.steamware.net:9000/"
},
"allUIVisible": true
}
+1 -1
View File
@@ -13,7 +13,7 @@
<script src="Scripts/jquery.mousewheel.js"></script>
<script src="Scripts/jquery.signalR-2.2.2.min.js"></script>
<script src="Scripts/raphael-2.1.4.min.js"></script>
<script src="http://localhost:9000/signalr/hubs" async></script>
<script src="http://seriate.steamware.net:9000/signalr/hubs" async></script>
<link href="assets/styles/style.css" rel="stylesheet" />
</head>
+28 -16
View File
@@ -1,19 +1,31 @@
declare module Prod{
declare module Prod {
interface IProd{
numTarget: number;
numDone: number;
timeWarm: number;
timeVent: number;
timeVacuum: number;
timeCycleGross: number;
timeCycleNet: number;
materialTempEndWarm: number;
materialTempEndVent: number;
moldTemp: number;
vacuumReadVal: number;
mouldEnergyOUT: number;
mouldEnergyIN: number;
}
interface IProd {
numTarget: number;
numDone: number;
timeWarm: number;
timeVent: number;
timeVacuum: number;
timeCycleGross: number;
timeCycleNet: number;
materialTempEndWarm: number;
materialTempEndVent: number;
moldTemp: number;
vacuumReadVal: number;
mouldEnergyOUT: number;// Generated by https://quicktype.io
}
interface IProdPanel {
numTarget: number;
numDone: number;
inizioProd: string;
stimaDurata: number;
tempAct: number;
tempSetpoint: number;
nomeRicetta: string;
lastCadenza: number;
lastTCiclo: number;
tS_Cadenza: { [key: string]: number };
tS_TCiclo: { [key: string]: number };
}
}
@@ -32,6 +32,9 @@ export default class MainGauge extends Vue {
viewBox: [6, 6, 88, 88]
}
);
this.gaugeDataChanged(this.gaugeData, null);
this.gaugeChanged();
}
get gaugeData() {
@@ -46,7 +49,7 @@ export default class MainGauge extends Vue {
};
}
get prod() { return store.state.prod.prod }
get prod() { return store.state.prod.panel }
@Watch('prod.numDone')
@Watch('prod.numTarget')
@@ -8,6 +8,8 @@ import { AppModel, appModelActions } from '@/store';
import { getColorFromName, isDarkColor } from "@/_base/utils";
import ArchInterface from "../components/arch-interface/arch-interface.vue";
import gauge from "./base-components/gauge.vue";
import { prodService } from '@/services/prodService';
import moment from 'moment';
@Component({
components: {
@@ -19,18 +21,25 @@ import gauge from "./base-components/gauge.vue";
})
export default class Dashboard extends Vue {
@Prop({ default: "18,2" })
piece_hours: string;
@Prop({ default: "3'12''" })
time_cycle: string;
@Prop({ default: 10 })
pieces: number;
@Prop({ default: 280 })
temperature: number;
@Prop({ default: 0 })
t_setpoint: number;
@Prop()
remaining_time: Date = new Date();
get panel() {
return (this.$store.state as AppModel).prod.panel;
}
now = moment();
get elapsed() {
var from = moment(this.panel.inizioProd);
return this.now.diff(from);
}
get endEstimation() {
return moment(this.panel.inizioProd).add(this.panel.stimaDurata, 'minutes');
}
get remainingTime() {
return this.endEstimation.diff(this.now);
}
get currentUser() {
return (this.$store.state as AppModel).currentUser;
@@ -49,8 +58,14 @@ export default class Dashboard extends Vue {
}
async mounted() {
await prodService.GetProdPanel();
// Ribbon
let $this = this;
setInterval(() => {
$this.now = moment();
}, 1000);
}
public get ribbonStatus(): ribbonStatusEnum {
@@ -91,27 +91,28 @@
<div class="timing-area">
<div class="start">
<small>{{'dashboard-timing-start' | localize('inizio')}}</small>
<time>10:53</time>
<time>{{panel.inizioProd | date('HH:mm')}}</time>
</div>
<div class="current">
<small>{{'dashboard-timing-elapsed' | localize('tempo trascorso')}}</small>
<time>10:53</time>
<time>{{elapsed | date('HH:mm')}}</time>
</div>
<div class="end">
<small>{{'dashboard-timing-end' | localize('fine')}}</small>
<time>~10:53</time>
<time v-if="panel.stimaDurata">~{{endEstimation | date('HH:mm')}}</time>
<time v-else>--:--</time>
</div>
</div>
<div class="setpoint">
<img src="assets/icons/png/inv.png" />
<label>{{temperature}}°C</label>
<label>{{panel.tempAct}}°C</label>
<button>
<i class="fa fa-minus"></i>
</button>
<div>
<small>{{'dashboard-setpoint' | localize('set point')}}</small>
<span>{{t_setpoint}}°C</span>
<span>{{panel.tempSetpoint}}°C</span>
</div>
<button>
<i class="fa fa-plus"></i>
@@ -123,20 +124,25 @@
<gauge></gauge>
<div class="remaining_time">
<small>{{'dashboard-remaining-time' | localize('tempo rimanente')}}</small>
<time>{{remaining_time | date('HH:mm:ss')}}</time>
<time v-if="panel.stimaDurata">{{remainingTime | date('HH:mm:ss')}}</time>
<time v-else>--:--:--</time>
</div>
</div>
<div class="third_col">
<div class="recipe"></div>
<div class="recipe">
<label>{{panel.nomeRicetta}}</label>
</div>
<div class="piece_time">
<div class="piece_hours">
<span>{{'dashboard-piece-hours' | localize('pezzi/ora')}}</span>
<span>{{piece_hours}}</span>
<span v-if="panel.lastCadenza">{{panel.lastCadenza}}</span>
<span v-else>--</span>
</div>
<div class="time_cycle">
<span>{{'dashboard-time-cycle' | localize('tempo/ciclo')}}</span>
<span>{{time_cycle}}</span>
<span v-if="panel.lastTCiclo">{{panel.lastTCiclo}}</span>
<span v-else>--</span>
</div>
</div>
</div>
@@ -103,6 +103,7 @@ export class Hub {
this._hub.client.recipeFullData = Hub.recipeFullData;
this._hub.client.recipeOverData = Hub.recipeOverData;
this._hub.client.prodInfoData = Hub.prodData;
this._hub.client.prodPanelData = Hub.prodPanelData;
this._hub.client.modulesData = Hub.modulesData;
// this._hub.client.warmersData = Hub.warmersData;
this._hub.client.gaugeData = Hub.gaugeData;
@@ -159,7 +160,13 @@ export class Hub {
recipeActions.setOverview(store, data);
}
public static prodPanelData(data) {
console.log('prodPanelData', data);
prodActions.setProdPanel(store, data);
}
public static prodData(data) {
console.log('prod', data);
prodActions.setProd(store, data);
}
@@ -8,10 +8,16 @@ export class ProdService extends baseRestService {
BASE_URL = async () => (await CONFIGURATION).api.apiServerUrl + "/api/prod/";
async GetProd() {
let result = await this.Put<any>((await this.BASE_URL()) + "get", true);
let result = await this.Get<any>((await this.BASE_URL()) + "get", true);
prodActions.setProd(store, result);
return result;
}
async GetProdPanel() {
let result = await this.Get<any>((await this.BASE_URL()) + "prodPanel", true);
prodActions.setProdPanel(store, result);
return result;
}
}
export const prodService = new ProdService();
+16 -2
View File
@@ -2,25 +2,30 @@ import Vue from "vue";
export interface ProdStoreModel {
prod: Prod.IProd;
panel: Prod.IProdPanel;
}
export interface ProdActions {
setProd(context, model: Prod.IProd);
setProdPanel(context, model: Prod.IProdPanel);
}
export interface ProdGetters {
getProd: () => Prod.IProd;
getProdPanel: () => Prod.IProdPanel;
}
export const prodStore = {
state: {
prod: {},
panel: {}
} as ProdStoreModel,
getters: {
getProd: (state) => (): Prod.IProd => (state as ProdStoreModel).prod,
getProdPanel: (state) => (): Prod.IProdPanel => (state as ProdStoreModel).panel,
},
mutations: {
@@ -28,12 +33,18 @@ export const prodStore = {
SetProd(state, model: Prod.IProd) {
for (const key in model) {
if (model.hasOwnProperty(key)) {
if (model[key])
Vue.set(state.prod, key, model[key]);
Vue.set(state.prod, key, model[key]);
}
}
},
SetProdPanel(state, model: Prod.IProdPanel) {
for (const key in model) {
if (model.hasOwnProperty(key)) {
Vue.set(state.panel, key, model[key]);
}
}
},
},
actions: {
@@ -42,6 +53,9 @@ export const prodStore = {
context.commit("SetProd", model);
},
setProdPanel(context, model: Prod.IProdPanel) {
context.commit("SetProdPanel", model);
},
} as ProdActions
}