Skip to content

Commit

Permalink
Merge pull request #44 from Jalle19/groups
Browse files Browse the repository at this point in the history
Add a "Group" page
  • Loading branch information
Jalle19 committed Nov 13, 2023
2 parents c382f73 + a3265ae commit d50e3bc
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 92 deletions.
10 changes: 9 additions & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,13 @@
"tabWidth": 2,
"semi": false,
"singleQuote": true,
"quoteProps": "preserve"
"quoteProps": "preserve",
"overrides": [
{
"files": "*.css",
"options": {
"tabWidth": 4
}
}
]
}
8 changes: 6 additions & 2 deletions src/sensor/shelly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ type Gen2EMGetStatusResult = {

const logger = createLogger('sensor.shelly')

const logError = (url: string, err: unknown): void => {
logger.error(`${url}: ${(err as Error).message}`)
}

const getSensorDataUrl = (sensor: ShellySensor | ShellyCharacteristicsSensor): string => {
const address = sensor.shelly.address
const meter = sensor.shelly.meter
Expand Down Expand Up @@ -137,7 +141,7 @@ export const getSensorData: PowerSensorPollFunction = async (
return parseGen2EMResponse(timestamp, circuit, httpResponse)
}
} catch (e) {
logger.error((e as Error).message)
logError(url, e)
return emptySensorData(timestamp, circuit)
}
}
Expand Down Expand Up @@ -182,7 +186,7 @@ export const getCharacteristicsSensorData: CharacteristicsSensorPollFunction = a
frequency: frequency,
}
} catch (e) {
logger.error((e as Error).message)
logError(url, e)
return emptyCharacteristicsSensorData(timestamp, characteristics)
}
}
37 changes: 37 additions & 0 deletions webif/src/lib/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export enum SensorType {
Iotawatt = 'iotawatt',
Shelly = 'shelly',
Virtual = 'virtual',
Unmetered = 'unmetered',
Dummy = 'dummy',
}

export interface PowerSensor {
type: SensorType
}

export enum CircuitType {
Main = 'main',
Circuit = 'circuit',
}

export type Circuit = {
name: string
type: CircuitType // resolved during parsing
parent?: Circuit // resolved to the circuit in question
children: Circuit[] // resolved from parent
phase?: string // resolved from parent
hidden?: boolean // defaults to false
sensor: PowerSensor
group?: string
}

export type PowerSensorData = {
timestamp: number
circuit: Circuit
// Mandatory data. Undefined means the data was not available.
power?: number
// Optional data, not all sensor types support them
apparentPower?: number
powerFactor?: number
}
82 changes: 1 addition & 81 deletions webif/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script>
import 'purecss/build/pure.css'
import './styles.css'
import {
configurationStore,
Expand Down Expand Up @@ -82,86 +83,5 @@
</div>

<style>
:root {
--background: #fff;
--color: #222;
--component-background: #e0e0e0;
--highlight-color: #ff3d00;
}
@media (prefers-color-scheme: dark){
:root {
--background: #272727;
--color: #aaa;
--component-background: #3b3b3b;
--highlight-color: #ff3d00;
}
nav {
background-color: var(--component-background);
}
/* pure-table overrides */
:global(.pure-table) {
border: 2px solid #424242;
}
:global(.pure-table thead) {
background-color: var(--component-background);
color: var(--color);
}
:global(.pure-table th, .pure-table td) {
border: 0;
}
:global(.pure-table-striped tr:nth-child(2n-1) td) {
background-color: #2E2E2E;
}
/* end pure-table overrides */
}
:global(body) {
background: var(--background);
color: var(--color);
}
:global(h1, h2, h3, h4, h5, h6) {
margin-top: 0;
padding-bottom: 0.2em;
display: inline-block;
border-bottom: 2px solid var(--highlight-color);
}
.container {
max-width: 1200px;
margin: 0 auto;
clear: both;
}
:global(table) {
width: 100%;
}
:global(.cell-right-align) {
text-align: right;
}
:global(.pure-g > div) {
box-sizing: border-box;
}
:global(.l-box) {
padding: 1em;
}
/* pure-menu tweaks */
:global(.pure-menu-link) {
border-bottom: 2px solid var(--component-background);
}
:global(.pure-menu-link:hover) {
border-bottom: 2px solid var(--highlight-color);
background: inherit !important;
}
/* end pure-menu tweaks */
</style>
6 changes: 4 additions & 2 deletions webif/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
import {
lastUpdateTimestampStore,
webSocketUrlStore,
circuitSensorDataStore,
characteristicsStore,
mainSensorDataStore,
} from '../lib/stores'
} from '$lib/stores'
import LastUpdate from './LastUpdate.svelte'
import Characteristics from './Characteristics.svelte'
Expand Down Expand Up @@ -41,6 +42,7 @@
</div>
{/if}
<div class="pure-u-1-1 l-box">
<Circuits />
<h2>All circuits</h2>
<Circuits sensorData="{$circuitSensorDataStore}" />
</div>
{/if}
17 changes: 11 additions & 6 deletions webif/src/routes/Circuits.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<script>
import { circuitSensorDataStore } from '../lib/stores'
import { formatPf } from '../lib/format'
<script lang="ts">
import { formatPf } from '$lib/format'
import type { PowerSensorData } from '$lib/types'
export let sensorData: PowerSensorData[]
</script>

