Skip to content

Commit

Permalink
Rename cmd folder to examples for clarity
Browse files Browse the repository at this point in the history
  • Loading branch information
DerAndereAndi committed Oct 28, 2024
1 parent fead1ce commit 7e021df
Show file tree
Hide file tree
Showing 12 changed files with 558 additions and 8 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ jobs:
- name: Test
run: go test -race -v -coverprofile=coverage_temp.out -covermode=atomic ./...

- name: Remove mocks and cmd from coverage
run: grep -v -e "/eebus-go/mocks/" -e "/eebus-go/usecases/mocks/" -e "/eebus-go/cmd/" coverage_temp.out > coverage.out
- name: Remove mocks and examples from coverage
run: grep -v -e "/eebus-go/mocks/" -e "/eebus-go/usecases/mocks/" -e "/eebus-go/examples/" coverage_temp.out > coverage.out

- name: Send coverage
uses: coverallsapp/github-action@v2
Expand Down
307 changes: 307 additions & 0 deletions examples/ced/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,307 @@
package main

import (
"crypto/ecdsa"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"fmt"
"log"
"os"
"os/signal"
"slices"
"strconv"
"syscall"
"time"

"github.com/enbility/eebus-go/api"
"github.com/enbility/eebus-go/service"
ucapi "github.com/enbility/eebus-go/usecases/api"
"github.com/enbility/eebus-go/usecases/eg/lpc"
"github.com/enbility/eebus-go/usecases/ma/mpc"
shipapi "github.com/enbility/ship-go/api"
"github.com/enbility/ship-go/cert"
spineapi "github.com/enbility/spine-go/api"
"github.com/enbility/spine-go/model"
)

var remoteSki string

type controlbox struct {
myService *service.Service

uclpc ucapi.EgLPCInterface
// uclpp ucapi.EgLPPInterface
ucmpc ucapi.MaMPCInterface

isConnected bool
}

func (h *controlbox) run() {
var err error
var certificate tls.Certificate

if len(os.Args) == 5 {
remoteSki = os.Args[2]

certificate, err = tls.LoadX509KeyPair(os.Args[3], os.Args[4])
if err != nil {
usage()
log.Fatal(err)
}
} else {
certificate, err = cert.CreateCertificate("Demo", "Demo", "DE", "Demo-Unit-01")
if err != nil {
log.Fatal(err)
}

pemdata := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: certificate.Certificate[0],
})
fmt.Println(string(pemdata))

b, err := x509.MarshalECPrivateKey(certificate.PrivateKey.(*ecdsa.PrivateKey))
if err != nil {
log.Fatal(err)
}
pemdata = pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: b})
fmt.Println(string(pemdata))
}

port, err := strconv.Atoi(os.Args[1])
if err != nil {
usage()
log.Fatal(err)
}

configuration, err := api.NewConfiguration(
"Bosch", "eebus-go", "myHP", "12345678",
[]shipapi.DeviceCategoryType{shipapi.DeviceCategoryTypeHVAC},
//JH model.DeviceTypeTypeElectricitySupplySystem,
model.DeviceTypeTypeGeneric,
// []model.EntityTypeType{model.EntityTypeTypeGridGuard},
[]model.EntityTypeType{model.EntityTypeTypeHeatPumpAppliance},
port, certificate, time.Second*60)
if err != nil {
log.Fatal(err)
}
// configuration.SetAlternateIdentifier("Demo-ControlBox-123456789")
configuration.SetAlternateIdentifier("Bosch-myHP-12345678")

h.myService = service.NewService(configuration, h)
h.myService.SetLogging(h)

if err = h.myService.Setup(); err != nil {
fmt.Println(err)
return
}

localEntity := h.myService.LocalDevice().EntityForType(model.EntityTypeTypeGridGuard)
h.uclpc = lpc.NewLPC(localEntity, h.OnLPCEvent)
h.myService.AddUseCase(h.uclpc)
// h.uclpp = lpp.NewLPP(localEntity, h.OnLPPEvent)
// h.myService.AddUseCase(h.uclpp)

