commit
88027ae773
|
|
@ -14,7 +14,7 @@ Oktopus is a multi-vendor management platform for CPEs and IoTs. <b>Any device t
|
||||||
|
|
||||||
<a href="https://www.inango.com/" target="_blank"><img src="https://github.com/OktopUSP/oktopus/assets/83298718/3b3e65d9-33fa-46c4-8b24-f9e2a84a04a6" width="100px"/></a>
|
<a href="https://www.inango.com/" target="_blank"><img src="https://github.com/OktopUSP/oktopus/assets/83298718/3b3e65d9-33fa-46c4-8b24-f9e2a84a04a6" width="100px"/></a>
|
||||||
|
|
||||||
<p>If you'd like to become a sponsor, start a partnership or somehow to contribute to the project, email <a href="">leandro@oktopus.app.br</a>, every contribution is welcome, and the resources will help the project to move on. Also, if your company uses this project and you'd like your logo to appear up here, contact us.
|
<p>If you'd like to become a sponsor, start a partnership or somehow to contribute to the project, email <a href="">contact@oktopus.app.br</a>, every contribution is welcome, and the resources will help the project to move on. Also, if your company uses this project and you'd like your logo to appear up here, contact us.
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
|
|
@ -23,7 +23,7 @@ Oktopus is a multi-vendor management platform for CPEs and IoTs. <b>Any device t
|
||||||
<p>
|
<p>
|
||||||
Our solution has an open-source software license, meaning you can modify/study the code and use it for free. You can perform all the configurations, allocate servers, and set it up on your network with the classic "do it yourself" approach, or save time and money: contact us for a quote and get commercial support.
|
Our solution has an open-source software license, meaning you can modify/study the code and use it for free. You can perform all the configurations, allocate servers, and set it up on your network with the classic "do it yourself" approach, or save time and money: contact us for a quote and get commercial support.
|
||||||
</p>
|
</p>
|
||||||
<p>Contact <a href="">leandro@oktopus.app.br</a> via email and get a quote.</p>
|
<p>Contact <a href="">sales@oktopus.app.br</a> via email and get a quote.</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@ const LOCAL_ENV = ".env.local"
|
||||||
type Nats struct {
|
type Nats struct {
|
||||||
Url string
|
Url string
|
||||||
Name string
|
Name string
|
||||||
VerifyCertificates bool
|
EnableTls bool
|
||||||
|
Cert Tls
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,6 +41,12 @@ type Config struct {
|
||||||
Nats Nats
|
Nats Nats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Tls struct {
|
||||||
|
CertFile string
|
||||||
|
KeyFile string
|
||||||
|
CaFile string
|
||||||
|
}
|
||||||
|
|
||||||
func NewConfig() *Config {
|
func NewConfig() *Config {
|
||||||
|
|
||||||
loadEnvVariables()
|
loadEnvVariables()
|
||||||
|
|
@ -47,7 +54,10 @@ func NewConfig() *Config {
|
||||||
|
|
||||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
|
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
|
||||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||||
|
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||||
|
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||||
|
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||||
acsPort := flag.String("acs_port", lookupEnvOrString("ACS_PORT", ":9292"), "port for acs server")
|
acsPort := flag.String("acs_port", lookupEnvOrString("ACS_PORT", ":9292"), "port for acs server")
|
||||||
acsRoute := flag.String("acs_route", lookupEnvOrString("ACS_ROUTE", "/acs"), "route for acs server")
|
acsRoute := flag.String("acs_route", lookupEnvOrString("ACS_ROUTE", "/acs"), "route for acs server")
|
||||||
connReqUser := flag.String("connrq_user", lookupEnvOrString("CONN_RQ_USER", ""), "Connection Request Username")
|
connReqUser := flag.String("connrq_user", lookupEnvOrString("CONN_RQ_USER", ""), "Connection Request Username")
|
||||||
|
|
@ -79,8 +89,13 @@ func NewConfig() *Config {
|
||||||
Nats: Nats{
|
Nats: Nats{
|
||||||
Url: *natsUrl,
|
Url: *natsUrl,
|
||||||
Name: *natsName,
|
Name: *natsName,
|
||||||
VerifyCertificates: *natsVerifyCertificates,
|
EnableTls: *natsEnableTls,
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
|
Cert: Tls{
|
||||||
|
CertFile: *clientCrt,
|
||||||
|
KeyFile: *clientKey,
|
||||||
|
CaFile: *serverCA,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Acs: Acs{
|
Acs: Acs{
|
||||||
Port: *acsPort,
|
Port: *acsPort,
|
||||||
|
|
|
||||||
|
|
@ -141,8 +141,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
||||||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||||
}))
|
}))
|
||||||
if c.VerifyCertificates {
|
if c.EnableTls {
|
||||||
opts = append(opts, nats.RootCAs())
|
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||||
|
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||||
|
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
return opts
|
return opts
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ const LOCAL_ENV = ".env.local"
|
||||||
type Nats struct {
|
type Nats struct {
|
||||||
Url string
|
Url string
|
||||||
Name string
|
Name string
|
||||||
VerifyCertificates bool
|
EnableTls bool
|
||||||
|
Cert Tls
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,6 +30,12 @@ type Config struct {
|
||||||
Nats Nats
|
Nats Nats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Tls struct {
|
||||||
|
CertFile string
|
||||||
|
KeyFile string
|
||||||
|
CaFile string
|
||||||
|
}
|
||||||
|
|
||||||
func NewConfig() *Config {
|
func NewConfig() *Config {
|
||||||
|
|
||||||
loadEnvVariables()
|
loadEnvVariables()
|
||||||
|
|
@ -36,7 +43,10 @@ func NewConfig() *Config {
|
||||||
|
|
||||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
|
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
|
||||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||||
|
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||||
|
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||||
|
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||||
flApiPort := flag.String("api_port", lookupEnvOrString("REST_API_PORT", "4000"), "Rest api port")
|
flApiPort := flag.String("api_port", lookupEnvOrString("REST_API_PORT", "4000"), "Rest api port")
|
||||||
flHelp := flag.Bool("help", false, "Help")
|
flHelp := flag.Bool("help", false, "Help")
|
||||||
|
|
||||||
|
|
@ -64,8 +74,13 @@ func NewConfig() *Config {
|
||||||
Nats: Nats{
|
Nats: Nats{
|
||||||
Url: *natsUrl,
|
Url: *natsUrl,
|
||||||
Name: *natsName,
|
Name: *natsName,
|
||||||
VerifyCertificates: *natsVerifyCertificates,
|
EnableTls: *natsEnableTls,
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
|
Cert: Tls{
|
||||||
|
CertFile: *clientCrt,
|
||||||
|
KeyFile: *clientKey,
|
||||||
|
CaFile: *serverCA,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
||||||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||||
}))
|
}))
|
||||||
if c.VerifyCertificates {
|
if c.EnableTls {
|
||||||
opts = append(opts, nats.RootCAs())
|
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||||
|
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||||
|
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
return opts
|
return opts
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,13 @@ func (a *Api) StartApi() {
|
||||||
authentication.HandleFunc("/password", a.changePassword).Methods("PUT")
|
authentication.HandleFunc("/password", a.changePassword).Methods("PUT")
|
||||||
authentication.HandleFunc("/admin/register", a.registerAdminUser).Methods("POST")
|
authentication.HandleFunc("/admin/register", a.registerAdminUser).Methods("POST")
|
||||||
authentication.HandleFunc("/admin/exists", a.adminUserExists).Methods("GET")
|
authentication.HandleFunc("/admin/exists", a.adminUserExists).Methods("GET")
|
||||||
|
if a.enterpise.Enable {
|
||||||
|
mapRoutes := r.PathPrefix("/api/map").Subrouter()
|
||||||
|
mapRoutes.HandleFunc("", a.devicesLocation).Methods("GET")
|
||||||
|
mapRoutes.Use(func(handler http.Handler) http.Handler {
|
||||||
|
return middleware.Middleware(handler)
|
||||||
|
})
|
||||||
|
}
|
||||||
iot := r.PathPrefix("/api/device").Subrouter()
|
iot := r.PathPrefix("/api/device").Subrouter()
|
||||||
iot.HandleFunc("/alias", a.setDeviceAlias).Methods("PUT")
|
iot.HandleFunc("/alias", a.setDeviceAlias).Methods("PUT")
|
||||||
iot.HandleFunc("/auth", a.deviceAuth).Methods("GET", "POST", "DELETE")
|
iot.HandleFunc("/auth", a.deviceAuth).Methods("GET", "POST", "DELETE")
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,22 @@ func (a *Api) getEnterpriseResource(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Api) getMapsResource(
|
||||||
|
action string,
|
||||||
|
w http.ResponseWriter,
|
||||||
|
body []byte,
|
||||||
|
) error {
|
||||||
|
|
||||||
|
err := bridge.NatsEnterpriseInteraction("geolocation.v1."+action, body, w, a.nc)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Api) devicesLocation(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method == http.MethodGet {
|
||||||
|
a.getMapsResource("get", w, []byte{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (a *Api) deviceSiteSurvey(w http.ResponseWriter, r *http.Request) {
|
func (a *Api) deviceSiteSurvey(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
sn := vars["sn"]
|
sn := vars["sn"]
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,6 @@ func adminUserExists(users []map[string]interface{}, supportEmail string) bool {
|
||||||
|
|
||||||
for _, x := range users {
|
for _, x := range users {
|
||||||
if db.UserLevels(x["level"].(int32)) == db.AdminUser && x["email"].(string) != supportEmail {
|
if db.UserLevels(x["level"].(int32)) == db.AdminUser && x["email"].(string) != supportEmail {
|
||||||
log.Println("Admin exists")
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -263,7 +263,7 @@ func NatsEnterpriseInteraction(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == nats.ErrNoResponders {
|
if err == nats.ErrNoResponders {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
w.Write(utils.Marshall("You have no enterprise license, to get one contact: leandro@oktopus.app.br"))
|
w.Write(utils.Marshall("You have no enterprise license, to get one contact: sales@oktopus.app.br"))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ const LOCAL_ENV = ".env.local"
|
||||||
type Nats struct {
|
type Nats struct {
|
||||||
Url string
|
Url string
|
||||||
Name string
|
Name string
|
||||||
VerifyCertificates bool
|
EnableTls bool
|
||||||
|
Cert Tls
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,6 +43,12 @@ type Config struct {
|
||||||
Enterprise Enterprise
|
Enterprise Enterprise
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Tls struct {
|
||||||
|
CertFile string
|
||||||
|
KeyFile string
|
||||||
|
CaFile string
|
||||||
|
}
|
||||||
|
|
||||||
func NewConfig() *Config {
|
func NewConfig() *Config {
|
||||||
|
|
||||||
loadEnvVariables()
|
loadEnvVariables()
|
||||||
|
|
@ -49,7 +56,10 @@ func NewConfig() *Config {
|
||||||
|
|
||||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "controller"), "name for nats client")
|
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "controller"), "name for nats client")
|
||||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||||
|
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||||
|
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||||
|
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||||
flApiPort := flag.String("api_port", lookupEnvOrString("REST_API_PORT", "8000"), "Rest api port")
|
flApiPort := flag.String("api_port", lookupEnvOrString("REST_API_PORT", "8000"), "Rest api port")
|
||||||
mongoUri := flag.String("mongo_uri", lookupEnvOrString("MONGO_URI", "mongodb://localhost:27017"), "uri for mongodb server")
|
mongoUri := flag.String("mongo_uri", lookupEnvOrString("MONGO_URI", "mongodb://localhost:27017"), "uri for mongodb server")
|
||||||
enterpise := flag.Bool("enterprise", lookupEnvOrBool("ENTERPRISE", false), "enterprise version enable")
|
enterpise := flag.Bool("enterprise", lookupEnvOrBool("ENTERPRISE", false), "enterprise version enable")
|
||||||
|
|
@ -81,8 +91,13 @@ func NewConfig() *Config {
|
||||||
Nats: Nats{
|
Nats: Nats{
|
||||||
Url: *natsUrl,
|
Url: *natsUrl,
|
||||||
Name: *natsName,
|
Name: *natsName,
|
||||||
VerifyCertificates: *natsVerifyCertificates,
|
EnableTls: *natsEnableTls,
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
|
Cert: Tls{
|
||||||
|
CertFile: *clientCrt,
|
||||||
|
KeyFile: *clientKey,
|
||||||
|
CaFile: *serverCA,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Mongo: Mongo{
|
Mongo: Mongo{
|
||||||
Uri: *mongoUri,
|
Uri: *mongoUri,
|
||||||
|
|
|
||||||
|
|
@ -77,8 +77,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
||||||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||||
}))
|
}))
|
||||||
if c.VerifyCertificates {
|
if c.EnableTls {
|
||||||
opts = append(opts, nats.RootCAs())
|
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||||
|
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||||
|
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
return opts
|
return opts
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,17 @@ const LOCAL_ENV = ".env.local"
|
||||||
type Nats struct {
|
type Nats struct {
|
||||||
Url string
|
Url string
|
||||||
Name string
|
Name string
|
||||||
VerifyCertificates bool
|
EnableTls bool
|
||||||
|
Cert Tls
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Tls struct {
|
||||||
|
CertFile string
|
||||||
|
KeyFile string
|
||||||
|
CaFile string
|
||||||
|
}
|
||||||
|
|
||||||
type Mongo struct {
|
type Mongo struct {
|
||||||
Uri string
|
Uri string
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
|
|
@ -42,7 +49,10 @@ func NewConfig() *Config {
|
||||||
|
|
||||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
|
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
|
||||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||||
|
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||||
|
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||||
|
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||||
mongoUri := flag.String("mongo_uri", lookupEnvOrString("MONGO_URI", "mongodb://localhost:27017"), "uri for mongodb server")
|
mongoUri := flag.String("mongo_uri", lookupEnvOrString("MONGO_URI", "mongodb://localhost:27017"), "uri for mongodb server")
|
||||||
controllerId := flag.String("controller_id", lookupEnvOrString("CONTROLLER_ID", "oktopusController"), "usp controller endpoint id")
|
controllerId := flag.String("controller_id", lookupEnvOrString("CONTROLLER_ID", "oktopusController"), "usp controller endpoint id")
|
||||||
controllerPassword := flag.String("controller_passwd", lookupEnvOrString("CONTROLLER_PASSWORD", ""), "usp controller endpoint password to connect to")
|
controllerPassword := flag.String("controller_passwd", lookupEnvOrString("CONTROLLER_PASSWORD", ""), "usp controller endpoint password to connect to")
|
||||||
|
|
@ -68,8 +78,13 @@ func NewConfig() *Config {
|
||||||
Nats: Nats{
|
Nats: Nats{
|
||||||
Url: *natsUrl,
|
Url: *natsUrl,
|
||||||
Name: *natsName,
|
Name: *natsName,
|
||||||
VerifyCertificates: *natsVerifyCertificates,
|
EnableTls: *natsEnableTls,
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
|
Cert: Tls{
|
||||||
|
CertFile: *clientCrt,
|
||||||
|
KeyFile: *clientKey,
|
||||||
|
CaFile: *serverCA,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Mongo: Mongo{
|
Mongo: Mongo{
|
||||||
Uri: *mongoUri,
|
Uri: *mongoUri,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package cwmp_handler
|
package cwmp_handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
|
@ -12,6 +13,10 @@ func (h *Handler) HandleDeviceInfo(device string, data []byte, ack func()) {
|
||||||
defer ack()
|
defer ack()
|
||||||
log.Printf("Device %s info", device)
|
log.Printf("Device %s info", device)
|
||||||
deviceInfo := parseDeviceInfoMsg(data)
|
deviceInfo := parseDeviceInfoMsg(data)
|
||||||
|
if deviceExists, _ := h.db.DeviceExists(deviceInfo.SN); !deviceExists {
|
||||||
|
fmtDeviceInfo, _ := json.Marshal(deviceInfo)
|
||||||
|
h.nc.Publish("device.v1.new", fmtDeviceInfo)
|
||||||
|
}
|
||||||
err := h.db.CreateDevice(deviceInfo)
|
err := h.db.CreateDevice(deviceInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to create device: %v", err)
|
log.Printf("Failed to create device: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package usp_handler
|
package usp_handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/OktopUSP/oktopus/backend/services/mtp/adapter/internal/db"
|
"github.com/OktopUSP/oktopus/backend/services/mtp/adapter/internal/db"
|
||||||
|
|
@ -14,6 +15,10 @@ func (h *Handler) HandleDeviceInfo(device, subject string, data []byte, mtp stri
|
||||||
defer ack()
|
defer ack()
|
||||||
log.Printf("Device %s info, mtp: %s", device, mtp)
|
log.Printf("Device %s info, mtp: %s", device, mtp)
|
||||||
deviceInfo := parseDeviceInfoMsg(device, subject, data, getMtp(mtp))
|
deviceInfo := parseDeviceInfoMsg(device, subject, data, getMtp(mtp))
|
||||||
|
if deviceExists, _ := h.db.DeviceExists(deviceInfo.SN); !deviceExists {
|
||||||
|
fmtDeviceInfo, _ := json.Marshal(deviceInfo)
|
||||||
|
h.nc.Publish("device.v1.new", fmtDeviceInfo)
|
||||||
|
}
|
||||||
err := h.db.CreateDevice(deviceInfo)
|
err := h.db.CreateDevice(deviceInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to create device: %v", err)
|
log.Printf("Failed to create device: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -150,8 +150,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
||||||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||||
}))
|
}))
|
||||||
if c.VerifyCertificates {
|
if c.EnableTls {
|
||||||
opts = append(opts, nats.RootCAs())
|
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||||
|
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||||
|
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
return opts
|
return opts
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,17 @@ const LOCAL_ENV = ".env.local"
|
||||||
type Nats struct {
|
type Nats struct {
|
||||||
Url string
|
Url string
|
||||||
Name string
|
Name string
|
||||||
VerifyCertificates bool
|
EnableTls bool
|
||||||
|
Cert Tls
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Tls struct {
|
||||||
|
CertFile string
|
||||||
|
KeyFile string
|
||||||
|
CaFile string
|
||||||
|
}
|
||||||
|
|
||||||
type Mqtt struct {
|
type Mqtt struct {
|
||||||
Url string
|
Url string
|
||||||
UrlForTls string
|
UrlForTls string
|
||||||
|
|
@ -42,7 +49,10 @@ func NewConfig() *Config {
|
||||||
|
|
||||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "mqtt-adapter"), "name for nats client")
|
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "mqtt-adapter"), "name for nats client")
|
||||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||||
|
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||||
|
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||||
|
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||||
mqttUrl := flag.String("mqtt_url", lookupEnvOrString("MQTT_URL", "tcp://localhost:1883"), "url for mqtt server")
|
mqttUrl := flag.String("mqtt_url", lookupEnvOrString("MQTT_URL", "tcp://localhost:1883"), "url for mqtt server")
|
||||||
mqttsUrl := flag.String("mqtts_url", lookupEnvOrString("MQTTS_URL", ""), "url for mqtts server")
|
mqttsUrl := flag.String("mqtts_url", lookupEnvOrString("MQTTS_URL", ""), "url for mqtts server")
|
||||||
mqttsSkipVerify := flag.Bool("mqtts_skip_verify", lookupEnvOrBool("MQTTS_SKIP_VERIFY", false), "skip verification of server certificate for mqtts")
|
mqttsSkipVerify := flag.Bool("mqtts_skip_verify", lookupEnvOrBool("MQTTS_SKIP_VERIFY", false), "skip verification of server certificate for mqtts")
|
||||||
|
|
@ -71,8 +81,13 @@ func NewConfig() *Config {
|
||||||
Nats: Nats{
|
Nats: Nats{
|
||||||
Url: *natsUrl,
|
Url: *natsUrl,
|
||||||
Name: *natsName,
|
Name: *natsName,
|
||||||
VerifyCertificates: *natsVerifyCertificates,
|
EnableTls: *natsEnableTls,
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
|
Cert: Tls{
|
||||||
|
CertFile: *clientCrt,
|
||||||
|
KeyFile: *clientKey,
|
||||||
|
CaFile: *serverCA,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Mqtt: Mqtt{
|
Mqtt: Mqtt{
|
||||||
Url: *mqttUrl,
|
Url: *mqttUrl,
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
||||||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||||
}))
|
}))
|
||||||
if c.VerifyCertificates {
|
if c.EnableTls {
|
||||||
opts = append(opts, nats.RootCAs())
|
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||||
|
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||||
|
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
return opts
|
return opts
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,17 @@ type Config struct {
|
||||||
type Nats struct {
|
type Nats struct {
|
||||||
Url string
|
Url string
|
||||||
Name string
|
Name string
|
||||||
VerifyCertificates bool
|
EnableTls bool
|
||||||
|
Cert Tls
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Tls struct {
|
||||||
|
CertFile string
|
||||||
|
KeyFile string
|
||||||
|
CaFile string
|
||||||
|
}
|
||||||
|
|
||||||
func NewConfig() Config {
|
func NewConfig() Config {
|
||||||
|
|
||||||
loadEnvVariables()
|
loadEnvVariables()
|
||||||
|
|
@ -66,7 +73,10 @@ func NewConfig() Config {
|
||||||
logLevel := flag.Int("log_level", lookupEnvOrInt("LOG_LEVEL", 1), "0=DEBUG, 1=INFO, 2=WARNING, 3=ERROR")
|
logLevel := flag.Int("log_level", lookupEnvOrInt("LOG_LEVEL", 1), "0=DEBUG, 1=INFO, 2=WARNING, 3=ERROR")
|
||||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
|
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "adapter"), "name for nats client")
|
||||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||||
|
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||||
|
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||||
|
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
flHelp := flag.Bool("help", false, "Help")
|
flHelp := flag.Bool("help", false, "Help")
|
||||||
|
|
@ -101,8 +111,13 @@ func NewConfig() Config {
|
||||||
Nats: Nats{
|
Nats: Nats{
|
||||||
Url: *natsUrl,
|
Url: *natsUrl,
|
||||||
Name: *natsName,
|
Name: *natsName,
|
||||||
VerifyCertificates: *natsVerifyCertificates,
|
EnableTls: *natsEnableTls,
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
|
Cert: Tls{
|
||||||
|
CertFile: *clientCrt,
|
||||||
|
KeyFile: *clientKey,
|
||||||
|
CaFile: *serverCA,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
||||||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||||
}))
|
}))
|
||||||
if c.VerifyCertificates {
|
if c.EnableTls {
|
||||||
opts = append(opts, nats.RootCAs())
|
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||||
|
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||||
|
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
return opts
|
return opts
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,17 @@ const LOCAL_ENV = ".env.local"
|
||||||
type Nats struct {
|
type Nats struct {
|
||||||
Url string
|
Url string
|
||||||
Name string
|
Name string
|
||||||
VerifyCertificates bool
|
EnableTls bool
|
||||||
|
Cert Tls
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Tls struct {
|
||||||
|
CertFile string
|
||||||
|
KeyFile string
|
||||||
|
CaFile string
|
||||||
|
}
|
||||||
|
|
||||||
type Stomp struct {
|
type Stomp struct {
|
||||||
Url string
|
Url string
|
||||||
User string
|
User string
|
||||||
|
|
@ -37,7 +44,10 @@ func NewConfig() *Config {
|
||||||
|
|
||||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "mqtt-adapter"), "name for nats client")
|
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "mqtt-adapter"), "name for nats client")
|
||||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||||
|
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||||
|
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||||
|
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||||
stompAddr := flag.String("stomp_server", lookupEnvOrString("STOMP_SERVER", "localhost:61613"), "STOMP server endpoint")
|
stompAddr := flag.String("stomp_server", lookupEnvOrString("STOMP_SERVER", "localhost:61613"), "STOMP server endpoint")
|
||||||
stompUser := flag.String("stomp_user", lookupEnvOrString("STOMP_USER", ""), "stomp server user")
|
stompUser := flag.String("stomp_user", lookupEnvOrString("STOMP_USER", ""), "stomp server user")
|
||||||
stompPassword := flag.String("stomp_passsword", lookupEnvOrString("STOMP_PASSWD", ""), "stomp server password")
|
stompPassword := flag.String("stomp_passsword", lookupEnvOrString("STOMP_PASSWD", ""), "stomp server password")
|
||||||
|
|
@ -63,8 +73,13 @@ func NewConfig() *Config {
|
||||||
Nats: Nats{
|
Nats: Nats{
|
||||||
Url: *natsUrl,
|
Url: *natsUrl,
|
||||||
Name: *natsName,
|
Name: *natsName,
|
||||||
VerifyCertificates: *natsVerifyCertificates,
|
EnableTls: *natsEnableTls,
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
|
Cert: Tls{
|
||||||
|
CertFile: *clientCrt,
|
||||||
|
KeyFile: *clientKey,
|
||||||
|
CaFile: *serverCA,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Stomp: Stomp{
|
Stomp: Stomp{
|
||||||
Url: *stompAddr,
|
Url: *stompAddr,
|
||||||
|
|
|
||||||
|
|
@ -81,9 +81,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
||||||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||||
}))
|
}))
|
||||||
if c.VerifyCertificates {
|
if c.EnableTls {
|
||||||
opts = append(opts, nats.RootCAs())
|
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||||
|
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||||
|
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,17 @@ const LOCAL_ENV = ".env.local"
|
||||||
type Nats struct {
|
type Nats struct {
|
||||||
Url string
|
Url string
|
||||||
Name string
|
Name string
|
||||||
VerifyCertificates bool
|
EnableTls bool
|
||||||
|
Cert Tls
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Tls struct {
|
||||||
|
CertFile string
|
||||||
|
KeyFile string
|
||||||
|
CaFile string
|
||||||
|
}
|
||||||
|
|
||||||
type Ws struct {
|
type Ws struct {
|
||||||
AuthEnable bool
|
AuthEnable bool
|
||||||
Addr string
|
Addr string
|
||||||
|
|
@ -42,7 +49,10 @@ func NewConfig() *Config {
|
||||||
|
|
||||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "ws-adapter"), "name for nats client")
|
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "ws-adapter"), "name for nats client")
|
||||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||||
|
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||||
|
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||||
|
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||||
wsAuthEnable := flag.Bool("ws_auth_enable", lookupEnvOrBool("WS_AUTH_ENABLE", false), "enable authentication for websocket server")
|
wsAuthEnable := flag.Bool("ws_auth_enable", lookupEnvOrBool("WS_AUTH_ENABLE", false), "enable authentication for websocket server")
|
||||||
wsAddr := flag.String("ws_addr", lookupEnvOrString("WS_ADDR", "localhost"), "websocket server address (domain or ip)")
|
wsAddr := flag.String("ws_addr", lookupEnvOrString("WS_ADDR", "localhost"), "websocket server address (domain or ip)")
|
||||||
wsPort := flag.String("ws_port", lookupEnvOrString("WS_PORT", ":8080"), "websocket server port")
|
wsPort := flag.String("ws_port", lookupEnvOrString("WS_PORT", ":8080"), "websocket server port")
|
||||||
|
|
@ -70,8 +80,13 @@ func NewConfig() *Config {
|
||||||
Nats: Nats{
|
Nats: Nats{
|
||||||
Url: *natsUrl,
|
Url: *natsUrl,
|
||||||
Name: *natsName,
|
Name: *natsName,
|
||||||
VerifyCertificates: *natsVerifyCertificates,
|
EnableTls: *natsEnableTls,
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
|
Cert: Tls{
|
||||||
|
CertFile: *clientCrt,
|
||||||
|
KeyFile: *clientKey,
|
||||||
|
CaFile: *serverCA,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Ws: Ws{
|
Ws: Ws{
|
||||||
AuthEnable: *wsAuthEnable,
|
AuthEnable: *wsAuthEnable,
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
||||||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||||
}))
|
}))
|
||||||
if c.VerifyCertificates {
|
if c.EnableTls {
|
||||||
opts = append(opts, nats.RootCAs())
|
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||||
|
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||||
|
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
return opts
|
return opts
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,17 @@ type Config struct {
|
||||||
type Nats struct {
|
type Nats struct {
|
||||||
Url string
|
Url string
|
||||||
Name string
|
Name string
|
||||||
VerifyCertificates bool
|
EnableTls bool
|
||||||
|
Cert Tls
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Tls struct {
|
||||||
|
CertFile string
|
||||||
|
KeyFile string
|
||||||
|
CaFile string
|
||||||
|
}
|
||||||
|
|
||||||
func NewConfig() Config {
|
func NewConfig() Config {
|
||||||
|
|
||||||
//Defines log format
|
//Defines log format
|
||||||
|
|
@ -47,7 +54,10 @@ func NewConfig() Config {
|
||||||
/* ------------------------------ define flags ------------------------------ */
|
/* ------------------------------ define flags ------------------------------ */
|
||||||
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
natsUrl := flag.String("nats_url", lookupEnvOrString("NATS_URL", "nats://localhost:4222"), "url for nats server")
|
||||||
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "ws-adapter"), "name for nats client")
|
natsName := flag.String("nats_name", lookupEnvOrString("NATS_NAME", "ws-adapter"), "name for nats client")
|
||||||
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
|
natsEnableTls := flag.Bool("nats_enable_tls", lookupEnvOrBool("NATS_ENABLE_TLS", false), "enbale TLS to nats server")
|
||||||
|
clientCrt := flag.String("client_crt", lookupEnvOrString("CLIENT_CRT", "cert.pem"), "client certificate file to TLS connection")
|
||||||
|
clientKey := flag.String("client_key", lookupEnvOrString("CLIENT_KEY", "key.pem"), "client key file to TLS connection")
|
||||||
|
serverCA := flag.String("server_ca", lookupEnvOrString("SERVER_CA", "rootCA.pem"), "server CA file to TLS connection")
|
||||||
flPort := flag.String("port", lookupEnvOrString("SERVER_PORT", ":8080"), "Server port")
|
flPort := flag.String("port", lookupEnvOrString("SERVER_PORT", ":8080"), "Server port")
|
||||||
flAuth := flag.Bool("auth", lookupEnvOrBool("SERVER_AUTH_ENABLE", false), "Server auth enable/disable")
|
flAuth := flag.Bool("auth", lookupEnvOrBool("SERVER_AUTH_ENABLE", false), "Server auth enable/disable")
|
||||||
flControllerEid := flag.String("controller-eid", lookupEnvOrString("CONTROLLER_EID", "oktopusController"), "Controller eid")
|
flControllerEid := flag.String("controller-eid", lookupEnvOrString("CONTROLLER_EID", "oktopusController"), "Controller eid")
|
||||||
|
|
@ -83,8 +93,13 @@ func NewConfig() Config {
|
||||||
Nats: Nats{
|
Nats: Nats{
|
||||||
Url: *natsUrl,
|
Url: *natsUrl,
|
||||||
Name: *natsName,
|
Name: *natsName,
|
||||||
VerifyCertificates: *natsVerifyCertificates,
|
EnableTls: *natsEnableTls,
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
|
Cert: Tls{
|
||||||
|
CertFile: *clientCrt,
|
||||||
|
KeyFile: *clientKey,
|
||||||
|
CaFile: *serverCA,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,8 +66,10 @@ func defineOptions(c config.Nats) []nats.Option {
|
||||||
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
opts = append(opts, nats.ClosedHandler(func(nc *nats.Conn) {
|
||||||
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
log.Printf("Connection closed. Reason: %q\n", nc.LastError())
|
||||||
}))
|
}))
|
||||||
if c.VerifyCertificates {
|
if c.EnableTls {
|
||||||
opts = append(opts, nats.RootCAs())
|
log.Printf("Load certificates: %s and %s\n", c.Cert.CertFile, c.Cert.KeyFile)
|
||||||
|
opts = append(opts, nats.RootCAs(c.Cert.CaFile))
|
||||||
|
opts = append(opts, nats.ClientCert(c.Cert.CertFile, c.Cert.KeyFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
return opts
|
return opts
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
DIRECTORY_PATH="./firmwares"
|
DIRECTORY_PATH="."
|
||||||
SERVER_PORT=":8004"
|
SERVER_PORT=":8004"
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
firmwares/
|
firmwares/
|
||||||
.env.local
|
.env.local
|
||||||
|
images/
|
||||||
8
backend/services/utils/file-server/build/Dockerfile
Normal file
8
backend/services/utils/file-server/build/Dockerfile
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
FROM golang:1.22.2@sha256:450e3822c7a135e1463cd83e51c8e2eb03b86a02113c89424e6f0f8344bb4168 as builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY ../ .
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux go build -o file-server main.go
|
||||||
|
|
||||||
|
FROM alpine:3.14@sha256:0f2d5c38dd7a4f4f733e688e3a6733cb5ab1ac6e3cb4603a5dd564e5bfb80eed
|
||||||
|
COPY --from=builder /app/file-server /
|
||||||
|
ENTRYPOINT ["/file-server"]
|
||||||
61
backend/services/utils/file-server/build/Makefile
Normal file
61
backend/services/utils/file-server/build/Makefile
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
.PHONY: help build push start stop release remove delete run logs bash
|
||||||
|
|
||||||
|
DOCKER_USER ?= oktopusp
|
||||||
|
DOCKER_APP ?= file-server
|
||||||
|
DOCKER_TAG ?= $(shell git log --format="%h" -n 1)
|
||||||
|
CONTAINER_SHELL ?= /bin/sh
|
||||||
|
|
||||||
|
.DEFAULT_GOAL := help
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo "Makefile arguments:"
|
||||||
|
@echo ""
|
||||||
|
@echo "DOCKER_USER - docker user to build image"
|
||||||
|
@echo "DOCKER_APP - docker image name"
|
||||||
|
@echo "DOCKER_TAG - docker image tag"
|
||||||
|
@echo "CONTAINER_SHELL - container shell e.g:'/bin/bash'"
|
||||||
|
@echo ""
|
||||||
|
@echo "Makefile commands:"
|
||||||
|
@echo ""
|
||||||
|
@echo "build - docker image build"
|
||||||
|
@echo "push - push docker iamge to registry"
|
||||||
|
@echo "run - create and start docker container with the image"
|
||||||
|
@echo "start - start existent docker container with the image"
|
||||||
|
@echo "stop - stop docker container running the image"
|
||||||
|
@echo "remove - remove docker container running the image"
|
||||||
|
@echo "delete - delete docker image"
|
||||||
|
@echo "logs - show logs of docker container"
|
||||||
|
@echo "bash - access container shell"
|
||||||
|
@echo "release - tag image as latest and push to registry"
|
||||||
|
|
||||||
|
build:
|
||||||
|
@docker build -t ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG} -f Dockerfile ../
|
||||||
|
|
||||||
|
run:
|
||||||
|
@docker run -d --name ${DOCKER_USER}-${DOCKER_APP} ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG}
|
||||||
|
|
||||||
|
stop:
|
||||||
|
@docker stop ${DOCKER_USER}-${DOCKER_APP}
|
||||||
|
|
||||||
|
remove: stop
|
||||||
|
@docker rm ${DOCKER_USER}-${DOCKER_APP}
|
||||||
|
|
||||||
|
delete:
|
||||||
|
@docker rmi ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG}
|
||||||
|
|
||||||
|
start:
|
||||||
|
@docker start ${DOCKER_USER}-${DOCKER_APP}
|
||||||
|
|
||||||
|
push:
|
||||||
|
@docker push ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG}
|
||||||
|
|
||||||
|
logs:
|
||||||
|
@docker logs -f ${DOCKER_USER}-${DOCKER_APP}
|
||||||
|
|
||||||
|
bash:
|
||||||
|
@docker exec -it ${DOCKER_USER}-${DOCKER_APP} ${CONTAINER_SHELL}
|
||||||
|
|
||||||
|
release: build
|
||||||
|
@docker push ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG}
|
||||||
|
@docker tag ${DOCKER_USER}/${DOCKER_APP}:${DOCKER_TAG} ${DOCKER_USER}/${DOCKER_APP}:latest
|
||||||
|
@docker push ${DOCKER_USER}/${DOCKER_APP}:latest
|
||||||
|
|
@ -42,7 +42,7 @@ func main() {
|
||||||
http.Handle("/", fileServer)
|
http.Handle("/", fileServer)
|
||||||
|
|
||||||
port := os.Getenv("SERVER_PORT")
|
port := os.Getenv("SERVER_PORT")
|
||||||
fmt.Printf("Server started at http://localhost:%s\n", port)
|
fmt.Printf("Server started at http://localhost%s\n", port)
|
||||||
err = http.ListenAndServe(port, nil)
|
err = http.ListenAndServe(port, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error starting server: %s\n", err)
|
fmt.Printf("Error starting server: %s\n", err)
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ build-backend:
|
||||||
@make build -C ../backend/services/controller/build/ DOCKER_USER=${DOCKER_USER}
|
@make build -C ../backend/services/controller/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
@make build -C ../backend/services/acs/build/ DOCKER_USER=${DOCKER_USER}
|
@make build -C ../backend/services/acs/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
@make build -C ../backend/services/utils/socketio/build/ DOCKER_USER=${DOCKER_USER}
|
@make build -C ../backend/services/utils/socketio/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
|
@make build -C ../backend/services/utils/file-server/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
@make build -C ../backend/services/mtp/adapter/build/ DOCKER_USER=${DOCKER_USER}
|
@make build -C ../backend/services/mtp/adapter/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
@make build -C ../backend/services/mtp/ws-adapter/build/ DOCKER_USER=${DOCKER_USER}
|
@make build -C ../backend/services/mtp/ws-adapter/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
@make build -C ../backend/services/mtp/ws/build/ DOCKER_USER=${DOCKER_USER}
|
@make build -C ../backend/services/mtp/ws/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
|
|
@ -43,6 +44,7 @@ release-backend:
|
||||||
@make release -C ../backend/services/controller/build/ DOCKER_USER=${DOCKER_USER}
|
@make release -C ../backend/services/controller/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
@make release -C ../backend/services/acs/build/ DOCKER_USER=${DOCKER_USER}
|
@make release -C ../backend/services/acs/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
@make release -C ../backend/services/utils/socketio/build/ DOCKER_USER=${DOCKER_USER}
|
@make release -C ../backend/services/utils/socketio/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
|
@make release -C ../backend/services/utils/file-server/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
@make release -C ../backend/services/mtp/adapter/build/ DOCKER_USER=${DOCKER_USER}
|
@make release -C ../backend/services/mtp/adapter/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
@make release -C ../backend/services/mtp/ws-adapter/build/ DOCKER_USER=${DOCKER_USER}
|
@make release -C ../backend/services/mtp/ws-adapter/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
@make release -C ../backend/services/mtp/ws/build/ DOCKER_USER=${DOCKER_USER}
|
@make release -C ../backend/services/mtp/ws/build/ DOCKER_USER=${DOCKER_USER}
|
||||||
|
|
|
||||||
|
|
@ -1 +1,5 @@
|
||||||
NATS_URL=nats://msg_broker:4222
|
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||||
|
NATS_ENABLE_TLS="true"
|
||||||
|
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||||
|
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||||
|
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,6 @@
|
||||||
NATS_URL=nats://msg_broker:4222
|
|
||||||
MONGO_URI=mongodb://mongo_usp:27017
|
MONGO_URI=mongodb://mongo_usp:27017
|
||||||
|
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||||
|
NATS_ENABLE_TLS="true"
|
||||||
|
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||||
|
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||||
|
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,6 @@
|
||||||
NATS_URL=nats://msg_broker:4222
|
|
||||||
MONGO_URI=mongodb://mongo_usp:27017
|
MONGO_URI=mongodb://mongo_usp:27017
|
||||||
|
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||||
|
NATS_ENABLE_TLS="true"
|
||||||
|
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||||
|
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||||
|
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||||
|
|
|
||||||
2
deploy/compose/.env.file-server
Normal file
2
deploy/compose/.env.file-server
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
DIRECTORY_PATH="."
|
||||||
|
SERVER_PORT=":8004"
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
REDIS_ENABLE=false
|
REDIS_ENABLE=false
|
||||||
REDIS_ADDR=redis_usp:6379
|
REDIS_ADDR=redis_usp:6379
|
||||||
NATS_URL=nats://msg_broker:4222
|
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||||
|
NATS_ENABLE_TLS="true"
|
||||||
|
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||||
|
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||||
|
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,6 @@
|
||||||
NATS_URL=nats://msg_broker:4222
|
|
||||||
MQTT_URL=tcp://mqtt:1883
|
MQTT_URL=tcp://mqtt:1883
|
||||||
|
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||||
|
NATS_ENABLE_TLS="true"
|
||||||
|
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||||
|
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||||
|
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||||
|
|
|
||||||
3
deploy/compose/.env.nats
Normal file
3
deploy/compose/.env.nats
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
NATS_NAME=oktopus
|
||||||
|
NATS_USER=oktopususer
|
||||||
|
NATS_PW=oktopuspw
|
||||||
|
|
@ -1 +1,5 @@
|
||||||
NATS_URL=nats://msg_broker:4222
|
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||||
|
NATS_ENABLE_TLS="true"
|
||||||
|
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||||
|
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||||
|
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,6 @@
|
||||||
NATS_URL=nats://msg_broker:4222
|
|
||||||
STOMP_SERVER=stomp:61613
|
STOMP_SERVER=stomp:61613
|
||||||
|
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||||
|
NATS_ENABLE_TLS="true"
|
||||||
|
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||||
|
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||||
|
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||||
|
|
|
||||||
|
|
@ -1 +1,5 @@
|
||||||
NATS_URL=nats://msg_broker:4222
|
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||||
|
NATS_ENABLE_TLS="true"
|
||||||
|
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||||
|
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||||
|
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,6 @@
|
||||||
NATS_URL=nats://msg_broker:4222
|
|
||||||
WS_ADDR=ws
|
WS_ADDR=ws
|
||||||
|
NATS_URL=nats://oktopususer:oktopuspw@msg_broker:4222
|
||||||
|
NATS_ENABLE_TLS="true"
|
||||||
|
CLIENT_CRT=/tmp/nats/config/cert.pem
|
||||||
|
CLIENT_KEY=/tmp/nats/config/key.pem
|
||||||
|
SERVER_CA=/tmp/nats/config/rootCA.pem
|
||||||
|
|
|
||||||
4
deploy/compose/.gitignore
vendored
4
deploy/compose/.gitignore
vendored
|
|
@ -4,3 +4,7 @@ mongo_data/*
|
||||||
!mongo_data/.gitkeep
|
!mongo_data/.gitkeep
|
||||||
nats_data/*
|
nats_data/*
|
||||||
!nats_data/.gitkeep
|
!nats_data/.gitkeep
|
||||||
|
firmwares/*
|
||||||
|
!firmwares/.gitkeep
|
||||||
|
images/*
|
||||||
|
!images/logo.png
|
||||||
|
|
@ -1,24 +1,26 @@
|
||||||
services:
|
services:
|
||||||
|
#/* ----------------------------- Message Broker ----------------------------- */
|
||||||
#/* ----------------------------- Message Broker ----------------------------- */
|
|
||||||
msg_broker:
|
msg_broker:
|
||||||
image: 'nats:latest'
|
image: "nats:latest"
|
||||||
container_name: nats
|
container_name: nats
|
||||||
ports:
|
ports:
|
||||||
- 4222:4222
|
- 4222:4222
|
||||||
- 8222:8222
|
- 8222:8222
|
||||||
command: -n oktopus -m 8222 -js
|
command: -c /tmp/nats/config/nats.cfg
|
||||||
|
env_file:
|
||||||
|
- .env.nats
|
||||||
volumes:
|
volumes:
|
||||||
- ./nats_data:/tmp/nats/jetstream
|
- ./nats_data:/tmp/nats/jetstream
|
||||||
|
- ./nats_config:/tmp/nats/config
|
||||||
networks:
|
networks:
|
||||||
usp_network:
|
usp_network:
|
||||||
ipv4_address: 172.16.235.2
|
ipv4_address: 172.16.235.2
|
||||||
profiles: [nats]
|
profiles: [nats]
|
||||||
#/* -------------------------------------------------------------------------- */
|
#/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#/* ------------------------ API REST / USP Controller ----------------------- */
|
#/* ------------------------ API REST / USP Controller ----------------------- */
|
||||||
controller:
|
controller:
|
||||||
image: 'oktopusp/controller'
|
image: "oktopusp/controller"
|
||||||
container_name: controller
|
container_name: controller
|
||||||
ports:
|
ports:
|
||||||
- 8000:8000
|
- 8000:8000
|
||||||
|
|
@ -26,13 +28,15 @@ services:
|
||||||
- mongo_usp
|
- mongo_usp
|
||||||
env_file:
|
env_file:
|
||||||
- .env.controller
|
- .env.controller
|
||||||
|
volumes:
|
||||||
|
- ./nats_config:/tmp/nats/config
|
||||||
networks:
|
networks:
|
||||||
usp_network:
|
usp_network:
|
||||||
ipv4_address: 172.16.235.3
|
ipv4_address: 172.16.235.3
|
||||||
profiles: [controller]
|
profiles: [controller]
|
||||||
#/* -------------------------------------------------------------------------- */
|
#/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#/* ---------------------------- Databases / Cache --------------------------- */
|
#/* ---------------------------- Databases / Cache --------------------------- */
|
||||||
mongo_usp:
|
mongo_usp:
|
||||||
image: mongo
|
image: mongo
|
||||||
container_name: mongo_usp
|
container_name: mongo_usp
|
||||||
|
|
@ -43,38 +47,42 @@ services:
|
||||||
ipv4_address: 172.16.235.4
|
ipv4_address: 172.16.235.4
|
||||||
volumes:
|
volumes:
|
||||||
- ./mongo_data:/data/db
|
- ./mongo_data:/data/db
|
||||||
profiles: [controller,adapter]
|
profiles: [controller, adapter]
|
||||||
|
|
||||||
#/* -------------------------------------------------------------------------- */
|
#/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#/* ----------------------- Message Transfer Protocols ----------------------- */
|
#/* ----------------------- Message Transfer Protocols ----------------------- */
|
||||||
mqtt:
|
mqtt:
|
||||||
image: 'oktopusp/mqtt'
|
image: "oktopusp/mqtt"
|
||||||
container_name: mqtt
|
container_name: mqtt
|
||||||
ports:
|
ports:
|
||||||
- 1883:1883
|
- 1883:1883
|
||||||
- 8883:8883
|
- 8883:8883
|
||||||
env_file:
|
env_file:
|
||||||
- .env.mqtt
|
- .env.mqtt
|
||||||
|
volumes:
|
||||||
|
- ./nats_config:/tmp/nats/config
|
||||||
networks:
|
networks:
|
||||||
usp_network:
|
usp_network:
|
||||||
ipv4_address: 172.16.235.6
|
ipv4_address: 172.16.235.6
|
||||||
profiles: [mqtt]
|
profiles: [mqtt]
|
||||||
|
|
||||||
ws:
|
ws:
|
||||||
image: 'oktopusp/ws'
|
image: "oktopusp/ws"
|
||||||
container_name: websockets
|
container_name: websockets
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
env_file:
|
env_file:
|
||||||
- .env.ws
|
- .env.ws
|
||||||
|
volumes:
|
||||||
|
- ./nats_config:/tmp/nats/config
|
||||||
networks:
|
networks:
|
||||||
usp_network:
|
usp_network:
|
||||||
ipv4_address: 172.16.235.7
|
ipv4_address: 172.16.235.7
|
||||||
profiles: [ws]
|
profiles: [ws]
|
||||||
|
|
||||||
stomp:
|
stomp:
|
||||||
image: 'oktopusp/stomp'
|
image: "oktopusp/stomp"
|
||||||
container_name: stomp
|
container_name: stomp
|
||||||
ports:
|
ports:
|
||||||
- 61613:61613
|
- 61613:61613
|
||||||
|
|
@ -82,76 +90,85 @@ services:
|
||||||
usp_network:
|
usp_network:
|
||||||
ipv4_address: 172.16.235.8
|
ipv4_address: 172.16.235.8
|
||||||
profiles: [stomp]
|
profiles: [stomp]
|
||||||
#/* -------------------------------------------------------------------------- */
|
#/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#/* --------------- Message transfer Protocols Adapters to NATS -------------- */
|
#/* --------------- Message transfer Protocols Adapters to NATS -------------- */
|
||||||
mqtt-adapter:
|
mqtt-adapter:
|
||||||
image: 'oktopusp/mqtt-adapter'
|
image: "oktopusp/mqtt-adapter"
|
||||||
container_name: mqtt-adapter
|
container_name: mqtt-adapter
|
||||||
depends_on:
|
depends_on:
|
||||||
- mqtt
|
- mqtt
|
||||||
env_file:
|
env_file:
|
||||||
- .env.mqtt-adapter
|
- .env.mqtt-adapter
|
||||||
|
volumes:
|
||||||
|
- ./nats_config:/tmp/nats/config
|
||||||
networks:
|
networks:
|
||||||
usp_network:
|
usp_network:
|
||||||
ipv4_address: 172.16.235.9
|
ipv4_address: 172.16.235.9
|
||||||
profiles: [mqtt]
|
profiles: [mqtt]
|
||||||
|
|
||||||
|
|
||||||
ws-adapter:
|
ws-adapter:
|
||||||
image: 'oktopusp/ws-adapter'
|
image: "oktopusp/ws-adapter"
|
||||||
container_name: ws-adapter
|
container_name: ws-adapter
|
||||||
depends_on:
|
depends_on:
|
||||||
- ws
|
- ws
|
||||||
env_file:
|
env_file:
|
||||||
- .env.ws-adapter
|
- .env.ws-adapter
|
||||||
|
volumes:
|
||||||
|
- ./nats_config:/tmp/nats/config
|
||||||
networks:
|
networks:
|
||||||
usp_network:
|
usp_network:
|
||||||
ipv4_address: 172.16.235.10
|
ipv4_address: 172.16.235.10
|
||||||
profiles: [ws]
|
profiles: [ws]
|
||||||
|
|
||||||
stomp-adapter:
|
stomp-adapter:
|
||||||
image: 'oktopusp/stomp-adapter'
|
image: "oktopusp/stomp-adapter"
|
||||||
container_name: stomp-adapter
|
container_name: stomp-adapter
|
||||||
depends_on:
|
depends_on:
|
||||||
- stomp
|
- stomp
|
||||||
env_file:
|
env_file:
|
||||||
- .env.stomp-adapter
|
- .env.stomp-adapter
|
||||||
|
volumes:
|
||||||
|
- ./nats_config:/tmp/nats/config
|
||||||
networks:
|
networks:
|
||||||
usp_network:
|
usp_network:
|
||||||
ipv4_address: 172.16.235.11
|
ipv4_address: 172.16.235.11
|
||||||
profiles: [stomp]
|
profiles: [stomp]
|
||||||
|
|
||||||
adapter:
|
adapter:
|
||||||
image: 'oktopusp/adapter'
|
image: "oktopusp/adapter"
|
||||||
container_name: adapter
|
container_name: adapter
|
||||||
depends_on:
|
depends_on:
|
||||||
- mongo_usp
|
- mongo_usp
|
||||||
env_file:
|
env_file:
|
||||||
- .env.adapter
|
- .env.adapter
|
||||||
|
volumes:
|
||||||
|
- ./nats_config:/tmp/nats/config
|
||||||
networks:
|
networks:
|
||||||
usp_network:
|
usp_network:
|
||||||
ipv4_address: 172.16.235.12
|
ipv4_address: 172.16.235.12
|
||||||
profiles: [adapter]
|
profiles: [adapter]
|
||||||
#/* -------------------------------------------------------------------------- */
|
#/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#/* ------------- SocketIO Real Time Communication With Frontend ------------- */
|
#/* ------------- SocketIO Real Time Communication With Frontend ------------- */
|
||||||
socketio:
|
socketio:
|
||||||
image: 'oktopusp/socketio'
|
image: "oktopusp/socketio"
|
||||||
container_name: socketio
|
container_name: socketio
|
||||||
ports:
|
ports:
|
||||||
- 5000:5000
|
- 5000:5000
|
||||||
env_file:
|
env_file:
|
||||||
- .env.socketio
|
- .env.socketio
|
||||||
|
volumes:
|
||||||
|
- ./nats_config:/tmp/nats/config
|
||||||
networks:
|
networks:
|
||||||
usp_network:
|
usp_network:
|
||||||
ipv4_address: 172.16.235.13
|
ipv4_address: 172.16.235.13
|
||||||
profiles: [frontend]
|
profiles: [frontend]
|
||||||
#/* -------------------------------------------------------------------------- */
|
#/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#/* -------------------------------- Frontend -------------------------------- */
|
#/* -------------------------------- Frontend -------------------------------- */
|
||||||
frontend:
|
frontend:
|
||||||
image: 'oktopusp/frontend-ce'
|
image: "oktopusp/frontend-ce"
|
||||||
container_name: frontend
|
container_name: frontend
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 3000:3000
|
||||||
|
|
@ -159,7 +176,7 @@ services:
|
||||||
usp_network:
|
usp_network:
|
||||||
ipv4_address: 172.16.235.14
|
ipv4_address: 172.16.235.14
|
||||||
profiles: [frontend]
|
profiles: [frontend]
|
||||||
#/* -------------------------------------------------------------------------- */
|
#/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
portainer:
|
portainer:
|
||||||
image: portainer/portainer-ce:latest
|
image: portainer/portainer-ce:latest
|
||||||
|
|
@ -175,12 +192,14 @@ services:
|
||||||
- ./portainer_data:/data
|
- ./portainer_data:/data
|
||||||
|
|
||||||
acs:
|
acs:
|
||||||
image: oktopusp/acs
|
image: "oktopusp/acs"
|
||||||
container_name: acs
|
container_name: acs
|
||||||
ports:
|
ports:
|
||||||
- 9292:9292
|
- 9292:9292
|
||||||
env_file:
|
env_file:
|
||||||
- .env.acs
|
- .env.acs
|
||||||
|
volumes:
|
||||||
|
- ./nats_config:/tmp/nats/config
|
||||||
networks:
|
networks:
|
||||||
usp_network:
|
usp_network:
|
||||||
ipv4_address: 172.16.235.16
|
ipv4_address: 172.16.235.16
|
||||||
|
|
@ -191,16 +210,28 @@ services:
|
||||||
container_name: nginx
|
container_name: nginx
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 80:80
|
||||||
depends_on:
|
|
||||||
- frontend
|
|
||||||
- controller
|
|
||||||
- socketio
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf
|
- ./nginx.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
networks:
|
networks:
|
||||||
usp_network:
|
usp_network:
|
||||||
ipv4_address: 172.16.235.17
|
ipv4_address: 172.16.235.17
|
||||||
|
|
||||||
|
file-server:
|
||||||
|
image: oktopusp/file-server
|
||||||
|
container_name: file-server
|
||||||
|
ports:
|
||||||
|
- 8004:8004
|
||||||
|
volumes:
|
||||||
|
- ./firmwares:/app/firmwares
|
||||||
|
- ./images:/app/images
|
||||||
|
env_file:
|
||||||
|
- .env.file-server
|
||||||
|
networks:
|
||||||
|
usp_network:
|
||||||
|
ipv4_address: 172.16.235.18
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
usp_network:
|
usp_network:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|
|
||||||
0
deploy/compose/firmwares/.gitkeep
Normal file
0
deploy/compose/firmwares/.gitkeep
Normal file
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
26
deploy/compose/nats_config/cert.pem
Normal file
26
deploy/compose/nats_config/cert.pem
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEeTCCAuGgAwIBAgIRAJenDys60PD3Cjh9VXeAzsowDQYJKoZIhvcNAQELBQAw
|
||||||
|
gY0xHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTExMC8GA1UECwwoY2hp
|
||||||
|
ZXNhQEFkcmlhbm9NYWMubG9jYWwgKEFkcmlhbm8gQ2hpZXNhKTE4MDYGA1UEAwwv
|
||||||
|
bWtjZXJ0IGNoaWVzYUBBZHJpYW5vTWFjLmxvY2FsIChBZHJpYW5vIENoaWVzYSkw
|
||||||
|
HhcNMjQwNzA2MTQzODQ2WhcNMjYxMDA2MTQzODQ2WjBcMScwJQYDVQQKEx5ta2Nl
|
||||||
|
cnQgZGV2ZWxvcG1lbnQgY2VydGlmaWNhdGUxMTAvBgNVBAsMKGNoaWVzYUBBZHJp
|
||||||
|
YW5vTWFjLmxvY2FsIChBZHJpYW5vIENoaWVzYSkwggEiMA0GCSqGSIb3DQEBAQUA
|
||||||
|
A4IBDwAwggEKAoIBAQCdQCgwn7M5jtkNzYv/yUelUV84ehsYjPTQspCXCjDdUltO
|
||||||
|
E6jafRM/2SopUWwzPTorIZkerIpqq/avi77e6wSdCKJZBA5DsrMSOmFjjMqG4H2b
|
||||||
|
euzr5b+ZKzKnw4nF/CuB2cmWkz/qAiluqVdRl+Gef/Ouyuer/NuhJhK6Mgy1VuAd
|
||||||
|
ynwizGsAgQ/oAGDuHWmcMhGw/2NVTnXqHei5ntr+F4r08YOgXnRsGId+16nJU5xd
|
||||||
|
Xs80sw2dFl+1zQiFJxWjVQk65CyZfLDcwC7e3PAMsT+8obzuBKCn6fW3JiIZ68tc
|
||||||
|
o8GZClHSkeS7IMp+/wtjMXf1iipE0bRWzzdl1xQnAgMBAAGjgYMwgYAwDgYDVR0P
|
||||||
|
AQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB8GA1UdIwQYMBaAFH2KEsMw
|
||||||
|
S7/Qu1eE1DxRhZTI0Z7RMDgGA1UdEQQxMC+CCm1zZ19icm9rZXKCCWxvY2FsaG9z
|
||||||
|
dIcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAYEAVr06
|
||||||
|
Kg/FaWxUbD6Q+e5OLzckeeFZOKcb/2mmEH+e99HebnCuydiiGebZVWcLsoOw+gmb
|
||||||
|
WG/4rFyp9D/ZYFiQxWNRm/nCcxiHIV+JHDxhBn3vKENxYNNbr+WTMBTqmaYqPARK
|
||||||
|
SelnX+XDRTZUnoRBo03wZFYwOYwHUFWrlMFz+o6jOo2KZa4J+pcEDbttkJEoVhiV
|
||||||
|
C8EKIxSsG9TuW4lh5UySfB62ZfQBNd8SyhD4LF5JHFbBV9ysnylg/8gVvavjHWtM
|
||||||
|
FleOk/lNi9oj2n8uQEGbBT6FpTaKKJDiF85E3J4fuv8iNiFy2nWhCpJFF9K5/hu6
|
||||||
|
s41Y2ZRb7luBoUj+CQWlTpGjCJPzzWmSkZUjf5kRP6b01bAXoLBzBBn50KWf8DWw
|
||||||
|
Rx7VaHtzbBRxfzESQxslGRgZvz2KxjY/x2jH6xdW+bzt93aHkgeGkDrjpY9q/uQF
|
||||||
|
SyEJYHIDt+FZupcc3KjvTY2p+icbckOrwQAtVWXzEjCsnDjf33+O7VGdACDm
|
||||||
|
-----END CERTIFICATE-----
|
||||||
28
deploy/compose/nats_config/key.pem
Normal file
28
deploy/compose/nats_config/key.pem
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCdQCgwn7M5jtkN
|
||||||
|
zYv/yUelUV84ehsYjPTQspCXCjDdUltOE6jafRM/2SopUWwzPTorIZkerIpqq/av
|
||||||
|
i77e6wSdCKJZBA5DsrMSOmFjjMqG4H2beuzr5b+ZKzKnw4nF/CuB2cmWkz/qAilu
|
||||||
|
qVdRl+Gef/Ouyuer/NuhJhK6Mgy1VuAdynwizGsAgQ/oAGDuHWmcMhGw/2NVTnXq
|
||||||
|
Hei5ntr+F4r08YOgXnRsGId+16nJU5xdXs80sw2dFl+1zQiFJxWjVQk65CyZfLDc
|
||||||
|
wC7e3PAMsT+8obzuBKCn6fW3JiIZ68tco8GZClHSkeS7IMp+/wtjMXf1iipE0bRW
|
||||||
|
zzdl1xQnAgMBAAECggEAMRDQuYNLJ/2DioQFV/WVDmdaf8PR6pIo3WmqJga/An/t
|
||||||
|
D2qg+DOoqvZ26leGnGJRYR3lqiWKNwibO2EuWF4anWkRRxc14DfFGj3vH2HR2832
|
||||||
|
Q2pSvLR+WSuabbBcr9MkPCsZdItTmQ+9n9Lk9QegFZW1Emgra4XFff3kQAbX4kjR
|
||||||
|
ATyEsvZsgnkK5jHi5bzVHEKY730MKyhYzmHmUgxH1ibD5x+tnFtRiBGK+qY24erW
|
||||||
|
rw+wu0YKu1ESp62orYDnaA8MH7aWlFZLniPB4liA0h0bElrgHA8Zndx+cEtXqF4m
|
||||||
|
5+igR3MjXbg2at80ah++z6EGUTtEPccRSpcA7qFqMQKBgQDFVp1msdn45Xwquw+8
|
||||||
|
CSZ45KAurvQEPNxtK/GMHtR5LjRZlKQEpNy3AVjz56azv72kqUfhNsP+ZNokMQTH
|
||||||
|
NTMvdkLzcwKe3qCnsfBRlSkRBVCwan266oCJW8SSX8pdaoME9lzc2BfMVAxJ1n+Y
|
||||||
|
289ZHXyyPYdNd+L4FxjreJDkKQKBgQDL/uD+kCSKZ/dYVZqwF06DIzYiBv1Xjne3
|
||||||
|
3H90J0h/2iU9/yX9UsCS7D5RWbVROUyMh64fpH0f2lVFT8Xo3SjBWISrMovOxEzl
|
||||||
|
C2wZwM2VQmrfhiUg9h46drJSl/JL9/V/QOnpuQe35bVWjROtFStaZagUK/3vx1hh
|
||||||
|
xCV4iVS/zwKBgQC2Ea3zvA/x9jlTa3ee84pNbBLmP4DgEA8Hos2fjCpZC+o85ElY
|
||||||
|
B4ukRVf+4TILEdM1AwJQpii6o+4oChnwegMZvTEUUH6QebMcRa4Gd2qGS7MgsYAD
|
||||||
|
XqztDoAU1NBu1ADCKVOQZse+O6WC0qazL8rk27Ha+a3GKeB9KUJSrtBv0QKBgCi5
|
||||||
|
IftPlSvYI2WL+Uxr6q19KwJR+OMwuq+Goh7y9KMpTkP5GoFesrjh1nLxAKRNVv26
|
||||||
|
3ETO1ne0Y09p5G1fMRKf9CQk/Anz4BHdXOArQB8q2iDzK5hP6arsJR8d3C3UOzsD
|
||||||
|
H28cE/FfNvsnQKVN05DBOHOGcLQcTIV/3acZa0S7AoGBAJqSujzhVkewH7wJWOOh
|
||||||
|
92F66vMnCsE4Qn10h84GQQWORgjr8z8d8UbW7VrobVfZP74IBqo3ZUBYm85+lUFu
|
||||||
|
FWHjTkXoZzwP8IvMW0gE2iC3W4QSr2Z96a6RlRJdxC70LB+Pm6FFwLTloKBGK8Bf
|
||||||
|
Kp53gUDjsvJcQGv6nOty0uHQ
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
18
deploy/compose/nats_config/nats.cfg
Normal file
18
deploy/compose/nats_config/nats.cfg
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
server_name: $NATS_NAME
|
||||||
|
port: 4222
|
||||||
|
http_port: 8222
|
||||||
|
authorization: {
|
||||||
|
users: [
|
||||||
|
{user: $NATS_USER, password: $NATS_PW}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
tls: {
|
||||||
|
cert_file: "/tmp/nats/config/cert.pem"
|
||||||
|
key_file: "/tmp/nats/config/key.pem"
|
||||||
|
ca_file: "/tmp/nats/config/rootCA.pem"
|
||||||
|
}
|
||||||
|
// enables jetstream, an empty block will enable and use defaults
|
||||||
|
jetstream {
|
||||||
|
// jetstream data will be in /data/nats-server/jetstream
|
||||||
|
store_dir: "/tmp/nats/jetstream"
|
||||||
|
}
|
||||||
29
deploy/compose/nats_config/rootCA.pem
Normal file
29
deploy/compose/nats_config/rootCA.pem
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIE6zCCA1OgAwIBAgIQcw3hWvi1nfQFSkUzrcdrhTANBgkqhkiG9w0BAQsFADCB
|
||||||
|
jTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMTEwLwYDVQQLDChjaGll
|
||||||
|
c2FAQWRyaWFub01hYy5sb2NhbCAoQWRyaWFubyBDaGllc2EpMTgwNgYDVQQDDC9t
|
||||||
|
a2NlcnQgY2hpZXNhQEFkcmlhbm9NYWMubG9jYWwgKEFkcmlhbm8gQ2hpZXNhKTAe
|
||||||
|
Fw0yMjA4MTIxNTM1NDdaFw0zMjA4MTIxNTM1NDdaMIGNMR4wHAYDVQQKExVta2Nl
|
||||||
|
cnQgZGV2ZWxvcG1lbnQgQ0ExMTAvBgNVBAsMKGNoaWVzYUBBZHJpYW5vTWFjLmxv
|
||||||
|
Y2FsIChBZHJpYW5vIENoaWVzYSkxODA2BgNVBAMML21rY2VydCBjaGllc2FAQWRy
|
||||||
|
aWFub01hYy5sb2NhbCAoQWRyaWFubyBDaGllc2EpMIIBojANBgkqhkiG9w0BAQEF
|
||||||
|
AAOCAY8AMIIBigKCAYEA4HBEZqDbKPB0StZX/ILPU1q2Tm/U4j32/HvaWOGt528q
|
||||||
|
15y5eqa4OqpYQ7waVhkSR+M6258yAk9BCCOGrI+oXcllO7LKv4bg/y+HVhfEg4E0
|
||||||
|
fnZS583+VWrIcIKOENQQX1cbFnIqLldBL/ph6YNMDT8wOoLqtQ2vp1EiXFA3ghQs
|
||||||
|
fK3iqDL31SQ7cZhdw7hnNACgvIM6MipwFLYbMsm27eMa9fCL4ZB3xokhbYVBmEcT
|
||||||
|
RTdhGvcRBs+QF8fcP/Y6uC9y7q2ddeIYEAf5xCVc15QepPqVskuAM3rktzVpBKEl
|
||||||
|
lzJGtW3EWu3kojrrW8dYZkZFJkHy9ymZVNUPjpAGiIIylp1Rik/o9VttXi+BQmrV
|
||||||
|
l1tpkrU1JfhLcktjBtRxtvRJTARpSkMM8gVc1rA2KgNsULzF4Zaas12wUh7r/VzW
|
||||||
|
4lwKiV3vgAM0wE5Fo4NLmv53/j3w7yX9GtSq0Ck/cKu2k0cOe+PTlG9aQ5MdhLCx
|
||||||
|
+BwMij/ohBfh0qtgPVPdAgMBAAGjRTBDMA4GA1UdDwEB/wQEAwICBDASBgNVHRMB
|
||||||
|
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBR9ihLDMEu/0LtXhNQ8UYWUyNGe0TANBgkq
|
||||||
|
hkiG9w0BAQsFAAOCAYEAyGNw197jniIGfCpcArC2lHbzNIQCq97BXsOj4h+CaUB+
|
||||||
|
ZfTpTOdtS5DK2fSQ4jwH6nzm7VQvrnHcbP2pCgVDWW9da+Acnh1U6dYXI1VPDDVA
|
||||||
|
KZGDiK63M6PneX3IDl2N2fubRDP1ALkZQ6zwjtJLC2nT6IVjAJdRNt8egbCUAyMb
|
||||||
|
nOb4F+Zrr0L2SILM0jHq9diJVpX4Lxqggldmd+5HdVGHoR8BGzw4MReuoRWOZtf/
|
||||||
|
H+opFtJ2f8GNTWsWtmN7FsjrGOOBgREB/Tz7WCWgGEeXQveJEfkOIddVVgb/n9Ly
|
||||||
|
mEOTbtJj36o4JJzv0v42SdT1WUkdvc6AmLVmYFn0uaLohNLVelJmU+aGavuVFpFb
|
||||||
|
08uVsSl8JMBWwVO23CpuvZFbI/1BFVix85UZgDj8BnpAWlsJxPYV1HqxS2oJJJbn
|
||||||
|
zRf8/0xzFPrLirXzebIr4jiCRVBRamacQTxlvPUz6c6FLTQLaqQdUV/IZaXsXX38
|
||||||
|
byH1ABmJPGjXLm1r2RWD
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
@ -11,19 +11,7 @@ server {
|
||||||
}
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://frontend:3000;
|
proxy_pass http://host.docker.internal:3000;
|
||||||
proxy_read_timeout 60;
|
|
||||||
proxy_connect_timeout 60;
|
|
||||||
proxy_redirect off;
|
|
||||||
}
|
|
||||||
location /api {
|
|
||||||
proxy_pass http://controller:8000;
|
|
||||||
proxy_read_timeout 60;
|
|
||||||
proxy_connect_timeout 60;
|
|
||||||
proxy_redirect off;
|
|
||||||
}
|
|
||||||
location /socket.io {
|
|
||||||
proxy_pass http://socketio:5000;
|
|
||||||
proxy_read_timeout 60;
|
proxy_read_timeout 60;
|
||||||
proxy_connect_timeout 60;
|
proxy_connect_timeout 60;
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
|
|
@ -34,6 +22,33 @@ server {
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_cache_bypass $http_upgrade;
|
proxy_cache_bypass $http_upgrade;
|
||||||
}
|
}
|
||||||
|
location /api {
|
||||||
|
proxy_pass http://host.docker.internal:8000;
|
||||||
|
proxy_read_timeout 60;
|
||||||
|
proxy_connect_timeout 60;
|
||||||
|
proxy_redirect off;
|
||||||
|
}
|
||||||
|
location /custom-frontend {
|
||||||
|
proxy_pass http://host.docker.internal:8005;
|
||||||
|
proxy_read_timeout 60;
|
||||||
|
proxy_connect_timeout 60;
|
||||||
|
proxy_redirect off;
|
||||||
|
}
|
||||||
|
location /socket.io {
|
||||||
|
proxy_pass http://host.docker.internal:5000;
|
||||||
|
proxy_read_timeout 60;
|
||||||
|
proxy_connect_timeout 60;
|
||||||
|
proxy_redirect off;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection 'upgrade';
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
}
|
||||||
|
location /companylink {
|
||||||
|
return 301 https://oktopus.app.br/controller;
|
||||||
|
}
|
||||||
|
|
||||||
error_page 500 502 503 504 /50x.html;
|
error_page 500 502 503 504 /50x.html;
|
||||||
location = /50x.html {
|
location = /50x.html {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
# ----------------------------- Local Environment ---------------------------- #
|
# ----------------------------- Local Environment ---------------------------- #
|
||||||
|
|
||||||
NEXT_PUBLIC_REST_ENDPOINT="http://localhost:8000"
|
|
||||||
NEXT_PUBLIC_WS_ENDPOINT="http://localhost:5000/"
|
NEXT_PUBLIC_WS_ENDPOINT="http://localhost:5000/"
|
||||||
NEXT_PUBLIC_ENTERPRISE_VERSION="false"
|
NEXT_PUBLIC_ENTERPRISE_VERSION="false"
|
||||||
NEXT_PUBLIC_GOOGLE_MAPS_KEY=""
|
NEXT_PUBLIC_GOOGLE_MAPS_KEY=""
|
||||||
|
|
|
||||||
46
frontend/package-lock.json
generated
46
frontend/package-lock.json
generated
|
|
@ -18,14 +18,14 @@
|
||||||
"@mui/system": "5.11.9",
|
"@mui/system": "5.11.9",
|
||||||
"@mui/x-date-pickers": "5.0.19",
|
"@mui/x-date-pickers": "5.0.19",
|
||||||
"@react-google-maps/api": "^2.19.3",
|
"@react-google-maps/api": "^2.19.3",
|
||||||
"apexcharts": "3.37.0",
|
"apexcharts": "^3.37.0",
|
||||||
"date-fns": "2.29.3",
|
"date-fns": "2.29.3",
|
||||||
"formik": "2.2.9",
|
"formik": "2.2.9",
|
||||||
"next": "^14.2.4",
|
"next": "^14.2.4",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"prop-types": "15.8.1",
|
"prop-types": "15.8.1",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-apexcharts": "1.4.0",
|
"react-apexcharts": "^1.4.0",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"simple-peer": "^9.11.1",
|
"simple-peer": "^9.11.1",
|
||||||
"simplebar-react": "^3.2.1",
|
"simplebar-react": "^3.2.1",
|
||||||
|
|
@ -1480,6 +1480,11 @@
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@yr/monotone-cubic-spline": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA=="
|
||||||
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.11.3",
|
"version": "8.11.3",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
||||||
|
|
@ -1538,10 +1543,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/apexcharts": {
|
"node_modules/apexcharts": {
|
||||||
"version": "3.37.0",
|
"version": "3.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.37.0.tgz",
|
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.50.0.tgz",
|
||||||
"integrity": "sha512-0mg1gDKUo3JG00Q//LK0jEXBS6OLjpuglqZ8ec9cqfA5oP8owopD9n5EhfARbWROb5o8GSPzFuohTJiCm2ecWw==",
|
"integrity": "sha512-LJT1PNAm+NoIU3aogL2P+ViC0y/Cjik54FdzzGV54UNnGQLBoLe5ok3fxsJDTgyez45BGYT8gqNpYKqhdfy5sg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@yr/monotone-cubic-spline": "^1.0.3",
|
||||||
"svg.draggable.js": "^2.2.2",
|
"svg.draggable.js": "^2.2.2",
|
||||||
"svg.easing.js": "^2.0.0",
|
"svg.easing.js": "^2.0.0",
|
||||||
"svg.filter.js": "^2.0.2",
|
"svg.filter.js": "^2.0.2",
|
||||||
|
|
@ -4722,14 +4728,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-apexcharts": {
|
"node_modules/react-apexcharts": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.1.tgz",
|
||||||
"integrity": "sha512-DrcMV4aAMrUG+n6412yzyATWEyCDWlpPBBhVbpzBC4PDeuYU6iF84SmExbck+jx5MUm4U5PM3/T307Mc3kzc9Q==",
|
"integrity": "sha512-G14nVaD64Bnbgy8tYxkjuXEUp/7h30Q0U33xc3AwtGFijJB9nHqOt1a6eG0WBn055RgRg+NwqbKGtqPxy15d0Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"prop-types": "^15.5.7"
|
"prop-types": "^15.8.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"apexcharts": "^3.18.0",
|
"apexcharts": "^3.41.0",
|
||||||
"react": ">=0.13"
|
"react": ">=0.13"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -7102,6 +7108,11 @@
|
||||||
"eslint-visitor-keys": "^3.3.0"
|
"eslint-visitor-keys": "^3.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@yr/monotone-cubic-spline": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA=="
|
||||||
|
},
|
||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "8.11.3",
|
"version": "8.11.3",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
||||||
|
|
@ -7142,10 +7153,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"apexcharts": {
|
"apexcharts": {
|
||||||
"version": "3.37.0",
|
"version": "3.50.0",
|
||||||
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.37.0.tgz",
|
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.50.0.tgz",
|
||||||
"integrity": "sha512-0mg1gDKUo3JG00Q//LK0jEXBS6OLjpuglqZ8ec9cqfA5oP8owopD9n5EhfARbWROb5o8GSPzFuohTJiCm2ecWw==",
|
"integrity": "sha512-LJT1PNAm+NoIU3aogL2P+ViC0y/Cjik54FdzzGV54UNnGQLBoLe5ok3fxsJDTgyez45BGYT8gqNpYKqhdfy5sg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"@yr/monotone-cubic-spline": "^1.0.3",
|
||||||
"svg.draggable.js": "^2.2.2",
|
"svg.draggable.js": "^2.2.2",
|
||||||
"svg.easing.js": "^2.0.0",
|
"svg.easing.js": "^2.0.0",
|
||||||
"svg.filter.js": "^2.0.2",
|
"svg.filter.js": "^2.0.2",
|
||||||
|
|
@ -9444,11 +9456,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-apexcharts": {
|
"react-apexcharts": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.1.tgz",
|
||||||
"integrity": "sha512-DrcMV4aAMrUG+n6412yzyATWEyCDWlpPBBhVbpzBC4PDeuYU6iF84SmExbck+jx5MUm4U5PM3/T307Mc3kzc9Q==",
|
"integrity": "sha512-G14nVaD64Bnbgy8tYxkjuXEUp/7h30Q0U33xc3AwtGFijJB9nHqOt1a6eG0WBn055RgRg+NwqbKGtqPxy15d0Q==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"prop-types": "^15.5.7"
|
"prop-types": "^15.8.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-dom": {
|
"react-dom": {
|
||||||
|
|
|
||||||
|
|
@ -24,14 +24,14 @@
|
||||||
"@mui/system": "5.11.9",
|
"@mui/system": "5.11.9",
|
||||||
"@mui/x-date-pickers": "5.0.19",
|
"@mui/x-date-pickers": "5.0.19",
|
||||||
"@react-google-maps/api": "^2.19.3",
|
"@react-google-maps/api": "^2.19.3",
|
||||||
"apexcharts": "3.37.0",
|
"apexcharts": "^3.37.0",
|
||||||
"date-fns": "2.29.3",
|
"date-fns": "2.29.3",
|
||||||
"formik": "2.2.9",
|
"formik": "2.2.9",
|
||||||
"next": "^14.2.4",
|
"next": "^14.2.4",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"prop-types": "15.8.1",
|
"prop-types": "15.8.1",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-apexcharts": "1.4.0",
|
"react-apexcharts": "^1.4.0",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"simple-peer": "^9.11.1",
|
"simple-peer": "^9.11.1",
|
||||||
"simplebar-react": "^3.2.1",
|
"simplebar-react": "^3.2.1",
|
||||||
|
|
|
||||||
BIN
frontend/public/assets/logo.png
Normal file
BIN
frontend/public/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
|
|
@ -1,13 +1,16 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import NextLink from 'next/link';
|
import NextLink from 'next/link';
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { Box, Typography, Unstable_Grid2 as Grid } from '@mui/material';
|
import { Box, Typography, Unstable_Grid2 as Grid, Stack } from '@mui/material';
|
||||||
import { Logo } from 'src/components/logo';
|
import { Logo } from 'src/components/logo';
|
||||||
|
import { useTheme, useMediaQuery } from '@mui/material'
|
||||||
// TODO: Change subtitle text
|
|
||||||
|
|
||||||
export const Layout = (props) => {
|
export const Layout = (props) => {
|
||||||
const { children } = props;
|
const { children } = props;
|
||||||
|
const lgUp = useMediaQuery((theme) => theme.breakpoints.up('lg'));
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
|
console.log("logUp", lgUp)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
|
|
@ -60,7 +63,7 @@ export const Layout = (props) => {
|
||||||
lg={6}
|
lg={6}
|
||||||
sx={{
|
sx={{
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
background: 'radial-gradient(50% 50% at 50% 50%, #306D6F 0%, #255355 100%)',
|
background: `radial-gradient(50% 50% at 50% 50%, ${theme.palette.primary.main} 0%, ${theme.palette.primary.dark } 100%)`,
|
||||||
color: 'white',
|
color: 'white',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
|
|
@ -70,20 +73,32 @@ export const Layout = (props) => {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ p: 3 }}>
|
<Box sx={{ p: 3 }}>
|
||||||
<Link href="https://oktopus.app.br" target="_blank">
|
<Link href="http://localhost/companylink" target="_blank">
|
||||||
<img
|
<img
|
||||||
alt=""
|
alt=""
|
||||||
src="/assets/oktopus.png"
|
src="http://localhost:8004/images/logo.png"
|
||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
<Typography
|
|
||||||
align="center"
|
|
||||||
sx={{ mb: 3 }}
|
|
||||||
>
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Stack style={{position:"absolute", bottom:"2px", left:"2px"}} direction={"row"} spacing={"1"}>
|
||||||
|
<Typography
|
||||||
|
align="center"
|
||||||
|
color={lgUp ? 'neutral[900]' : 'primary.contrastText'}
|
||||||
|
component="footer"
|
||||||
|
variant="body2"
|
||||||
|
sx={{ p: 2 }}
|
||||||
|
>
|
||||||
|
Powered by
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
<a href='https://oktopus.app.br' style={{position:"absolute", bottom:"10px", left:"100px"}} target='_blank'>
|
||||||
|
<img
|
||||||
|
src="/assets/logo.png"
|
||||||
|
alt="Oktopus logo image"
|
||||||
|
width={80}/>
|
||||||
|
</a>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -35,15 +35,15 @@ export const items = [
|
||||||
// </SvgIcon>
|
// </SvgIcon>
|
||||||
// )
|
// )
|
||||||
// },
|
// },
|
||||||
// {
|
{
|
||||||
// title: 'Map',
|
title: 'Map',
|
||||||
// path: '/map',
|
path: '/map',
|
||||||
// icon: (
|
icon: (
|
||||||
// <SvgIcon fontSize="small">
|
<SvgIcon fontSize="small">
|
||||||
// <MapIcon/>
|
<MapIcon/>
|
||||||
// </SvgIcon>
|
</SvgIcon>
|
||||||
// ),
|
),
|
||||||
// },
|
},
|
||||||
{
|
{
|
||||||
title: 'Credentials',
|
title: 'Credentials',
|
||||||
path: '/credentials',
|
path: '/credentials',
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@ import { styled } from '@mui/material/styles';
|
||||||
import { withAuthGuard } from 'src/hocs/with-auth-guard';
|
import { withAuthGuard } from 'src/hocs/with-auth-guard';
|
||||||
import { SideNav } from './side-nav';
|
import { SideNav } from './side-nav';
|
||||||
import { TopNav } from './top-nav';
|
import { TopNav } from './top-nav';
|
||||||
import Image from 'next/image'
|
|
||||||
import { Link } from '@mui/material';
|
|
||||||
|
|
||||||
const SIDE_NAV_WIDTH = 280;
|
const SIDE_NAV_WIDTH = 280;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@ import NextLink from 'next/link';
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname } from 'next/navigation';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import ArrowTopRightOnSquareIcon from '@heroicons/react/24/solid/ArrowTopRightOnSquareIcon';
|
|
||||||
import ChevronUpDownIcon from '@heroicons/react/24/solid/ChevronUpDownIcon';
|
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
|
|
@ -18,12 +16,15 @@ import { Logo } from 'src/components/logo';
|
||||||
import { Scrollbar } from 'src/components/scrollbar';
|
import { Scrollbar } from 'src/components/scrollbar';
|
||||||
import { items } from './config';
|
import { items } from './config';
|
||||||
import { SideNavItem } from './side-nav-item';
|
import { SideNavItem } from './side-nav-item';
|
||||||
|
import { useTheme } from '@mui/material';
|
||||||
|
|
||||||
export const SideNav = (props) => {
|
export const SideNav = (props) => {
|
||||||
const { open, onClose } = props;
|
const { open, onClose } = props;
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const lgUp = useMediaQuery((theme) => theme.breakpoints.up('lg'));
|
const lgUp = useMediaQuery((theme) => theme.breakpoints.up('lg'));
|
||||||
|
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
const isItemActive = (currentPath, itemPath) => {
|
const isItemActive = (currentPath, itemPath) => {
|
||||||
if (currentPath === itemPath) {
|
if (currentPath === itemPath) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -34,7 +35,6 @@ export const SideNav = (props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
//TODO: test frontend with color of the landing page
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
|
|
@ -80,9 +80,9 @@ export const SideNav = (props) => {
|
||||||
p: '12px'
|
p: '12px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Link href="https://oktopus.app.br" target="_blank">
|
<Link href="http://localhost/companylink" target="_blank">
|
||||||
<div style={{display:'flex',justifyContent:'center'}}>
|
<div style={{display:'flex',justifyContent:'center'}}>
|
||||||
<img src="/assets/oktopus.png"
|
<img src="http://localhost:8004/images/logo.png"
|
||||||
width={'60%'}
|
width={'60%'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -113,6 +113,9 @@ export const SideNav = (props) => {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{items.map((item) => {
|
{items.map((item) => {
|
||||||
|
if (item.title == "Map" && process.env.NEXT_PUBLIC_ENTERPRISE_VERSION != "true"){
|
||||||
|
return
|
||||||
|
}
|
||||||
const active = isItemActive(pathname, item.path);
|
const active = isItemActive(pathname, item.path);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -129,7 +132,24 @@ export const SideNav = (props) => {
|
||||||
})}
|
})}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
<Divider sx={{ borderColor: 'neutral.700' }} />
|
<Stack style={{position:"absolute", bottom:"2px", left:"2px"}} direction={"row"} spacing={"1"} zIndex={9999}>
|
||||||
|
<Typography
|
||||||
|
align="center"
|
||||||
|
color="primary.contrastText"
|
||||||
|
component="footer"
|
||||||
|
variant="body2"
|
||||||
|
sx={{ p: 2 }}
|
||||||
|
>
|
||||||
|
Powered by
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
<a href='https://oktopus.app.br' style={{position:"absolute", bottom:"10px", left:"100px"}} target='_blank'>
|
||||||
|
<img
|
||||||
|
src="/assets/logo.png"
|
||||||
|
alt="Oktopus logo image"
|
||||||
|
width={80}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
</Box>
|
</Box>
|
||||||
</Scrollbar>
|
</Scrollbar>
|
||||||
);
|
);
|
||||||
|
|
@ -141,7 +161,7 @@ export const SideNav = (props) => {
|
||||||
open
|
open
|
||||||
PaperProps={{
|
PaperProps={{
|
||||||
sx: {
|
sx: {
|
||||||
backgroundColor: 'neutral.800',
|
background: `linear-gradient(0deg, ${theme.palette.neutral["800"]} 0%, ${theme.palette.primary.dark} 90%);`,
|
||||||
color: 'common.white',
|
color: 'common.white',
|
||||||
width: 280
|
width: 280
|
||||||
}
|
}
|
||||||
|
|
@ -160,7 +180,7 @@ export const SideNav = (props) => {
|
||||||
open={open}
|
open={open}
|
||||||
PaperProps={{
|
PaperProps={{
|
||||||
sx: {
|
sx: {
|
||||||
backgroundColor: 'neutral.800',
|
background: `linear-gradient(0deg, ${theme.palette.primary.main} 0%, ${theme.palette.primary.dark} 90%);`,
|
||||||
color: 'common.white',
|
color: 'common.white',
|
||||||
width: 280
|
width: 280
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,21 +10,26 @@ import { createTheme } from 'src/theme';
|
||||||
import { createEmotionCache } from 'src/utils/create-emotion-cache';
|
import { createEmotionCache } from 'src/utils/create-emotion-cache';
|
||||||
import 'simplebar-react/dist/simplebar.min.css';
|
import 'simplebar-react/dist/simplebar.min.css';
|
||||||
import { WsProvider } from 'src/contexts/socketio-context';
|
import { WsProvider } from 'src/contexts/socketio-context';
|
||||||
|
import '../utils/map.css';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
const clientSideEmotionCache = createEmotionCache();
|
const clientSideEmotionCache = createEmotionCache();
|
||||||
|
|
||||||
const SplashScreen = () => null;
|
const SplashScreen = () => null;
|
||||||
|
|
||||||
const App = (props) => {
|
const App = (props) => {
|
||||||
|
const [theme, setTheme] = useState(null);
|
||||||
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
|
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
|
||||||
|
|
||||||
useNProgress();
|
useNProgress();
|
||||||
|
|
||||||
const getLayout = Component.getLayout ?? ((page) => page);
|
const getLayout = Component.getLayout ?? ((page) => page);
|
||||||
|
|
||||||
const theme = createTheme();
|
useEffect(() => {
|
||||||
|
setTheme(createTheme());
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return theme && (
|
||||||
<CacheProvider value={emotionCache}>
|
<CacheProvider value={emotionCache}>
|
||||||
<Head>
|
<Head>
|
||||||
<title>
|
<title>
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,140 @@
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import { GoogleMap, useLoadScript } from "@react-google-maps/api"
|
import { GoogleMap, useLoadScript, Marker, OverlayView } from "@react-google-maps/api"
|
||||||
import { Layout as DashboardLayout } from 'src/layouts/dashboard/layout';
|
import { Layout as DashboardLayout } from 'src/layouts/dashboard/layout';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import mapStyles from '../utils/mapStyles.json';
|
import mapStyles from '../utils/mapStyles.json';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
|
||||||
|
const getPixelPositionOffset = pixelOffset => (width, height) => ({
|
||||||
|
x: -(width / 2) + pixelOffset.x,
|
||||||
|
y: -(height / 2) + pixelOffset.y
|
||||||
|
});
|
||||||
|
|
||||||
|
const Popup = props => {
|
||||||
|
return (
|
||||||
|
<OverlayView
|
||||||
|
position={props.anchorPosition}
|
||||||
|
mapPaneName={OverlayView.OVERLAY_MOUSE_TARGET}
|
||||||
|
getPixelPositionOffset={getPixelPositionOffset(props.markerPixelOffset)}
|
||||||
|
>
|
||||||
|
<div className="popup-tip-anchor">
|
||||||
|
<div className="popup-bubble-anchor">
|
||||||
|
<div className="popup-bubble-content">{props.content}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</OverlayView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const Page = () => {
|
const Page = () => {
|
||||||
|
|
||||||
const libraries = useMemo(() => ['places'], []);
|
const libraries = useMemo(() => ['places'], []);
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const [mapRef, setMapRef] = useState(null);
|
||||||
|
|
||||||
const [mapCenter, setMapCenter] = useState(null);
|
const [mapCenter, setMapCenter] = useState(null);
|
||||||
|
const [markers, setMarkers] = useState([]);
|
||||||
|
const [activeMarker, setActiveMarker] = useState(null);
|
||||||
|
const [activeMarkerdata, setActiveMarkerdata] = useState(null);
|
||||||
|
const [zoom, setZoom] = useState(null)
|
||||||
|
|
||||||
|
const handleDragEnd = () => {
|
||||||
|
if (mapRef) {
|
||||||
|
const newCenter = mapRef.getCenter();
|
||||||
|
console.log("newCenter:",newCenter.lat(), newCenter.lng());
|
||||||
|
localStorage.setItem("mapCenter", JSON.stringify({"lat":newCenter.lat(),"lng":newCenter.lng()}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleZoomChange = () => {
|
||||||
|
if (mapRef) {
|
||||||
|
const newZoom = mapRef.getZoom();
|
||||||
|
console.log("new zoom", newZoom)
|
||||||
|
localStorage.setItem("zoom", newZoom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleOnLoad = map => {
|
||||||
|
setMapRef(map);
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchMarkers = async () => {
|
||||||
|
|
||||||
|
var myHeaders = new Headers();
|
||||||
|
myHeaders.append("Content-Type", "application/json");
|
||||||
|
myHeaders.append("Authorization", localStorage.getItem("token"));
|
||||||
|
|
||||||
|
var requestOptions = {
|
||||||
|
method: 'GET',
|
||||||
|
headers: myHeaders,
|
||||||
|
redirect: 'follow'
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/map`, requestOptions)
|
||||||
|
|
||||||
|
if (result.status == 200) {
|
||||||
|
const content = await result.json()
|
||||||
|
setMarkers(content)
|
||||||
|
}else if (result.status == 403) {
|
||||||
|
console.log("num tenx permissão, seu boca de sandália")
|
||||||
|
return router.push("/403")
|
||||||
|
}else if (result.status == 401){
|
||||||
|
console.log("taix nem autenticado, sai fora oh")
|
||||||
|
return router.push("/auth/login")
|
||||||
|
} else {
|
||||||
|
setMarkers([])
|
||||||
|
console.log("error to get map markers")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchActiveMarkerData = async (id) => {
|
||||||
|
var myHeaders = new Headers();
|
||||||
|
myHeaders.append("Content-Type", "application/json");
|
||||||
|
myHeaders.append("Authorization", localStorage.getItem("token"));
|
||||||
|
|
||||||
|
var requestOptions = {
|
||||||
|
method: 'GET',
|
||||||
|
headers: myHeaders,
|
||||||
|
redirect: 'follow'
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = await fetch(`${process.env.NEXT_PUBLIC_REST_ENDPOINT || ""}/api/device?id=`+id, requestOptions)
|
||||||
|
|
||||||
|
if (result.status == 200) {
|
||||||
|
const content = await result.json()
|
||||||
|
setActiveMarkerdata(content)
|
||||||
|
}else if (result.status == 403) {
|
||||||
|
return router.push("/403")
|
||||||
|
}else if (result.status == 401){
|
||||||
|
return router.push("/auth/login")
|
||||||
|
} else {
|
||||||
|
console.log("no device info found")
|
||||||
|
const content = await result.json()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(()=> {
|
useEffect(()=> {
|
||||||
|
fetchMarkers();
|
||||||
|
|
||||||
|
let zoomFromLocalStorage = localStorage.getItem("zoom")
|
||||||
|
if (zoomFromLocalStorage) {
|
||||||
|
setZoom(Number(zoomFromLocalStorage))
|
||||||
|
}else{
|
||||||
|
setZoom(25)
|
||||||
|
}
|
||||||
|
|
||||||
|
let mapCenterFromLocalStorage = localStorage.getItem("mapCenter")
|
||||||
|
if (mapCenterFromLocalStorage){
|
||||||
|
let fmtMapCenter = JSON.parse(localStorage.getItem("mapCenter"))
|
||||||
|
console.log("mapCenterFromLocalStorage:", fmtMapCenter)
|
||||||
|
setMapCenter({
|
||||||
|
lat: Number(fmtMapCenter.lat),
|
||||||
|
lng: Number(fmtMapCenter.lng),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
// Check if geolocation is supported by the browser
|
// Check if geolocation is supported by the browser
|
||||||
if ("geolocation" in navigator) {
|
if ("geolocation" in navigator) {
|
||||||
// Prompt user for permission to access their location
|
// Prompt user for permission to access their location
|
||||||
|
|
@ -27,12 +151,12 @@ const Page = () => {
|
||||||
// Error callback function
|
// Error callback function
|
||||||
function(error) {
|
function(error) {
|
||||||
// Handle errors, e.g. user denied location sharing permissions
|
// Handle errors, e.g. user denied location sharing permissions
|
||||||
console.error("Error getting user location:", error);
|
console.log("Error getting user location:", error);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Geolocation is not supported by the browser
|
// Geolocation is not supported by the browser
|
||||||
console.error("Geolocation is not supported by this browser.");
|
console.log("Geolocation is not supported by this browser, or the user denied access");
|
||||||
}
|
}
|
||||||
},[])
|
},[])
|
||||||
|
|
||||||
|
|
@ -59,7 +183,7 @@ const Page = () => {
|
||||||
return <p>Loading...</p>;
|
return <p>Loading...</p>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( mapCenter &&
|
return ( markers && zoom &&
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>
|
<title>
|
||||||
|
|
@ -68,12 +192,61 @@ const Page = () => {
|
||||||
</Head>
|
</Head>
|
||||||
<GoogleMap
|
<GoogleMap
|
||||||
options={mapOptions}
|
options={mapOptions}
|
||||||
zoom={14}
|
zoom={zoom}
|
||||||
center={mapCenter}
|
center={mapCenter ? mapCenter : {
|
||||||
|
lat: 0.0,
|
||||||
|
lng: 0.0,
|
||||||
|
}}
|
||||||
mapContainerStyle={{ width: '100%', height: '100%' }}
|
mapContainerStyle={{ width: '100%', height: '100%' }}
|
||||||
onLoad={() => console.log('Map Component Loaded...')}
|
onLoad={handleOnLoad}
|
||||||
clickableIcons={false}
|
clickableIcons={false}
|
||||||
/>
|
onDragEnd={handleDragEnd}
|
||||||
|
onZoomChanged={handleZoomChange}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
markers.map((marker, index) => (
|
||||||
|
<Marker
|
||||||
|
key={index}
|
||||||
|
position={{ lat: marker.coordinates.lat, lng: marker.coordinates.lng }}
|
||||||
|
icon={{
|
||||||
|
url: marker.img,
|
||||||
|
scaledSize: new window.google.maps.Size(50, 50),
|
||||||
|
anchor: new window.google.maps.Point(25, 25),
|
||||||
|
}}
|
||||||
|
draggable={false}
|
||||||
|
clickable={true}
|
||||||
|
onClick={() => {
|
||||||
|
setActiveMarkerdata(null);
|
||||||
|
if (activeMarker?.sn === marker.sn) {
|
||||||
|
setActiveMarker(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fetchActiveMarkerData(marker.sn);
|
||||||
|
setActiveMarker({
|
||||||
|
sn: marker.sn,
|
||||||
|
position: { lat: marker.coordinates.lat, lng: marker.coordinates.lng }
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
</Marker>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
{activeMarker &&
|
||||||
|
<Popup
|
||||||
|
anchorPosition={activeMarker.position}
|
||||||
|
markerPixelOffset={{ x: 0, y: -32 }}
|
||||||
|
content={activeMarkerdata ?
|
||||||
|
<div>
|
||||||
|
<div>SN: {activeMarker.sn}</div>
|
||||||
|
<div>
|
||||||
|
<div>Model: {activeMarkerdata.Model?activeMarkerdata.Model:activeMarkerdata.ProductClass}</div>
|
||||||
|
<div>Alias: {activeMarkerdata.Alias}</div>
|
||||||
|
<div>Status: {activeMarkerdata.Status == 2 ? <span style={{color:"green"}}>online</span> : <span style={{color:"red"}}>offline</span>}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
: <p>no device info found</p>}
|
||||||
|
/>}
|
||||||
|
</GoogleMap>
|
||||||
</>
|
</>
|
||||||
)};
|
)};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,19 @@ export const ConnectedDevices = () => {
|
||||||
const [interfaces, setInterfaces] = useState([]);
|
const [interfaces, setInterfaces] = useState([]);
|
||||||
const [interfaceValue, setInterfaceValue] = useState(null);
|
const [interfaceValue, setInterfaceValue] = useState(null);
|
||||||
|
|
||||||
|
const getConnectionState = (rssi) => {
|
||||||
|
let connectionStatus = "Signal "
|
||||||
|
if (rssi > -30) {
|
||||||
|
return connectionStatus + "Excellent"
|
||||||
|
} else if (rssi > -60) {
|
||||||
|
return connectionStatus + "Good"
|
||||||
|
} else if (rssi > -70) {
|
||||||
|
return connectionStatus + "Bad"
|
||||||
|
} else {
|
||||||
|
return connectionStatus + "Awful"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const fetchConnectedDevicesData = async () => {
|
const fetchConnectedDevicesData = async () => {
|
||||||
|
|
||||||
var myHeaders = new Headers();
|
var myHeaders = new Headers();
|
||||||
|
|
@ -47,19 +60,19 @@ export const ConnectedDevices = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchConnectedDevicesData();
|
fetchConnectedDevicesData();
|
||||||
},[])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack
|
<Stack
|
||||||
justifyContent="center"
|
justifyContent="center"
|
||||||
alignItems={(!content || interfaces.length == 0) &&"center"}
|
alignItems={(!content || interfaces.length == 0) && "center"}
|
||||||
>
|
>
|
||||||
{content && interfaces.length > 0 ?
|
{content && interfaces.length > 0 ?
|
||||||
<Card>
|
<Card>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<Grid mb={3}>
|
<Grid mb={3}>
|
||||||
<InputLabel> Interface </InputLabel>
|
<InputLabel> Interface </InputLabel>
|
||||||
<Select label="interface" variant="standard" value={interfaceValue} onChange={(e)=> setInterfaceValue(e.target.value)}>
|
<Select label="interface" variant="standard" value={interfaceValue} onChange={(e) => setInterfaceValue(e.target.value)}>
|
||||||
{(
|
{(
|
||||||
interfaces.map((item, index) => (
|
interfaces.map((item, index) => (
|
||||||
<MenuItem key={index} value={item}>
|
<MenuItem key={index} value={item}>
|
||||||
|
|
@ -70,13 +83,13 @@ export const ConnectedDevices = () => {
|
||||||
</Select>
|
</Select>
|
||||||
</Grid>
|
</Grid>
|
||||||
{
|
{
|
||||||
content[interfaceValue].map((property,index) => (
|
content[interfaceValue].map((property, index) => (
|
||||||
<Card key={index}>
|
<Card key={index}>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<Grid container justifyContent={"center"}>
|
<Grid container justifyContent={"center"}>
|
||||||
<Stack direction="row" spacing={5}>
|
<Stack direction="row" spacing={5}>
|
||||||
<Stack justifyItems={"center"} direction={"row"} mt={2}>
|
<Stack justifyItems={"center"} direction={"row"} mt={2}>
|
||||||
<Tooltip title={property.active ? "Online": "Offline"}>
|
<Tooltip title={property.active ? "Online" : "Offline"}>
|
||||||
<SvgIcon>
|
<SvgIcon>
|
||||||
<CpuChipIcon color={property.active ? theme.palette.success.main : theme.palette.error.main}></CpuChipIcon>
|
<CpuChipIcon color={property.active ? theme.palette.success.main : theme.palette.error.main}></CpuChipIcon>
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
|
|
@ -85,7 +98,7 @@ export const ConnectedDevices = () => {
|
||||||
{property.hostname}
|
{property.hostname}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Divider orientation="vertical"/>
|
<Divider orientation="vertical" />
|
||||||
<Stack spacing={2}>
|
<Stack spacing={2}>
|
||||||
<Typography>
|
<Typography>
|
||||||
IP address: {property.ip_adress}
|
IP address: {property.ip_adress}
|
||||||
|
|
@ -95,12 +108,30 @@ export const ConnectedDevices = () => {
|
||||||
</Typography>
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Stack spacing={2}>
|
<Stack spacing={2}>
|
||||||
<Typography>
|
|
||||||
RSSI: {property.rssi} dbm
|
|
||||||
</Typography>
|
|
||||||
<Typography>
|
<Typography>
|
||||||
Source: {property.adress_source}
|
Source: {property.adress_source}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<Tooltip title={getConnectionState(property.rssi)}>
|
||||||
|
<Typography display={"flex"} color={() => {
|
||||||
|
let rssi = property.rssi
|
||||||
|
if(rssi == 0){
|
||||||
|
return theme.palette.neutral[900]
|
||||||
|
} else if (rssi > -30) {
|
||||||
|
return theme.palette.success.main
|
||||||
|
} else if (rssi > -60) {
|
||||||
|
return theme.palette.success.main
|
||||||
|
} else if (rssi > -70) {
|
||||||
|
return theme.palette.warning.main
|
||||||
|
} else {
|
||||||
|
return theme.palette.error.main
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<Typography color={theme.palette.neutral[900]} sx={{pr:"5px"}}>
|
||||||
|
RSSI:
|
||||||
|
</Typography>
|
||||||
|
{property.rssi} dbm
|
||||||
|
</Typography>
|
||||||
|
</Tooltip>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
@ -109,8 +140,8 @@ export const ConnectedDevices = () => {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>: (
|
</Card> : (
|
||||||
content ? <Typography> No connected devices found </Typography> : <CircularProgress/>
|
content ? <Typography> No connected devices found </Typography> : <CircularProgress />
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -80,9 +80,9 @@ export const DevicesWiFi = () => {
|
||||||
.catch(error => console.log('error', error));
|
.catch(error => console.log('error', error));
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(() => {
|
||||||
fetchWifiData()
|
fetchWifiData()
|
||||||
},[])
|
}, [])
|
||||||
|
|
||||||
return (<div>
|
return (<div>
|
||||||
<Stack
|
<Stack
|
||||||
|
|
@ -99,24 +99,24 @@ export const DevicesWiFi = () => {
|
||||||
title={item.name.value}
|
title={item.name.value}
|
||||||
avatar={
|
avatar={
|
||||||
<SvgIcon>
|
<SvgIcon>
|
||||||
<GlobeAltIcon/>
|
<GlobeAltIcon />
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<Stack spacing={3}>
|
<Stack spacing={3}>
|
||||||
{ item.enable.value != null &&
|
{item.enable.value != null &&
|
||||||
<FormControlLabel control={<Checkbox defaultChecked={item.enable.value == 1 ? true : false}
|
<FormControlLabel control={<Checkbox defaultChecked={item.enable.value == 1 ? true : false}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
let enable = item.enable.value == 1 ? "0" : "1"
|
let enable = item.enable.value == 1 ? "0" : "1"
|
||||||
console.log(enable)
|
console.log(enable)
|
||||||
applyContent[index].hasChanges = true
|
applyContent[index].hasChanges = true
|
||||||
applyContent[index].enable = {
|
applyContent[index].enable = {
|
||||||
value : enable
|
value: enable
|
||||||
}
|
}
|
||||||
setApplyContent([...applyContent])
|
setApplyContent([...applyContent])
|
||||||
item.enable.value = enable
|
item.enable.value = enable
|
||||||
}}/>}
|
}} />}
|
||||||
label="Enabled" />}
|
label="Enabled" />}
|
||||||
{item.ssid.value != null && <TextField
|
{item.ssid.value != null && <TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
|
|
@ -126,7 +126,7 @@ export const DevicesWiFi = () => {
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
applyContent[index].hasChanges = true
|
applyContent[index].hasChanges = true
|
||||||
applyContent[index].ssid = {
|
applyContent[index].ssid = {
|
||||||
value : e.target.value
|
value: e.target.value
|
||||||
}
|
}
|
||||||
setApplyContent([...applyContent])
|
setApplyContent([...applyContent])
|
||||||
item.ssid.value = e.target.value
|
item.ssid.value = e.target.value
|
||||||
|
|
@ -148,17 +148,41 @@ export const DevicesWiFi = () => {
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
if (e.target.value.length >= 8) {
|
if (e.target.value.length >= 8) {
|
||||||
applyContent[index].hasChanges = true
|
applyContent[index].hasChanges = true
|
||||||
}else{
|
} else {
|
||||||
applyContent[index].hasChanges = false
|
applyContent[index].hasChanges = false
|
||||||
}
|
}
|
||||||
applyContent[index].password = {
|
applyContent[index].password = {
|
||||||
value : e.target.value
|
value: e.target.value
|
||||||
}
|
}
|
||||||
setApplyContent([...applyContent])
|
setApplyContent([...applyContent])
|
||||||
item.password.value = e.target.value
|
item.password.value = e.target.value
|
||||||
console.log("applyContent: ", applyContent)
|
console.log("applyContent: ", applyContent)
|
||||||
}}
|
}}
|
||||||
/>}
|
/>}
|
||||||
|
{item.channel?.value != null && item.possibleChannels?.value != null &&
|
||||||
|
<FormControl variant='filled'>
|
||||||
|
<InputLabel id="channel">Channel</InputLabel>
|
||||||
|
<Select
|
||||||
|
fullWidth
|
||||||
|
defaultValue={item.channel.value}
|
||||||
|
value={item.channel.value}
|
||||||
|
onChange={(e) => {
|
||||||
|
applyContent[index].hasChanges = true
|
||||||
|
applyContent[index].channel = {
|
||||||
|
value: e.target.value
|
||||||
|
}
|
||||||
|
setApplyContent([...applyContent])
|
||||||
|
item.channel.value = e.target.value
|
||||||
|
}}
|
||||||
|
label="Channel"
|
||||||
|
>
|
||||||
|
{item.possibleChannels.value.map((channel, index) => {
|
||||||
|
return (
|
||||||
|
<MenuItem key={index} value={channel}>{channel}</MenuItem>)
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
}
|
||||||
{item.standard.value != null &&
|
{item.standard.value != null &&
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
|
|
@ -168,20 +192,20 @@ export const DevicesWiFi = () => {
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
applyContent[index].hasChanges = true
|
applyContent[index].hasChanges = true
|
||||||
applyContent[index].standard = {
|
applyContent[index].standard = {
|
||||||
value : e.target.value
|
value: e.target.value
|
||||||
}
|
}
|
||||||
setApplyContent([...applyContent])
|
setApplyContent([...applyContent])
|
||||||
item.standard.value = e.target.value
|
item.standard.value = e.target.value
|
||||||
}}
|
}}
|
||||||
/>}
|
/>}
|
||||||
</Stack>
|
</Stack>
|
||||||
<CardActions sx={{display:"flex", justifyContent:"flex-end"}}>
|
<CardActions sx={{ display: "flex", justifyContent: "flex-end" }}>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
disabled={!applyContent[index].hasChanges}
|
disabled={!applyContent[index].hasChanges}
|
||||||
endIcon={<SvgIcon><Check /></SvgIcon>}
|
endIcon={<SvgIcon><Check /></SvgIcon>}
|
||||||
onClick={
|
onClick={
|
||||||
()=>{
|
() => {
|
||||||
setApply(true)
|
setApply(true)
|
||||||
var myHeaders = new Headers();
|
var myHeaders = new Headers();
|
||||||
myHeaders.append("Content-Type", "application/json");
|
myHeaders.append("Content-Type", "application/json");
|
||||||
|
|
@ -221,7 +245,7 @@ export const DevicesWiFi = () => {
|
||||||
.catch(error => console.log('error', error));
|
.catch(error => console.log('error', error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sx={{mt:'25px', mb:'-15px'}}
|
sx={{ mt: '25px', mb: '-15px' }}
|
||||||
>
|
>
|
||||||
Apply
|
Apply
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -229,7 +253,7 @@ export const DevicesWiFi = () => {
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
)
|
||||||
})):
|
})) :
|
||||||
<CircularProgress />
|
<CircularProgress />
|
||||||
}
|
}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
@ -241,7 +265,7 @@ export const DevicesWiFi = () => {
|
||||||
</Backdrop>
|
</Backdrop>
|
||||||
<Dialog open={errorModal && errorModalText != ""}
|
<Dialog open={errorModal && errorModalText != ""}
|
||||||
slotProps={{ backdrop: { style: { backgroundColor: 'rgba(255,255,255,0.5)' } } }}
|
slotProps={{ backdrop: { style: { backgroundColor: 'rgba(255,255,255,0.5)' } } }}
|
||||||
fullWidth={ true }
|
fullWidth={true}
|
||||||
maxWidth={"md"}
|
maxWidth={"md"}
|
||||||
scroll={"paper"}
|
scroll={"paper"}
|
||||||
aria-labelledby="scroll-dialog-title"
|
aria-labelledby="scroll-dialog-title"
|
||||||
|
|
@ -251,27 +275,27 @@ export const DevicesWiFi = () => {
|
||||||
<Box display="flex" alignItems="center">
|
<Box display="flex" alignItems="center">
|
||||||
<Box flexGrow={1} >Response</Box>
|
<Box flexGrow={1} >Response</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<IconButton onClick={()=>{
|
<IconButton onClick={() => {
|
||||||
setErrorModalText("")
|
setErrorModalText("")
|
||||||
setErrorModal(false)
|
setErrorModal(false)
|
||||||
}}>
|
}}>
|
||||||
<SvgIcon
|
<SvgIcon
|
||||||
>
|
>
|
||||||
< XMarkIcon/>
|
< XMarkIcon />
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<DialogContent dividers={scroll === 'paper'}>
|
<DialogContent dividers={scroll === 'paper'}>
|
||||||
<DialogContentText id="scroll-dialog-description"tabIndex={-1}>
|
<DialogContentText id="scroll-dialog-description" tabIndex={-1}>
|
||||||
<pre style={{color: 'black'}}>
|
<pre style={{ color: 'black' }}>
|
||||||
{errorModalText}
|
{errorModalText}
|
||||||
</pre>
|
</pre>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={()=>{
|
<Button onClick={() => {
|
||||||
setErrorModalText("")
|
setErrorModalText("")
|
||||||
setErrorModal(false)
|
setErrorModal(false)
|
||||||
}}>OK</Button>
|
}}>OK</Button>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import ArrowPathIcon from '@heroicons/react/24/solid/ArrowPathIcon';
|
|
||||||
import ArrowRightIcon from '@heroicons/react/24/solid/ArrowRightIcon';
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
|
|
@ -22,12 +19,11 @@ import {
|
||||||
TableHead,
|
TableHead,
|
||||||
TableRow,
|
TableRow,
|
||||||
TableContainer,
|
TableContainer,
|
||||||
Paper,
|
CircularProgress,
|
||||||
Container,
|
ToggleButton,
|
||||||
CircularProgress
|
ToggleButtonGroup
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { Scrollbar } from 'src/components/scrollbar';
|
import { useTheme } from '@mui/material/styles';
|
||||||
import { alpha, useTheme } from '@mui/material/styles';
|
|
||||||
import { Chart } from 'src/components/chart';
|
import { Chart } from 'src/components/chart';
|
||||||
import ChartBarSquareIcon from '@heroicons/react/24/outline/ChartBarSquareIcon';
|
import ChartBarSquareIcon from '@heroicons/react/24/outline/ChartBarSquareIcon';
|
||||||
import ListBulletIcon from '@heroicons/react/24/outline/ListBulletIcon';
|
import ListBulletIcon from '@heroicons/react/24/outline/ListBulletIcon';
|
||||||
|
|
@ -35,7 +31,103 @@ import { useRouter } from 'next/router';
|
||||||
import { Stack } from '@mui/system';
|
import { Stack } from '@mui/system';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
const useChartOptions = () => {
|
export const SiteSurvey = (props) => {
|
||||||
|
|
||||||
|
// const getMaxChannel = () => {
|
||||||
|
// if (frequency == "2.4GHz") {
|
||||||
|
// return 13;
|
||||||
|
// } else {
|
||||||
|
// return 128;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const geMinChannel = () => {
|
||||||
|
// if (frequency == "2.4GHz") {
|
||||||
|
// return 0;
|
||||||
|
// } else {
|
||||||
|
// return 36;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const getChannelSpacing = () => {
|
||||||
|
// if (frequency == "2.4GHz") {
|
||||||
|
// return 1;
|
||||||
|
// } else {
|
||||||
|
// return 4;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const getChannelAmount = () => {
|
||||||
|
// if (frequency == "2.4GHz") {
|
||||||
|
// return 13;
|
||||||
|
// } else {
|
||||||
|
// return 20;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
const getCategories = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const [frequency, setFrequency] = useState("2.4GHz");
|
||||||
|
const [view, setView] = useState("chart");
|
||||||
|
const [content, setContent] = useState(null);
|
||||||
|
|
||||||
|
const getSeries = () => {
|
||||||
|
let series = []
|
||||||
|
content[frequency].map((network) => {
|
||||||
|
|
||||||
|
let data = []
|
||||||
|
|
||||||
|
if (frequency == "2.4GHz") {
|
||||||
|
if (Number(network.bandwidth) == 20) {
|
||||||
|
data.push({"x": Number(network.channel) -2, "y": -100})
|
||||||
|
data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
|
||||||
|
data.push({"x": Number(network.channel) +2, "y": -100})
|
||||||
|
}
|
||||||
|
if (Number(network.bandwidth) == 40) {
|
||||||
|
data.push({"x": Number(network.channel) -4, "y": -100})
|
||||||
|
data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
|
||||||
|
data.push({"x": Number(network.channel) +4, "y": -100})
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
if (Number(network.bandwidth) == 20) {
|
||||||
|
data.push({"x": Number(network.channel) -4, "y": -100})
|
||||||
|
data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
|
||||||
|
data.push({"x": Number(network.channel) +4, "y": -100})
|
||||||
|
}
|
||||||
|
if (Number(network.bandwidth) == 40) {
|
||||||
|
data.push({"x": Number(network.channel) -8, "y": -100})
|
||||||
|
data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
|
||||||
|
data.push({"x": Number(network.channel) +8, "y": -100})
|
||||||
|
}
|
||||||
|
if (Number(network.bandwidth) == 80) {
|
||||||
|
data.push({"x": Number(network.channel) -16, "y": -100})
|
||||||
|
data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
|
||||||
|
data.push({"x": Number(network.channel) +16, "y": -100})
|
||||||
|
}
|
||||||
|
if (Number(network.bandwidth) == 160) {
|
||||||
|
data.push({"x": Number(network.channel) -32, "y": -100})
|
||||||
|
data.push({"x": Number(network.channel), "y": Number(network.signal_level)})
|
||||||
|
data.push({"x": Number(network.channel) +32, "y": -100})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let ssid = network.ssid
|
||||||
|
if ( ssid == "") {
|
||||||
|
ssid = " "
|
||||||
|
}
|
||||||
|
return series.push({
|
||||||
|
name: ssid,
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return series;
|
||||||
|
}
|
||||||
|
|
||||||
|
const useChartOptions = () => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -44,100 +136,151 @@ const useChartOptions = () => {
|
||||||
stacked: false,
|
stacked: false,
|
||||||
toolbar: {
|
toolbar: {
|
||||||
show: true
|
show: true
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
zoom: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
text: 'Site Survey Results',
|
||||||
|
},
|
||||||
|
// markers: {
|
||||||
|
// size: 5,
|
||||||
|
// hover: {
|
||||||
|
// size: 9
|
||||||
|
// }
|
||||||
|
// },
|
||||||
colors: [
|
colors: [
|
||||||
theme.palette.graphics.dark,
|
theme.palette.graphics.dark,
|
||||||
|
theme.palette.warning.main,
|
||||||
theme.palette.graphics.darkest,
|
theme.palette.graphics.darkest,
|
||||||
theme.palette.graphics.light,
|
|
||||||
theme.palette.graphics.main,
|
theme.palette.graphics.main,
|
||||||
|
theme.palette.info.light,
|
||||||
theme.palette.graphics.lightest,
|
theme.palette.graphics.lightest,
|
||||||
|
theme.palette.primary.main,
|
||||||
|
theme.palette.graphics.light,
|
||||||
|
theme.palette.error.light,
|
||||||
|
theme.palette.error.dark
|
||||||
],
|
],
|
||||||
dataLabels: {
|
dataLabels: {
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
fill: {
|
|
||||||
opacity: 1,
|
|
||||||
type: 'solid'
|
|
||||||
},
|
|
||||||
grid: {
|
grid: {
|
||||||
borderColor: theme.palette.divider,
|
//borderColor: theme.palette.divider,
|
||||||
strokeDashArray: 2,
|
strokeDashArray: 2,
|
||||||
xaxis: {
|
xaxis: {
|
||||||
lines: {
|
lines: {
|
||||||
show: false
|
show: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
yaxis: {
|
yaxis: {
|
||||||
lines: {
|
lines: {
|
||||||
show: true
|
show: true
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
show: true
|
show: true,
|
||||||
|
showForSingleSeries: true,
|
||||||
},
|
},
|
||||||
plotOptions: {
|
plotOptions: {
|
||||||
bar: {
|
area: {
|
||||||
columnWidth: '40px'
|
fillTo: 'end',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
stroke: {
|
stroke: {
|
||||||
colors: ['transparent'],
|
|
||||||
show: true,
|
show: true,
|
||||||
width: 2
|
curve: 'smooth',
|
||||||
|
lineCap: 'round',
|
||||||
},
|
},
|
||||||
theme: {
|
theme: {
|
||||||
mode: theme.palette.mode
|
mode: theme.palette.mode
|
||||||
},
|
},
|
||||||
xaxis: {
|
|
||||||
axisBorder: {
|
|
||||||
color: theme.palette.divider,
|
|
||||||
show: true
|
|
||||||
},
|
|
||||||
axisTicks: {
|
|
||||||
color: theme.palette.divider,
|
|
||||||
show: true
|
|
||||||
},
|
|
||||||
categories: [
|
|
||||||
'Jan',
|
|
||||||
'Feb',
|
|
||||||
'Mar',
|
|
||||||
'Apr',
|
|
||||||
'May',
|
|
||||||
'Jun',
|
|
||||||
'Jul',
|
|
||||||
'Aug',
|
|
||||||
'Sep',
|
|
||||||
'Oct',
|
|
||||||
'Nov',
|
|
||||||
'Dec'
|
|
||||||
],
|
|
||||||
labels: {
|
|
||||||
offsetY: 5,
|
|
||||||
style: {
|
|
||||||
colors: theme.palette.text.secondary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
yaxis: {
|
yaxis: {
|
||||||
|
min: -100,
|
||||||
|
max: 0,
|
||||||
labels: {
|
labels: {
|
||||||
formatter: (value) => (value > 0 ? `${value}K` : `${value}`),
|
formatter: function (value) {
|
||||||
offsetX: -10,
|
return value + ' dBm';
|
||||||
|
},
|
||||||
|
//offsetY: -10,
|
||||||
style: {
|
style: {
|
||||||
colors: theme.palette.text.secondary
|
//colors: theme.palette.text.secondary
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// annotations: {
|
||||||
|
// xaxis: [
|
||||||
|
// {
|
||||||
|
// x: 9,
|
||||||
|
// x2: 10,
|
||||||
|
// borderColor: '#0b54ff',
|
||||||
|
// label: {
|
||||||
|
// style: {
|
||||||
|
// color: 'black',
|
||||||
|
// },
|
||||||
|
// text: 'Channel 10',
|
||||||
|
// offsetX: 45,
|
||||||
|
// borderColor: 'transparent',
|
||||||
|
// style: {
|
||||||
|
// background: 'transparent',
|
||||||
|
// color: theme.palette.text.secondary,
|
||||||
|
// fontSize: '17px',
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// },
|
||||||
|
// annotations: {
|
||||||
|
// points: [{
|
||||||
|
// x: 9,
|
||||||
|
// y: -5,
|
||||||
|
// label: {
|
||||||
|
// borderColor: '#775DD0',
|
||||||
|
// offsetY: 0,
|
||||||
|
// style: {
|
||||||
|
// color: '#fff',
|
||||||
|
// background: '#775DD0',
|
||||||
|
// },
|
||||||
|
// rotate: -45,
|
||||||
|
// text: 'Bananas are good',
|
||||||
|
// }
|
||||||
|
// }]
|
||||||
|
// },
|
||||||
|
xaxis: {
|
||||||
|
// tickPlacement: 'on',
|
||||||
|
// tickAmount: getChannelAmount(),
|
||||||
|
tickPlacement: 'on',
|
||||||
|
labels: {
|
||||||
|
show: true,
|
||||||
|
style: {
|
||||||
|
//colors: theme.palette.text.secondary
|
||||||
|
},
|
||||||
|
trim: true,
|
||||||
|
},
|
||||||
|
// max: getMaxChannel(),
|
||||||
|
// min: geMinChannel(),
|
||||||
|
// stepSize: getChannelSpacing(),
|
||||||
|
//type: 'category',
|
||||||
|
//categories: [getCategories()],
|
||||||
|
type: 'numeric',
|
||||||
|
decimalsInFloat: 0,
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
x: {
|
||||||
|
show: true,
|
||||||
|
formatter: (seriesName) => "Channel "+ seriesName,
|
||||||
|
},
|
||||||
|
followCursor: false,
|
||||||
|
intersect: false,
|
||||||
|
shared: true,
|
||||||
|
enabled: true,
|
||||||
|
onDatasetHover: {
|
||||||
|
highlightDataSeries: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SiteSurvey = (props) => {
|
|
||||||
const chartSeries = [{ name: 'This year', data: [18, 16, 5, 8, 3, 14, 14, 16, 17, 19, 18, 20] }, { name: 'Last year', data: [12, 11, 4, 6, 2, 9, 9, 10, 11, 12, 13, 13] }]
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const [content, setContent] = useState(null);
|
|
||||||
const [frequency, setFrequency] = useState("2.4GHz");
|
|
||||||
|
|
||||||
const chartOptions = useChartOptions();
|
const chartOptions = useChartOptions();
|
||||||
|
|
||||||
|
|
@ -181,23 +324,30 @@ export const SiteSurvey = (props) => {
|
||||||
<Grid spacing={1}>
|
<Grid spacing={1}>
|
||||||
<Grid container>
|
<Grid container>
|
||||||
<Card>
|
<Card>
|
||||||
<Button
|
<ToggleButtonGroup
|
||||||
color="inherit"
|
value={view}
|
||||||
|
exclusive
|
||||||
|
onChange={(e, value) => {
|
||||||
|
setView(value)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ToggleButton
|
||||||
size="small"
|
size="small"
|
||||||
disabled="true"
|
value="chart"
|
||||||
>
|
>
|
||||||
<SvgIcon>
|
<SvgIcon>
|
||||||
<ChartBarSquareIcon />
|
<ChartBarSquareIcon />
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
</Button>
|
</ToggleButton>
|
||||||
<Button
|
<ToggleButton
|
||||||
color="inherit"
|
|
||||||
size="small"
|
size="small"
|
||||||
|
value="list"
|
||||||
>
|
>
|
||||||
<SvgIcon>
|
<SvgIcon>
|
||||||
<ListBulletIcon />
|
<ListBulletIcon />
|
||||||
</SvgIcon>
|
</SvgIcon>
|
||||||
</Button>
|
</ToggleButton>
|
||||||
|
</ToggleButtonGroup>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Box display="flex"
|
<Box display="flex"
|
||||||
|
|
@ -221,7 +371,7 @@ export const SiteSurvey = (props) => {
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</Box>
|
</Box>
|
||||||
<Card sx={{ height: '100%' }}>
|
{view == "list" && <Card sx={{ height: '100%' }}>
|
||||||
<Box sx={{ minWidth: 800, }}>
|
<Box sx={{ minWidth: 800, }}>
|
||||||
<TableContainer sx={{ maxHeight: 600 }}>
|
<TableContainer sx={{ maxHeight: 600 }}>
|
||||||
<Table exportButton={true}>
|
<Table exportButton={true}>
|
||||||
|
|
@ -273,31 +423,18 @@ export const SiteSurvey = (props) => {
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
</Box>
|
</Box>
|
||||||
{/* <CardContent>
|
</Card>}
|
||||||
|
{view == "chart" && <Card>
|
||||||
|
<CardContent>
|
||||||
<Chart
|
<Chart
|
||||||
height={500}
|
height={500}
|
||||||
options={chartOptions}
|
options={chartOptions}
|
||||||
series={chartSeries}
|
series={getSeries()}
|
||||||
type="bar"
|
type="area"
|
||||||
width="100%"
|
width="100%"
|
||||||
/>
|
/>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<Divider />
|
</Card>}
|
||||||
<CardActions sx={{ justifyContent: 'center' }}>
|
|
||||||
<FormControl xs={2}>
|
|
||||||
<RadioGroup
|
|
||||||
aria-labelledby="demo-controlled-radio-buttons-group"
|
|
||||||
name="controlled-radio-buttons-group"
|
|
||||||
value={"2.4GHz"}
|
|
||||||
>
|
|
||||||
<Grid container>
|
|
||||||
<FormControlLabel value="2.4GHz" control={<Radio />} label="2.4GHz" />
|
|
||||||
<FormControlLabel value="5GHz" control={<Radio />} label="5GHz" />
|
|
||||||
</Grid>
|
|
||||||
</RadioGroup>
|
|
||||||
</FormControl>
|
|
||||||
</CardActions> */}
|
|
||||||
</Card>
|
|
||||||
</Grid>: <CircularProgress></CircularProgress>}
|
</Grid>: <CircularProgress></CircularProgress>}
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ const showIcon = (mtpType) => {
|
||||||
</Stack>
|
</Stack>
|
||||||
<Avatar
|
<Avatar
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: '#f28950',
|
backgroundColor: 'primary.darkest',
|
||||||
height: 56,
|
height: 56,
|
||||||
width: 56
|
width: 56
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,6 @@ const useChartOptions = (labels,title) => {
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
options.colors = [
|
options.colors = [
|
||||||
theme.palette.primary.main,
|
|
||||||
theme.palette.info.main,
|
theme.palette.info.main,
|
||||||
theme.palette.warning.main,
|
theme.palette.warning.main,
|
||||||
theme.palette.graphics.lightest,
|
theme.palette.graphics.lightest,
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,16 @@ const withAlphas = (color) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const neutral = {
|
export const neutral = (colors) => {
|
||||||
50: '#306d6f',
|
console.log("neutral colors:", colors);
|
||||||
|
let parsedColors = JSON.parse(colors);
|
||||||
|
|
||||||
|
let tableColor = parsedColors["tables"]
|
||||||
|
let sidebarColorInitial = parsedColors["sidebar_initial"]
|
||||||
|
let wordsOutsideSidebarColor = parsedColors["words_outside_sidebar"]
|
||||||
|
|
||||||
|
return {
|
||||||
|
50: tableColor,
|
||||||
100: '#F3F4F6',
|
100: '#F3F4F6',
|
||||||
200: '#E5E7EB',
|
200: '#E5E7EB',
|
||||||
300: '#D2D6DB',
|
300: '#D2D6DB',
|
||||||
|
|
@ -20,18 +28,29 @@ export const neutral = {
|
||||||
500: '#6C737F',
|
500: '#6C737F',
|
||||||
600: '#4D5761',
|
600: '#4D5761',
|
||||||
700: '#FFFFFF',
|
700: '#FFFFFF',
|
||||||
800: '#306d6f',
|
800: sidebarColorInitial,
|
||||||
900: '#30596f'
|
900: wordsOutsideSidebarColor,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const indigo = withAlphas({
|
export const indigo = (colors) => {
|
||||||
|
|
||||||
|
console.log("indigo colors:", colors);
|
||||||
|
let parsedColors = JSON.parse(colors);
|
||||||
|
|
||||||
|
let buttonColor = parsedColors["buttons"]
|
||||||
|
let sidebarColorEnd = parsedColors["sidebar_end"]
|
||||||
|
let mtpsColor = parsedColors["connected_mtps_color"]
|
||||||
|
|
||||||
|
return withAlphas({
|
||||||
lightest: '#FFFFFF',
|
lightest: '#FFFFFF',
|
||||||
light: '#306D6F',
|
light: '#ff3383',
|
||||||
main: '#306D6F',
|
main: buttonColor,
|
||||||
dark: '#255355',
|
dark: sidebarColorEnd,
|
||||||
darkest: '#00a0b8',
|
darkest: mtpsColor,
|
||||||
contrastText: '#FFFFFF'
|
contrastText: '#FFFFFF'
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export const success = withAlphas({
|
export const success = withAlphas({
|
||||||
lightest: '#F0FDF9',
|
lightest: '#F0FDF9',
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,62 @@ import { common } from '@mui/material/colors';
|
||||||
import { alpha } from '@mui/material/styles';
|
import { alpha } from '@mui/material/styles';
|
||||||
import { error, indigo, info, neutral, success, warning, graphics } from './colors';
|
import { error, indigo, info, neutral, success, warning, graphics } from './colors';
|
||||||
|
|
||||||
|
const getColorScheme = async () => {
|
||||||
|
|
||||||
|
let result = await fetch('http://localhost/custom-frontend/colors').catch((error) => {
|
||||||
|
console.log('Error fetching colors');
|
||||||
|
sessionStorage.setItem('colors', JSON.stringify({
|
||||||
|
"buttons": "#306d6f",
|
||||||
|
"sidebar_end": "#306d6f",
|
||||||
|
"sidebar_initial": "#306d6f",
|
||||||
|
"tables": "#306d6f",
|
||||||
|
"words_outside_sidebar": "#30596f",
|
||||||
|
"connected_mtps_color": "#f28950"
|
||||||
|
}));
|
||||||
|
location.reload();
|
||||||
|
return
|
||||||
|
});
|
||||||
|
if (result.status!=200) {
|
||||||
|
console.log('Error fetching colors');
|
||||||
|
sessionStorage.setItem('colors', JSON.stringify({
|
||||||
|
"buttons": "#306d6f",
|
||||||
|
"sidebar_end": "#306d6f",
|
||||||
|
"sidebar_initial": "#306d6f",
|
||||||
|
"tables": "#306d6f",
|
||||||
|
"words_outside_sidebar": "#30596f",
|
||||||
|
"connected_mtps_color": "#f28950"
|
||||||
|
}));
|
||||||
|
location.reload();
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = await result.json();
|
||||||
|
let fmtresponse = JSON.stringify(response);
|
||||||
|
sessionStorage.setItem('colors', fmtresponse);
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
export function createPalette() {
|
export function createPalette() {
|
||||||
|
|
||||||
|
let colors = sessionStorage.getItem('colors');
|
||||||
|
|
||||||
|
if (colors !== null) {
|
||||||
|
console.log('colors already fetched');
|
||||||
|
} else {
|
||||||
|
getColorScheme();
|
||||||
|
}
|
||||||
|
console.log("colors scheme:", colors);
|
||||||
|
|
||||||
|
let neutralColors = neutral(colors);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
action: {
|
action: {
|
||||||
active: neutral[500],
|
active: neutralColors[500],
|
||||||
disabled: alpha(neutral[900], 0.38),
|
disabled: alpha(neutralColors[900], 0.38),
|
||||||
disabledBackground: alpha(neutral[900], 0.12),
|
disabledBackground: alpha(neutralColors[900], 0.12),
|
||||||
focus: alpha(neutral[900], 0.16),
|
focus: alpha(neutralColors[900], 0.16),
|
||||||
hover: alpha(neutral[900], 0.04),
|
hover: alpha(neutralColors[900], 0.04),
|
||||||
selected: alpha(neutral[900], 0.12)
|
selected: alpha(neutralColors[900], 0.12)
|
||||||
},
|
},
|
||||||
background: {
|
background: {
|
||||||
default: common.white,
|
default: common.white,
|
||||||
|
|
@ -21,13 +68,13 @@ export function createPalette() {
|
||||||
graphics,
|
graphics,
|
||||||
info,
|
info,
|
||||||
mode: 'light',
|
mode: 'light',
|
||||||
neutral,
|
neutral: neutralColors,
|
||||||
primary: indigo,
|
primary: indigo(colors),
|
||||||
success,
|
success,
|
||||||
text: {
|
text: {
|
||||||
primary: neutral[900],
|
primary: neutralColors[900],
|
||||||
secondary: neutral[500],
|
secondary: neutralColors[500],
|
||||||
disabled: alpha(neutral[900], 0.38)
|
disabled: alpha(neutralColors[900], 0.38)
|
||||||
},
|
},
|
||||||
warning
|
warning
|
||||||
};
|
};
|
||||||
|
|
|
||||||
47
frontend/src/utils/map.css
Normal file
47
frontend/src/utils/map.css
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
/* The location pointed to by the popup tip. */
|
||||||
|
.popup-tip-anchor {
|
||||||
|
height: 0;
|
||||||
|
position: absolute;
|
||||||
|
/* The max width of the info window. */
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
/* The bubble is anchored above the tip. */
|
||||||
|
.popup-bubble-anchor {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
bottom: /* TIP_HEIGHT= */ 8px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
/* Draw the tip. */
|
||||||
|
.popup-bubble-anchor::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
/* Center the tip horizontally. */
|
||||||
|
transform: translate(-50%, 0);
|
||||||
|
/* The tip is a https://css-tricks.com/snippets/css/css-triangle/ */
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
/* The tip is 8px high, and 12px wide. */
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-right: 6px solid transparent;
|
||||||
|
border-top: /* TIP_HEIGHT= */ 8px solid white;
|
||||||
|
}
|
||||||
|
/* The popup bubble itself. */
|
||||||
|
.popup-bubble-content {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
transform: translate(-50%, -100%);
|
||||||
|
/* Style the info window. */
|
||||||
|
background-color: white;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px ;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: 80px;
|
||||||
|
box-shadow: 0px 2px 10px 1px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user