mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-01-12 00:02:53 +00:00
Added norwegian as a option for language
This commit is contained in:
parent
068f5e4d46
commit
fcb678013b
122
README.md
122
README.md
@ -8,41 +8,6 @@ Later development have added Energy usage graph for both day and month, as well
|
||||
|
||||
Go to the [WiKi](https://github.com/UtilitechAS/amsreader-firmware/wiki) for information on how to get your own device! And find the latest prebuilt firmware file at the [release section](https://github.com/UtilitechAS/amsreader-firmware/releases).
|
||||
|
||||
## OTA updates from GitHub releases
|
||||
|
||||
The firmware now supports downloading updates straight from GitHub Pages using a
|
||||
lightweight manifest file. Each time you push a tag like `v1.2.3`, the
|
||||
`.github/workflows/release.yml` pipeline will:
|
||||
|
||||
1. Build every supported PlatformIO environment and publish `.bin`/`.zip`
|
||||
assets on the release page (existing behaviour).
|
||||
2. Run `scripts/package_firmware.py` to assemble a static structure under
|
||||
`dist/firmware/<chip>/<channel>/` with the firmware binary, an MD5 checksum,
|
||||
and a `manifest.json` pointing at the binary.
|
||||
3. Deploy the contents of `dist/` to GitHub Pages, yielding public URLs such as
|
||||
`https://<your-user>.github.io/neas-amsreader-firmware-test/firmware/esp32s2/stable/manifest.json`.
|
||||
|
||||
> ℹ️ Make sure GitHub Pages for the repository is configured to "GitHub
|
||||
> Actions" under *Settings → Pages* the first time you run the workflow.
|
||||
|
||||
To make the device follow those releases, set the default OTA endpoint before
|
||||
flashing:
|
||||
|
||||
```cpp
|
||||
#define FIRMWARE_UPDATE_BASE_URL "https://<your-user>.github.io/neas-amsreader-firmware-test"
|
||||
#define FIRMWARE_UPDATE_CHANNEL "stable"
|
||||
```
|
||||
|
||||
You can override the defaults either by editing
|
||||
`lib/AmsFirmwareUpdater/include/UpgradeDefaults.h` or by adding corresponding
|
||||
`-D` flags in `platformio.ini`. When a release is available, the device fetches
|
||||
`manifest.json`, compares the `version` against its current firmware, and then
|
||||
downloads the referenced binary in chunks.
|
||||
|
||||
If you need parallel release tracks (for example `beta` versus `stable`), pass
|
||||
`--channel beta` to `package_firmware.py` inside your automation and override
|
||||
`FIRMWARE_UPDATE_CHANNEL` for the devices you want on that track.
|
||||
|
||||
## Building this project with PlatformIO
|
||||
To build this project, you need [PlatformIO](https://platformio.org/) installed.
|
||||
|
||||
@ -54,39 +19,6 @@ It is recommended to use Visual Studio Code with the PlatformIO plugin for devel
|
||||
|
||||
For development purposes, copy the ```platformio-user.ini-example``` to ```platformio-user.ini``` and customize to your preference. The code will adapt to the platform and board set in your profile.
|
||||
|
||||
### Running builds on macOS Apple Silicon
|
||||
|
||||
The ESP8266 and ESP32-C3 toolchains bundled with the custom Tasmota platform
|
||||
are still compiled for Intel macOS. To keep `pio run` working without forcing
|
||||
you to remember `arch -x86_64`, the repository now ships a tiny wrapper:
|
||||
|
||||
```bash
|
||||
./scripts/pio-run.sh run # build every default environment (all boards)
|
||||
./scripts/pio-run.sh run -e esp8266 # build a specific environment only
|
||||
```
|
||||
|
||||
The script automatically re-launches PlatformIO under Rosetta 2 when you are on
|
||||
an Apple Silicon Mac. On first run it also provisions a dedicated x86 Python
|
||||
virtual environment in `~/.platformio/penv-x86` and installs PlatformIO inside
|
||||
it, so expect an extra minute for the initial setup. If Rosetta is missing you
|
||||
will see a friendly reminder to install it with
|
||||
`softwareupdate --install-rosetta --agree-to-license`.
|
||||
|
||||
If you prefer using npm scripts, the same wrapper is available through:
|
||||
|
||||
```bash
|
||||
npm run pio:run # builds every configured board
|
||||
npm run pio:run:env -- esp32c3 # pass any PlatformIO environment name
|
||||
```
|
||||
|
||||
> **Heads-up:** invoking `pio run` directly on an Apple Silicon Mac will still
|
||||
> fail for the ESP8266/ESP32-C3 environments unless you prefix it with
|
||||
> `arch -x86_64`. Using `scripts/pio-run.sh` (or the npm aliases) keeps the
|
||||
> command portable across macOS and Linux without special flags.
|
||||
|
||||
> The first macOS run may print `NotOpenSSLWarning` from `urllib3`; this comes
|
||||
> from Apple's LibreSSL build and can safely be ignored for local development.
|
||||
|
||||
## Licensing
|
||||
Initially, this project began as a hobby, consuming countless hours of our spare time. However, the time required to support this project has expanded beyond the scope of a hobby. As a result, we established ‘Utilitech’, a company dedicated to maintaining the software and hardware for this project as part of our regular work.
|
||||
|
||||
@ -96,59 +28,7 @@ For more information, please refer to our [LICENSE](/LICENSE) file.
|
||||
|
||||
If your usage falls outside the scope of this license and you require a separate license, please contact us at [post@utilitech.no](mailto:post@utilitech.no) for further details.
|
||||
|
||||
|
||||
## MQTT auto-provisioning defaults
|
||||
If you want devices to connect to a known MQTT broker immediately after flashing, keep credentials in a local `.env` file rather than committing them:
|
||||
|
||||
1. Copy `.env.example` to `.env` and fill in the MQTT values (host, port, username/password, client ID, topics, etc.).
|
||||
2. Commit the `.env.example` changes only—`.env` is ignored so secrets stay local.
|
||||
3. Build the firmware; the PlatformIO pre-build hook injects these values so the device boots with your broker settings.
|
||||
|
||||
Any field you leave empty will fall back to the defaults in `lib/AmsConfiguration/include/MqttDefaults.h`, meaning the web UI will prompt for credentials during first-time setup.
|
||||
|
||||
### Shipping credentials with GitHub releases (without committing secrets)
|
||||
|
||||
The OTA manifest generated by `scripts/package_firmware.py` now carries an
|
||||
optional `mqtt` block. If the build machine provides values for
|
||||
`MQTT_DEFAULT_*` (through environment variables or a `.env` file), the script
|
||||
embeds those defaults alongside the firmware checksum. Devices that upgrade via
|
||||
GitHub Pages will download the manifest, detect the `mqtt` section, and apply
|
||||
the broker settings automatically—unless the installer has already customised
|
||||
the device through the web UI.
|
||||
|
||||
To keep secrets out of source control while still provisioning releases:
|
||||
|
||||
1. Store your broker credentials as GitHub Action secrets (for example
|
||||
`MQTT_DEFAULT_USERNAME`, `MQTT_DEFAULT_PASSWORD`, etc.).
|
||||
2. In the release workflow, write a temporary `.env` file before invoking the
|
||||
PlatformIO build:
|
||||
|
||||
```yaml
|
||||
- name: Write MQTT defaults
|
||||
run: |
|
||||
cat <<'EOF' > .env
|
||||
MQTT_DEFAULT_HOST=${{ secrets.MQTT_DEFAULT_HOST }}
|
||||
MQTT_DEFAULT_PORT=${{ secrets.MQTT_DEFAULT_PORT }}
|
||||
MQTT_DEFAULT_USERNAME=${{ secrets.MQTT_DEFAULT_USERNAME }}
|
||||
MQTT_DEFAULT_PASSWORD=${{ secrets.MQTT_DEFAULT_PASSWORD }}
|
||||
MQTT_DEFAULT_CLIENT_ID=${{ secrets.MQTT_DEFAULT_CLIENT_ID }}
|
||||
MQTT_DEFAULT_PUBLISH_TOPIC=${{ secrets.MQTT_DEFAULT_PUBLISH_TOPIC }}
|
||||
MQTT_DEFAULT_SUBSCRIBE_TOPIC=${{ secrets.MQTT_DEFAULT_SUBSCRIBE_TOPIC }}
|
||||
EOF
|
||||
```
|
||||
|
||||
3. Build the firmware and run `scripts/package_firmware.py` as usual; the
|
||||
generated `manifest.json` will include the broker defaults.
|
||||
4. Upload `dist/` to GitHub Pages (the existing release workflow already covers
|
||||
this), so devices retrieving the manifest can bootstrap the MQTT connection
|
||||
immediately after flashing.
|
||||
|
||||
Because the `.env` file is created on-the-fly inside CI and never committed,
|
||||
your credentials remain private while every release published to GitHub ships
|
||||
with working MQTT settings out of the box.
|
||||
|
||||
|
||||
# How to wipe bricked board?
|
||||
# How to wipe bricked firmware?
|
||||
|
||||
To wipe the board you need to set it in USB mode. Connect the board to a usb board on you computor, hold AP/Prog button and shortly click reset before letting go of AP/Prog. To check if device is in usb mode you can check connections on this [site](https://www.amsleser.cloud/flasher)
|
||||
|
||||
|
||||
14
lib/SvelteUi/app/dist/index.js
vendored
14
lib/SvelteUi/app/dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -2,7 +2,7 @@
|
||||
import { getConfiguration, configurationStore } from './ConfigurationStore'
|
||||
import { sysinfoStore, networksStore } from './DataStores.js';
|
||||
import fetchWithTimeout from './fetchWithTimeout';
|
||||
import { translationsStore } from './TranslationService';
|
||||
import { translationsStore, getTranslations } from './TranslationService';
|
||||
import { wiki, ipPattern, asciiPattern, asciiPatternExt, charAndNumPattern, hexPattern, numPattern, wifiStateFromRssi } from './Helpers.js';
|
||||
import UartSelectOptions from './UartSelectOptions.svelte';
|
||||
import Mask from './Mask.svelte'
|
||||
@ -94,7 +94,11 @@
|
||||
cloudenabled = update?.c?.e;
|
||||
configuration = update;
|
||||
loading = false;
|
||||
languages = [{ code: 'en', name: 'English'}];
|
||||
const hubLabel = translations.consent?.load_from_server ?? 'Load from server';
|
||||
languages = [
|
||||
{ code: 'en', name: 'English'},
|
||||
{ code: 'no', name: 'Norsk'}
|
||||
];
|
||||
if(!configuration?.fw) {
|
||||
configuration = {
|
||||
...configuration,
|
||||
@ -111,14 +115,27 @@
|
||||
e: Number(configuration.fw.e ?? 3)
|
||||
};
|
||||
}
|
||||
if(configuration?.u?.lang && configuration.u.lang != 'en') {
|
||||
if(configuration?.u?.lang && !languages.find(lang => lang.code === configuration.u.lang)) {
|
||||
languages.push({ code: configuration.u.lang, name: translations.language?.name ?? "Unknown"})
|
||||
}
|
||||
languages.push({ code: 'hub', name: 'Load from server'})
|
||||
languages.push({ code: 'hub', name: hubLabel })
|
||||
}
|
||||
});
|
||||
getConfiguration();
|
||||
|
||||
$: if(languages.length) {
|
||||
const hubLabel = translations.consent?.load_from_server ?? 'Load from server';
|
||||
const hasHub = languages.some(lang => lang.code === 'hub');
|
||||
if(!hasHub) {
|
||||
languages = [...languages, { code: 'hub', name: hubLabel }];
|
||||
} else {
|
||||
const needsUpdate = languages.find(lang => lang.code === 'hub' && lang.name !== hubLabel);
|
||||
if(needsUpdate) {
|
||||
languages = languages.map(lang => lang.code === 'hub' ? { ...lang, name: hubLabel } : lang);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let manual = true;
|
||||
let networks = {};
|
||||
let networkSignalInfos = [];
|
||||
@ -253,6 +270,11 @@
|
||||
const response = await fetchWithTimeout("http://hub.amsleser.no/hub/language/list.json");
|
||||
languages = (await response.json())
|
||||
configuration.u.lang = translations.language.code;
|
||||
return;
|
||||
}
|
||||
|
||||
if(configuration.u.lang) {
|
||||
await getTranslations(configuration.u.lang);
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,6 +351,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-1">
|
||||
{translations.conf?.general?.language ?? translations.conf?.ui?.lang ?? "Language"}<br/>
|
||||
<select name="ulang" class="in-s" bind:value={configuration.u.lang} on:change={languageChanged}>
|
||||
{#each languages as lang}
|
||||
<option value={lang.code}>{lang.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<input type="hidden" name="p" value="true"/>
|
||||
<div class="my-1">
|
||||
<div class="flex">
|
||||
@ -914,14 +944,6 @@
|
||||
</select>
|
||||
</div>
|
||||
{/each}
|
||||
<div class="w-1/2">
|
||||
{translations.conf?.ui?.lang ?? "Language"}
|
||||
<select name="ulang" class="in-s" bind:value={configuration.u.lang} on:change={languageChanged}>
|
||||
{#each languages as lang}
|
||||
<option value={lang.code}>{lang.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
<script>
|
||||
import { sysinfoStore } from './DataStores.js';
|
||||
import { translationsStore } from './TranslationService.js';
|
||||
import { translationsStore, getTranslations } from './TranslationService.js';
|
||||
import fetchWithTimeout from './fetchWithTimeout';
|
||||
import Mask from './Mask.svelte'
|
||||
import { navigate } from 'svelte-navigator';
|
||||
import { wiki } from './Helpers';
|
||||
@ -16,8 +17,17 @@
|
||||
let loadingOrSaving = false;
|
||||
let consentChoice = '';
|
||||
let autoUpdateChoice = '';
|
||||
let languageChoice = '';
|
||||
let languages = [
|
||||
{ code: 'en', name: 'English' },
|
||||
{ code: 'no', name: 'Norsk' }
|
||||
];
|
||||
let canSave = false;
|
||||
|
||||
$: if (translations?.language?.code && !languages.find(lang => lang.code === translations.language.code)) {
|
||||
languages = [...languages, { code: translations.language.code, name: translations.language.name ?? translations.language.code }];
|
||||
}
|
||||
|
||||
$: if (sysinfo) {
|
||||
if (sysinfo.fwconsent === 1 || sysinfo.fwconsent === 2) {
|
||||
consentChoice = String(sysinfo.fwconsent);
|
||||
@ -28,10 +38,43 @@
|
||||
} else if (autoFlag === false) {
|
||||
autoUpdateChoice = 'false';
|
||||
}
|
||||
const sysLang = sysinfo?.ui?.lang;
|
||||
if (sysLang && !languages.find(lang => lang.code === sysLang)) {
|
||||
languages = [...languages, { code: sysLang, name: translations.language?.name ?? sysLang.toUpperCase() }];
|
||||
}
|
||||
if (!languageChoice && sysLang) {
|
||||
languageChoice = sysLang;
|
||||
}
|
||||
}
|
||||
|
||||
$: {
|
||||
if (!languageChoice && translations?.language?.code) {
|
||||
languageChoice = translations.language.code;
|
||||
}
|
||||
}
|
||||
|
||||
$: canSave = consentChoice !== '' && autoUpdateChoice !== '' && !loadingOrSaving;
|
||||
|
||||
async function handleLanguageChange(e) {
|
||||
const selected = e.target.value;
|
||||
if (selected === 'hub') {
|
||||
try {
|
||||
const response = await fetchWithTimeout('http://hub.amsleser.no/hub/language/list.json');
|
||||
languages = await response.json();
|
||||
languageChoice = translations.language.code;
|
||||
} catch (err) {
|
||||
console.error('Failed to load languages from hub', err);
|
||||
languageChoice = translations.language.code;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
languageChoice = selected;
|
||||
if (languageChoice) {
|
||||
await getTranslations(languageChoice);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmit(e) {
|
||||
loadingOrSaving = true;
|
||||
const formData = new FormData(e.target)
|
||||
@ -54,6 +97,12 @@
|
||||
|
||||
sysinfoStore.update(s => {
|
||||
s.fwconsent = consentValue === '1' ? 1 : consentValue === '2' ? 2 : 0;
|
||||
if (!s.ui || typeof s.ui !== 'object') {
|
||||
s.ui = {};
|
||||
}
|
||||
if (languageChoice) {
|
||||
s.ui.lang = languageChoice;
|
||||
}
|
||||
if (!s.upgrade || typeof s.upgrade !== 'object') {
|
||||
s.upgrade = {};
|
||||
}
|
||||
@ -86,6 +135,15 @@
|
||||
<label><input type="radio" name="fwa" value="true" bind:group={autoUpdateChoice} class="rounded m-2" required/> {translations.consent?.yes ?? "Yes"}</label>
|
||||
<label><input type="radio" name="fwa" value="false" bind:group={autoUpdateChoice} class="rounded m-2" required/> {translations.consent?.no ?? "No"}</label><br/>
|
||||
</div>
|
||||
<div class="my-3">
|
||||
{translations.consent?.language ?? "Language"}<br/>
|
||||
<select name="ulang" class="in-s" bind:value={languageChoice} on:change={handleLanguageChange}>
|
||||
{#each languages as lang}
|
||||
<option value={lang.code}>{lang.name}</option>
|
||||
{/each}
|
||||
<option value="hub">{translations.consent?.load_from_server ?? "Load from server"}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="my-3">
|
||||
<button type="submit" class="btn-pri" disabled={!canSave}>{translations.btn?.save ?? "Save"}</button>
|
||||
</div>
|
||||
|
||||
@ -204,11 +204,6 @@
|
||||
</div>
|
||||
{/if}
|
||||
<div>
|
||||
<div class="my-3">
|
||||
{translations.consent?.auto_update ?? "Automatic firmware updates"}<br/>
|
||||
<label><input type="radio" name="fwa" value="true" bind:group={autoUpdateChoice} class="rounded m-2"/> {translations.consent?.yes ?? "Yes"}</label>
|
||||
<label><input type="radio" name="fwa" value="false" bind:group={autoUpdateChoice} class="rounded m-2"/> {translations.consent?.no ?? "No"}</label>
|
||||
</div>
|
||||
{translations.conf?.general?.hostname ?? "Hostname"}
|
||||
<input name="sh" bind:value={sysinfo.hostname} type="text" class="in-s" maxlength="32" pattern={charAndNumPattern} placeholder="Optional, ex.: ams-reader" autocomplete="off"/>
|
||||
</div>
|
||||
|
||||
413
lib/SvelteUi/app/translations-no.json
Normal file
413
lib/SvelteUi/app/translations-no.json
Normal file
@ -0,0 +1,413 @@
|
||||
{
|
||||
"language": {
|
||||
"code": "no",
|
||||
"name": "Norsk"
|
||||
},
|
||||
"common": {
|
||||
"import": "Import",
|
||||
"export": "Eksport",
|
||||
"voltage": "Spenning",
|
||||
"amperage": "Strøm",
|
||||
"seconds": "sekunder",
|
||||
"minute": "minutt",
|
||||
"minutes": "minutter",
|
||||
"hour": "time",
|
||||
"hours": "timer",
|
||||
"day": "dag",
|
||||
"days": "dager",
|
||||
"month": "måned",
|
||||
"unknown": "Ukjent"
|
||||
},
|
||||
"btn": {
|
||||
"reboot": "Start på nytt",
|
||||
"save": "Lagre",
|
||||
"upload": "Last opp"
|
||||
},
|
||||
"header": {
|
||||
"mem": "Ledig minne",
|
||||
"price": "Pristjeneste",
|
||||
"booting": "Starter",
|
||||
"config": "Konfigurasjon",
|
||||
"status": "Enhetsinformasjon",
|
||||
"doc": "Dokumentasjon",
|
||||
"new_version": "Ny versjon",
|
||||
"upgrade": "Vil du oppgradere denne enheten til {0}?",
|
||||
"uptime": "Oppetid"
|
||||
},
|
||||
"dashboard": {
|
||||
"phase": "Faseeffekt",
|
||||
"pf": "Effektfaktor",
|
||||
"tariffpeak": "Topper for nettleie",
|
||||
"realtime": "Sanntidsgraf",
|
||||
"price": "Fremtidig energipris",
|
||||
"day": "Energibruk siste 24 timer",
|
||||
"month": "Energibruk siste {0} dager",
|
||||
"temperature": "Temperaturfølere"
|
||||
},
|
||||
"reactive": {
|
||||
"title": "Reaktiv",
|
||||
"instant_in": "Øyeblikk inn",
|
||||
"instant_out": "Øyeblikk ut",
|
||||
"total_in": "Total inn",
|
||||
"total_out": "Total ut"
|
||||
},
|
||||
"realtime": {
|
||||
"title": "Sanntidsberegninger",
|
||||
"consumption": "Forbruk",
|
||||
"cost": "Kostnad",
|
||||
"last_month": "Forrige måned",
|
||||
"last_mo": "Forr. mnd."
|
||||
},
|
||||
"status": {
|
||||
"device": {
|
||||
"title": "Enhetsinformasjon",
|
||||
"chip": "Brikke",
|
||||
"device": "Enhet",
|
||||
"mac": "MAC",
|
||||
"apmac": "AP-MAC",
|
||||
"last_boot": "Siste oppstart",
|
||||
"reason": "Årsak",
|
||||
"btn_consents": "Oppdater samtykker",
|
||||
"reboot_confirm": "Er du sikker på at du vil starte enheten på nytt"
|
||||
},
|
||||
"meter": {
|
||||
"title": "Måler",
|
||||
"manufacturer": "Produsent",
|
||||
"model": "Modell",
|
||||
"id": "ID"
|
||||
},
|
||||
"network": {
|
||||
"title": "Nettverk"
|
||||
},
|
||||
"firmware": {
|
||||
"title": "Fastvare",
|
||||
"installed": "Installert versjon",
|
||||
"latest": "Nyeste versjon",
|
||||
"install": "Installer denne versjonen",
|
||||
"failed": "Forrige oppgradering fra {0} til {1} mislyktes",
|
||||
"btn_select_file": "Velg fastvarefil for oppgradering",
|
||||
"no_one_click": "Du har deaktivert ett-klikks oppgradering, lenken for egen oppgradering er deaktivert"
|
||||
},
|
||||
"backup": {
|
||||
"title": "Sikkerhetskopi og gjenoppretting",
|
||||
"iw": "WiFi",
|
||||
"im": "MQTT",
|
||||
"ie": "Web",
|
||||
"it": "Måler",
|
||||
"ih": "Grenser",
|
||||
"ig": "GPIO",
|
||||
"in": "NTP",
|
||||
"is": "Pris-API",
|
||||
"secrets": "Ta med hemmeligheter",
|
||||
"secrets_desc": "(SSID, PSK, passord og token)",
|
||||
"btn_select_file": "Velg fil...",
|
||||
"btn_download": "Last ned"
|
||||
},
|
||||
"mask": {
|
||||
"firmware": "Laster opp fastvare, vennligst vent",
|
||||
"config": "Laster opp konfigurasjon, vennligst vent"
|
||||
}
|
||||
},
|
||||
"conf": {
|
||||
"general": {
|
||||
"title": "Generelt",
|
||||
"hostname": "Vertsnavn",
|
||||
"timezone": "Tidssone",
|
||||
"security": {
|
||||
"title": "Sikkerhet",
|
||||
"none": "Ingen",
|
||||
"conf": "Kun konfigurasjon",
|
||||
"all": "Alt"
|
||||
},
|
||||
"context": "Kontekst",
|
||||
"context_placeholder": "[rot]"
|
||||
},
|
||||
"price": {
|
||||
"title": "Priskonfigurasjon",
|
||||
"region": "Prisområde",
|
||||
"currency": "Valuta",
|
||||
"conf": "Konfigurer pris",
|
||||
"enabled": "Aktiver pris fra ekstern server",
|
||||
"api_key_placeholder": "ENTSO-E API-nøkkel, valgfritt, se dokumentasjon",
|
||||
"both": "Begge",
|
||||
"fixed": "Fast",
|
||||
"btn_add": "Legg til",
|
||||
"mask_loading": "Laster priskonfigurasjon",
|
||||
"mask_saving": "Lagrer priskonfigurasjon"
|
||||
},
|
||||
"meter": {
|
||||
"title": "Måler",
|
||||
"comm": {
|
||||
"title": "Kommunikasjon",
|
||||
"passive": "Passiv (push)",
|
||||
"pulse": "Puls"
|
||||
},
|
||||
"serial": "Seriell konf.",
|
||||
"inverted": "invertert",
|
||||
"buffer": "Bufferstørrelse",
|
||||
"pulses": "Pulser per kWh",
|
||||
"voltage": "Spenning",
|
||||
"fuse": "Hovedsikring",
|
||||
"prod": "Produksjon",
|
||||
"encrypted": "Måleren er kryptert",
|
||||
"authkey": "Autentiseringsnøkkel",
|
||||
"multipliers": {
|
||||
"title": "Multiplikatorer",
|
||||
"watt": "Watt",
|
||||
"volt": "Volt",
|
||||
"amp": "Ampere",
|
||||
"kwh": "kWh"
|
||||
}
|
||||
},
|
||||
"connection": {
|
||||
"title": "Tilkobling",
|
||||
"wifi": "Koble til WiFi",
|
||||
"ap": "Eget aksesspunkt",
|
||||
"eth": "Ethernet",
|
||||
"ssid": "SSID",
|
||||
"psk": "Passord",
|
||||
"ps": {
|
||||
"title": "Strømsparing",
|
||||
"default": "Standard",
|
||||
"off": "Av",
|
||||
"min": "Minimal",
|
||||
"max": "Maksimal"
|
||||
},
|
||||
"pwr": "Effekt",
|
||||
"tick_11b": "Tillat 802.11b-hastigheter"
|
||||
},
|
||||
"network": {
|
||||
"title": "Nettverk",
|
||||
"ip": "IP",
|
||||
"static": "Statisk",
|
||||
"dhcp": "DHCP",
|
||||
"gw": "Gateway",
|
||||
"dns": "DNS",
|
||||
"tick_mdns": "aktiver mDNS",
|
||||
"ntp": "NTP",
|
||||
"tick_ntp_dhcp": "hent fra DHCP"
|
||||
},
|
||||
"mqtt": {
|
||||
"title": "MQTT",
|
||||
"server": "Server",
|
||||
"user": "Brukernavn",
|
||||
"pass": "Passord",
|
||||
"id": "Klient-ID",
|
||||
"payload": "Payload",
|
||||
"publish": "Publiserings-emne",
|
||||
"btn_ca_upload": "Last opp CA",
|
||||
"btn_crt_upload": "Last opp sertifikat",
|
||||
"btn_key_upload": "Last opp nøkkel",
|
||||
"ca_ok": "CA ok",
|
||||
"crt_ok": "Sertifikat ok",
|
||||
"key_ok": "Nøkkel ok",
|
||||
"title_ca": "Klikk her for å laste opp CA",
|
||||
"title_crt": "Klikk her for å laste opp sertifikat",
|
||||
"title_key": "Klikk her for å laste opp privat nøkkel",
|
||||
"domoticz": {
|
||||
"title": "Domoticz",
|
||||
"eidx": "Strøm-IDX",
|
||||
"cidx": "Strøm-IDX",
|
||||
"vidx": "Spenning-IDX"
|
||||
},
|
||||
"ha": {
|
||||
"title": "Home Assistant",
|
||||
"discovery": "Prefiks for oppdagelsestopic",
|
||||
"hostname": "Vertsnavn for URL",
|
||||
"tag": "Navnetagg"
|
||||
}
|
||||
},
|
||||
"cloud": {
|
||||
"title": "Skytjenester",
|
||||
"ams": "AMS-leser sky",
|
||||
"es": "Energy Speedometer"
|
||||
},
|
||||
"thresholds": {
|
||||
"title": "Tariffgrenser",
|
||||
"avg": "Snitt av"
|
||||
},
|
||||
"ui": {
|
||||
"title": "Brukergrensesnitt",
|
||||
"i": "Importmåler",
|
||||
"e": "Eksportmåler",
|
||||
"v": "Spenning",
|
||||
"a": "Strøm",
|
||||
"h": "Per fase",
|
||||
"f": "Effektfaktor",
|
||||
"r": "Reaktiv",
|
||||
"c": "Sanntid",
|
||||
"t": "Topper",
|
||||
"l": "Sanntidsgraf",
|
||||
"p": "Pris",
|
||||
"d": "Døgngraf",
|
||||
"m": "Månedsgraf",
|
||||
"s": "Temperaturgraf",
|
||||
"k": "Mørk modus",
|
||||
"lang": "Språk",
|
||||
"enabled": "Aktivert",
|
||||
"disabled": "Deaktivert",
|
||||
"auto": "Auto"
|
||||
},
|
||||
"hw": {
|
||||
"title": "Maskinvare",
|
||||
"han": {
|
||||
"rx": "HAN RX",
|
||||
"tx": "HAN TX",
|
||||
"pullup": "Pullup"
|
||||
},
|
||||
"ap_btn": "AP-knapp",
|
||||
"led": {
|
||||
"title": "LED",
|
||||
"rgb": "RGB",
|
||||
"inverted": "invertert",
|
||||
"disable": "LED-deaktiverings-GPIO",
|
||||
"behaviour": {
|
||||
"title": "LED-oppførsel",
|
||||
"enabled": "Aktivert",
|
||||
"disabled": "Deaktivert"
|
||||
}
|
||||
},
|
||||
"temp": "Temperatur",
|
||||
"temp_analog": "Analog temp",
|
||||
"vcc": {
|
||||
"title": "Vcc",
|
||||
"offset": "Vcc-offset",
|
||||
"multiplier": "Multiplikator",
|
||||
"divider": "Motstandsdelere",
|
||||
"div_vcc": "VCC",
|
||||
"div_gnd": "GND",
|
||||
"boot": "Oppstartsgrense"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"title": "Feilsøking",
|
||||
"enable": "Aktiver feilsøking",
|
||||
"danger": "Feilsøking kan gi plutselige omstarter. Ikke la den stå på!",
|
||||
"telnet": "Aktiver telnet",
|
||||
"telnet_danger": "Telnet er usikkert og bør være av når det ikke brukes"
|
||||
},
|
||||
"btn_reset": "Fabrikktilbakestill",
|
||||
"mask": {
|
||||
"loading": "Laster konfigurasjon",
|
||||
"saving": "Lagrer konfigurasjon",
|
||||
"reset": "Utfører fabrikktilbakestilling",
|
||||
"reset_done": "Enheten er fabrikktilbakestilt og satt i AP-modus"
|
||||
}
|
||||
},
|
||||
"consent": {
|
||||
"title": "Tillatelser vi trenger for å gjøre jobben",
|
||||
"one_click": "Aktiver ett-klikks oppgradering? (innebærer datainnsamling)",
|
||||
"read_more": "Les mer",
|
||||
"yes": "Ja",
|
||||
"no": "Nei",
|
||||
"mask_saving": "Lagrer valg",
|
||||
"language": "Språk",
|
||||
"load_from_server": "Last fra server"
|
||||
},
|
||||
"upload": {
|
||||
"title": "Last opp",
|
||||
"desc": "Velg riktig fil og klikk last opp",
|
||||
"mask": "Laster opp fil, vennligst vent"
|
||||
},
|
||||
"setup": {
|
||||
"title": "Oppsett",
|
||||
"static": "Statisk IP",
|
||||
"mask": "Lagrer konfigurasjonen på enheten"
|
||||
},
|
||||
"errors": {
|
||||
"han": {
|
||||
"-1": "Analysefeil",
|
||||
"-2": "Ufullstendige data mottatt",
|
||||
"-3": "Markør for datafelt mangler",
|
||||
"-4": "Kontrollsum i header er feil",
|
||||
"-5": "Kontrollsum i footer er feil",
|
||||
"-9": "Ukjente data mottatt, sjekk måleroppsettet",
|
||||
"-41": "Rammelengde stemmer ikke",
|
||||
"-51": "Autentisering mislyktes",
|
||||
"-52": "Dekryptering mislyktes",
|
||||
"-53": "Krypteringsnøkkel er ugyldig",
|
||||
"89": "Ukjente data mottatt fra måler",
|
||||
"90": "Ingen HAN-data mottatt på minst 30 s",
|
||||
"91": "Serielt brudd",
|
||||
"92": "Seriell buffer er full",
|
||||
"93": "Seriell FIFO-overløp",
|
||||
"94": "Seriell rammekonflikt",
|
||||
"95": "Seriell paritetsfeil",
|
||||
"96": "RX-feil",
|
||||
"98": "Unntak i kode, feilsøking nødvendig",
|
||||
"99": "Autodeteksjon mislyktes"
|
||||
},
|
||||
"mqtt": {
|
||||
"-3": "Tilkobling mislyktes",
|
||||
"-4": "Nettverkstidsavbrudd",
|
||||
"-10": "Tilkobling nektet",
|
||||
"-11": "Klarte ikke å abonnere",
|
||||
"-13": "Tilkobling mistet"
|
||||
},
|
||||
"price": {
|
||||
"400": "Ukjente data i forespørsel",
|
||||
"401": "Ikke autorisert, sjekk API-nøkkel",
|
||||
"403": "Ikke autorisert, sjekk API-nøkkel",
|
||||
"404": "Pris utilgjengelig, ikke funnet",
|
||||
"425": "Serveren sier det er for tidlig",
|
||||
"429": "API-grensen er nådd",
|
||||
"500": "Intern serverfeil",
|
||||
"-1": "Tilkoblingsfeil",
|
||||
"-2": "Ufullstendige data mottatt",
|
||||
"-3": "Ugyldige data, tag mangler",
|
||||
"-51": "Autentisering mislyktes",
|
||||
"-52": "Dekryptering mislyktes",
|
||||
"-53": "Krypteringsnøkkel er ugyldig"
|
||||
},
|
||||
"http": {
|
||||
"255": "Kan ikke starte oppgradering",
|
||||
"-1": "Tilkobling ble nektet",
|
||||
"-2": "Klarte ikke å sende headere",
|
||||
"-3": "Klarte ikke å sende payload",
|
||||
"-4": "Ikke tilkoblet",
|
||||
"-5": "Tilkobling mistet",
|
||||
"-6": "Ingen datastrøm",
|
||||
"-7": "Ikke en HTTP-server",
|
||||
"-8": "Ikke nok minne",
|
||||
"-9": "Kodingsfeil",
|
||||
"-10": "Feil ved strøm-skriving",
|
||||
"-11": "Lese-timeout"
|
||||
}
|
||||
},
|
||||
"esp8266": {
|
||||
"reason": {
|
||||
"0": "Normal",
|
||||
"1": "WDT-reset",
|
||||
"2": "Unntaksreset",
|
||||
"3": "Myk WDT-reset",
|
||||
"4": "Programvarestart",
|
||||
"5": "Dvale",
|
||||
"6": "Ekstern reset"
|
||||
}
|
||||
},
|
||||
"esp32": {
|
||||
"reason": {
|
||||
"1": "Vbat power on reset",
|
||||
"3": "Programvarestyrt reset",
|
||||
"4": "WDT-reset",
|
||||
"5": "Dvale",
|
||||
"6": "SLC-reset",
|
||||
"7": "Timer Group0 WDT-reset",
|
||||
"8": "Timer Group1 WDT-reset",
|
||||
"9": "RTC WDT-reset",
|
||||
"10": "Intrusion test reset CPU",
|
||||
"11": "Timer Group reset CPU",
|
||||
"12": "Programvarestyrt reset CPU",
|
||||
"13": "RTC WTD reset CPU",
|
||||
"14": "PRO CPU",
|
||||
"15": "AP CPU",
|
||||
"16": "Brownout reset",
|
||||
"17": "HP core reset",
|
||||
"18": "LP core reset",
|
||||
"19": "HP-app reset",
|
||||
"20": "LP-app reset",
|
||||
"21": "HP-system reset",
|
||||
"22": "LP-system reset"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -300,7 +300,9 @@
|
||||
"read_more" : "Read more",
|
||||
"yes" : "Yes",
|
||||
"no" : "No",
|
||||
"mask_saving" : "Saving preferences"
|
||||
"mask_saving" : "Saving preferences",
|
||||
"language" : "Language",
|
||||
"load_from_server" : "Load from server"
|
||||
},
|
||||
"upload" : {
|
||||
"title" : "Upload",
|
||||
|
||||
413
lib/SvelteUi/json/translations-no.json
Normal file
413
lib/SvelteUi/json/translations-no.json
Normal file
@ -0,0 +1,413 @@
|
||||
{
|
||||
"language": {
|
||||
"code": "no",
|
||||
"name": "Norsk"
|
||||
},
|
||||
"common": {
|
||||
"import": "Import",
|
||||
"export": "Eksport",
|
||||
"voltage": "Spenning",
|
||||
"amperage": "Strøm",
|
||||
"seconds": "sekunder",
|
||||
"minute": "minutt",
|
||||
"minutes": "minutter",
|
||||
"hour": "time",
|
||||
"hours": "timer",
|
||||
"day": "dag",
|
||||
"days": "dager",
|
||||
"month": "måned",
|
||||
"unknown": "Ukjent"
|
||||
},
|
||||
"btn": {
|
||||
"reboot": "Start på nytt",
|
||||
"save": "Lagre",
|
||||
"upload": "Last opp"
|
||||
},
|
||||
"header": {
|
||||
"mem": "Ledig minne",
|
||||
"price": "Pristjeneste",
|
||||
"booting": "Starter",
|
||||
"config": "Konfigurasjon",
|
||||
"status": "Enhetsinformasjon",
|
||||
"doc": "Dokumentasjon",
|
||||
"new_version": "Ny versjon",
|
||||
"upgrade": "Vil du oppgradere denne enheten til {0}?",
|
||||
"uptime": "Oppetid"
|
||||
},
|
||||
"dashboard": {
|
||||
"phase": "Faseeffekt",
|
||||
"pf": "Effektfaktor",
|
||||
"tariffpeak": "Topper for nettleie",
|
||||
"realtime": "Sanntidsgraf",
|
||||
"price": "Fremtidig energipris",
|
||||
"day": "Energibruk siste 24 timer",
|
||||
"month": "Energibruk siste {0} dager",
|
||||
"temperature": "Temperaturfølere"
|
||||
},
|
||||
"reactive": {
|
||||
"title": "Reaktiv",
|
||||
"instant_in": "Øyeblikk inn",
|
||||
"instant_out": "Øyeblikk ut",
|
||||
"total_in": "Total inn",
|
||||
"total_out": "Total ut"
|
||||
},
|
||||
"realtime": {
|
||||
"title": "Sanntidsberegninger",
|
||||
"consumption": "Forbruk",
|
||||
"cost": "Kostnad",
|
||||
"last_month": "Forrige måned",
|
||||
"last_mo": "Forr. mnd."
|
||||
},
|
||||
"status": {
|
||||
"device": {
|
||||
"title": "Enhetsinformasjon",
|
||||
"chip": "Brikke",
|
||||
"device": "Enhet",
|
||||
"mac": "MAC",
|
||||
"apmac": "AP-MAC",
|
||||
"last_boot": "Siste oppstart",
|
||||
"reason": "Årsak",
|
||||
"btn_consents": "Oppdater samtykker",
|
||||
"reboot_confirm": "Er du sikker på at du vil starte enheten på nytt"
|
||||
},
|
||||
"meter": {
|
||||
"title": "Måler",
|
||||
"manufacturer": "Produsent",
|
||||
"model": "Modell",
|
||||
"id": "ID"
|
||||
},
|
||||
"network": {
|
||||
"title": "Nettverk"
|
||||
},
|
||||
"firmware": {
|
||||
"title": "Fastvare",
|
||||
"installed": "Installert versjon",
|
||||
"latest": "Nyeste versjon",
|
||||
"install": "Installer denne versjonen",
|
||||
"failed": "Forrige oppgradering fra {0} til {1} mislyktes",
|
||||
"btn_select_file": "Velg fastvarefil for oppgradering",
|
||||
"no_one_click": "Du har deaktivert ett-klikks oppgradering, lenken for egen oppgradering er deaktivert"
|
||||
},
|
||||
"backup": {
|
||||
"title": "Sikkerhetskopi og gjenoppretting",
|
||||
"iw": "WiFi",
|
||||
"im": "MQTT",
|
||||
"ie": "Web",
|
||||
"it": "Måler",
|
||||
"ih": "Grenser",
|
||||
"ig": "GPIO",
|
||||
"in": "NTP",
|
||||
"is": "Pris-API",
|
||||
"secrets": "Ta med hemmeligheter",
|
||||
"secrets_desc": "(SSID, PSK, passord og token)",
|
||||
"btn_select_file": "Velg fil...",
|
||||
"btn_download": "Last ned"
|
||||
},
|
||||
"mask": {
|
||||
"firmware": "Laster opp fastvare, vennligst vent",
|
||||
"config": "Laster opp konfigurasjon, vennligst vent"
|
||||
}
|
||||
},
|
||||
"conf": {
|
||||
"general": {
|
||||
"title": "Generelt",
|
||||
"hostname": "Vertsnavn",
|
||||
"timezone": "Tidssone",
|
||||
"security": {
|
||||
"title": "Sikkerhet",
|
||||
"none": "Ingen",
|
||||
"conf": "Kun konfigurasjon",
|
||||
"all": "Alt"
|
||||
},
|
||||
"context": "Kontekst",
|
||||
"context_placeholder": "[rot]"
|
||||
},
|
||||
"price": {
|
||||
"title": "Priskonfigurasjon",
|
||||
"region": "Prisområde",
|
||||
"currency": "Valuta",
|
||||
"conf": "Konfigurer pris",
|
||||
"enabled": "Aktiver pris fra ekstern server",
|
||||
"api_key_placeholder": "ENTSO-E API-nøkkel, valgfritt, se dokumentasjon",
|
||||
"both": "Begge",
|
||||
"fixed": "Fast",
|
||||
"btn_add": "Legg til",
|
||||
"mask_loading": "Laster priskonfigurasjon",
|
||||
"mask_saving": "Lagrer priskonfigurasjon"
|
||||
},
|
||||
"meter": {
|
||||
"title": "Måler",
|
||||
"comm": {
|
||||
"title": "Kommunikasjon",
|
||||
"passive": "Passiv (push)",
|
||||
"pulse": "Puls"
|
||||
},
|
||||
"serial": "Seriell konf.",
|
||||
"inverted": "invertert",
|
||||
"buffer": "Bufferstørrelse",
|
||||
"pulses": "Pulser per kWh",
|
||||
"voltage": "Spenning",
|
||||
"fuse": "Hovedsikring",
|
||||
"prod": "Produksjon",
|
||||
"encrypted": "Måleren er kryptert",
|
||||
"authkey": "Autentiseringsnøkkel",
|
||||
"multipliers": {
|
||||
"title": "Multiplikatorer",
|
||||
"watt": "Watt",
|
||||
"volt": "Volt",
|
||||
"amp": "Ampere",
|
||||
"kwh": "kWh"
|
||||
}
|
||||
},
|
||||
"connection": {
|
||||
"title": "Tilkobling",
|
||||
"wifi": "Koble til WiFi",
|
||||
"ap": "Eget aksesspunkt",
|
||||
"eth": "Ethernet",
|
||||
"ssid": "SSID",
|
||||
"psk": "Passord",
|
||||
"ps": {
|
||||
"title": "Strømsparing",
|
||||
"default": "Standard",
|
||||
"off": "Av",
|
||||
"min": "Minimal",
|
||||
"max": "Maksimal"
|
||||
},
|
||||
"pwr": "Effekt",
|
||||
"tick_11b": "Tillat 802.11b-hastigheter"
|
||||
},
|
||||
"network": {
|
||||
"title": "Nettverk",
|
||||
"ip": "IP",
|
||||
"static": "Statisk",
|
||||
"dhcp": "DHCP",
|
||||
"gw": "Gateway",
|
||||
"dns": "DNS",
|
||||
"tick_mdns": "aktiver mDNS",
|
||||
"ntp": "NTP",
|
||||
"tick_ntp_dhcp": "hent fra DHCP"
|
||||
},
|
||||
"mqtt": {
|
||||
"title": "MQTT",
|
||||
"server": "Server",
|
||||
"user": "Brukernavn",
|
||||
"pass": "Passord",
|
||||
"id": "Klient-ID",
|
||||
"payload": "Payload",
|
||||
"publish": "Publiserings-emne",
|
||||
"btn_ca_upload": "Last opp CA",
|
||||
"btn_crt_upload": "Last opp sertifikat",
|
||||
"btn_key_upload": "Last opp nøkkel",
|
||||
"ca_ok": "CA ok",
|
||||
"crt_ok": "Sertifikat ok",
|
||||
"key_ok": "Nøkkel ok",
|
||||
"title_ca": "Klikk her for å laste opp CA",
|
||||
"title_crt": "Klikk her for å laste opp sertifikat",
|
||||
"title_key": "Klikk her for å laste opp privat nøkkel",
|
||||
"domoticz": {
|
||||
"title": "Domoticz",
|
||||
"eidx": "Strøm-IDX",
|
||||
"cidx": "Strøm-IDX",
|
||||
"vidx": "Spenning-IDX"
|
||||
},
|
||||
"ha": {
|
||||
"title": "Home Assistant",
|
||||
"discovery": "Prefiks for oppdagelsestopic",
|
||||
"hostname": "Vertsnavn for URL",
|
||||
"tag": "Navnetagg"
|
||||
}
|
||||
},
|
||||
"cloud": {
|
||||
"title": "Skytjenester",
|
||||
"ams": "AMS-leser sky",
|
||||
"es": "Energy Speedometer"
|
||||
},
|
||||
"thresholds": {
|
||||
"title": "Tariffgrenser",
|
||||
"avg": "Snitt av"
|
||||
},
|
||||
"ui": {
|
||||
"title": "Brukergrensesnitt",
|
||||
"i": "Importmåler",
|
||||
"e": "Eksportmåler",
|
||||
"v": "Spenning",
|
||||
"a": "Strøm",
|
||||
"h": "Per fase",
|
||||
"f": "Effektfaktor",
|
||||
"r": "Reaktiv",
|
||||
"c": "Sanntid",
|
||||
"t": "Topper",
|
||||
"l": "Sanntidsgraf",
|
||||
"p": "Pris",
|
||||
"d": "Døgngraf",
|
||||
"m": "Månedsgraf",
|
||||
"s": "Temperaturgraf",
|
||||
"k": "Mørk modus",
|
||||
"lang": "Språk",
|
||||
"enabled": "Aktivert",
|
||||
"disabled": "Deaktivert",
|
||||
"auto": "Auto"
|
||||
},
|
||||
"hw": {
|
||||
"title": "Maskinvare",
|
||||
"han": {
|
||||
"rx": "HAN RX",
|
||||
"tx": "HAN TX",
|
||||
"pullup": "Pullup"
|
||||
},
|
||||
"ap_btn": "AP-knapp",
|
||||
"led": {
|
||||
"title": "LED",
|
||||
"rgb": "RGB",
|
||||
"inverted": "invertert",
|
||||
"disable": "LED-deaktiverings-GPIO",
|
||||
"behaviour": {
|
||||
"title": "LED-oppførsel",
|
||||
"enabled": "Aktivert",
|
||||
"disabled": "Deaktivert"
|
||||
}
|
||||
},
|
||||
"temp": "Temperatur",
|
||||
"temp_analog": "Analog temp",
|
||||
"vcc": {
|
||||
"title": "Vcc",
|
||||
"offset": "Vcc-offset",
|
||||
"multiplier": "Multiplikator",
|
||||
"divider": "Motstandsdelere",
|
||||
"div_vcc": "VCC",
|
||||
"div_gnd": "GND",
|
||||
"boot": "Oppstartsgrense"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"title": "Feilsøking",
|
||||
"enable": "Aktiver feilsøking",
|
||||
"danger": "Feilsøking kan gi plutselige omstarter. Ikke la den stå på!",
|
||||
"telnet": "Aktiver telnet",
|
||||
"telnet_danger": "Telnet er usikkert og bør være av når det ikke brukes"
|
||||
},
|
||||
"btn_reset": "Fabrikktilbakestill",
|
||||
"mask": {
|
||||
"loading": "Laster konfigurasjon",
|
||||
"saving": "Lagrer konfigurasjon",
|
||||
"reset": "Utfører fabrikktilbakestilling",
|
||||
"reset_done": "Enheten er fabrikktilbakestilt og satt i AP-modus"
|
||||
}
|
||||
},
|
||||
"consent": {
|
||||
"title": "Tillatelser vi trenger for å gjøre jobben",
|
||||
"one_click": "Aktiver ett-klikks oppgradering? (innebærer datainnsamling)",
|
||||
"read_more": "Les mer",
|
||||
"yes": "Ja",
|
||||
"no": "Nei",
|
||||
"mask_saving": "Lagrer valg",
|
||||
"language": "Språk",
|
||||
"load_from_server": "Last fra server"
|
||||
},
|
||||
"upload": {
|
||||
"title": "Last opp",
|
||||
"desc": "Velg riktig fil og klikk last opp",
|
||||
"mask": "Laster opp fil, vennligst vent"
|
||||
},
|
||||
"setup": {
|
||||
"title": "Oppsett",
|
||||
"static": "Statisk IP",
|
||||
"mask": "Lagrer konfigurasjonen på enheten"
|
||||
},
|
||||
"errors": {
|
||||
"han": {
|
||||
"-1": "Analysefeil",
|
||||
"-2": "Ufullstendige data mottatt",
|
||||
"-3": "Markør for datafelt mangler",
|
||||
"-4": "Kontrollsum i header er feil",
|
||||
"-5": "Kontrollsum i footer er feil",
|
||||
"-9": "Ukjente data mottatt, sjekk måleroppsettet",
|
||||
"-41": "Rammelengde stemmer ikke",
|
||||
"-51": "Autentisering mislyktes",
|
||||
"-52": "Dekryptering mislyktes",
|
||||
"-53": "Krypteringsnøkkel er ugyldig",
|
||||
"89": "Ukjente data mottatt fra måler",
|
||||
"90": "Ingen HAN-data mottatt på minst 30 s",
|
||||
"91": "Serielt brudd",
|
||||
"92": "Seriell buffer er full",
|
||||
"93": "Seriell FIFO-overløp",
|
||||
"94": "Seriell rammekonflikt",
|
||||
"95": "Seriell paritetsfeil",
|
||||
"96": "RX-feil",
|
||||
"98": "Unntak i kode, feilsøking nødvendig",
|
||||
"99": "Autodeteksjon mislyktes"
|
||||
},
|
||||
"mqtt": {
|
||||
"-3": "Tilkobling mislyktes",
|
||||
"-4": "Nettverkstidsavbrudd",
|
||||
"-10": "Tilkobling nektet",
|
||||
"-11": "Klarte ikke å abonnere",
|
||||
"-13": "Tilkobling mistet"
|
||||
},
|
||||
"price": {
|
||||
"400": "Ukjente data i forespørsel",
|
||||
"401": "Ikke autorisert, sjekk API-nøkkel",
|
||||
"403": "Ikke autorisert, sjekk API-nøkkel",
|
||||
"404": "Pris utilgjengelig, ikke funnet",
|
||||
"425": "Serveren sier det er for tidlig",
|
||||
"429": "API-grensen er nådd",
|
||||
"500": "Intern serverfeil",
|
||||
"-1": "Tilkoblingsfeil",
|
||||
"-2": "Ufullstendige data mottatt",
|
||||
"-3": "Ugyldige data, tag mangler",
|
||||
"-51": "Autentisering mislyktes",
|
||||
"-52": "Dekryptering mislyktes",
|
||||
"-53": "Krypteringsnøkkel er ugyldig"
|
||||
},
|
||||
"http": {
|
||||
"255": "Kan ikke starte oppgradering",
|
||||
"-1": "Tilkobling ble nektet",
|
||||
"-2": "Klarte ikke å sende headere",
|
||||
"-3": "Klarte ikke å sende payload",
|
||||
"-4": "Ikke tilkoblet",
|
||||
"-5": "Tilkobling mistet",
|
||||
"-6": "Ingen datastrøm",
|
||||
"-7": "Ikke en HTTP-server",
|
||||
"-8": "Ikke nok minne",
|
||||
"-9": "Kodingsfeil",
|
||||
"-10": "Feil ved strøm-skriving",
|
||||
"-11": "Lese-timeout"
|
||||
}
|
||||
},
|
||||
"esp8266": {
|
||||
"reason": {
|
||||
"0": "Normal",
|
||||
"1": "WDT-reset",
|
||||
"2": "Unntaksreset",
|
||||
"3": "Myk WDT-reset",
|
||||
"4": "Programvarestart",
|
||||
"5": "Dvale",
|
||||
"6": "Ekstern reset"
|
||||
}
|
||||
},
|
||||
"esp32": {
|
||||
"reason": {
|
||||
"1": "Vbat power on reset",
|
||||
"3": "Programvarestyrt reset",
|
||||
"4": "WDT-reset",
|
||||
"5": "Dvale",
|
||||
"6": "SLC-reset",
|
||||
"7": "Timer Group0 WDT-reset",
|
||||
"8": "Timer Group1 WDT-reset",
|
||||
"9": "RTC WDT-reset",
|
||||
"10": "Intrusion test reset CPU",
|
||||
"11": "Timer Group reset CPU",
|
||||
"12": "Programvarestyrt reset CPU",
|
||||
"13": "RTC WTD reset CPU",
|
||||
"14": "PRO CPU",
|
||||
"15": "AP CPU",
|
||||
"16": "Brownout reset",
|
||||
"17": "HP core reset",
|
||||
"18": "LP core reset",
|
||||
"19": "HP-app reset",
|
||||
"20": "LP-app reset",
|
||||
"21": "HP-system reset",
|
||||
"22": "LP-system reset"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -300,7 +300,9 @@
|
||||
"read_more" : "Read more",
|
||||
"yes" : "Yes",
|
||||
"no" : "No",
|
||||
"mask_saving" : "Saving preferences"
|
||||
"mask_saving" : "Saving preferences",
|
||||
"language" : "Language",
|
||||
"load_from_server" : "Load from server"
|
||||
},
|
||||
"upload" : {
|
||||
"title" : "Upload",
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#include "html/conf_upgrade_json.h"
|
||||
#include "html/conf_cloud_json.h"
|
||||
#include "html/translations_json.h"
|
||||
#include "html/translations_no_json.h"
|
||||
#include "html/firmware_html.h"
|
||||
#include "html/neas_logotype_white_svg.h"
|
||||
#include "html/wifi_high_light_svg.h"
|
||||
@ -1267,6 +1268,12 @@ void AmsWebServer::translationsJson() {
|
||||
server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE);
|
||||
server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF);
|
||||
|
||||
if(lang.equalsIgnoreCase(F("no"))) {
|
||||
uint16_t len = pgm_read_word(&TRANSLATIONS_NO_JSON_LEN);
|
||||
server.send_P(200, MIME_JSON, TRANSLATIONS_NO_JSON, len);
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t len = pgm_read_word(&TRANSLATIONS_JSON_LEN);
|
||||
server.send_P(200, MIME_JSON, TRANSLATIONS_JSON, len);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user