h.ucmpc = mpc.NewMPC(localEntity, h.OnMPCEvent)
h.myService.AddUseCase(h.ucmpc)

if len(remoteSki) == 0 {
os.Exit(0)
}

h.myService.RegisterRemoteSKI(remoteSki)

h.myService.Start()
// defer h.myService.Shutdown()
}

// EEBUSServiceHandler

func (h *controlbox) RemoteSKIConnected(service api.ServiceInterface, ski string) {
h.isConnected = true
}

func (h *controlbox) RemoteSKIDisconnected(service api.ServiceInterface, ski string) {
h.isConnected = false
}

func (h *controlbox) VisibleRemoteServicesUpdated(service api.ServiceInterface, entries []shipapi.RemoteService) {
}

func (h *controlbox) ServiceShipIDUpdate(ski string, shipdID string) {}

func (h *controlbox) ServicePairingDetailUpdate(ski string, detail *shipapi.ConnectionStateDetail) {
if ski == remoteSki && detail.State() == shipapi.ConnectionStateRemoteDeniedTrust {
fmt.Println("The remote service denied trust. Exiting.")
h.myService.CancelPairingWithSKI(ski)
h.myService.UnregisterRemoteSKI(ski)
h.myService.Shutdown()
os.Exit(0)
}
}

func (h *controlbox) AllowWaitingForTrust(ski string) bool {
return ski == remoteSki
}

// LPC Event Handler

func (h *controlbox) sendLimit(entity spineapi.EntityRemoteInterface) {
scenarios := h.uclpc.AvailableScenariosForEntity(entity)
if len(scenarios) == 0 ||
!slices.Contains(scenarios, 1) {
return
}

fmt.Println("Sending a limit in 5s...")
time.AfterFunc(time.Second*5, func() {
limit := ucapi.LoadLimit{
Duration: time.Minute * 2,
IsActive: true,
Value: 7000,
}

resultCB := func(msg model.ResultDataType) {
if *msg.ErrorNumber == model.ErrorNumberTypeNoError {
fmt.Println("Limit accepted.")
} else {
fmt.Println("Limit rejected. Code", *msg.ErrorNumber, "Description", *msg.Description)
}
}
msgCounter, err := h.uclpc.WriteConsumptionLimit(entity, limit, resultCB)
if err != nil {
fmt.Println("Failed to send limit", err)
return
}
fmt.Println("Sent limit to", entity.Device().Ski(), "with msgCounter", msgCounter)
})
}
func (h *controlbox) OnLPCEvent(ski string, device spineapi.DeviceRemoteInterface, entity spineapi.EntityRemoteInterface, event api.EventType) {
if !h.isConnected {
return
}

switch event {
case lpc.UseCaseSupportUpdate:
h.sendLimit(entity)
case lpc.DataUpdateLimit:
if currentLimit, err := h.uclpc.ConsumptionLimit(entity); err == nil {
fmt.Println("New Limit received", currentLimit.Value, "W")
}
default:
return
}
}

func (h *controlbox) OnLPPEvent(ski string, device spineapi.DeviceRemoteInterface, entity spineapi.EntityRemoteInterface, event api.EventType) {
if !h.isConnected {
return
}

switch event {
case lpc.UseCaseSupportUpdate:
h.sendLimit(entity)
case lpc.DataUpdateLimit:
if currentLimit, err := h.uclpc.ConsumptionLimit(entity); err == nil {
fmt.Println("New Limit received", currentLimit.Value, "W")
}
default:
return
}
}

