EcoInterfaces
Die Display-Bibliothek installieren, einen DisplayInput bauen, ein Display rendern, das Stylesheet laden und den passenden Export finden.
Diese Seite ist die Anleitung zur Display-Bibliothek @ecosimlab/ecodisplays.
Sie beschreibt Installation, Eingabevertrag, Exporte und Stylesheet. Wozu die
Bibliothek gut ist, steht auf der Tool-Seite.
Alle Angaben sind aus dem Repo ecodisplays belegt, Branch main (Commit
94b20a3), Paketversion 1.0.2, neuester Tag v1.0.2. Wo README und Code
auseinanderlaufen, gilt der Code, und diese Seite benennt die Abweichung.
Die Bibliothek zeichnet Displays. Sie spricht weder mit einem Simulator noch mit einem Broker noch mit dem Netz. Die Daten bringt der Konsument mit.
Voraussetzungen
- Ein Bundler für SolidJS. Das Paket liefert übersetztes JSX als ES-Module.
Ein Vite-Projekt mit
vite-plugin-solidist der geprüfte Fall. - Drei Peer-Dependencies:
solid-js1.9,d37 undlodash4.17. Das Paket deklariert sie, installiert sie aber nicht mit. - Genau eine Kopie von
solid-jsje Seite. Zwei Kopien zerstören die Reaktivität. Den Bundler notfalls auf eine Kopie festlegen. - Node oder Bun mit einem Paketmanager für die Installation. Das Paket
deklariert kein
engines-Feld.
Installation
Das Paket liegt in keiner Registry. Es kommt aus dem öffentlichen
GitLab-Repo, festgenagelt auf einen Tag. Das gebaute dist/ liegt im Repo, die
Installation baut also nichts. Token und .npmrc sind nicht nötig.
Mit npm:
npm install gitlab:ecosimlab/ecodisplays#v1.0.2
Mit bun, als Eintrag in den Abhängigkeiten:
"dependencies": {
"@ecosimlab/ecodisplays": "git+https://gitlab.com/ecosimlab/ecodisplays.git#v1.0.2"
}
Immer genau einen Tag festnageln, nie einen Branch.
Das README nennt in beiden Beispielen noch
v0.5.0. Diepackage.jsonvonmainträgt Version 1.0.2, undv1.0.2ist der neueste Tag. Es gilt die Version im Code.
Quickstart
Das kleinste vollständige Beispiel: ein Display, eine Eingabe, ein Stylesheet.
import { createSignal } from "solid-js"
import { AP6DefaultDisplay, displayInput } from "@ecosimlab/ecodisplays"
import "@ecosimlab/ecodisplays/styles.css"
export function Screen() {
const [input] = createSignal(
displayInput({ hasSimulationData: true, speedKmh: 48, gear: "D" }),
)
return (
<div style={{ width: "640px", height: "400px" }}>
<AP6DefaultDisplay input={input()} fit="contain" />
</div>
)
}
Jedes Display nimmt dieselben zwei Props:
| Prop | Bedeutung |
|---|---|
input |
der aktuelle DisplayInput |
fit |
wie das Display seine Elternbox füllt: "contain" (Vorgabe) passt den ganzen Entwurf in die Box ein, "width" lässt die Breite führen |
InputTransparenzDisplay nimmt eine weitere Prop, vehiclesAheadMode, ohne
Vorgabe. Sie wird auf "all" oder auf "closest" gesetzt. Dasselbe Display
nimmt die optionale Prop signsMode mit der Vorgabe "list"; sie legt fest, wo
die Schilder stehen.
Paket-Exporte
Die package.json deklariert vier Einstiege.
| Einstieg | Inhalt |
|---|---|
@ecosimlab/ecodisplays |
die 20 Displays, DisplayInput, displayInput, defaultDisplayInput, VehicleProfile, InputPanel, DisplayFrame, die Design-Größen und die reinen Rechenfunktionen |
@ecosimlab/ecodisplays/input |
nur der Eingabevertrag: DisplayInput, displayInput, defaultDisplayInput, INPUT_FIELDS, deriveDisplayGate, VehicleProfile. Lädt weder SolidJS noch das DOM. |
@ecosimlab/ecodisplays/styles.css |
das Stylesheet als Datei |
@ecosimlab/ecodisplays/styles |
dasselbe Stylesheet als Strings css und fontFaceCss |
./input ist der Einstieg für einen Parser oder einen Test, der in reinem Node
oder Bun laufen muss.
Der Eingabevertrag
DisplayInput ist ein flaches Objekt mit 31 Feldern. Die Bibliothek prüft zur
Laufzeit keinen Wert. Der Vertrag ist der Typ, die Prüfung gehört an die Grenze
des Konsumenten.
Eine Eingabe baut displayInput(partial). Jedes ausgelassene Feld kommt aus
defaultDisplayInput:
import { type DisplayInput, displayInput } from "@ecosimlab/ecodisplays/input"
const input: DisplayInput = displayInput({
hasSimulationData: true,
hasEnergyData: true,
timeS: 12.5,
wheelspeedMps: 13.3,
batterySocPercent: 72,
})
Die Einheit steht im Namen
Jeder Feldname endet auf seine Einheit.
| Endung | Bedeutung |
|---|---|
Percent |
0 bis 100 |
S |
Sekunden |
M |
Meter |
Mps |
Meter je Sekunde |
Kmh |
Kilometer je Stunde |
W, Kw, Kwh |
Watt, Kilowatt, Kilowattstunden |
Die Felder
| Feld | Einheit | Vorgabe | Bedeutung |
|---|---|---|---|
hasSimulationData |
Flag | false |
false, solange keine gültige Nachricht ankam. Den Zustand „keine Daten“ zeichnet der Konsument. |
hasEnergyData |
Flag | false |
false, wenn der Tick keine Fahrzeugmodell-Daten trägt |
timeS |
s | 0 |
Zeit seit Beginn der Fahrt. Ein kleinerer Wert als zuvor gilt als neue Fahrt und setzt die Akkumulatoren zurück. |
distanceM |
m | 0 |
absolut zurückgelegte Strecke |
wheelspeedMps |
m/s | 0 |
Radgeschwindigkeit, ungeglättet. Grundlage der Rechnung. |
speedKmh |
km/h | 0 |
geglättete Geschwindigkeit für die Anzeige |
gear |
— | "P" |
"P", "R", "N", "D" oder eine Gangzahl |
batteryEnergyKwh |
kWh | 0 |
Energie in der Batterie. Aus ihrer Abnahme kommen Verbrauch und Reichweite. |
batterySocPercent |
% | 0 |
Ladestand der Batterie |
pBatteryKw |
kW | 0 |
aktuelle Batterieleistung, negativ beim Rekuperieren |
pAeroW, pRollW, pUpW, pPowertrainLossW, pHydraulicW |
W | 0 |
die Leistungsanteile: Luftwiderstand, Rollwiderstand, Steigung, Antriebsstrang-Verlust, hydraulische Bremse |
optimalSpeedKmh |
km/h | 0 |
vom Optimierer empfohlene Geschwindigkeit. 0 heißt „keine Empfehlung“. |
optimalPowerW |
W | 0 |
vom Optimierer empfohlene Batterieleistung |
referenceSpeedLine |
Liste | [] |
Referenzgeschwindigkeit aus der Offline-Optimierung. Leer heißt „keine Referenz“. |
mpcSpeedLine |
Liste | [] |
Geschwindigkeitsprognose des MPC über die Strecke |
mpcPowerLine, mpcPowerLineTime |
Liste | [] |
Leistungsprognose des MPC, über die Strecke und über die Zeit |
mpcStateMachineState |
— | null |
Zustand der MPC-Zustandsmaschine. null zeigt nichts. |
vehiclesAhead |
Liste | [] |
die Fahrzeuge voraus auf der eigenen Spur, nach Abstand sortiert |
speedLimitKmh |
km/h | 0 |
geltendes Tempolimit. 0 heißt „unbekannt“. |
nextSpeedLimitKmh |
km/h | null |
Tempolimit des nächsten Schilds voraus |
nextSpeedLimitDistanceM |
m | null |
Abstand bis zum nächsten Tempolimit-Schild |
trafficLightsAhead |
Liste | [] |
Ampeln und Stoppschilder voraus, nach Abstand sortiert |
stopDistanceBrakeM, stopDistanceStrongRecuperationM, stopDistanceLightRecuperationM, stopDistanceCoastingM |
m | null |
die vier Haltepunkte des Kinetic Beam, je Bremsart einer |
INPUT_FIELDS trägt dieselbe Tabelle im Code: Einheit, Bereich und Schrittweite
je Feld. Daraus lässt sich ein Regler-Panel bauen, oder man liest sie als
Beleg für einen plausiblen Wert.
Die Displays
Die Export-Namen stammen aus den Arbeitspaketen des Projekts, nicht aus der Funktion. Die Spalte „zeigt“ sagt, was zu erwarten ist.
| Familie | Export | Zeigt |
|---|---|---|
AP4 |
AP4ConsumptionDisplay |
eine bildfüllende Straße mit dem Verbrauch der letzten 150 m als Spur |
AP4 |
AP4VelocityDisplay |
dieselbe Straße, mit der gefahrenen Geschwindigkeit gegen die Linie des Optimierers |
AP5 |
AP5BaselineDisplay |
Geschwindigkeit, Gang, Ladestand und Verbrauch, dazu ein hoher Leistungsbalken |
AP5 |
AP5BoxDisplay |
graue Kästen in den Größen der AP5-Teile: eine Layout-Vorlage, und das einzige Display ohne Eingabe |
AP5 |
AP5ComperatorDisplay |
das Leistungsbalken-Feld, dazu den Energie-Score als Balken |
AP5 |
AP5DecisionDisplay |
das Leistungsbalken-Feld, mit einer Marke für die empfohlene Leistung |
AP5 |
AP5DecisionSpeedDisplay |
einen Geschwindigkeitsbalken mit je einer Marke für aktuelle und empfohlene Geschwindigkeit |
AP5 |
AP5InputDisplay |
den Leistungsbalken geteilt in Steigung, Luftwiderstand, Rollwiderstand, Antriebsstrang-Verlust und Bremse |
AP5 |
AP5SpeedometerDisplay |
Geschwindigkeit und Gang vor einem großen Bogen |
AP6 |
AP6DefaultDisplay |
nur Geschwindigkeit und Gang, in der Größe ihres Inhalts |
AP6 |
AP6StatusQuoDisplay |
ein Tacho-Feld mit zweiteiligem Balken, gefüllt nach dem Anteil an der Höchstleistung |
AP6 |
AP6VariationDisplay |
denselben zweiteiligen Balken, gefüllt nach dem Verbrauch je Strecke |
LEM |
LEMDisplay |
Leistung gegen empfohlene Leistung über 150 m zurück und voraus |
LEM |
LEMTimeDisplay |
dieselbe Leistungskurve über 20 Sekunden zurück und voraus |
LEM |
LEMVelocityTimeDisplay |
Geschwindigkeit über 20 Sekunden zurück und voraus, mit Prognose und Referenzlinie |
LEM |
LEMDecisionDisplay |
ein AP5-Feld mit farbiger Zielgeschwindigkeit, daneben einen Leistungsbalken mit Bremsanteil |
InputTransparenz |
InputTransparenzDisplay |
die Strecke voraus mit Fahrzeugen, dem nächsten Tempo-Schild und der nächsten Ampel |
EnergyScore |
EnergyScoreBarDisplay |
ein kleines Feld über dem Video: Geschwindigkeit, Gang und Ladestand neben einem grünen Effizienz-Balken |
EnergyScore |
EnergyScoreGlyphDisplay |
dasselbe kleine Feld, mit einem Smiley statt des Balkens |
EnergyScore |
MinimalGaugeDisplay |
nur Geschwindigkeit und Gang, klein gezeichnet |
Zwei Namen führen in die Irre. LEMDecisionDisplay ist ein AP5-Feld mit
LEM-Namen und liest die AP5-Felder. MinimalGaugeDisplay steht in der
EnergyScore-Familie, rechnet aber wie AP6.
Fahrzeugprofil
Die Displays skalieren die Eingabe gegen ein Fahrzeug. Jedes Display, dessen
Rechnung davon abhängt, nimmt die optionale Prop vehicle. Ohne die Prop gilt
defaultVehicleProfile mit den Werten des Simulator-Pkw.
import { AP6DefaultDisplay, defaultVehicleProfile } from "@ecosimlab/ecodisplays"
const smallCar = { ...defaultVehicleProfile, maxPowerKw: 80, batteryCapacityKwh: 22 }
| Feld | Einheit | Was es skaliert |
|---|---|---|
maxPowerKw |
kW | den Leistungsbalken |
batteryCapacityKwh |
kWh | den Ladestand in Prozent (LEM) |
rangeAtFullBatteryKm |
km | die Reichweite, die LEM zeigt |
consumptionMaxKwh, consumptionMinKwh |
kWh | oberes und unteres Ende des Verbrauchsbalkens |
defaultConsumptionKwhPer100Km |
kWh/100 km | den Ersatzverbrauch, solange der gemessene noch 0 ist |
scorePowerMaxKw |
kW | wie stark eine Abweichung von der Empfehlung den Energie-Score senkt |
Die AP4-Displays zeichnen die rohe Spur und nehmen kein Profil.
Stylesheet
Das Paket liefert sein CSS zweimal. Der Text ist in beiden Fällen derselbe.
Als Datei, wenn der Build CSS bündelt:
import "@ecosimlab/ecodisplays/styles.css"
Als String, wenn er das nicht tut — etwa bei einem Bundle aus einer Datei:
import { css, fontFaceCss } from "@ecosimlab/ecodisplays/styles"
const style = document.createElement("style")
style.textContent = css
document.head.append(style)
Wird ein Display in einem Shadow Root gezeichnet, gehört fontFaceCss
zusätzlich ins Dokument. Der Browser liest @font-face nur aus dem Dokument,
nie aus einem Shadow Root. Ohne diesen Schritt fallen die Displays auf eine
Systemschrift zurück.
Das Stylesheet enthält keinen globalen CSS-Reset. Es lässt die Seite um sich herum unberührt. Wer einen Reset braucht, lädt ihn selbst.
Die Schrift ist Inter, unter der SIL Open Font License 1.1. Die Schriftdateien liegen als woff2 im Paket, eingebettet ins CSS als Data-URI. Zur Laufzeit lädt nichts aus dem Netz.
Entwicklung & Tests
Das Repo klonen und mit bun installieren. Die Skripte der package.json:
| Befehl | Wirkung |
|---|---|
bun run dev |
startet das Showcase: jedes Display mit einer erfundenen Fahrt, eine Seite je Display |
bun run build |
schreibt dist/ neu |
bun run test |
führt die Tests mit bun test --conditions browser aus |
bun run typecheck |
prüft Quelle und Tests mit tsc --noEmit |
bun run lint |
prüft src/ mit Biome |
bun run check |
baut erneut und schlägt fehl, wenn dist/ nicht zur Quelle passt oder die Version nicht zum Tag |
Ein Release ist ein Commit mit neuer Version, passendem dist/ und einem Tag.
Es gibt keinen Publish-Schritt und keine Registry.
Lizenz & Zitation
MIT. Die Datei LICENSE trägt den Text, AUTHORS nennt die Personen hinter dem
Code, und ASSETS.md listet jedes Bild und jede Schrift mit Quelle und Lizenz.
Zitiert wird die Bibliothek in Version 1.0.2, Tag v1.0.2.
Offene Punkte
- Das README nennt in seinen Installationsbeispielen noch
v0.5.0, neuester Tag istv1.0.2. Das README ist an dieser Stelle veraltet.- Die Konsumenten
videosimlab-cockpit-replayundvideosimlab-templatenagelnv1.0.1fest, einen Tag hinter der Bibliothek.- Die Prop
kineticBeamvonInputTransparenzDisplayzeichnet die vier Haltepunkte auf die Fahrbahn. Die Quelle nennt sie einen Versuch, noch keine Studienbedingung. Vorgabe ist aus.