-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implemented in go to reduce memory amount
- Loading branch information
1 parent
5ba74ed
commit 376f5c7
Showing
8 changed files
with
333 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<component name="ProjectRunConfigurationManager"> | ||
<configuration default="false" name="run" type="GoApplicationRunConfiguration" factoryName="Go Application"> | ||
<module name="miele-to-mqtt-gw" /> | ||
<working_directory value="$PROJECT_DIR$/v2" /> | ||
<parameters value="../production/config/config.json" /> | ||
<kind value="PACKAGE" /> | ||
<package value="github.com/mqtt-home/eltako-to-mqtt-gw" /> | ||
<directory value="$PROJECT_DIR$" /> | ||
<filePath value="$PROJECT_DIR$/v2/main.go" /> | ||
<method v="2" /> | ||
</configuration> | ||
</component> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package config | ||
|
||
import ( | ||
"encoding/json" | ||
"github.com/philipparndt/go-logger" | ||
"github.com/philipparndt/mqtt-gateway/config" | ||
"os" | ||
) | ||
|
||
type Config struct { | ||
MQTT config.MQTTConfig `json:"mqtt"` | ||
Eltako Eltako `json:"eltako"` | ||
LogLevel string `json:"loglevel,omitempty"` | ||
} | ||
|
||
type Device struct { | ||
Ip string `json:"ip"` | ||
Username string `json:"username"` | ||
Password string `json:"password"` | ||
Name string `json:"name"` | ||
BlindsConfig struct { | ||
HalfOpenPercentage float64 `json:"halfOpenPercentage"` | ||
} `json:"blindsConfig"` | ||
} | ||
|
||
type Eltako struct { | ||
Devices []Device `json:"devices"` | ||
PollingInterval int `json:"polling-interval"` | ||
} | ||
|
||
func LoadConfig(file string) (Config, error) { | ||
data, err := os.ReadFile(file) | ||
if err != nil { | ||
logger.Error("Error reading config file", err) | ||
return Config{}, err | ||
} | ||
|
||
data = config.ReplaceEnvVariables(data) | ||
|
||
// Create a Config object | ||
var cfg Config | ||
|
||
// Unmarshal the JSON data into the Config object | ||
err = json.Unmarshal(data, &cfg) | ||
if err != nil { | ||
logger.Error("Unmarshalling JSON:", err) | ||
return Config{}, err | ||
} | ||
|
||
if cfg.LogLevel == "" { | ||
cfg.LogLevel = "info" | ||
} | ||
|
||
return cfg, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package eltako | ||
|
||
import ( | ||
"crypto/tls" | ||
"io" | ||
"net/http" | ||
) | ||
|
||
type HTTPClient struct { | ||
BaseURL string | ||
Client *http.Client | ||
AuthToken string | ||
} | ||
|
||
func NewHTTPClient(baseURL string) *HTTPClient { | ||
// Create a http.Client that ignores the certificate | ||
// errors. This is necessary because the Eltako devices | ||
// use self-signed certificates. | ||
tr := &http.Transport{ | ||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, | ||
} | ||
|
||
return &HTTPClient{ | ||
BaseURL: baseURL, | ||
Client: &http.Client{ | ||
Transport: tr, | ||
}, | ||
} | ||
} | ||
|
||
func (c *HTTPClient) SetAuthToken(token string) { | ||
c.AuthToken = token | ||
} | ||
|
||
func (c *HTTPClient) GetAuthToken() string { | ||
return c.AuthToken | ||
} | ||
|
||
func (c *HTTPClient) Get(url string) (*http.Response, error) { | ||
return c.NewRequest("GET", url, nil) | ||
} | ||
|
||
func (c *HTTPClient) Post(url string, body io.Reader) (*http.Response, error) { | ||
req, err := http.NewRequest("POST", c.BaseURL+url, body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return c.Client.Do(req) | ||
} | ||
|
||
func (c *HTTPClient) NewRequest(method, url string, body io.Reader) (*http.Response, error) { | ||
req, err := http.NewRequest(method, c.BaseURL+url, body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
req.Header.Set("Content-Type", "application/json") | ||
|
||
if c.AuthToken != "" { | ||
req.Header.Set("Authorization", c.AuthToken) | ||
} | ||
|
||
return c.Client.Do(req) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package eltako | ||
|
||
type Data struct { | ||
Type string `json:"type"` | ||
Identifier string `json:"identifier"` | ||
Value interface{} `json:"value"` | ||
} | ||
|
||
type Device struct { | ||
DeviceGuid string `json:"deviceGuid"` | ||
ProductGuid string `json:"productGuid"` | ||
DisplayName string `json:"displayName"` | ||
Infos []Data `json:"infos"` | ||
Settings []Data `json:"settings"` | ||
Functions []Data `json:"functions"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package eltako | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"github.com/mqtt-home/eltako-to-mqtt-gw/config" | ||
"io" | ||
"net/http" | ||
) | ||
|
||
type ShadingActor struct { | ||
device config.Device | ||
client *HTTPClient | ||
Devices []Device | ||
} | ||
|
||
func NewShadingActor(device config.Device) *ShadingActor { | ||
client := NewHTTPClient("https://" + device.Ip + ":443/api/v0") | ||
actor := &ShadingActor{ | ||
device: device, | ||
client: client, | ||
} | ||
err := actor.init() | ||
if err != nil { | ||
panic(err) | ||
} | ||
return actor | ||
} | ||
|
||
func (s *ShadingActor) init() error { | ||
err := s.UpdateToken() | ||
if err != nil { | ||
return err | ||
} | ||
devices, err := s.getDevices() | ||
s.Devices = devices | ||
return nil | ||
} | ||
|
||
func (s *ShadingActor) UpdateToken() error { | ||
usernamePassword := map[string]string{ | ||
"user": s.device.Username, | ||
"password": s.device.Password, | ||
} | ||
|
||
body, err := json.Marshal(usernamePassword) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
resp, err := s.client.Post("/login", bytes.NewReader(body)) | ||
if err != nil { | ||
return err | ||
} | ||
defer func(Body io.ReadCloser) { | ||
_ = Body.Close() | ||
}(resp.Body) | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return fmt.Errorf("failed to update token, status code: %d", resp.StatusCode) | ||
} | ||
|
||
var result map[string]string | ||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { | ||
return err | ||
} | ||
|
||
token, ok := result["apiKey"] | ||
if !ok { | ||
return fmt.Errorf("apiKey not found in response") | ||
} | ||
|
||
s.client.SetAuthToken(token) | ||
return nil | ||
} | ||
|
||
func (s *ShadingActor) getDevices() ([]Device, error) { | ||
resp, err := s.client.Get("/devices") | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer func(Body io.ReadCloser) { | ||
_ = Body.Close() | ||
}(resp.Body) | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return nil, fmt.Errorf("failed to get devices, status code: %d", resp.StatusCode) | ||
} | ||
|
||
var devices []Device | ||
if err := json.NewDecoder(resp.Body).Decode(&devices); err != nil { | ||
return nil, err | ||
} | ||
|
||
return devices, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
module github.com/mqtt-home/eltako-to-mqtt-gw | ||
|
||
go 1.22.2 | ||
|
||
require ( | ||
github.com/philipparndt/go-logger v1.0.0 | ||
github.com/philipparndt/mqtt-gateway v1.3.0 | ||
) | ||
|
||
require ( | ||
github.com/eclipse/paho.mqtt.golang v1.4.3 // indirect | ||
github.com/gorilla/websocket v1.5.0 // indirect | ||
golang.org/x/net v0.8.0 // indirect | ||
golang.org/x/sync v0.1.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik= | ||
github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE= | ||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= | ||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | ||
github.com/philipparndt/go-logger v1.0.0 h1:5khKl1q8q6FH74S1wF5KPl6DvdZnRdPKqKbBPQDr9P4= | ||
github.com/philipparndt/go-logger v1.0.0/go.mod h1:4mWf8eNH82GhKl5byAFwXcux9WPNuaePaPaAFbgjHXg= | ||
github.com/philipparndt/mqtt-gateway v1.3.0 h1:QeJ0XIEnlzH4Qm7vqAQN3WTrI45UcPxlcQFcTrCXvn8= | ||
github.com/philipparndt/mqtt-gateway v1.3.0/go.mod h1:N6LC57xFs/u41Xc5csPHTACm/00GyOyMgIC+oOqp32Y= | ||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= | ||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= | ||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= | ||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/mqtt-home/eltako-to-mqtt-gw/config" | ||
"github.com/mqtt-home/eltako-to-mqtt-gw/eltako" | ||
"github.com/philipparndt/go-logger" | ||
"github.com/philipparndt/mqtt-gateway/mqtt" | ||
"os" | ||
"os/signal" | ||
"syscall" | ||
) | ||
|
||
func main() { | ||
if len(os.Args) < 2 { | ||
logger.Error("No config file specified") | ||
os.Exit(1) | ||
} | ||
|
||
configFile := os.Args[1] | ||
logger.Info("Config file", configFile) | ||
err := error(nil) | ||
|
||
cfg, err := config.LoadConfig(configFile) | ||
if err != nil { | ||
logger.Error("Failed loading config", err) | ||
return | ||
} | ||
|
||
logger.Info("Config file", cfg) | ||
|
||
for _, device := range cfg.Eltako.Devices { | ||
logger.Info("Device", device) | ||
actor := eltako.NewShadingActor(device) | ||
//actor.Start() | ||
err := actor.UpdateToken() | ||
if err != nil { | ||
logger.Error("Failed updating token", err) | ||
return | ||
} | ||
|
||
for _, device := range actor.Devices { | ||
logger.Info("Device", device) | ||
} | ||
} | ||
|
||
//api = nuki.New(cfg.Nuki.Target.Web.SmartlockId, cfg.Nuki.Target.Web.Bearer) | ||
|
||
logger.SetLevel(cfg.LogLevel) | ||
mqtt.Start(cfg.MQTT, "eltako_mqtt") | ||
|
||
//mqtt.Subscribe(cfg.Nuki.Source, OnMessage) | ||
//mqtt.Subscribe(cfg.Nuki.Fingerprint, OnFingerprintButton) | ||
//mqtt.Subscribe(cfg.MQTT.Topic+"/fingerprint_state", OnFingerprintState) | ||
|
||
logger.Info("Application is now ready. Press Ctrl+C to quit.") | ||
|
||
quitChannel := make(chan os.Signal, 1) | ||
signal.Notify(quitChannel, syscall.SIGINT, syscall.SIGTERM) | ||
<-quitChannel | ||
|
||
logger.Info("Received quit signal") | ||
} |