<h2>All circuits</h2>
<table class="pure-table pure-table-striped">
<thead>
<tr>
Expand All @@ -18,10 +19,14 @@
</tr>
</thead>
<tbody>
{#each $circuitSensorDataStore as data}
{#each sensorData as data}
<tr>
<td>{data.circuit.name}</td>
<td>{data.circuit.group ?? ''}</td>
<td>
{#if data.circuit.group}
<a href="/group/{data.circuit.group}">{data.circuit.group}</a>
{/if}
</td>
<td>{data.circuit.phase ?? ''}</td>
<td>{data.circuit.type}</td>
<td>{data.circuit.sensor.type}</td>
Expand Down
19 changes: 19 additions & 0 deletions webif/src/routes/group/[group]/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script lang="ts">
import { page } from '$app/stores'
import { circuitSensorDataStore } from '$lib/stores'
import Circuits from '../../Circuits.svelte'
import { derived } from 'svelte/store'
import type { PowerSensorData } from '$lib/types'
// Create a derived store containing the sensor data for just the circuits belonging
// to the current group
const group = $page.params?.group
let groupSensorData = derived(circuitSensorDataStore, (data) => {
return data.filter((data: PowerSensorData) => data.circuit.group === group)
})
</script>

<div class="pure-u-1-1 l-box">
<h2>Group <i>{group}</i></h2>
<Circuits sensorData="{$groupSensorData}" />
</div>
98 changes: 98 additions & 0 deletions webif/src/routes/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
:root {
--background: #fff;
--color: #222;
--component-background: #e0e0e0;
--highlight-color: #ff3d00;
}

@media (prefers-color-scheme: dark) {
:root {
--background: #272727;
--color: #aaa;
--component-background: #3b3b3b;
--highlight-color: #ff3d00;
}

nav {
background-color: var(--component-background);
}

/* pure-table overrides */
.pure-table {
border: 2px solid #424242;
}

.pure-table thead {
background-color: var(--component-background);
color: var(--color);
}

.pure-table th,
.pure-table td {
border: 0;
}

.pure-table-striped tr:nth-child(2n-1) td {
background-color: #2e2e2e;
}

/* end pure-table overrides */
}

body {
background: var(--background);
color: var(--color);
}

h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: 0;
padding-bottom: 0.2em;
display: inline-block;
border-bottom: 2px solid var(--highlight-color);
}

a {
color: var(--color);
text-decoration: none;
padding-bottom: 0.2em;
border-bottom: 2px solid var(--highlight-color);
}

.container {
max-width: 1200px;
margin: 0 auto;
clear: both;
}

table {
width: 100%;
}

.cell-right-align {
text-align: right;
}

.pure-g > div {
box-sizing: border-box;
}

.l-box {
padding: 1em;
}

/* pure-menu tweaks */
.pure-menu-link {
border-bottom: 2px solid var(--component-background);
}

.pure-menu-link:hover {
border-bottom: 2px solid var(--highlight-color);
background: inherit !important;
}

/* end pure-menu tweaks */

0 comments on commit d50e3bc

Please sign in to comment.