Merge pull request #131475 from mweinelt/evcc
This commit is contained in:
commit
69335c46c4
9 changed files with 328 additions and 0 deletions
|
@ -278,6 +278,16 @@
|
||||||
<link linkend="opt-services.prometheus.sachet.enable">services.prometheus.sachet</link>.
|
<link linkend="opt-services.prometheus.sachet.enable">services.prometheus.sachet</link>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://evcc.io">EVCC</link> is an EV charge
|
||||||
|
controller with PV integration. It supports a multitude of
|
||||||
|
chargers, meters, vehicle APIs and more and ties that together
|
||||||
|
with a well-tested backend and a lightweight web frontend.
|
||||||
|
Available as
|
||||||
|
<link linkend="opt-services.evcc.enable">services.evcc</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<link xlink:href="https://github.com/leetronics/infnoise">infnoise</link>,
|
<link xlink:href="https://github.com/leetronics/infnoise">infnoise</link>,
|
||||||
|
|
|
@ -98,6 +98,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||||
|
|
||||||
- [Sachet](https://github.com/messagebird/sachet/), an SMS alerting tool for the Prometheus Alertmanager. Available as [services.prometheus.sachet](#opt-services.prometheus.sachet.enable).
|
- [Sachet](https://github.com/messagebird/sachet/), an SMS alerting tool for the Prometheus Alertmanager. Available as [services.prometheus.sachet](#opt-services.prometheus.sachet.enable).
|
||||||
|
|
||||||
|
- [EVCC](https://evcc.io) is an EV charge controller with PV integration. It supports a multitude of chargers, meters, vehicle APIs and more and ties that together with a well-tested backend and a lightweight web frontend. Available as [services.evcc](#opt-services.evcc.enable).
|
||||||
|
|
||||||
- [infnoise](https://github.com/leetronics/infnoise), a hardware True Random Number Generator dongle.
|
- [infnoise](https://github.com/leetronics/infnoise), a hardware True Random Number Generator dongle.
|
||||||
Available as [services.infnoise](options.html#opt-services.infnoise.enable).
|
Available as [services.infnoise](options.html#opt-services.infnoise.enable).
|
||||||
|
|
||||||
|
|
|
@ -491,6 +491,7 @@
|
||||||
./services/hardware/vdr.nix
|
./services/hardware/vdr.nix
|
||||||
./services/home-automation/home-assistant.nix
|
./services/home-automation/home-assistant.nix
|
||||||
./services/home-automation/zigbee2mqtt.nix
|
./services/home-automation/zigbee2mqtt.nix
|
||||||
|
./services/home-automation/evcc.nix
|
||||||
./services/logging/SystemdJournal2Gelf.nix
|
./services/logging/SystemdJournal2Gelf.nix
|
||||||
./services/logging/awstats.nix
|
./services/logging/awstats.nix
|
||||||
./services/logging/filebeat.nix
|
./services/logging/filebeat.nix
|
||||||
|
|
92
nixos/modules/services/home-automation/evcc.nix
Normal file
92
nixos/modules/services/home-automation/evcc.nix
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
{ lib
|
||||||
|
, pkgs
|
||||||
|
, config
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.evcc;
|
||||||
|
|
||||||
|
format = pkgs.formats.yaml {};
|
||||||
|
configFile = format.generate "evcc.yml" cfg.settings;
|
||||||
|
|
||||||
|
package = pkgs.evcc;
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
meta.maintainers = with lib.maintainers; [ hexa ];
|
||||||
|
|
||||||
|
options.services.evcc = with types; {
|
||||||
|
enable = mkEnableOption (lib.mdDoc "EVCC, the extensible EV Charge Controller with PV integration");
|
||||||
|
|
||||||
|
extraArgs = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
default = [];
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Extra arguments to pass to the evcc executable.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
type = format.type;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
evcc configuration as a Nix attribute set.
|
||||||
|
|
||||||
|
Check for possible options in the sample [evcc.dist.yaml](https://github.com/andig/evcc/blob/${package.version}/evcc.dist.yaml].
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.services.evcc = {
|
||||||
|
after = [
|
||||||
|
"network-online.target"
|
||||||
|
"mosquitto.target"
|
||||||
|
];
|
||||||
|
wantedBy = [
|
||||||
|
"multi-user.target"
|
||||||
|
];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${package}/bin/evcc --config ${configFile} ${escapeShellArgs cfg.extraArgs}";
|
||||||
|
CapabilityBoundingSet = [ "" ];
|
||||||
|
DeviceAllow = [
|
||||||
|
"char-ttyUSB"
|
||||||
|
];
|
||||||
|
DevicePolicy = "closed";
|
||||||
|
DynamicUser = true;
|
||||||
|
LockPersonality = true;
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
RestrictAddressFamilies = [
|
||||||
|
"AF_INET"
|
||||||
|
"AF_INET6"
|
||||||
|
"AF_UNIX"
|
||||||
|
];
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateUsers = true;
|
||||||
|
ProcSubset = "pid";
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectControlGroups= true;
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
SystemCallFilter = [
|
||||||
|
"@system-service"
|
||||||
|
"~@privileged"
|
||||||
|
];
|
||||||
|
UMask = "0077";
|
||||||
|
User = "evcc";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.buildDocsInSandbox = false;
|
||||||
|
}
|
|
@ -198,6 +198,7 @@ in {
|
||||||
etebase-server = handleTest ./etebase-server.nix {};
|
etebase-server = handleTest ./etebase-server.nix {};
|
||||||
etesync-dav = handleTest ./etesync-dav.nix {};
|
etesync-dav = handleTest ./etesync-dav.nix {};
|
||||||
extra-python-packages = handleTest ./extra-python-packages.nix {};
|
extra-python-packages = handleTest ./extra-python-packages.nix {};
|
||||||
|
evcc = handleTest ./evcc.nix {};
|
||||||
fancontrol = handleTest ./fancontrol.nix {};
|
fancontrol = handleTest ./fancontrol.nix {};
|
||||||
fcitx = handleTest ./fcitx {};
|
fcitx = handleTest ./fcitx {};
|
||||||
fenics = handleTest ./fenics.nix {};
|
fenics = handleTest ./fenics.nix {};
|
||||||
|
|
96
nixos/tests/evcc.nix
Normal file
96
nixos/tests/evcc.nix
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
import ./make-test-python.nix ({ pkgs, lib, ...} :
|
||||||
|
|
||||||
|
{
|
||||||
|
name = "evcc";
|
||||||
|
meta.maintainers = with lib.maintainers; [ hexa ];
|
||||||
|
|
||||||
|
nodes = {
|
||||||
|
machine = { config, ... }: {
|
||||||
|
services.evcc = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
network = {
|
||||||
|
schema = "http";
|
||||||
|
host = "localhost";
|
||||||
|
port = 7070;
|
||||||
|
};
|
||||||
|
|
||||||
|
log = "info";
|
||||||
|
|
||||||
|
site = {
|
||||||
|
title = "NixOS Test";
|
||||||
|
meters = {
|
||||||
|
grid = "grid";
|
||||||
|
pv = "pv";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
meters = [ {
|
||||||
|
type = "custom";
|
||||||
|
name = "grid";
|
||||||
|
power = {
|
||||||
|
source = "script";
|
||||||
|
cmd = "/bin/sh -c 'echo -4500'";
|
||||||
|
};
|
||||||
|
} {
|
||||||
|
type = "custom";
|
||||||
|
name = "pv";
|
||||||
|
power = {
|
||||||
|
source = "script";
|
||||||
|
cmd = "/bin/sh -c 'echo 7500'";
|
||||||
|
};
|
||||||
|
} ];
|
||||||
|
|
||||||
|
chargers = [ {
|
||||||
|
name = "dummy-charger";
|
||||||
|
type = "custom";
|
||||||
|
status = {
|
||||||
|
source = "script";
|
||||||
|
cmd = "/bin/sh -c 'echo charger status F'";
|
||||||
|
};
|
||||||
|
enabled = {
|
||||||
|
source = "script";
|
||||||
|
cmd = "/bin/sh -c 'echo charger enabled state false'";
|
||||||
|
};
|
||||||
|
enable = {
|
||||||
|
source = "script";
|
||||||
|
cmd = "/bin/sh -c 'echo set charger enabled state true'";
|
||||||
|
};
|
||||||
|
maxcurrent = {
|
||||||
|
source = "script";
|
||||||
|
cmd = "/bin/sh -c 'echo set charger max current 7200'";
|
||||||
|
};
|
||||||
|
} ];
|
||||||
|
|
||||||
|
loadpoints = [ {
|
||||||
|
title = "Dummy";
|
||||||
|
charger = "dummy-charger";
|
||||||
|
} ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
start_all()
|
||||||
|
|
||||||
|
machine.wait_for_unit("evcc.service")
|
||||||
|
machine.wait_for_open_port(7070)
|
||||||
|
|
||||||
|
with subtest("Check package version propagates into frontend"):
|
||||||
|
machine.fail(
|
||||||
|
"curl --fail http://localhost:7070 | grep '0.0.1-alpha'"
|
||||||
|
)
|
||||||
|
machine.succeed(
|
||||||
|
"curl --fail http://localhost:7070 | grep '${pkgs.evcc.version}'"
|
||||||
|
)
|
||||||
|
|
||||||
|
with subtest("Check journal for errors"):
|
||||||
|
_, output = machine.execute("journalctl -o cat -u evcc.service")
|
||||||
|
assert "ERROR" not in output
|
||||||
|
|
||||||
|
with subtest("Check systemd hardening"):
|
||||||
|
_, output = machine.execute("systemd-analyze security evcc.service | grep -v '✓'")
|
||||||
|
machine.log(output)
|
||||||
|
'';
|
||||||
|
})
|
96
pkgs/servers/home-automation/evcc/default.nix
Normal file
96
pkgs/servers/home-automation/evcc/default.nix
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
{ lib
|
||||||
|
, buildGoModule
|
||||||
|
, fetchFromGitHub
|
||||||
|
, fetchNpmDeps
|
||||||
|
, cacert
|
||||||
|
, go
|
||||||
|
, git
|
||||||
|
, enumer
|
||||||
|
, mockgen
|
||||||
|
, nodejs
|
||||||
|
, npmHooks
|
||||||
|
, nix-update-script
|
||||||
|
, nixosTests
|
||||||
|
, stdenv
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildGoModule rec {
|
||||||
|
pname = "evcc";
|
||||||
|
version = "0.107.1";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "evcc-io";
|
||||||
|
repo = pname;
|
||||||
|
rev = version;
|
||||||
|
hash = "sha256-Yu7ebZ6WkLpdvmg7H9A1Sveyu9SRuQ+78gFrCZrYhCU=";
|
||||||
|
};
|
||||||
|
|
||||||
|
vendorHash = "sha256-10W1BNHcdP77m7lJ/mc+jQeUigoUid3K0wI4bUm5y+s=";
|
||||||
|
|
||||||
|
npmDeps = fetchNpmDeps {
|
||||||
|
inherit src;
|
||||||
|
hash = "sha256-+l5LuxJAjrTvOL5XEQ4OIktdupSpn6IqrNX5x4MRmNw=";
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
nodejs
|
||||||
|
npmHooks.npmConfigHook
|
||||||
|
];
|
||||||
|
|
||||||
|
overrideModAttrs = _: {
|
||||||
|
nativeBuildInputs = [
|
||||||
|
enumer
|
||||||
|
go
|
||||||
|
git
|
||||||
|
cacert
|
||||||
|
mockgen
|
||||||
|
];
|
||||||
|
|
||||||
|
preBuild = ''
|
||||||
|
make assets
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
tags = [
|
||||||
|
"release"
|
||||||
|
];
|
||||||
|
|
||||||
|
ldflags = [
|
||||||
|
"-X github.com/evcc-io/evcc/server.Version=${version}"
|
||||||
|
"-X github.com/evcc-io/evcc/server.Commit=${src.rev}"
|
||||||
|
"-s"
|
||||||
|
"-w"
|
||||||
|
];
|
||||||
|
|
||||||
|
npmInstallFlags = [
|
||||||
|
"--legacy-peer-deps"
|
||||||
|
];
|
||||||
|
|
||||||
|
preBuild = ''
|
||||||
|
make ui
|
||||||
|
'';
|
||||||
|
|
||||||
|
doCheck = !stdenv.isDarwin; # tries to bind to local network, doesn't work in darwin sandbox
|
||||||
|
|
||||||
|
preCheck = ''
|
||||||
|
# requires network access
|
||||||
|
rm meter/template_test.go
|
||||||
|
'';
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
tests = {
|
||||||
|
inherit (nixosTests) evcc;
|
||||||
|
};
|
||||||
|
updateScript = nix-update-script {
|
||||||
|
attrPath = pname;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "EV Charge Controller";
|
||||||
|
homepage = "https://evcc.io";
|
||||||
|
changelog = "https://github.com/andig/evcc/releases/tag/${version}";
|
||||||
|
license = licenses.mit;
|
||||||
|
maintainers = with maintainers; [ hexa ];
|
||||||
|
};
|
||||||
|
}
|
26
pkgs/tools/misc/enumer/default.nix
Normal file
26
pkgs/tools/misc/enumer/default.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ lib
|
||||||
|
, stdenv
|
||||||
|
, fetchFromGitHub
|
||||||
|
, buildGoModule
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildGoModule rec {
|
||||||
|
pname = "enumer";
|
||||||
|
version = "1.5.7";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "dmarkham";
|
||||||
|
repo = "enumer";
|
||||||
|
rev = "refs/tags/v${version}";
|
||||||
|
hash = "sha256-2fVWrrWOiCtg7I3Lul2PgQ2u/qDEDioPSB61Tp0rfEo=";
|
||||||
|
};
|
||||||
|
|
||||||
|
vendorSha256 = "sha256-BmFv0ytRnjaB7z7Gb+38Fw2ObagnaFMnMhlejhaGxsk=";
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Go tool to auto generate methods for enums";
|
||||||
|
homepage = "https://github.com/dmarkham/enumer";
|
||||||
|
license = licenses.bsd2;
|
||||||
|
maintainers = with maintainers; [ hexa ];
|
||||||
|
};
|
||||||
|
}
|
|
@ -480,6 +480,8 @@ with pkgs;
|
||||||
|
|
||||||
efficient-compression-tool = callPackage ../tools/compression/efficient-compression-tool { };
|
efficient-compression-tool = callPackage ../tools/compression/efficient-compression-tool { };
|
||||||
|
|
||||||
|
enumer = callPackage ../tools/misc/enumer { };
|
||||||
|
|
||||||
evans = callPackage ../development/tools/evans { };
|
evans = callPackage ../development/tools/evans { };
|
||||||
|
|
||||||
expressvpn = callPackage ../applications/networking/expressvpn { };
|
expressvpn = callPackage ../applications/networking/expressvpn { };
|
||||||
|
@ -6452,6 +6454,8 @@ with pkgs;
|
||||||
|
|
||||||
ettercap = callPackage ../applications/networking/sniffers/ettercap { };
|
ettercap = callPackage ../applications/networking/sniffers/ettercap { };
|
||||||
|
|
||||||
|
evcc = callPackage ../servers/home-automation/evcc { };
|
||||||
|
|
||||||
eventstat = callPackage ../os-specific/linux/eventstat { };
|
eventstat = callPackage ../os-specific/linux/eventstat { };
|
||||||
|
|
||||||
evillimiter = python3Packages.callPackage ../tools/networking/evillimiter { };
|
evillimiter = python3Packages.callPackage ../tools/networking/evillimiter { };
|
||||||
|
|
Loading…
Reference in a new issue