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>.
|
||||
</para>
|
||||
</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>
|
||||
<para>
|
||||
<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).
|
||||
|
||||
- [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.
|
||||
Available as [services.infnoise](options.html#opt-services.infnoise.enable).
|
||||
|
||||
|
|
|
@ -491,6 +491,7 @@
|
|||
./services/hardware/vdr.nix
|
||||
./services/home-automation/home-assistant.nix
|
||||
./services/home-automation/zigbee2mqtt.nix
|
||||
./services/home-automation/evcc.nix
|
||||
./services/logging/SystemdJournal2Gelf.nix
|
||||
./services/logging/awstats.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 {};
|
||||
etesync-dav = handleTest ./etesync-dav.nix {};
|
||||
extra-python-packages = handleTest ./extra-python-packages.nix {};
|
||||
evcc = handleTest ./evcc.nix {};
|
||||
fancontrol = handleTest ./fancontrol.nix {};
|
||||
fcitx = handleTest ./fcitx {};
|
||||
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 { };
|
||||
|
||||
enumer = callPackage ../tools/misc/enumer { };
|
||||
|
||||
evans = callPackage ../development/tools/evans { };
|
||||
|
||||
expressvpn = callPackage ../applications/networking/expressvpn { };
|
||||
|
@ -6452,6 +6454,8 @@ with pkgs;
|
|||
|
||||
ettercap = callPackage ../applications/networking/sniffers/ettercap { };
|
||||
|
||||
evcc = callPackage ../servers/home-automation/evcc { };
|
||||
|
||||
eventstat = callPackage ../os-specific/linux/eventstat { };
|
||||
|
||||
evillimiter = python3Packages.callPackage ../tools/networking/evillimiter { };
|
||||
|
|
Loading…
Reference in a new issue