Config UI: suggest serial devices for modbus (#25780)
This commit is contained in:
parent
25625e461b
commit
3c7476762b
9 changed files with 89 additions and 6 deletions
|
|
@ -108,6 +108,7 @@
|
|||
v-model:device="values['device']"
|
||||
v-model:baudrate="values['baudrate']"
|
||||
v-model:comset="values['comset']"
|
||||
component-id="device"
|
||||
:defaultId="modbus.ID ? Number(modbus.ID) : undefined"
|
||||
:defaultComset="modbus.Comset"
|
||||
:defaultBaudrate="modbus.Baudrate"
|
||||
|
|
|
|||
|
|
@ -121,15 +121,16 @@
|
|||
:id="formId('modbusDevice')"
|
||||
:label="$t('config.modbus.device')"
|
||||
:help="$t('config.modbus.deviceHint')"
|
||||
data-testid="modbus-device"
|
||||
>
|
||||
<PropertyField
|
||||
:id="formId('modbusDevice')"
|
||||
v-model:model-value="deviceModel"
|
||||
property="device"
|
||||
type="String"
|
||||
class="me-2"
|
||||
required
|
||||
:model-value="device"
|
||||
@change="$emit('update:device', $event.target.value)"
|
||||
:service-values="deviceServiceValues"
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow :id="formId('modbusBaudrate')" :label="$t('config.modbus.baudrate')">
|
||||
|
|
@ -165,6 +166,7 @@ import FormRow from "../FormRow.vue";
|
|||
import PropertyField from "../PropertyField.vue";
|
||||
import type { PropType } from "vue";
|
||||
import type { ModbusCapability } from "./index";
|
||||
import { loadServiceValues } from "./index";
|
||||
import {
|
||||
MODBUS_BAUDRATE,
|
||||
MODBUS_COMSET,
|
||||
|
|
@ -177,6 +179,7 @@ export default defineComponent({
|
|||
name: "Modbus",
|
||||
components: { FormRow, PropertyField },
|
||||
props: {
|
||||
componentId: { type: String, required: true },
|
||||
capabilities: {
|
||||
type: Array as PropType<ModbusCapability[]>,
|
||||
default: () => [],
|
||||
|
|
@ -209,9 +212,20 @@ export default defineComponent({
|
|||
protocol: MODBUS_PROTOCOL.TCP as MODBUS_PROTOCOL,
|
||||
MODBUS_PROTOCOL,
|
||||
MODBUS_CONNECTION,
|
||||
deviceServiceValues: [] as string[],
|
||||
localDevice: undefined as string | undefined,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
deviceModel: {
|
||||
get(): string | undefined {
|
||||
return this.localDevice !== undefined ? this.localDevice : this.device;
|
||||
},
|
||||
set(value: string | undefined) {
|
||||
this.localDevice = value;
|
||||
this.$emit("update:device", value);
|
||||
},
|
||||
},
|
||||
selectedModbus(): MODBUS_TYPE {
|
||||
if (this.connection === MODBUS_CONNECTION.SERIAL) {
|
||||
return MODBUS_TYPE.RS485_SERIAL;
|
||||
|
|
@ -254,10 +268,21 @@ export default defineComponent({
|
|||
this.setConnectionAndProtocolByModbus(newValue);
|
||||
}
|
||||
},
|
||||
connection() {
|
||||
this.applyServiceDefault();
|
||||
},
|
||||
device(newValue: string | undefined) {
|
||||
// Sync prop to local state
|
||||
if (newValue !== this.localDevice) {
|
||||
this.localDevice = newValue;
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.localDevice = this.device;
|
||||
this.setConnectionAndProtocolByModbus(this.modbus);
|
||||
this.$emit("update:modbus", this.selectedModbus);
|
||||
this.updateServiceValues();
|
||||
},
|
||||
methods: {
|
||||
setProtocolByCapabilities(capabilities: ModbusCapability[]) {
|
||||
|
|
@ -282,7 +307,21 @@ export default defineComponent({
|
|||
}
|
||||
},
|
||||
formId(name: string): string {
|
||||
return `${name}-${this.id}`;
|
||||
return `${name}-${this.componentId}`;
|
||||
},
|
||||
async updateServiceValues() {
|
||||
this.deviceServiceValues = await loadServiceValues("hardware/serial");
|
||||
this.applyServiceDefault();
|
||||
},
|
||||
applyServiceDefault() {
|
||||
// auto-apply device value if it's needed and exactly one option exists
|
||||
if (
|
||||
this.connection === MODBUS_CONNECTION.SERIAL &&
|
||||
this.deviceServiceValues.length === 1 &&
|
||||
!this.device
|
||||
) {
|
||||
this.deviceModel = this.deviceServiceValues[0];
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -87,11 +87,11 @@
|
|||
</h5>
|
||||
</div>
|
||||
<Modbus
|
||||
:id="index"
|
||||
v-model:baudrate="c.settings.baudrate"
|
||||
v-model:comset="c.settings.comset"
|
||||
v-model:device="c.settings.device"
|
||||
:modbus="getModbus(c.settings)"
|
||||
:component-id="`proxy-${index}`"
|
||||
:host="getHost(c.settings.uri)"
|
||||
:port="getPort(c.settings.uri)"
|
||||
:capabilities="['rs485', 'tcpip']"
|
||||
|
|
|
|||
|
|
@ -42,10 +42,10 @@ import (
|
|||
"github.com/evcc-io/evcc/tariff"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/util/config"
|
||||
_ "github.com/evcc-io/evcc/util/demo"
|
||||
"github.com/evcc-io/evcc/util/locale"
|
||||
"github.com/evcc-io/evcc/util/machine"
|
||||
"github.com/evcc-io/evcc/util/request"
|
||||
_ "github.com/evcc-io/evcc/util/service"
|
||||
"github.com/evcc-io/evcc/util/sponsor"
|
||||
"github.com/evcc-io/evcc/util/templates"
|
||||
"github.com/evcc-io/evcc/vehicle"
|
||||
|
|
|
|||
2
go.mod
2
go.mod
|
|
@ -103,6 +103,7 @@ require (
|
|||
github.com/volkszaehler/mbmd v0.0.0-20250808161051-499ae856f44e
|
||||
github.com/writeas/go-strip-markdown/v2 v2.1.1
|
||||
gitlab.com/bboehmke/sunny v0.16.0
|
||||
go.bug.st/serial v1.6.4
|
||||
go.uber.org/mock v0.6.0
|
||||
go.yaml.in/yaml/v4 v4.0.0-rc.3
|
||||
golang.org/x/crypto v0.45.0
|
||||
|
|
@ -146,6 +147,7 @@ require (
|
|||
github.com/clipperhouse/stringish v0.1.1 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
|
||||
github.com/creack/goselect v0.1.2 // indirect
|
||||
github.com/cronokirby/saferith v0.33.0 // indirect
|
||||
github.com/cstockton/go-conv v1.0.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -146,6 +146,8 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc
|
|||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
||||
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
|
||||
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
|
|
@ -779,6 +781,8 @@ gitlab.com/bboehmke/sunny v0.16.0 h1:arcU5MNupJ9KELOcSC82mYPGP/friBop+PxtybhqRwo
|
|||
gitlab.com/bboehmke/sunny v0.16.0/go.mod h1:F5AIuL7kYteSJFR5E+YEocxIdpyCXmtDciFmMQVjP88=
|
||||
gitlab.com/c0b/go-ordered-json v0.0.0-20201030195603-febf46534d5a h1:DxppxFKRqJ8WD6oJ3+ZXKDY0iMONQDl5UTg2aTyHh8k=
|
||||
gitlab.com/c0b/go-ordered-json v0.0.0-20201030195603-febf46534d5a/go.mod h1:NREvu3a57BaK0R1+ztrEzHWiZAihohNLQ6trPxlIqZI=
|
||||
go.bug.st/serial v1.6.4 h1:7FmqNPgVp3pu2Jz5PoPtbZ9jJO5gnEnZIvnI1lzve8A=
|
||||
go.bug.st/serial v1.6.4/go.mod h1:nofMJxTeNVny/m6+KaafC6vJGj3miwQZ6vW4BZUGJPI=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package demo
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
36
util/service/hardware.go
Normal file
36
util/service/hardware.go
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/evcc-io/evcc/server/service"
|
||||
serialports "go.bug.st/serial"
|
||||
)
|
||||
|
||||
func init() {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("GET /serial", getSerialPorts)
|
||||
|
||||
service.Register("hardware", mux)
|
||||
}
|
||||
|
||||
var (
|
||||
once sync.Once
|
||||
ports []string
|
||||
)
|
||||
|
||||
func getSerialPorts(w http.ResponseWriter, req *http.Request) {
|
||||
once.Do(func() {
|
||||
if env := os.Getenv("EVCC_SERIAL_PORTS"); env != "" {
|
||||
ports = strings.Split(env, ",")
|
||||
} else {
|
||||
ports, _ = serialports.GetPortsList()
|
||||
}
|
||||
})
|
||||
|
||||
json.NewEncoder(w).Encode(ports)
|
||||
}
|
||||
|
|
@ -706,6 +706,7 @@ modbus:
|
|||
help:
|
||||
de: USB-RS485 Gerätename
|
||||
en: USB-RS485 device name
|
||||
service: hardware/serial # not actually used
|
||||
example: /dev/ttyUSB0
|
||||
- name: baudrate
|
||||
description:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue