-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
37 changed files
with
4,504 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
icon/*.go | ||
statik/ | ||
*.exe | ||
*.sum | ||
*.iml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,11 @@ | ||
# miio-serial-tools | ||
MIIO Serial Tools | ||
# MIIO Serial Tools | ||
**软件所有功能基于[iot.mi.com](https://iot.mi.com/new/doc/embedded-development/wifi/standard-protocol.html)开发** | ||
`后端`开发者(固件开发)可以依据**产品功能定义**利用[mst](https://github.com/kerwin612/miio-serial-tools)来**模拟固件功能**,便于`前端`开发者(米家APP插件开发)真实且高效的**联调接口** | ||
|
||
> 串口配置信息: | ||
串口 -> miot模组 | ||
VCC -> (ESP-WROOM-02: 3V3) / (ESP-WROOM-32: 3V3) / (MHCWB4P: VDD) | ||
GND -> GND | ||
RXD -> (ESP-WROOM-02: IO15-CMD|IO2-LOG) / (ESP-WROOM-32: GPIO17-CMD|TXD0-LOG) / (MHCWB4P: IO14-CMD) | ||
TXD -> (ESP-WROOM-02: IO13-CMDIN) / (ESP-WROOM-32: GPIO16-CMDIN) / (MHCWB4P: IO13-CMDIN) | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
go install github.com/rakyll/statik | ||
go get github.com/kerwin612/miio-serial-tools/mst | ||
statik -f -src=static && go build -ldflags -H=windowsgui |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
module github.com/kerwin612/miio-serial-tools | ||
|
||
go 1.20 | ||
|
||
require ( | ||
github.com/getlantern/systray v1.2.2 | ||
github.com/gorilla/websocket v1.5.1 | ||
github.com/kerwin612/hybrid-launcher v0.0.2 | ||
github.com/rakyll/statik v0.1.7 | ||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 | ||
) | ||
|
||
require ( | ||
github.com/getlantern/context v0.0.0-20220418194847-3d5e7a086201 // indirect | ||
github.com/getlantern/errors v1.0.3 // indirect | ||
github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65 // indirect | ||
github.com/getlantern/hex v0.0.0-20220104173244-ad7e4b9194dc // indirect | ||
github.com/getlantern/hidden v0.0.0-20220104173330-f221c5a24770 // indirect | ||
github.com/getlantern/ops v0.0.0-20231025133620-f368ab734534 // indirect | ||
github.com/go-logr/logr v1.4.1 // indirect | ||
github.com/go-logr/stdr v1.2.2 // indirect | ||
github.com/go-stack/stack v1.8.1 // indirect | ||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect | ||
go.opentelemetry.io/otel v1.21.0 // indirect | ||
go.opentelemetry.io/otel/metric v1.21.0 // indirect | ||
go.opentelemetry.io/otel/trace v1.21.0 // indirect | ||
go.uber.org/multierr v1.11.0 // indirect | ||
go.uber.org/zap v1.26.0 // indirect | ||
golang.org/x/net v0.19.0 // indirect | ||
golang.org/x/sys v0.15.0 // indirect | ||
) | ||
|
||
//replace github.com/kerwin612/hybrid-launcher => ../hybrid-launcher |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/kerwin612/miio-serial-tools/mst" | ||
) | ||
|
||
func main() { | ||
mst.Main() | ||
} |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,328 @@ | ||
package mst | ||
|
||
import ( | ||
"os" | ||
"fmt" | ||
"time" | ||
"strings" | ||
"net/http" | ||
"io/ioutil" | ||
"encoding/json" | ||
"github.com/gorilla/websocket" | ||
) | ||
|
||
var upgrader = websocket.Upgrader{ | ||
ReadBufferSize: 1024, | ||
WriteBufferSize: 1024, | ||
} | ||
var ws *websocket.Conn | ||
var wssender chan string | ||
var scoff chan bool | ||
var off chan bool | ||
var _status bool | ||
var autoRespMap map[string]interface{} | ||
var shortCmdFile string | ||
var autoRespFile string | ||
var serialConfigFile string | ||
|
||
func api(homedir string) { | ||
|
||
_status = false | ||
autoRespMap = make(map[string]interface{}) | ||
shortCmdFile = homedir + "short_cmd.json" | ||
autoRespFile = homedir + "auto_resp.json" | ||
serialConfigFile = homedir + "serial_config.json" | ||
|
||
autoRespArray := []struct { | ||
ReqCmd string | ||
RespCmd []string | ||
}{} | ||
file, err := os.OpenFile(autoRespFile, os.O_RDWR, 0644) | ||
defer file.Close() | ||
if err == nil { | ||
b, err := ioutil.ReadAll(file) | ||
if err == nil { | ||
json.Unmarshal(b, &autoRespArray) | ||
|
||
for _, obj := range autoRespArray { | ||
autoRespMap[obj.ReqCmd] = obj.RespCmd | ||
} | ||
logger.Println("auto_resp: ", autoRespMap) | ||
} | ||
} | ||
|
||
http.HandleFunc("/v1/status", func (w http.ResponseWriter, r *http.Request) { | ||
w.Header().Set("Content-Type", "application/json") | ||
fmt.Fprintf(w, "{\"status\": %t}", _status) | ||
}) | ||
|
||
http.HandleFunc("/v1/start", _start) | ||
|
||
http.HandleFunc("/v1/stop", _stop) | ||
|
||
http.HandleFunc("/v1/send", _send) | ||
|
||
http.HandleFunc("/v1/serial_config", _serial_config) | ||
|
||
http.HandleFunc("/v1/auto_resp", _auto_resp) | ||
|
||
http.HandleFunc("/v1/short_cmd", _short_cmd) | ||
|
||
http.HandleFunc("/ws", _ws) | ||
|
||
} | ||
|
||
func wssend(msg string) { | ||
if wssender != nil { | ||
go func() { | ||
wssender <- msg | ||
}() | ||
} | ||
} | ||
|
||
func _start(w http.ResponseWriter, r *http.Request) { | ||
decoder := json.NewDecoder(r.Body) | ||
var sc *SerialConfig | ||
err := decoder.Decode(&sc) | ||
if err != nil { | ||
logger.Println("start params error: ", err) | ||
w.WriteHeader(500) | ||
return | ||
} | ||
outer := make(chan string, 1024) | ||
err = Start(sc, outer) | ||
if err != nil { | ||
logger.Println("start port error: ", err) | ||
w.WriteHeader(500) | ||
return | ||
} | ||
off = make(chan bool) | ||
go func() { | ||
for { | ||
select { | ||
case <- off: | ||
logger.Println("off true") | ||
return | ||
default: | ||
outstr := <-outer | ||
if "recv: down none" != outstr && "send: get_down" != outstr { | ||
logger.Println(outstr) | ||
} | ||
if outstr == "stop!" { | ||
return | ||
} | ||
wssend(outstr) | ||
if strings.HasPrefix(outstr, "recv: ") { | ||
req_cmd := outstr[6:] | ||
if resp_cmd, ok := autoRespMap[req_cmd]; ok { | ||
for _, _cmd := range resp_cmd.([]string) { | ||
wssend("auto_resp: " + _cmd) | ||
Send(_cmd) | ||
time.Sleep(time.Millisecond * 100) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}() | ||
scoff = make(chan bool) | ||
go func() { | ||
for { | ||
select { | ||
case <- scoff: | ||
logger.Println("scoff true") | ||
return | ||
default: | ||
_status = Status() | ||
if !_status { | ||
logger.Println("port status is flase") | ||
wssend("_cmd:stop") | ||
outer <- "stop!" | ||
return | ||
} | ||
} | ||
} | ||
}() | ||
w.WriteHeader(200) | ||
} | ||
|
||
func _stop(w http.ResponseWriter, r *http.Request) { | ||
w.WriteHeader(200) | ||
if _status { | ||
off <- true | ||
scoff <- true | ||
_status = false | ||
} | ||
Stop() | ||
} | ||
|
||
func _send(w http.ResponseWriter, r *http.Request) { | ||
decoder := json.NewDecoder(r.Body) | ||
obj := struct { | ||
Cmd string | ||
}{} | ||
err := decoder.Decode(&obj) | ||
if err != nil { | ||
wssend("send params error: " + err.Error()) | ||
w.WriteHeader(500) | ||
return | ||
} | ||
if !_status { | ||
wssend("send [" + obj.Cmd + "] error: server not startup.") | ||
w.WriteHeader(500) | ||
return | ||
} | ||
err = Send(obj.Cmd) | ||
if err != nil { | ||
wssend("send [" + obj.Cmd + "] error: " + err.Error()) | ||
w.WriteHeader(500) | ||
return | ||
} | ||
w.WriteHeader(200) | ||
} | ||
|
||
func _serial_config(w http.ResponseWriter, r *http.Request) { | ||
switch r.Method { | ||
case http.MethodGet: | ||
data, err := ioutil.ReadFile(serialConfigFile) | ||
if err != nil { | ||
w.WriteHeader(200) | ||
return | ||
} | ||
w.Header().Set("Content-Type", "application/json") | ||
fmt.Fprintf(w, string(data)) | ||
case http.MethodPost: | ||
decoder := json.NewDecoder(r.Body) | ||
var sc *SerialConfig | ||
err := decoder.Decode(&sc) | ||
if err != nil { | ||
panic(err) | ||
} | ||
scBytes, err := json.MarshalIndent(&sc, "", " ") | ||
ioutil.WriteFile(serialConfigFile, scBytes, 0666) | ||
w.WriteHeader(200) | ||
default: | ||
http.NotFound(w, r) | ||
return | ||
} | ||
} | ||
|
||
func _auto_resp(w http.ResponseWriter, r *http.Request) { | ||
switch r.Method { | ||
case http.MethodGet: | ||
data, err := ioutil.ReadFile(autoRespFile) | ||
if err != nil { | ||
w.WriteHeader(200) | ||
return | ||
} | ||
w.Header().Set("Content-Type", "application/json") | ||
fmt.Fprintf(w, string(data)) | ||
case http.MethodPost: | ||
decoder := json.NewDecoder(r.Body) | ||
objArray := []struct { | ||
ReqCmd string | ||
RespCmd []string | ||
}{} | ||
err := decoder.Decode(&objArray) | ||
if err != nil { | ||
panic(err) | ||
} | ||
autoRespMap = make(map[string]interface{}) | ||
for _, obj := range objArray { | ||
autoRespMap[obj.ReqCmd] = obj.RespCmd | ||
} | ||
logger.Println("auto_resp: ", autoRespMap) | ||
objArrayBytes, err := json.MarshalIndent(&objArray, "", " ") | ||
ioutil.WriteFile(autoRespFile, objArrayBytes, 0666) | ||
w.WriteHeader(200) | ||
default: | ||
http.NotFound(w, r) | ||
return | ||
} | ||
} | ||
|
||
func _short_cmd(w http.ResponseWriter, r *http.Request) { | ||
switch r.Method { | ||
case http.MethodGet: | ||
data, err := ioutil.ReadFile(shortCmdFile) | ||
if err != nil { | ||
w.WriteHeader(200) | ||
return | ||
} | ||
w.Header().Set("Content-Type", "application/json") | ||
fmt.Fprintf(w, string(data)) | ||
case http.MethodPost: | ||
decoder := json.NewDecoder(r.Body) | ||
cmdArray := []string{} | ||
err := decoder.Decode(&cmdArray) | ||
if err != nil { | ||
panic(err) | ||
} | ||
logger.Println("short_cmd: ", cmdArray) | ||
cmdArrayBytes, err := json.MarshalIndent(&cmdArray, "", " ") | ||
ioutil.WriteFile(shortCmdFile, cmdArrayBytes, 0666) | ||
w.WriteHeader(200) | ||
default: | ||
http.NotFound(w, r) | ||
return | ||
} | ||
} | ||
|
||
func _ws(w http.ResponseWriter, r *http.Request) { | ||
upgrader.CheckOrigin = func(r *http.Request) bool { return true } | ||
|
||
// upgrade this connection to a WebSocket | ||
// connection | ||
conn, err := upgrader.Upgrade(w, r, nil) | ||
if err != nil { | ||
logger.Println(err) | ||
} | ||
if ws != nil { | ||
ws.Close() | ||
ws = nil | ||
} | ||
ws = conn | ||
|
||
wssender = make(chan string) | ||
go func() { | ||
for { | ||
select { | ||
default: | ||
if ws == nil { | ||
break | ||
} | ||
sendstr := <-wssender | ||
if err := ws.WriteMessage(websocket.TextMessage, []byte(time.Now().Format("[15:04:05.000] ") + sendstr)); err != nil { | ||
logger.Println(err) | ||
wssender = nil | ||
ws.Close() | ||
return | ||
} | ||
} | ||
} | ||
}() | ||
|
||
logger.Println("Client Connected") | ||
// listen indefinitely for new messages coming | ||
// through on our WebSocket connection | ||
_reader() | ||
} | ||
|
||
// define a reader which will listen for | ||
// new messages being sent to our WebSocket | ||
// endpoint | ||
func _reader() { | ||
for { | ||
// read in a message | ||
_, p, err := ws.ReadMessage() | ||
if err != nil { | ||
logger.Println(err) | ||
ws.Close() | ||
return | ||
} | ||
// print out that message for clarity | ||
fmt.Println(string(p)) | ||
|
||
wssend(string(p)) | ||
} | ||
} |
Oops, something went wrong.