// JH experimental ----------------------------------------
func (h *controlbox) OnMPCEvent(ski string, device spineapi.DeviceRemoteInterface, entity spineapi.EntityRemoteInterface, event api.EventType) {
if !h.isConnected {
return
}

switch event {
case mpc.DataUpdateEnergyConsumed: //.UseCaseSupportUpdate:
fmt.Println("EVENT: DataUpdateEnergyConsumed")
// TODO h.sendLimit(entity)
case mpc.DataUpdatePower: //UpdateLimit:
fmt.Println("EVENT: DataUpdatePower")
// if currentLimit, err := h.uclpc.ConsumptionLimit(entity); err == nil {
// fmt.Println("New Limit received", currentLimit.Value, "W")
// }
default:
return
}
}

// JH experimental ----------------------------------------

// main app
func usage() {
fmt.Println("First Run:")
fmt.Println(" go run /examples/controlbox/main.go <serverport>")
fmt.Println()
fmt.Println("General Usage:")
fmt.Println(" go run /examples/controlbox/main.go <serverport> <cem-ski> <crtfile> <keyfile>")
}

func main() {
if len(os.Args) < 2 {
usage()
return
}

h := controlbox{}
h.run()

// Clean exit to make sure mdns shutdown is invoked
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
<-sig
// User exit
}

// Logging interface

func (h *controlbox) Trace(args ...interface{}) {
// h.print("TRACE", args...)
}

func (h *controlbox) Tracef(format string, args ...interface{}) {
// h.printFormat("TRACE", format, args...)
}

func (h *controlbox) Debug(args ...interface{}) {
// h.print("DEBUG", args...)
}

func (h *controlbox) Debugf(format string, args ...interface{}) {
// h.printFormat("DEBUG", format, args...)
}

func (h *controlbox) Info(args ...interface{}) {
h.print("INFO ", args...)
}

func (h *controlbox) Infof(format string, args ...interface{}) {
h.printFormat("INFO ", format, args...)
}

func (h *controlbox) Error(args ...interface{}) {
h.print("ERROR", args...)
}

func (h *controlbox) Errorf(format string, args ...interface{}) {
h.printFormat("ERROR", format, args...)
}

func (h *controlbox) currentTimestamp() string {
return time.Now().Format("2006-01-02 15:04:05")
}

func (h *controlbox) print(msgType string, args ...interface{}) {
value := fmt.Sprintln(args...)
fmt.Printf("%s %s %s", h.currentTimestamp(), msgType, value)
}

func (h *controlbox) printFormat(msgType, format string, args ...interface{}) {
value := fmt.Sprintf(format, args...)
fmt.Println(h.currentTimestamp(), msgType, value)
}
4 changes: 2 additions & 2 deletions cmd/controlbox/main.go → examples/controlbox/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,10 @@ func (h *controlbox) OnLPPEvent(ski string, device spineapi.DeviceRemoteInterfac
// main app
func usage() {
fmt.Println("First Run:")
fmt.Println(" go run /cmd/controlbox/main.go <serverport>")
fmt.Println(" go run /examples/controlbox/main.go <serverport>")
fmt.Println()
fmt.Println("General Usage:")
fmt.Println(" go run /cmd/controlbox/main.go <serverport> <remoteski> <crtfile> <keyfile>")
fmt.Println(" go run /examples/controlbox/main.go <serverport> <remoteski> <crtfile> <keyfile>")
}

func main() {
Expand Down
4 changes: 2 additions & 2 deletions cmd/evse/main.go → examples/evse/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,10 @@ func (h *evse) OnLPCEvent(ski string, device spineapi.DeviceRemoteInterface, ent
// main app
func usage() {
fmt.Println("First Run:")
fmt.Println(" go run /cmd/evse/main.go <serverport>")
fmt.Println(" go run /examples/evse/main.go <serverport>")
fmt.Println()
fmt.Println("General Usage:")
fmt.Println(" go run /cmd/evse/main.go <serverport> <remoteski> <crtfile> <keyfile>")
fmt.Println(" go run /examples/evse/main.go <serverport> <remoteski> <crtfile> <keyfile>")
}

func main() {
Expand Down
Loading

0 comments on commit 7e021df

Please sign in to comment.