Skip to content

Commit

Permalink
gojrk: turn into Google Actions server
Browse files Browse the repository at this point in the history
Allows to turn set target of the motor via voice commands.
  • Loading branch information
timoha committed May 25, 2021
1 parent fa86e1f commit 1ab45b0
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 28 deletions.
18 changes: 14 additions & 4 deletions index.html → cmd/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,17 @@
<script>
function setTarget(v) {
return function() {
fetch('./jrk?target=' + v).then(function(response) {
fetch('./actions/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
handler: {
name: v,
},
})
}).then(function(response) {
return response.blob();
}).then(function(text) {
console.log(text);
Expand All @@ -54,13 +64,13 @@
}

var leftBtn = document.querySelector('#left');
leftBtn.addEventListener('click', setTarget(4000));
leftBtn.addEventListener('click', setTarget('handler_left'));

var centerBtn = document.querySelector('#center');
centerBtn.addEventListener('click', setTarget(1000));
centerBtn.addEventListener('click', setTarget('handler_center'));

var rightBtn = document.querySelector('#right');
rightBtn.addEventListener('click', setTarget(0));
rightBtn.addEventListener('click', setTarget('handler_right'));
</script>
</body>
</html>
106 changes: 88 additions & 18 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,41 +1,111 @@
package main

import (
_ "embed"
"encoding/json"
"flag"
"fmt"
"log"
"net/http"

"github.com/timoha/gojrk"
"github.com/timoha/gojrk/jrk"
)

var target = flag.Int("target", -1, "target to set the motor at (0-4095)")
var device = flag.String("device", "", "filepath to device")
var password = flag.String("password", "", "password to be used as last component for actions webhook")
var addr = flag.String("addr", ":8080", "address to serve from")
var certFile = flag.String("cert", "", "location of cert file")
var keyFile = flag.String("key", "", "location of key file")

func main() {
flag.Parse()
//go:embed index.html
var index []byte

type ActionRequest struct {
Handler Handler
Session Session
}

type Handler struct {
Name string
}

type Session struct {
ID string
Params map[string]interface{}
}

type ActionResponse struct {
Session Session
}

type ResponseJSON struct {
}

func actionsHandlerFunc(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}

var ar ActionRequest
if err := json.NewDecoder(r.Body).Decode(&ar); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

fmt.Println(ar)

if *target < 0 || *target > 4095 {
log.Fatalln("target has to be in range 0 to 4095")
target, ok := handlers[ar.Handler.Name]
if !ok {
http.Error(w, fmt.Sprintf("unknown handler %q", ar.Handler.Name), http.StatusBadRequest)
return
}

j, err := gojrk.NewJRK(*device)
j, err := jrk.New(*device)
if err != nil {
log.Fatalln("failed to connect to jrk controller:", err)
http.Error(w, fmt.Sprint("connecting to jrk controller:", err), http.StatusInternalServerError)
return
}
defer j.Close()

if f, err := j.Feedback(); err != nil {
log.Fatalln("failed to get current feedback value", err)
} else {
log.Println("Current feedback:", f)
if err := j.SetTarget(target); err != nil {
http.Error(w, fmt.Sprint("setting new target value", err), http.StatusInternalServerError)
return
}

if t, err := j.Target(); err != nil {
log.Fatalln("failed to get current target value", err)
} else {
log.Println("Current target:", t)
resp := ActionResponse{
Session: ar.Session,
}

if err := j.SetTarget(*target); err != nil {
log.Fatalln("failed to set new target value:", err)
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(resp); err != nil {
http.Error(w, fmt.Sprint("marshalling json response", err), http.StatusInternalServerError)
return
}
}

var handlers = map[string]int{
"handler_left": 3000,
"handler_center": 1700,
"handler_right": 751,
}

func main() {
flag.Parse()

if *password == "" {
// running on local network
http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
w.Write(index)
})
}
http.HandleFunc("/actions/"+*password, actionsHandlerFunc)

var err error
if *certFile != "" && *keyFile != "" {
err = http.ListenAndServeTLS(*addr, *certFile, *keyFile, nil)
} else {
err = http.ListenAndServe(*addr, nil)
}
log.Fatal(err)
}
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/timoha/gojrk

go 1.16

require (
github.com/pkg/term v1.1.0
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 // indirect
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk=
github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
13 changes: 7 additions & 6 deletions jrk.go → jrk/jrk.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package gojrk
package jrk

import (
"io"
"os"
"syscall"

"github.com/pkg/term/termios"
"golang.org/x/sys/unix"
)

// JRK is used communicate with jrk USB motor controller
Expand Down Expand Up @@ -43,20 +44,20 @@ func (jrk *JRK) SetTarget(v int) error {
return err
}

// NewJRK connects to jrk USB motor contoller.
func NewJRK(path string) (*JRK, error) {
// New connects to jrk USB motor contoller.
func New(path string) (*JRK, error) {
f, err := os.OpenFile(path, os.O_RDWR|syscall.O_NOCTTY, 0)
if err != nil {
return nil, err
}

var o syscall.Termios
var o unix.Termios
if err := termios.Tcgetattr(f.Fd(), &o); err != nil {
return nil, err
}

o.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN
o.Oflag &^= syscall.ONLCR | syscall.OCRNL
o.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
o.Oflag &^= unix.ONLCR | unix.OCRNL

if err := termios.Tcsetattr(f.Fd(), termios.TCSANOW, &o); err != nil {
return nil, err
Expand Down

0 comments on commit 1ab45b0

Please sign in to comment.