Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kerwin612 committed Feb 19, 2024
1 parent d475f51 commit 31c6f95
Show file tree
Hide file tree
Showing 37 changed files with 4,504 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
icon/*.go
statik/
*.exe
*.sum
*.iml
13 changes: 11 additions & 2 deletions README.md
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)
3 changes: 3 additions & 0 deletions build.cmd
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
33 changes: 33 additions & 0 deletions go.mod
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
Binary file added icons/128x128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/128x128@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/Square107x107Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/Square142x142Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/Square150x150Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/Square284x284Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/Square30x30Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/Square310x310Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/Square44x44Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/Square71x71Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/Square89x89Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/StoreLogo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/icon.icns
Binary file not shown.
Binary file added icons/icon.ico
Binary file not shown.
Binary file added icons/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions main.go
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 added miio_serial_tools_386.syso
Binary file not shown.
Binary file added miio_serial_tools_amd64.syso
Binary file not shown.
328 changes: 328 additions & 0 deletions mst/api.go
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))
}
}
Loading

0 comments on commit 31c6f95

Please # to comment.