diff --git a/packages/modules/web_themes/standard/source/public/icons/icon_Data.md b/packages/modules/web_themes/standard/source/public/icons/icon_Data.md
new file mode 100644
index 0000000000..b3141f9b3d
--- /dev/null
+++ b/packages/modules/web_themes/standard/source/public/icons/icon_Data.md
@@ -0,0 +1,2 @@
+Herkunft der Icons:
+https://www.veryicon.com/
diff --git a/packages/modules/web_themes/standard/source/public/icons/openWB_logo_dark.png b/packages/modules/web_themes/standard/source/public/icons/openWB_logo_dark.png
new file mode 100644
index 0000000000..a9af7f0eb0
Binary files /dev/null and b/packages/modules/web_themes/standard/source/public/icons/openWB_logo_dark.png differ
diff --git a/packages/modules/web_themes/standard/source/public/icons/owbBattery.svg b/packages/modules/web_themes/standard/source/public/icons/owbBattery.svg
new file mode 100644
index 0000000000..dd1fc748d3
--- /dev/null
+++ b/packages/modules/web_themes/standard/source/public/icons/owbBattery.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/packages/modules/web_themes/standard/source/public/icons/owbChargePoint.svg b/packages/modules/web_themes/standard/source/public/icons/owbChargePoint.svg
new file mode 100644
index 0000000000..29cca3f93c
--- /dev/null
+++ b/packages/modules/web_themes/standard/source/public/icons/owbChargePoint.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/packages/modules/web_themes/standard/source/public/icons/owbGrid.svg b/packages/modules/web_themes/standard/source/public/icons/owbGrid.svg
new file mode 100644
index 0000000000..e098048efa
--- /dev/null
+++ b/packages/modules/web_themes/standard/source/public/icons/owbGrid.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/packages/modules/web_themes/standard/source/public/icons/owbHouse.svg b/packages/modules/web_themes/standard/source/public/icons/owbHouse.svg
new file mode 100644
index 0000000000..412dc8613b
--- /dev/null
+++ b/packages/modules/web_themes/standard/source/public/icons/owbHouse.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/modules/web_themes/standard/source/public/icons/owbPV.svg b/packages/modules/web_themes/standard/source/public/icons/owbPV.svg
new file mode 100644
index 0000000000..becf88bc97
--- /dev/null
+++ b/packages/modules/web_themes/standard/source/public/icons/owbPV.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/packages/modules/web_themes/standard/source/public/icons/owbVehicle.svg b/packages/modules/web_themes/standard/source/public/icons/owbVehicle.svg
new file mode 100644
index 0000000000..e721de12f4
--- /dev/null
+++ b/packages/modules/web_themes/standard/source/public/icons/owbVehicle.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/packages/modules/web_themes/standard/source/src/components/ChartCarousel.vue b/packages/modules/web_themes/standard/source/src/components/ChartCarousel.vue
index f113ea5543..f755b71059 100644
--- a/packages/modules/web_themes/standard/source/src/components/ChartCarousel.vue
+++ b/packages/modules/web_themes/standard/source/src/components/ChartCarousel.vue
@@ -15,9 +15,8 @@
v-for="(chartComponent, index) in chartCarouselItems"
:key="index"
:name="chartComponent.name"
- class="col items-center justify-center"
>
-
+
@@ -39,7 +38,7 @@
import { ref } from 'vue';
import { useQuasar } from 'quasar';
-import EnergyFlowChart from './charts/EnergyFlowChart.vue';
+import EnergyFlowChart from './charts/energyFlowChart/EnergyFlowChart.vue';
import HistoryChart from './charts/HistoryChart.vue';
defineOptions({
@@ -48,6 +47,15 @@ defineOptions({
const $q = useQuasar();
const fullscreen = ref(false);
-const chartCarouselItems = [EnergyFlowChart, HistoryChart];
-const currentSlide = ref(EnergyFlowChart.__name ?? '');
+const chartCarouselItems = [
+ {
+ name: 'EnergyFlowChart',
+ component: EnergyFlowChart,
+ },
+ {
+ name: 'HistoryChart',
+ component: HistoryChart,
+ },
+];
+const currentSlide = ref(chartCarouselItems[0].name);
diff --git a/packages/modules/web_themes/standard/source/src/components/charts/EnergyFlowChart.vue b/packages/modules/web_themes/standard/source/src/components/charts/EnergyFlowChart.vue
deleted file mode 100644
index dda3dcb933..0000000000
--- a/packages/modules/web_themes/standard/source/src/components/charts/EnergyFlowChart.vue
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
diff --git a/packages/modules/web_themes/standard/source/src/components/charts/energyFlowChart/EnergyFlowChart.vue b/packages/modules/web_themes/standard/source/src/components/charts/energyFlowChart/EnergyFlowChart.vue
new file mode 100644
index 0000000000..54d69ca291
--- /dev/null
+++ b/packages/modules/web_themes/standard/source/src/components/charts/energyFlowChart/EnergyFlowChart.vue
@@ -0,0 +1,899 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/modules/web_themes/standard/source/src/components/charts/energyFlowChart/energy-flow-chart-models.ts b/packages/modules/web_themes/standard/source/src/components/charts/energyFlowChart/energy-flow-chart-models.ts
new file mode 100644
index 0000000000..519aec3150
--- /dev/null
+++ b/packages/modules/web_themes/standard/source/src/components/charts/energyFlowChart/energy-flow-chart-models.ts
@@ -0,0 +1,32 @@
+export interface SvgSize {
+ xMin: number;
+ xMax: number;
+ yMin: number;
+ yMax: number;
+ circleRadius: number;
+ strokeWidth: number;
+ textSize: number;
+ numRows: number;
+ numColumns: number;
+}
+
+export interface ComponentClass {
+ base: string;
+ valueLabel: string;
+ animated?: boolean;
+ animatedReverse?: boolean;
+}
+
+export interface ComponentPosition {
+ row: number;
+ column: number;
+}
+
+export interface FlowComponent {
+ id: string;
+ class: ComponentClass;
+ position: ComponentPosition;
+ label: string[];
+ soc?: number;
+ icon: string;
+}
diff --git a/packages/modules/web_themes/standard/source/src/css/quasar.variables.scss b/packages/modules/web_themes/standard/source/src/css/quasar.variables.scss
index f2d8ce27d1..f78c601d78 100644
--- a/packages/modules/web_themes/standard/source/src/css/quasar.variables.scss
+++ b/packages/modules/web_themes/standard/source/src/css/quasar.variables.scss
@@ -32,17 +32,18 @@
// Default Light Theme Base Colors
$primary: #5c93d1;
$secondary: #d2d2d7;
-$accent: #b691bd;
+$accent: #546e7a;
$positive: #66bd7a;
$negative: #db4f5f;
$info: #7dc5d4;
-$warning: #f7b267;
+$warning: #d98e44;
$background-1: #e3e3ec;
$background-2: #eeeef3;
$brown-text: #524f57;
$white: #ffffff;
$grey: #9e9e9e; // Quasar's default grey
$toggle-off: #e0e0e0;
+$battery: #ba7128;
// Light theme (default)
:root {
@@ -59,6 +60,8 @@ $toggle-off: #e0e0e0;
--q-white: #{$white};
--q-grey: #{$grey};
--q-toggle-off: #{$toggle-off};
+ --q-flow-home-stroke: #{$grey};
+ --q-battery: #{$battery};
// Main background
background-color: var(--q-background-1);
@@ -139,7 +142,7 @@ $toggle-off: #e0e0e0;
$dark-page: #030627; // This overrides Quasar's default dark page color
$dark-primary: #3874db;
$dark-secondary: #28293d;
-$dark-accent: #7a7a9c;
+$dark-accent: #546e7a;
$dark-positive: #3e8f5e;
$dark-negative: #c54d57;
$dark-info: #4b89aa;
@@ -167,6 +170,8 @@ $dark-tab-icon: #d7d9e0;
--q-toggle-off: #{$toggle-off};
--q-list: #{$dark-list};
--q-tab-icon: #{$dark-tab-icon};
+ --q-flow-home-stroke: #{$grey};
+ --q-battery: #{$dark-warning};
// Main background
background-color: var($dark-page);
// Text color
diff --git a/packages/modules/web_themes/standard/source/src/layouts/MainLayout.vue b/packages/modules/web_themes/standard/source/src/layouts/MainLayout.vue
index 01ba929eef..3668beefef 100644
--- a/packages/modules/web_themes/standard/source/src/layouts/MainLayout.vue
+++ b/packages/modules/web_themes/standard/source/src/layouts/MainLayout.vue
@@ -21,7 +21,7 @@
-
diff --git a/packages/modules/web_themes/standard/source/src/pages/InfoPage.vue b/packages/modules/web_themes/standard/source/src/pages/InfoPage.vue
new file mode 100644
index 0000000000..9b64ed811b
--- /dev/null
+++ b/packages/modules/web_themes/standard/source/src/pages/InfoPage.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/modules/web_themes/standard/source/src/pages/TestPage.vue b/packages/modules/web_themes/standard/source/src/pages/TestPage.vue
deleted file mode 100644
index eaba26b7c6..0000000000
--- a/packages/modules/web_themes/standard/source/src/pages/TestPage.vue
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/modules/web_themes/standard/source/src/router/routes.ts b/packages/modules/web_themes/standard/source/src/router/routes.ts
index db94804157..19112ab4af 100644
--- a/packages/modules/web_themes/standard/source/src/router/routes.ts
+++ b/packages/modules/web_themes/standard/source/src/router/routes.ts
@@ -2,15 +2,15 @@ import { RouteRecordRaw } from 'vue-router';
const routes: RouteRecordRaw[] = [
{
- path: '/',
+ path: '/info',
component: () => import('layouts/MainLayout.vue'),
- children: [{ path: '', component: () => import('pages/IndexPage.vue') }],
+ children: [{ path: '', component: () => import('pages/InfoPage.vue') }],
},
{
- path: '/test',
+ path: '/',
component: () => import('layouts/MainLayout.vue'),
- children: [{ path: '', component: () => import('pages/TestPage.vue') }],
+ children: [{ path: '', component: () => import('pages/IndexPage.vue') }],
},
// Always leave this as last one,
diff --git a/packages/modules/web_themes/standard/source/src/stores/mqtt-store.ts b/packages/modules/web_themes/standard/source/src/stores/mqtt-store.ts
index 60327035bb..9ed2f076ad 100644
--- a/packages/modules/web_themes/standard/source/src/stores/mqtt-store.ts
+++ b/packages/modules/web_themes/standard/source/src/stores/mqtt-store.ts
@@ -680,6 +680,29 @@ export const useMqttStore = defineStore('mqtt', () => {
};
});
+ /**
+ * Get power sum total for all charge points
+ * @param returnType type of return value, 'textValue', 'value', 'scaledValue', 'scaledUnit' or 'object'
+ * @returns string | number | ValueObject
+ */
+ const chargePointSumPower = computed(() => {
+ return (returnType: string = 'textValue') => {
+ const power = getValue.value(
+ 'openWB/chargepoint/get/power',
+ undefined,
+ 0,
+ ) as number;
+ const valueObject = getValueObject.value(power);
+ if (Object.hasOwnProperty.call(valueObject, returnType)) {
+ return valueObject[returnType];
+ }
+ if (returnType == 'object') {
+ return valueObject as ValueObject;
+ }
+ console.error('returnType not found!', returnType, power);
+ };
+ });
+
/**
* Get the charge point power identified by the charge point id
* @param chargePointId charge point id
@@ -1270,8 +1293,8 @@ export const useMqttStore = defineStore('mqtt', () => {
});
/**
- * Get the battery power identified by the charge point id
- * @param batteryId charge point id
+ * Get the battery power identified by the battery point id
+ * @param batteryId battery point id
* @param returnType type of return value, 'textValue', 'absoluteTextValue', 'value', 'scaledValue', 'scaledUnit' or 'object'
* @returns string | number | ValueObject
*/
@@ -1348,6 +1371,14 @@ export const useMqttStore = defineStore('mqtt', () => {
////////////////////////////// Battery totals ////////////////////////////////
+ /**
+ * Get battery configured boolean true or false
+ * @returns boolean
+ */
+ const batteryConfigured = computed(() => {
+ return getValue.value('openWB/bat/config/configured', undefined) as boolean;
+ });
+
/**
* Get the battery ids
* @returns number[]
@@ -1371,7 +1402,7 @@ export const useMqttStore = defineStore('mqtt', () => {
/**
* Get the total power of all batteries
* @param returnType type of return value, 'textValue', 'absoluteTextValue', 'value', 'scaledValue', 'scaledUnit' or 'object'
- * @returns number | string | ValueObject
+ * @returns number | string
*/
const batteryTotalPower = computed(() => {
return (returnType: string = 'textValue') => {
@@ -1901,6 +1932,111 @@ export const useMqttStore = defineStore('mqtt', () => {
});
};
+ /////////////////////////////// Grid Data /////////////////////////////////////
+
+ /**
+ * Get counter id from root of component hierarchy
+ * @returns number | undefined
+ */
+ const getGridId = computed(() => {
+ const hierarchy = getValue.value(
+ 'openWB/counter/get/hierarchy',
+ ) as Hierarchy[];
+
+ if (hierarchy && hierarchy.length > 0) {
+ const firstElement = hierarchy[0];
+ if (firstElement.type === 'counter') {
+ return firstElement.id;
+ }
+ }
+ return undefined;
+ });
+
+ /**
+ * Get grid power identified from root of component hierarchy
+ * @param returnType type of return value, 'textValue', 'value', 'scaledValue', 'scaledUnit' or 'object'
+ * @returns string | number | ValueObject | undefined
+ */
+ const getGridPower = computed(() => {
+ return (returnType: string = 'textValue') => {
+ const gridId = getGridId.value;
+ if (gridId === undefined) {
+ return '---';
+ }
+ const power = getValue.value(
+ `openWB/counter/${gridId}/get/power`,
+ undefined,
+ 0,
+ ) as number;
+ const valueObject = getValueObject.value(power);
+ if (returnType in valueObject) {
+ return valueObject[returnType as keyof ValueObject];
+ }
+ if (returnType == 'object') {
+ return valueObject as ValueObject;
+ }
+ console.error('returnType not found!', returnType, power);
+ };
+ });
+
+ ////////////////// Home data //////////////////////////
+
+ /**
+ * Get home power
+ * @param returnType type of return value, 'textValue', 'value', 'scaledValue', 'scaledUnit' or 'object'
+ * @returns string | number | ValueObject | undefined
+ */
+ const getHomePower = computed(() => {
+ return (returnType: string = 'textValue') => {
+ const power = getValue.value(
+ 'openWB/counter/set/home_consumption',
+ undefined,
+ 0,
+ ) as number;
+ const valueObject = getValueObject.value(power);
+ if (returnType in valueObject) {
+ return valueObject[returnType as keyof ValueObject];
+ }
+ if (returnType == 'object') {
+ return valueObject as ValueObject;
+ }
+ console.error('returnType not found!', returnType, power);
+ };
+ });
+
+ ////////////////// PV data //////////////////////////
+
+ /**
+ * Get pv configured true or false
+ * @returns boolean
+ */
+ const getPvConfigured = computed(() => {
+ return getValue.value('openWB/pv/config/configured', undefined) as boolean;
+ });
+
+ /**
+ * Get pv power
+ * @param returnType type of return value, 'textValue', 'value', 'scaledValue', 'scaledUnit' or 'object'
+ * @returns string | number | ValueObject | undefined
+ */
+ const getPvPower = computed(() => {
+ return (returnType: string = 'textValue') => {
+ const power = getValue.value(
+ 'openWB/pv/get/power',
+ undefined,
+ 0,
+ ) as number;
+ const valueObject = getValueObject.value(power);
+ if (returnType in valueObject) {
+ return valueObject[returnType as keyof ValueObject];
+ }
+ if (returnType == 'object') {
+ return valueObject as ValueObject;
+ }
+ console.error('returnType not found!', returnType, power);
+ };
+ });
+
// exports
return {
topics,
@@ -1925,6 +2061,7 @@ export const useMqttStore = defineStore('mqtt', () => {
chargePointManualLock,
chargePointPlugState,
chargePointChargeState,
+ chargePointSumPower,
chargePointPower,
chargePointEnergyCharged,
chargePointEnergyChargedPlugged,
@@ -1965,6 +2102,7 @@ export const useMqttStore = defineStore('mqtt', () => {
vehicleScheduledChargingPlanSocLimit,
vehicleScheduledChargingPlanSocScheduled,
// Battery data
+ batteryConfigured,
batteryIds,
batteryName,
batterySoc,
@@ -1976,5 +2114,13 @@ export const useMqttStore = defineStore('mqtt', () => {
batteryDailyExportedTotal,
batteryTotalPower,
batteryMode,
+ // Grid data
+ getGridId,
+ getGridPower,
+ // Home data
+ getHomePower,
+ // PV data
+ getPvConfigured,
+ getPvPower,
};
});