Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d08915b541 |
No files matched your search
@@ -2,7 +2,6 @@ _final: prev:
|
|||||||
(import ./abseil { inherit prev; })
|
(import ./abseil { inherit prev; })
|
||||||
// {
|
// {
|
||||||
gnutls = import ./gnutls { inherit (prev) gnutls; };
|
gnutls = import ./gnutls { inherit (prev) gnutls; };
|
||||||
libjpeg_turbo = import ./libjpeg-turbo { inherit (prev) lib libjpeg_turbo stdenv; };
|
|
||||||
prometheus = import ./prometheus { inherit (prev) prometheus; };
|
prometheus = import ./prometheus { inherit (prev) prometheus; };
|
||||||
zopfli = import ./zopfli { inherit (prev) zopfli; };
|
zopfli = import ./zopfli { inherit (prev) zopfli; };
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
libjpeg_turbo,
|
|
||||||
stdenv,
|
|
||||||
}:
|
|
||||||
libjpeg_turbo.overrideAttrs (old: {
|
|
||||||
# This overlay also reaches pkgsi686Linux. Its 12-bit floating-point code
|
|
||||||
# uses x87, while x86-64-v3 uses FMA. Keep the tests enabled for both.
|
|
||||||
cmakeFlags =
|
|
||||||
(old.cmakeFlags or [ ])
|
|
||||||
++ lib.optional (
|
|
||||||
stdenv.hostPlatform.isx86_64 && (stdenv.hostPlatform.gcc.arch or null) == "x86-64-v3"
|
|
||||||
) "-DFLOATTEST12=fp-contract"
|
|
||||||
++ lib.optional stdenv.hostPlatform.isi686 "-DFLOATTEST12=387";
|
|
||||||
})
|
|
||||||
Generated
+21
-21
@@ -7,11 +7,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1792526520,
|
"lastModified": 1789770686,
|
||||||
"narHash": "sha256-3hSJlv8mUVnZPMWK2+CM7a9O+nR6Z4mCh27NfLCmTPc=",
|
"narHash": "sha256-uZkBR7yHdIKUFB5SZdfgh1qkGfI3XmYmI/lTiquxbck=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "disko",
|
"repo": "disko",
|
||||||
"rev": "cedd626e11b635470fa6f9fdb8ad79b0075dd7f9",
|
"rev": "725ea35e410ad83be4931d1bff7e090eacaf3563",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -45,11 +45,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1793193205,
|
"lastModified": 1791293500,
|
||||||
"narHash": "sha256-X6xa6sGA7RnJQuZGbFMC+K+KToWAlBDCCjJXfTwEPsw=",
|
"narHash": "sha256-3hwJd2/vG/VYV1P/g7oDgdbNsWODhN5F//Od+hPMm2k=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "095fef2f265c3c0da4fe315efba8f8a04495ab34",
|
"rev": "0e11b7bcba1d74ef8ea10bfdfb1e1a5811a21087",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -67,11 +67,11 @@
|
|||||||
"rust-overlay": "rust-overlay"
|
"rust-overlay": "rust-overlay"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1793017781,
|
"lastModified": 1791127101,
|
||||||
"narHash": "sha256-YRem1WRn//ruQ7QukBCjpn/Uwmd17vGLml8w3i+Swd8=",
|
"narHash": "sha256-SmrBBhcv9iNHA2vlafi7Zpe8bkcsMjVNSmCCVf5/jrQ=",
|
||||||
"owner": "LLukas22",
|
"owner": "LLukas22",
|
||||||
"repo": "Jellyswarrm",
|
"repo": "Jellyswarrm",
|
||||||
"rev": "90cca4fe7e6f855453866b71ca5b38773342a0c4",
|
"rev": "0b4301c6c74efff9c3634296913032579c98faf6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -85,11 +85,11 @@
|
|||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1793236063,
|
"lastModified": 1791128201,
|
||||||
"narHash": "sha256-jGFe4xdrCw6xpgH2zgKwslACyt/NGuPwGILPEMFxmcQ=",
|
"narHash": "sha256-rlsYY/Dg/LhbIj51Aa6TLvRpZeb3KZgUTd7llQ5XcJE=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixos-hardware",
|
"repo": "nixos-hardware",
|
||||||
"rev": "b6754c901c21478fd8450d62101e712b2a4f0d75",
|
"rev": "31cc5f4d9b9ba601071e8b8504601b9b176e2756",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -114,11 +114,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-master": {
|
"nixpkgs-master": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1793315900,
|
"lastModified": 1791296764,
|
||||||
"narHash": "sha256-z5lZoCwheBzMgRtfYlGLMhmPwhv1Rty16Kf269n8ctc=",
|
"narHash": "sha256-N2b6Uxdr1MFhscEPqDyntTTtGZASgq3XYE0ujRzfeNI=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "db379a58acfef9783b46ffde2957dac397c92b85",
|
"rev": "a15afac8691bd24f746255ffbd76306693e4cf7a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -146,11 +146,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1793110635,
|
"lastModified": 1791260994,
|
||||||
"narHash": "sha256-dhoW6VgFWlaodSY5jrBn+CF2FLmaUvDVgM7+C7T2+NM=",
|
"narHash": "sha256-Miqqk/ammqnTUxaoCyvtwoPeLbI1ksFyLxi/CazZpWY=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "31ecbaca1bdefa45dffc409f0250bd8039ea0010",
|
"rev": "151fa4e8ddfdd8dd25d945ad94ed54a13de9f6e4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -201,11 +201,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1793052255,
|
"lastModified": 1791103873,
|
||||||
"narHash": "sha256-Y/JIHTnMlOabDfyaSBubWGLDIVGihLEUuoMhFvQKaDo=",
|
"narHash": "sha256-nFxM+pKoZ8LJAEnUXARyCaOAloWgaW9kZQOSjWzKcTE=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "60182817ee048ac94b4c68ea76d5ef2e8aac730d",
|
"rev": "dcd241ba97088c22569d1573286e1b9daad340c0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -5,13 +5,11 @@
|
|||||||
extra-substituters = [
|
extra-substituters = [
|
||||||
"https://cache.nixos.org/?priority=2&want-mass-query=true"
|
"https://cache.nixos.org/?priority=2&want-mass-query=true"
|
||||||
"https://nix-community.cachix.org/?priority=10&want-mass-query=true"
|
"https://nix-community.cachix.org/?priority=10&want-mass-query=true"
|
||||||
"https://attic.nayeonie.com/nix-cache/?priority=10&want-mass-query=true"
|
|
||||||
];
|
];
|
||||||
extra-trusted-public-keys = [
|
extra-trusted-public-keys = [
|
||||||
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" # cspell:disable-line
|
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" # cspell:disable-line
|
||||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" # cspell:disable-line
|
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" # cspell:disable-line
|
||||||
"cache-nix-dot:Od9KN34LXc6Lu7y1ozzV1kIXZa8coClozgth/SYE7dU=" # cspell:disable-line
|
"cache-nix-dot:Od9KN34LXc6Lu7y1ozzV1kIXZa8coClozgth/SYE7dU=" # cspell:disable-line
|
||||||
"nix-cache:grGRsHhqNDhkEuTODvHJXYmoCClntC+U8XAJQzwMaZM=" # cspell:disable-line
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,6 @@
|
|||||||
extraComponents = [
|
extraComponents = [
|
||||||
"isal"
|
"isal"
|
||||||
"modbus" # for victron modbus integration
|
"modbus" # for victron modbus integration
|
||||||
"template" # MultiPlus mode selector, input current limit and derived sensors
|
|
||||||
];
|
];
|
||||||
customComponents = with pkgs.x86-v1.home-assistant-custom-components; [
|
customComponents = with pkgs.x86-v1.home-assistant-custom-components; [
|
||||||
garmin_connect
|
garmin_connect
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
title: Van Overview
|
||||||
|
views:
|
||||||
|
- title: Overview
|
||||||
|
path: overview
|
||||||
|
type: sections
|
||||||
|
sections:
|
||||||
|
# Battery Status Section
|
||||||
|
- type: grid
|
||||||
|
title: Battery Status
|
||||||
|
cards:
|
||||||
|
- type: gauge
|
||||||
|
entity: sensor.jk0_soc
|
||||||
|
name: Battery 0
|
||||||
|
min: 0
|
||||||
|
max: 100
|
||||||
|
severity:
|
||||||
|
green: 50
|
||||||
|
yellow: 20
|
||||||
|
red: 0
|
||||||
|
needle: true
|
||||||
|
|
||||||
|
- type: gauge
|
||||||
|
entity: sensor.jk1_soc
|
||||||
|
name: Battery 1
|
||||||
|
min: 0
|
||||||
|
max: 100
|
||||||
|
severity:
|
||||||
|
green: 50
|
||||||
|
yellow: 20
|
||||||
|
red: 0
|
||||||
|
needle: true
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.jk0_total_voltage
|
||||||
|
name: Batt 0 Voltage
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.jk1_total_voltage
|
||||||
|
name: Batt 1 Voltage
|
||||||
|
|
||||||
|
# Solar Production Section
|
||||||
|
- type: grid
|
||||||
|
title: Solar Production
|
||||||
|
cards:
|
||||||
|
- type: gauge
|
||||||
|
entity: sensor.solar_wattage
|
||||||
|
name: Solar Now
|
||||||
|
min: 0
|
||||||
|
max: 400
|
||||||
|
severity:
|
||||||
|
green: 100
|
||||||
|
yellow: 50
|
||||||
|
red: 0
|
||||||
|
needle: true
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.solar_yield_today
|
||||||
|
name: Today's Yield
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.estimated_energy_production_today
|
||||||
|
name: Forecast Today
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.estimated_energy_production_tomorrow
|
||||||
|
name: Forecast Tomorrow
|
||||||
|
|
||||||
|
# Environment Section
|
||||||
|
- type: grid
|
||||||
|
title: Van Environment
|
||||||
|
cards:
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.environment_temperature
|
||||||
|
name: Inside Temp
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.environment_humidity
|
||||||
|
name: Inside Humidity
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.current_weather_temperature
|
||||||
|
name: Outside Temp
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.current_weather_humidity
|
||||||
|
name: Outside Humidity
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.current_weather_condition
|
||||||
|
name: Weather
|
||||||
|
|
||||||
|
# Charger Status Section
|
||||||
|
- type: grid
|
||||||
|
title: Charger
|
||||||
|
cards:
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.charger_dc_wattage
|
||||||
|
name: Charging Power
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.charger_charge_state
|
||||||
|
name: Charge State
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.charger_dc_wattage_daily
|
||||||
|
name: Charged Today
|
||||||
|
|
||||||
|
# Location Section
|
||||||
|
- type: grid
|
||||||
|
title: Location
|
||||||
|
cards:
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.gps_location
|
||||||
|
name: Current Location
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
entity: sensor.gps_speed
|
||||||
|
name: Speed
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
entity: binary_sensor.gps_fix_available
|
||||||
|
name: GPS Fix
|
||||||
@@ -220,120 +220,10 @@ modbus:
|
|||||||
state_class: measurement
|
state_class: measurement
|
||||||
unique_id: gps_altitude_id_1
|
unique_id: gps_altitude_id_1
|
||||||
|
|
||||||
# ---- MULTIPLUS-II (VE.Bus, Cerbo GX unit ID 227) ----
|
# ---- CHARGER (Unit ID 223) ----
|
||||||
# Confirmed on this GX: one AC phase, AC input 1, 30 A shore-power plug.
|
- name: Charger Output 1 Voltage
|
||||||
# Register map: https://www.victronenergy.com/upload/documents/CCGX-Modbus-TCP-register-list-3.81.xlsx
|
slave: 223
|
||||||
# Victron's scale column is a divisor: AC power registers use 0.1,
|
address: 2307
|
||||||
# so Home Assistant must multiply their signed raw values by 10.
|
|
||||||
# Change the unit ID anchor here if the GX service mapping changes.
|
|
||||||
- name: MultiPlus AC Input Voltage
|
|
||||||
unique_id: multiplus_ac_input_voltage
|
|
||||||
slave: &multiplus_unit_id 227
|
|
||||||
address: 3
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
scale: 0.1
|
|
||||||
precision: 1
|
|
||||||
unit_of_measurement: "V"
|
|
||||||
device_class: voltage
|
|
||||||
state_class: measurement
|
|
||||||
scan_interval: 10
|
|
||||||
|
|
||||||
- name: MultiPlus AC Input Current
|
|
||||||
unique_id: multiplus_ac_input_current
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 6
|
|
||||||
input_type: holding
|
|
||||||
data_type: int16
|
|
||||||
scale: 0.1
|
|
||||||
precision: 1
|
|
||||||
unit_of_measurement: "A"
|
|
||||||
device_class: current
|
|
||||||
state_class: measurement
|
|
||||||
scan_interval: 10
|
|
||||||
|
|
||||||
- name: MultiPlus AC Input Frequency
|
|
||||||
unique_id: multiplus_ac_input_frequency
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 9
|
|
||||||
input_type: holding
|
|
||||||
data_type: int16
|
|
||||||
scale: 0.01
|
|
||||||
precision: 2
|
|
||||||
unit_of_measurement: "Hz"
|
|
||||||
device_class: frequency
|
|
||||||
state_class: measurement
|
|
||||||
scan_interval: 10
|
|
||||||
|
|
||||||
- name: MultiPlus AC Input Power
|
|
||||||
unique_id: multiplus_ac_input_power
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 12
|
|
||||||
input_type: holding
|
|
||||||
data_type: int16
|
|
||||||
scale: 10
|
|
||||||
precision: 0
|
|
||||||
unit_of_measurement: "W"
|
|
||||||
device_class: power
|
|
||||||
state_class: measurement
|
|
||||||
scan_interval: 10
|
|
||||||
|
|
||||||
- name: MultiPlus AC Output Voltage
|
|
||||||
unique_id: multiplus_ac_output_voltage
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 15
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
scale: 0.1
|
|
||||||
precision: 1
|
|
||||||
unit_of_measurement: "V"
|
|
||||||
device_class: voltage
|
|
||||||
state_class: measurement
|
|
||||||
scan_interval: 10
|
|
||||||
|
|
||||||
- name: MultiPlus AC Output Current
|
|
||||||
unique_id: multiplus_ac_output_current
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 18
|
|
||||||
input_type: holding
|
|
||||||
data_type: int16
|
|
||||||
scale: 0.1
|
|
||||||
precision: 1
|
|
||||||
unit_of_measurement: "A"
|
|
||||||
device_class: current
|
|
||||||
state_class: measurement
|
|
||||||
scan_interval: 10
|
|
||||||
|
|
||||||
- name: MultiPlus AC Output Frequency
|
|
||||||
unique_id: multiplus_ac_output_frequency
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 21
|
|
||||||
input_type: holding
|
|
||||||
data_type: int16
|
|
||||||
scale: 0.01
|
|
||||||
precision: 2
|
|
||||||
unit_of_measurement: "Hz"
|
|
||||||
device_class: frequency
|
|
||||||
state_class: measurement
|
|
||||||
scan_interval: 10
|
|
||||||
|
|
||||||
- name: MultiPlus AC Output Power
|
|
||||||
unique_id: multiplus_ac_output_power
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 23
|
|
||||||
input_type: holding
|
|
||||||
data_type: int16
|
|
||||||
scale: 10
|
|
||||||
precision: 0
|
|
||||||
unit_of_measurement: "W"
|
|
||||||
device_class: power
|
|
||||||
state_class: measurement
|
|
||||||
scan_interval: 10
|
|
||||||
|
|
||||||
- name: MultiPlus Battery Voltage
|
|
||||||
unique_id: multiplus_battery_voltage
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 26
|
|
||||||
input_type: holding
|
input_type: holding
|
||||||
data_type: uint16
|
data_type: uint16
|
||||||
scale: 0.01
|
scale: 0.01
|
||||||
@@ -341,12 +231,11 @@ modbus:
|
|||||||
unit_of_measurement: "V"
|
unit_of_measurement: "V"
|
||||||
device_class: voltage
|
device_class: voltage
|
||||||
state_class: measurement
|
state_class: measurement
|
||||||
scan_interval: 10
|
unique_id: charger_output_1_voltage
|
||||||
|
|
||||||
- name: MultiPlus Battery Current
|
- name: Charger Output 1 Current
|
||||||
unique_id: multiplus_battery_current
|
slave: 223
|
||||||
slave: *multiplus_unit_id
|
address: 2308
|
||||||
address: 27
|
|
||||||
input_type: holding
|
input_type: holding
|
||||||
data_type: int16
|
data_type: int16
|
||||||
scale: 0.1
|
scale: 0.1
|
||||||
@@ -354,12 +243,11 @@ modbus:
|
|||||||
unit_of_measurement: "A"
|
unit_of_measurement: "A"
|
||||||
device_class: current
|
device_class: current
|
||||||
state_class: measurement
|
state_class: measurement
|
||||||
scan_interval: 10
|
unique_id: charger_output_1_current
|
||||||
|
|
||||||
- name: MultiPlus Battery Temperature
|
- name: Charger Output 1 Temperature
|
||||||
unique_id: multiplus_battery_temperature
|
slave: 223
|
||||||
slave: *multiplus_unit_id
|
address: 2309
|
||||||
address: 61
|
|
||||||
input_type: holding
|
input_type: holding
|
||||||
data_type: int16
|
data_type: int16
|
||||||
scale: 0.1
|
scale: 0.1
|
||||||
@@ -367,23 +255,11 @@ modbus:
|
|||||||
unit_of_measurement: "°C"
|
unit_of_measurement: "°C"
|
||||||
device_class: temperature
|
device_class: temperature
|
||||||
state_class: measurement
|
state_class: measurement
|
||||||
|
unique_id: charger_output_1_temperature
|
||||||
|
|
||||||
- name: MultiPlus State of Charge
|
- name: Charger AC Current
|
||||||
unique_id: multiplus_state_of_charge
|
slave: 223
|
||||||
slave: *multiplus_unit_id
|
address: 2314
|
||||||
address: 30
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
scale: 0.1
|
|
||||||
precision: 1
|
|
||||||
unit_of_measurement: "%"
|
|
||||||
device_class: battery
|
|
||||||
state_class: measurement
|
|
||||||
|
|
||||||
- name: MultiPlus AC Input Current Limit Readback
|
|
||||||
unique_id: multiplus_ac_input_current_limit_readback
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 22
|
|
||||||
input_type: holding
|
input_type: holding
|
||||||
data_type: int16
|
data_type: int16
|
||||||
scale: 0.1
|
scale: 0.1
|
||||||
@@ -391,272 +267,73 @@ modbus:
|
|||||||
unit_of_measurement: "A"
|
unit_of_measurement: "A"
|
||||||
device_class: current
|
device_class: current
|
||||||
state_class: measurement
|
state_class: measurement
|
||||||
scan_interval: 10
|
unique_id: charger_ac_current
|
||||||
|
|
||||||
- name: MultiPlus Mode Raw
|
- name: Charger AC Current Limit
|
||||||
unique_id: multiplus_mode_raw
|
slave: 223
|
||||||
slave: *multiplus_unit_id
|
address: 2316
|
||||||
address: 33
|
|
||||||
input_type: holding
|
input_type: holding
|
||||||
data_type: uint16
|
data_type: int16
|
||||||
scan_interval: 10
|
scale: 0.1
|
||||||
|
precision: 1
|
||||||
- name: MultiPlus State Raw
|
unit_of_measurement: "A"
|
||||||
unique_id: multiplus_state_raw
|
device_class: current
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 31
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
scan_interval: 10
|
|
||||||
|
|
||||||
- name: MultiPlus Charge State Raw
|
|
||||||
unique_id: multiplus_charge_state_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 95
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
scan_interval: 10
|
|
||||||
|
|
||||||
- name: MultiPlus Active Input Raw
|
|
||||||
unique_id: multiplus_active_input_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 29
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
scan_interval: 10
|
|
||||||
|
|
||||||
- name: MultiPlus Phase Count
|
|
||||||
unique_id: multiplus_phase_count
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 28
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus VE Bus Error
|
|
||||||
unique_id: multiplus_ve_bus_error
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 32
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus High Temperature Alarm Raw
|
|
||||||
unique_id: multiplus_high_temperature_alarm_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 34
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus Low Battery Alarm Raw
|
|
||||||
unique_id: multiplus_low_battery_alarm_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 35
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus Overload Alarm Raw
|
|
||||||
unique_id: multiplus_overload_alarm_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 36
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus Ripple Alarm Raw
|
|
||||||
unique_id: multiplus_ripple_alarm_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 47
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus Temperature Sensor Alarm Raw
|
|
||||||
unique_id: multiplus_temperature_sensor_alarm_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 42
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus Voltage Sensor Alarm Raw
|
|
||||||
unique_id: multiplus_voltage_sensor_alarm_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 43
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus Grid Lost Alarm Raw
|
|
||||||
unique_id: multiplus_grid_lost_alarm_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 64
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus BMS Pre Alarm Raw
|
|
||||||
unique_id: multiplus_bms_pre_alarm_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 94
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus BMS Allows Charging Raw
|
|
||||||
unique_id: multiplus_bms_allows_charging_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 57
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus BMS Allows Discharging Raw
|
|
||||||
unique_id: multiplus_bms_allows_discharging_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 58
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus BMS Expected Raw
|
|
||||||
unique_id: multiplus_bms_expected_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 59
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus BMS Error
|
|
||||||
unique_id: multiplus_bms_error
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 60
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus AC Input Ignored Raw
|
|
||||||
unique_id: multiplus_ac_input_ignored_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 69
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus AC Input to Output Energy
|
|
||||||
unique_id: multiplus_ac_input_to_output_energy
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 74
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint32
|
|
||||||
scale: 0.01
|
|
||||||
precision: 2
|
|
||||||
unit_of_measurement: "kWh"
|
|
||||||
device_class: energy
|
|
||||||
state_class: total_increasing
|
|
||||||
# Hardware counters reset on Multi/GX restart; total_increasing handles this.
|
|
||||||
|
|
||||||
- name: MultiPlus AC Input to Battery Energy
|
|
||||||
unique_id: multiplus_ac_input_to_battery_energy
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 76
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint32
|
|
||||||
scale: 0.01
|
|
||||||
precision: 2
|
|
||||||
unit_of_measurement: "kWh"
|
|
||||||
device_class: energy
|
|
||||||
state_class: total_increasing
|
|
||||||
|
|
||||||
- name: MultiPlus AC Output to Input Energy
|
|
||||||
unique_id: multiplus_ac_output_to_input_energy
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 82
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint32
|
|
||||||
scale: 0.01
|
|
||||||
precision: 2
|
|
||||||
unit_of_measurement: "kWh"
|
|
||||||
device_class: energy
|
|
||||||
state_class: total_increasing
|
|
||||||
|
|
||||||
- name: MultiPlus Battery to AC Input Energy
|
|
||||||
unique_id: multiplus_battery_to_ac_input_energy
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 86
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint32
|
|
||||||
scale: 0.01
|
|
||||||
precision: 2
|
|
||||||
unit_of_measurement: "kWh"
|
|
||||||
device_class: energy
|
|
||||||
state_class: total_increasing
|
|
||||||
|
|
||||||
- name: MultiPlus Battery to AC Output Energy
|
|
||||||
unique_id: multiplus_battery_to_ac_output_energy
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 90
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint32
|
|
||||||
scale: 0.01
|
|
||||||
precision: 2
|
|
||||||
unit_of_measurement: "kWh"
|
|
||||||
device_class: energy
|
|
||||||
state_class: total_increasing
|
|
||||||
|
|
||||||
- name: MultiPlus AC Output to Battery Energy
|
|
||||||
unique_id: multiplus_ac_output_to_battery_energy
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 92
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint32
|
|
||||||
scale: 0.01
|
|
||||||
precision: 2
|
|
||||||
unit_of_measurement: "kWh"
|
|
||||||
device_class: energy
|
|
||||||
state_class: total_increasing
|
|
||||||
|
|
||||||
- name: MultiPlus PowerAssist Boost Factor
|
|
||||||
unique_id: multiplus_powerassist_boost_factor
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 106
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
scale: 0.01
|
|
||||||
precision: 2
|
|
||||||
state_class: measurement
|
state_class: measurement
|
||||||
|
unique_id: charger_ac_current_limit
|
||||||
|
|
||||||
- name: MultiPlus Configured Output Voltage
|
- name: Charger On Off Raw
|
||||||
unique_id: multiplus_configured_output_voltage
|
slave: 223
|
||||||
slave: *multiplus_unit_id
|
address: 2317
|
||||||
address: 107
|
|
||||||
input_type: holding
|
input_type: holding
|
||||||
data_type: uint16
|
data_type: uint16
|
||||||
scale: 0.01
|
|
||||||
precision: 2
|
|
||||||
unit_of_measurement: "V"
|
|
||||||
device_class: voltage
|
|
||||||
state_class: measurement
|
|
||||||
|
|
||||||
- name: MultiPlus PowerAssist Enabled Raw
|
|
||||||
unique_id: multiplus_powerassist_enabled_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 108
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus UPS Function Raw
|
|
||||||
unique_id: multiplus_ups_function_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 109
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus Weak AC Input Raw
|
|
||||||
unique_id: multiplus_weak_ac_input_raw
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 129
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint16
|
|
||||||
|
|
||||||
- name: MultiPlus Nominal Inverter Power
|
|
||||||
unique_id: multiplus_nominal_inverter_power
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 130
|
|
||||||
input_type: holding
|
|
||||||
data_type: uint32
|
|
||||||
scale: 1
|
scale: 1
|
||||||
precision: 0
|
|
||||||
unit_of_measurement: "W"
|
|
||||||
device_class: power
|
|
||||||
state_class: measurement
|
state_class: measurement
|
||||||
|
unique_id: charger_on_off_raw
|
||||||
|
|
||||||
|
- name: Charger Charge State Raw
|
||||||
|
slave: 223
|
||||||
|
address: 2318
|
||||||
|
input_type: holding
|
||||||
|
data_type: uint16
|
||||||
|
scale: 1
|
||||||
|
state_class: measurement
|
||||||
|
unique_id: charger_charge_state_raw
|
||||||
|
|
||||||
|
- name: Charger Error Code
|
||||||
|
slave: 223
|
||||||
|
address: 2319
|
||||||
|
input_type: holding
|
||||||
|
data_type: uint16
|
||||||
|
scale: 1
|
||||||
|
state_class: measurement
|
||||||
|
unique_id: charger_error_code
|
||||||
|
|
||||||
|
- name: Charger Relay State
|
||||||
|
slave: 223
|
||||||
|
address: 2320
|
||||||
|
input_type: holding
|
||||||
|
data_type: uint16
|
||||||
|
scale: 1
|
||||||
|
state_class: measurement
|
||||||
|
unique_id: charger_relay_state
|
||||||
|
|
||||||
|
- name: Charger Low Voltage Alarm
|
||||||
|
slave: 223
|
||||||
|
address: 2321
|
||||||
|
input_type: holding
|
||||||
|
data_type: uint16
|
||||||
|
scale: 1
|
||||||
|
state_class: measurement
|
||||||
|
unique_id: charger_low_voltage_alarm
|
||||||
|
|
||||||
|
- name: Charger High Voltage Alarm
|
||||||
|
slave: 223
|
||||||
|
address: 2322
|
||||||
|
input_type: holding
|
||||||
|
data_type: uint16
|
||||||
|
scale: 1
|
||||||
|
state_class: measurement
|
||||||
|
unique_id: charger_high_voltage_alarm
|
||||||
|
|
||||||
template:
|
template:
|
||||||
- sensor:
|
- sensor:
|
||||||
@@ -762,208 +439,34 @@ template:
|
|||||||
{{ v100 }}
|
{{ v100 }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
- name: MultiPlus State
|
- name: Charger On Off
|
||||||
unique_id: multiplus_state
|
|
||||||
availability: "{{ is_number(states('sensor.multiplus_state_raw')) }}"
|
|
||||||
state: >-
|
state: >-
|
||||||
{% set v = states('sensor.multiplus_state_raw') | int(-1) %}
|
{% set v = states('sensor.charger_on_off_raw')|int %}
|
||||||
{{ {
|
{{ {0:'Off',1:'On',2:'Error',3:'Unavailable'}.get(v, 'Unknown') }}
|
||||||
0:'Off',1:'Low power',2:'Fault',3:'Bulk',4:'Absorption',5:'Float',
|
|
||||||
6:'Storage',7:'Equalize',8:'Pass-through',9:'Inverting',
|
|
||||||
10:'PowerAssist',11:'Power supply',244:'Sustain',252:'External control'
|
|
||||||
}.get(v, 'Unknown') }}
|
|
||||||
|
|
||||||
# Keep the existing charger entities and energy history.
|
|
||||||
- name: Charger Charge State
|
- name: Charger Charge State
|
||||||
availability: "{{ is_number(states('sensor.multiplus_charge_state_raw')) }}"
|
|
||||||
state: >-
|
state: >-
|
||||||
{% set v = states('sensor.multiplus_charge_state_raw') | int(-1) %}
|
{% set v = states('sensor.charger_charge_state_raw')|int %}
|
||||||
{{ {
|
{{ {
|
||||||
0:'Initialising',1:'Bulk',2:'Absorption',3:'Float',4:'Storage',
|
0:'Off',1:'Low Power',2:'Fault',3:'Bulk',4:'Absorption',5:'Float',
|
||||||
5:'Absorption repeat',6:'Forced absorption',7:'Equalize',
|
6:'Storage',7:'Equalize/Manual',8:'External Control'
|
||||||
8:'Bulk stopped',9:'Unknown'
|
}.get(v,'Unknown') }}
|
||||||
}.get(v, 'Unknown') }}
|
|
||||||
|
|
||||||
- name: MultiPlus Active Input
|
|
||||||
unique_id: multiplus_active_input
|
|
||||||
availability: "{{ is_number(states('sensor.multiplus_active_input_raw')) }}"
|
|
||||||
state: >-
|
|
||||||
{{ {0:'AC input 1',1:'AC input 2',240:'Disconnected'}
|
|
||||||
.get(states('sensor.multiplus_active_input_raw') | int(-1), 'Unknown') }}
|
|
||||||
|
|
||||||
# VE.Bus DC current is positive while charging and negative while inverting.
|
|
||||||
- name: MultiPlus DC Power
|
|
||||||
unique_id: multiplus_dc_power
|
|
||||||
unit_of_measurement: "W"
|
|
||||||
device_class: power
|
|
||||||
state_class: measurement
|
|
||||||
availability: >-
|
|
||||||
{{ is_number(states('sensor.multiplus_battery_voltage'))
|
|
||||||
and is_number(states('sensor.multiplus_battery_current')) }}
|
|
||||||
state: >-
|
|
||||||
{{ (states('sensor.multiplus_battery_voltage') | float(0)
|
|
||||||
* states('sensor.multiplus_battery_current') | float(0)) | round(1) }}
|
|
||||||
|
|
||||||
- name: "Charger DC Wattage"
|
- name: "Charger DC Wattage"
|
||||||
unique_id: charger_dc_wattage
|
unique_id: charger_dc_wattage
|
||||||
unit_of_measurement: "W"
|
unit_of_measurement: "W"
|
||||||
device_class: power
|
device_class: power
|
||||||
state_class: measurement
|
state_class: measurement
|
||||||
availability: "{{ is_number(states('sensor.multiplus_dc_power')) }}"
|
|
||||||
state: >-
|
state: >-
|
||||||
{{ [states('sensor.multiplus_dc_power') | float(0), 0] | max }}
|
{% set v = states('sensor.charger_output_1_voltage')|float(0) %}
|
||||||
|
{% set a = states('sensor.charger_output_1_current')|float(0) %}
|
||||||
- name: MultiPlus Inverter DC Power
|
{{ (v * a) | round(1) }}
|
||||||
unique_id: multiplus_inverter_dc_power
|
|
||||||
unit_of_measurement: "W"
|
|
||||||
device_class: power
|
|
||||||
state_class: measurement
|
|
||||||
availability: "{{ is_number(states('sensor.multiplus_dc_power')) }}"
|
|
||||||
state: >-
|
|
||||||
{{ [0 - states('sensor.multiplus_dc_power') | float(0), 0] | max }}
|
|
||||||
|
|
||||||
- binary_sensor:
|
- binary_sensor:
|
||||||
- name: MultiPlus AC Input Connected
|
- name: Charger Low Voltage Alarm Active
|
||||||
unique_id: multiplus_ac_input_connected
|
state: "{{ states('sensor.charger_low_voltage_alarm')|int == 2 }}"
|
||||||
device_class: power
|
- name: Charger High Voltage Alarm Active
|
||||||
# Register 29 identifies the selected input; it alone does not establish
|
state: "{{ states('sensor.charger_high_voltage_alarm')|int == 2 }}"
|
||||||
# that the Multi is using AC. Keep the entity ID, but report active use.
|
|
||||||
availability: >-
|
|
||||||
{{ states('sensor.multiplus_active_input_raw') | int(-1) in [0, 1, 240]
|
|
||||||
and states('sensor.multiplus_mode_raw') | int(-1) in [1, 2, 3, 4]
|
|
||||||
and states('sensor.multiplus_state_raw') | int(-1)
|
|
||||||
in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 244, 252] }}
|
|
||||||
state: >-
|
|
||||||
{{ states('sensor.multiplus_active_input_raw') | int(-1) in [0, 1]
|
|
||||||
and states('sensor.multiplus_mode_raw') | int(-1) in [1, 2, 3]
|
|
||||||
and states('sensor.multiplus_state_raw') | int(-1)
|
|
||||||
in [3, 4, 5, 6, 7, 8, 10, 11, 244, 252] }}
|
|
||||||
|
|
||||||
- name: MultiPlus High Temperature Alarm
|
|
||||||
unique_id: multiplus_high_temperature_alarm
|
|
||||||
device_class: problem
|
|
||||||
availability: >-
|
|
||||||
{{ states('sensor.multiplus_high_temperature_alarm_raw') | int(-1) in [0, 1, 2] }}
|
|
||||||
state: "{{ states('sensor.multiplus_high_temperature_alarm_raw') | int(0) > 0 }}"
|
|
||||||
|
|
||||||
- name: MultiPlus Low Battery Alarm
|
|
||||||
unique_id: multiplus_low_battery_alarm
|
|
||||||
device_class: problem
|
|
||||||
availability: >-
|
|
||||||
{{ states('sensor.multiplus_low_battery_alarm_raw') | int(-1) in [0, 1, 2] }}
|
|
||||||
state: "{{ states('sensor.multiplus_low_battery_alarm_raw') | int(0) > 0 }}"
|
|
||||||
|
|
||||||
- name: MultiPlus Overload Alarm
|
|
||||||
unique_id: multiplus_overload_alarm
|
|
||||||
device_class: problem
|
|
||||||
availability: >-
|
|
||||||
{{ states('sensor.multiplus_overload_alarm_raw') | int(-1) in [0, 1, 2] }}
|
|
||||||
state: "{{ states('sensor.multiplus_overload_alarm_raw') | int(0) > 0 }}"
|
|
||||||
|
|
||||||
- name: MultiPlus Ripple Alarm
|
|
||||||
unique_id: multiplus_ripple_alarm
|
|
||||||
device_class: problem
|
|
||||||
availability: >-
|
|
||||||
{{ states('sensor.multiplus_ripple_alarm_raw') | int(-1) in [0, 1, 2] }}
|
|
||||||
state: "{{ states('sensor.multiplus_ripple_alarm_raw') | int(0) > 0 }}"
|
|
||||||
|
|
||||||
- name: MultiPlus Temperature Sensor Alarm
|
|
||||||
unique_id: multiplus_temperature_sensor_alarm
|
|
||||||
device_class: problem
|
|
||||||
availability: >-
|
|
||||||
{{ states('sensor.multiplus_temperature_sensor_alarm_raw') | int(-1) in [0, 1, 2] }}
|
|
||||||
state: "{{ states('sensor.multiplus_temperature_sensor_alarm_raw') | int(0) > 0 }}"
|
|
||||||
|
|
||||||
- name: MultiPlus Voltage Sensor Alarm
|
|
||||||
unique_id: multiplus_voltage_sensor_alarm
|
|
||||||
device_class: problem
|
|
||||||
availability: >-
|
|
||||||
{{ states('sensor.multiplus_voltage_sensor_alarm_raw') | int(-1) in [0, 1, 2] }}
|
|
||||||
state: "{{ states('sensor.multiplus_voltage_sensor_alarm_raw') | int(0) > 0 }}"
|
|
||||||
|
|
||||||
- name: MultiPlus Grid Lost Alarm
|
|
||||||
unique_id: multiplus_grid_lost_alarm
|
|
||||||
device_class: problem
|
|
||||||
availability: >-
|
|
||||||
{{ states('sensor.multiplus_grid_lost_alarm_raw') | int(-1) in [0, 2] }}
|
|
||||||
state: "{{ is_state('sensor.multiplus_grid_lost_alarm_raw', '2') }}"
|
|
||||||
|
|
||||||
- name: MultiPlus PowerAssist Enabled
|
|
||||||
unique_id: multiplus_powerassist_enabled
|
|
||||||
availability: >-
|
|
||||||
{{ states('sensor.multiplus_powerassist_enabled_raw') | int(-1) in [0, 1] }}
|
|
||||||
state: "{{ is_state('sensor.multiplus_powerassist_enabled_raw', '1') }}"
|
|
||||||
|
|
||||||
- name: MultiPlus UPS Enabled
|
|
||||||
unique_id: multiplus_ups_enabled
|
|
||||||
availability: >-
|
|
||||||
{{ states('sensor.multiplus_ups_function_raw') | int(-1) in [0, 1] }}
|
|
||||||
# Victron register 109 uses 0 for enabled and 1 for disabled.
|
|
||||||
state: "{{ is_state('sensor.multiplus_ups_function_raw', '0') }}"
|
|
||||||
|
|
||||||
# These controls read their state from the Multi; they never write on startup.
|
|
||||||
# GX/Digital Multi Control/VE.Bus BMS settings can restrict remote control.
|
|
||||||
- select:
|
|
||||||
- name: MultiPlus Mode
|
|
||||||
unique_id: multiplus_mode
|
|
||||||
icon: mdi:power-settings
|
|
||||||
availability: >-
|
|
||||||
{{ states('sensor.multiplus_mode_raw') | int(-1) in [1, 2, 3, 4] }}
|
|
||||||
state: >-
|
|
||||||
{{ {1:'Charger only',2:'Inverter only',3:'On',4:'Off'}
|
|
||||||
.get(states('sensor.multiplus_mode_raw') | int(-1), 'Unknown') }}
|
|
||||||
options: "{{ ['On', 'Charger only', 'Inverter only', 'Off'] }}"
|
|
||||||
select_option:
|
|
||||||
- condition: template
|
|
||||||
value_template: >-
|
|
||||||
{{ states('sensor.multiplus_mode_raw') | int(-1) in [1, 2, 3, 4]
|
|
||||||
and option in ['On', 'Charger only', 'Inverter only', 'Off'] }}
|
|
||||||
- action: modbus.write_register
|
|
||||||
data:
|
|
||||||
hub: victron_gx
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 33
|
|
||||||
value: "{{ {'Charger only':1,'Inverter only':2,'On':3,'Off':4}[option] }}"
|
|
||||||
- delay:
|
|
||||||
seconds: 2
|
|
||||||
- action: homeassistant.update_entity
|
|
||||||
target:
|
|
||||||
entity_id:
|
|
||||||
- sensor.multiplus_mode_raw
|
|
||||||
- sensor.multiplus_state_raw
|
|
||||||
- sensor.multiplus_active_input_raw
|
|
||||||
|
|
||||||
- number:
|
|
||||||
- name: MultiPlus AC Input Current Limit
|
|
||||||
unique_id: multiplus_ac_input_current_limit
|
|
||||||
icon: mdi:current-ac
|
|
||||||
device_class: current
|
|
||||||
unit_of_measurement: "A"
|
|
||||||
min: 0
|
|
||||||
# Van shore-power plug rating; this is a UI bound, not a startup setting.
|
|
||||||
max: 30
|
|
||||||
step: 0.1
|
|
||||||
availability: >-
|
|
||||||
{{ is_number(states('sensor.multiplus_ac_input_current_limit_readback'))
|
|
||||||
and states('sensor.multiplus_ac_input_current_limit_readback') | float(-1) >= 0 }}
|
|
||||||
state: "{{ states('sensor.multiplus_ac_input_current_limit_readback') | float(0) }}"
|
|
||||||
set_value:
|
|
||||||
- condition: template
|
|
||||||
value_template: >-
|
|
||||||
{{ is_number(states('sensor.multiplus_ac_input_current_limit_readback'))
|
|
||||||
and is_number(value) and 0 <= value | float(-1) <= 30 }}
|
|
||||||
- action: modbus.write_register
|
|
||||||
data:
|
|
||||||
hub: victron_gx
|
|
||||||
slave: *multiplus_unit_id
|
|
||||||
address: 22
|
|
||||||
# Register 22 is in tenths of an amp: 10.8 A -> 108.
|
|
||||||
value: "{{ (value | float * 10) | round(0) | int }}"
|
|
||||||
- delay:
|
|
||||||
seconds: 2
|
|
||||||
- action: homeassistant.update_entity
|
|
||||||
target:
|
|
||||||
entity_id: sensor.multiplus_ac_input_current_limit_readback
|
|
||||||
|
|
||||||
sensor:
|
sensor:
|
||||||
- platform: integration
|
- platform: integration
|
||||||
@@ -993,16 +496,6 @@ sensor:
|
|||||||
max_sub_interval:
|
max_sub_interval:
|
||||||
minutes: 5
|
minutes: 5
|
||||||
|
|
||||||
- platform: integration
|
|
||||||
source: sensor.multiplus_inverter_dc_power
|
|
||||||
name: MultiPlus Inverter DC Energy
|
|
||||||
unique_id: multiplus_inverter_dc_energy
|
|
||||||
unit_prefix: k
|
|
||||||
round: 2
|
|
||||||
method: trapezoidal
|
|
||||||
max_sub_interval:
|
|
||||||
minutes: 5
|
|
||||||
|
|
||||||
utility_meter:
|
utility_meter:
|
||||||
dc_load_energy_daily:
|
dc_load_energy_daily:
|
||||||
source: sensor.dc_system_energy
|
source: sensor.dc_system_energy
|
||||||
@@ -1027,11 +520,3 @@ utility_meter:
|
|||||||
charger_dc_wattage_monthly:
|
charger_dc_wattage_monthly:
|
||||||
source: sensor.dc_charger_energy
|
source: sensor.dc_charger_energy
|
||||||
cycle: monthly
|
cycle: monthly
|
||||||
|
|
||||||
multiplus_inverter_dc_energy_daily:
|
|
||||||
source: sensor.multiplus_inverter_dc_energy
|
|
||||||
cycle: daily
|
|
||||||
|
|
||||||
multiplus_inverter_dc_energy_monthly:
|
|
||||||
source: sensor.multiplus_inverter_dc_energy
|
|
||||||
cycle: monthly
|
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
# Kanidm on Jeeves
|
||||||
|
|
||||||
|
Kanidm is served at **https://auth.tmmworkshop.com**. Portal terminates public
|
||||||
|
HTTPS and forwards requests over Tailscale to Jeeves on port 8443, verifying
|
||||||
|
Jeeves's TLS certificate. Only the Tailscale interface exposes that backend port.
|
||||||
|
|
||||||
|
The service module is automatically imported by `services/default.nix`.
|
||||||
|
`services/kanidm.nix` pins Kanidm to the 1.11 release series; review the
|
||||||
|
[upgrade guide](https://kanidm.github.io/kanidm/stable/server_updates.html)
|
||||||
|
before changing that series. The flake lock determines the patch release.
|
||||||
|
|
||||||
|
## Before deployment
|
||||||
|
|
||||||
|
1. Point `auth.tmmworkshop.com` at Portal's public address, using the same DNS
|
||||||
|
arrangement as `gitea.tmmworkshop.com`. Port 80 must reach Portal for ACME.
|
||||||
|
2. Enable [HTTPS certificates in Tailscale](https://tailscale.com/kb/1153/enabling-https).
|
||||||
|
Jeeves must be able to obtain a certificate for `jeeves.taile39c31.ts.net`.
|
||||||
|
3. Allow Portal to reach Jeeves on TCP 8443 in your Tailscale policy.
|
||||||
|
|
||||||
|
The trusted proxy address in `services/kanidm.nix` is Portal's current Tailscale
|
||||||
|
IPv4 address, `100.80.102.33`. Update it if Portal is re-enrolled with a new address.
|
||||||
|
HAProxy connects over IPv4 and replaces incoming `X-Forwarded-For` headers.
|
||||||
|
|
||||||
|
## Deploy
|
||||||
|
|
||||||
|
Ensure the new Nix file is tracked by Git before using this Git-backed flake.
|
||||||
|
From this repository, using the existing SSH aliases:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nixos-rebuild switch --flake .#jeeves --target-host jeeves --sudo
|
||||||
|
nixos-rebuild switch --flake .#portal-1 --target-host portal-1 --sudo
|
||||||
|
```
|
||||||
|
|
||||||
|
Deploy Jeeves first, then Portal. Portal manages the public Let's Encrypt
|
||||||
|
certificate. `kanidm-tls.service` on Jeeves obtains the backend certificate and
|
||||||
|
checks for renewal daily, restarting Kanidm only when the certificate changes.
|
||||||
|
Private keys are generated at runtime and never stored in this repository or
|
||||||
|
the Nix store.
|
||||||
|
|
||||||
|
On Jeeves, check startup:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo systemctl status kanidm-tls.service kanidm.service
|
||||||
|
sudo journalctl -u kanidm-tls.service -u kanidm.service -n 100
|
||||||
|
```
|
||||||
|
|
||||||
|
If the initial certificate request fails, fix the Tailscale HTTPS configuration
|
||||||
|
and run `sudo systemctl restart kanidm.service`; its dependency retries the
|
||||||
|
certificate request. A successful oneshot certificate service normally appears
|
||||||
|
as inactive after finishing.
|
||||||
|
|
||||||
|
After both hosts are deployed:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl --fail https://auth.tmmworkshop.com/status
|
||||||
|
```
|
||||||
|
|
||||||
|
## First login
|
||||||
|
|
||||||
|
On Jeeves, recover the initial administrator passwords interactively:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo kanidmd recover-account admin
|
||||||
|
sudo kanidmd recover-account idm_admin
|
||||||
|
kanidm login --name idm_admin
|
||||||
|
kanidm person create richie "Richie"
|
||||||
|
kanidm person credential create-reset-token richie
|
||||||
|
```
|
||||||
|
|
||||||
|
Store the recovered passwords securely. Follow the reset URL to enroll your
|
||||||
|
personal account's passkey. `admin` manages the Kanidm server; `idm_admin`
|
||||||
|
manages people, groups, and application integrations. Creating `richie` does
|
||||||
|
not automatically grant administrator rights. The client is installed and
|
||||||
|
configured to use `https://auth.tmmworkshop.com`.
|
||||||
|
|
||||||
|
Register each website as its own OAuth2/OIDC client and each backend identity
|
||||||
|
as a service account, then grant application scopes through groups. This
|
||||||
|
deployment does not create application clients or change existing sites' login
|
||||||
|
settings. See the [OAuth2 guide](https://kanidm.github.io/kanidm/stable/integrations/oauth2.html)
|
||||||
|
and [service-account guide](https://kanidm.github.io/kanidm/stable/accounts/service_accounts.html).
|
||||||
|
|
||||||
|
## Storage and recovery
|
||||||
|
|
||||||
|
- Database: `/var/lib/kanidm/kanidm.db` on Jeeves's existing ZFS `/var` filesystem.
|
||||||
|
- Online backups: `/var/lib/kanidm/backups`, daily at 02:30, retaining 14.
|
||||||
|
- Backend certificate and key: `/var/lib/kanidm-tls`, readable by Kanidm.
|
||||||
|
- Server configuration: `/etc/kanidm/server.toml`.
|
||||||
|
|
||||||
|
The existing `root_pool/var` snapshot policy covers the database and backups.
|
||||||
|
Copy backups off Jeeves as part of disaster recovery; local snapshots do not
|
||||||
|
protect against loss of the host. Follow Kanidm's
|
||||||
|
[backup and restore instructions](https://kanidm.github.io/kanidm/stable/backup_and_restore.html).
|
||||||
|
|
||||||
|
The configured identity domain and origin are both `auth.tmmworkshop.com`.
|
||||||
|
Changing them after enrollment can affect passkeys and application integrations;
|
||||||
|
follow the [domain rename guide](https://kanidm.github.io/kanidm/stable/domain_rename.html).
|
||||||
@@ -8,6 +8,7 @@ let
|
|||||||
grafana = 3000;
|
grafana = 3000;
|
||||||
jellyfin_http = 8096;
|
jellyfin_http = 8096;
|
||||||
jellyswarrm = 3100;
|
jellyswarrm = 3100;
|
||||||
|
kanidm = 8443;
|
||||||
nix_binary_cache = 5000;
|
nix_binary_cache = 5000;
|
||||||
ollama = 11434;
|
ollama = 11434;
|
||||||
open_webui = 8080;
|
open_webui = 8080;
|
||||||
@@ -28,6 +29,7 @@ in
|
|||||||
ports.gems
|
ports.gems
|
||||||
ports.jellyfin_http
|
ports.jellyfin_http
|
||||||
ports.jellyswarrm
|
ports.jellyswarrm
|
||||||
|
ports.kanidm
|
||||||
ports.nix_binary_cache
|
ports.nix_binary_cache
|
||||||
ports.share
|
ports.share
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
{ config, pkgs, ... }:
|
||||||
|
let
|
||||||
|
certificateDir = "/var/lib/kanidm-tls";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.kanidm = {
|
||||||
|
# Pin the minor release: Kanidm upgrades require following its upgrade guide.
|
||||||
|
package = pkgs.kanidm_1_11;
|
||||||
|
server = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
domain = "auth.tmmworkshop.com";
|
||||||
|
origin = "https://auth.tmmworkshop.com";
|
||||||
|
bindaddress = "0.0.0.0:8443";
|
||||||
|
db_fs_type = "zfs";
|
||||||
|
tls_chain = "${certificateDir}/certificate.pem";
|
||||||
|
tls_key = "${certificateDir}/private-key.pem";
|
||||||
|
|
||||||
|
# Only Portal may supply the original client address. HAProxy replaces
|
||||||
|
# X-Forwarded-For, so clients cannot supply a forged address themselves.
|
||||||
|
http_client_address_info.x-forward-for = [ "100.80.102.33" ];
|
||||||
|
|
||||||
|
# /var/lib/kanidm is on root_pool/var, which is already snapshotted.
|
||||||
|
online_backup = {
|
||||||
|
schedule = "30 2 * * *";
|
||||||
|
versions = 14;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
client = {
|
||||||
|
enable = true;
|
||||||
|
settings.uri = "https://auth.tmmworkshop.com";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd = {
|
||||||
|
services = {
|
||||||
|
kanidm = {
|
||||||
|
requires = [ "kanidm-tls.service" ];
|
||||||
|
after = [ "kanidm-tls.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Kanidm requires TLS even behind HAProxy. Use Jeeves's Tailscale
|
||||||
|
# certificate so Portal can verify both the CA and the backend hostname.
|
||||||
|
# HTTPS certificates must be enabled in the Tailscale admin console.
|
||||||
|
kanidm-tls = {
|
||||||
|
description = "Obtain and renew Kanidm's backend TLS certificate";
|
||||||
|
requires = [ "tailscaled.service" ];
|
||||||
|
wants = [ "tailscaled-autoconnect.service" ];
|
||||||
|
after = [
|
||||||
|
"tailscaled.service"
|
||||||
|
"tailscaled-autoconnect.service"
|
||||||
|
];
|
||||||
|
path = [
|
||||||
|
config.services.tailscale.package
|
||||||
|
pkgs.coreutils
|
||||||
|
pkgs.systemd
|
||||||
|
];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = "root";
|
||||||
|
Group = "kanidm";
|
||||||
|
StateDirectory = "kanidm-tls";
|
||||||
|
StateDirectoryMode = "0750";
|
||||||
|
RuntimeDirectory = "kanidm-tls";
|
||||||
|
RuntimeDirectoryMode = "0700";
|
||||||
|
UMask = "0077";
|
||||||
|
TimeoutStartSec = "2min";
|
||||||
|
};
|
||||||
|
script = ''
|
||||||
|
set -euo pipefail
|
||||||
|
tailscale cert --min-validity 720h \
|
||||||
|
--cert-file /run/kanidm-tls/certificate.pem \
|
||||||
|
--key-file /run/kanidm-tls/private-key.pem \
|
||||||
|
jeeves.taile39c31.ts.net
|
||||||
|
|
||||||
|
if ! cmp -s /run/kanidm-tls/certificate.pem ${certificateDir}/certificate.pem \
|
||||||
|
|| ! cmp -s /run/kanidm-tls/private-key.pem ${certificateDir}/private-key.pem; then
|
||||||
|
install -m 0640 -o root -g kanidm /run/kanidm-tls/certificate.pem ${certificateDir}/certificate.pem
|
||||||
|
install -m 0640 -o root -g kanidm /run/kanidm-tls/private-key.pem ${certificateDir}/private-key.pem
|
||||||
|
|
||||||
|
# The NixOS service bind-mounts the certificate files, so restart to
|
||||||
|
# pick up renewals. Do not wait on a service that depends on this one.
|
||||||
|
if systemctl is-active --quiet kanidm.service; then
|
||||||
|
systemctl --no-block try-restart kanidm.service
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
timers.kanidm-tls = {
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "daily";
|
||||||
|
Persistent = true;
|
||||||
|
RandomizedDelaySec = "1h";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -32,7 +32,7 @@ defaults
|
|||||||
#Application Setup
|
#Application Setup
|
||||||
frontend ContentSwitching
|
frontend ContentSwitching
|
||||||
bind [::]:80 v4v6
|
bind [::]:80 v4v6
|
||||||
bind [::]:443 v4v6 ssl crt /var/lib/acme/audiobookshelf.tmmworkshop.com/full.pem crt /var/lib/acme/cache.tmmworkshop.com/full.pem crt /var/lib/acme/gems.tmmworkshop.com/full.pem crt /var/lib/acme/jellyfin.tmmworkshop.com/full.pem crt /var/lib/acme/share.tmmworkshop.com/full.pem crt /var/lib/acme/gitea.tmmworkshop.com/full.pem
|
bind [::]:443 v4v6 ssl crt /var/lib/acme/audiobookshelf.tmmworkshop.com/full.pem crt /var/lib/acme/auth.tmmworkshop.com/full.pem crt /var/lib/acme/cache.tmmworkshop.com/full.pem crt /var/lib/acme/gems.tmmworkshop.com/full.pem crt /var/lib/acme/jellyfin.tmmworkshop.com/full.pem crt /var/lib/acme/share.tmmworkshop.com/full.pem crt /var/lib/acme/gitea.tmmworkshop.com/full.pem
|
||||||
mode http
|
mode http
|
||||||
|
|
||||||
# ACME challenge routing (must be first)
|
# ACME challenge routing (must be first)
|
||||||
@@ -40,6 +40,7 @@ frontend ContentSwitching
|
|||||||
|
|
||||||
# Host ACLs (defined early so rate-limiting can scope to a single vhost)
|
# Host ACLs (defined early so rate-limiting can scope to a single vhost)
|
||||||
acl host_audiobookshelf hdr(host) -i audiobookshelf.tmmworkshop.com
|
acl host_audiobookshelf hdr(host) -i audiobookshelf.tmmworkshop.com
|
||||||
|
acl host_auth hdr(host) -i auth.tmmworkshop.com
|
||||||
acl host_cache hdr(host) -i cache.tmmworkshop.com
|
acl host_cache hdr(host) -i cache.tmmworkshop.com
|
||||||
acl host_jellyfin hdr(host) -i jellyfin.tmmworkshop.com
|
acl host_jellyfin hdr(host) -i jellyfin.tmmworkshop.com
|
||||||
acl host_share hdr(host) -i share.tmmworkshop.com
|
acl host_share hdr(host) -i share.tmmworkshop.com
|
||||||
@@ -111,6 +112,7 @@ frontend ContentSwitching
|
|||||||
|
|
||||||
use_backend acme_challenge if is_acme
|
use_backend acme_challenge if is_acme
|
||||||
use_backend audiobookshelf_nodes if host_audiobookshelf
|
use_backend audiobookshelf_nodes if host_audiobookshelf
|
||||||
|
use_backend kanidm if host_auth
|
||||||
use_backend cache_nodes if host_cache
|
use_backend cache_nodes if host_cache
|
||||||
use_backend jellyfin if host_jellyfin
|
use_backend jellyfin if host_jellyfin
|
||||||
use_backend share_nodes if host_share
|
use_backend share_nodes if host_share
|
||||||
@@ -141,6 +143,15 @@ backend audiobookshelf_nodes
|
|||||||
mode http
|
mode http
|
||||||
server server jeeves:8000
|
server server jeeves:8000
|
||||||
|
|
||||||
|
backend kanidm
|
||||||
|
mode http
|
||||||
|
http-request set-header X-Forwarded-For %[src]
|
||||||
|
http-request set-header X-Forwarded-Proto https
|
||||||
|
option httpchk
|
||||||
|
http-check send meth GET uri /status ver HTTP/1.1 hdr Host auth.tmmworkshop.com
|
||||||
|
http-check expect status 200
|
||||||
|
server kanidm jeeves.taile39c31.ts.net:8443 ssl verify required ca-file /etc/ssl/certs/ca-certificates.crt verifyhost jeeves.taile39c31.ts.net sni str(jeeves.taile39c31.ts.net) check check-sni jeeves.taile39c31.ts.net resolve-prefer ipv4
|
||||||
|
|
||||||
backend cache_nodes
|
backend cache_nodes
|
||||||
mode http
|
mode http
|
||||||
server server jeeves:5000
|
server server jeeves:5000
|
||||||
|
|||||||
@@ -82,7 +82,6 @@
|
|||||||
"Michal",
|
"Michal",
|
||||||
"Nornsight",
|
"Nornsight",
|
||||||
"pydantic",
|
"pydantic",
|
||||||
"pyproject",
|
|
||||||
"sandboxing",
|
"sandboxing",
|
||||||
"syncthing",
|
"syncthing",
|
||||||
"vllm",
|
"vllm",
|
||||||
|
|||||||
Reference in new issue
Block a user