// vim: shiftwidth=4 tabstop=4 noexpandtab package main import ( "log" "os/exec" "io" ) type Camera struct { statemachine Machine } func NewCamera() Camera { return Camera{ statemachine: Machine{ name: "camera", initial: "idle", states: StateMap{ "idle": MachineState{ on: TransitionMap{ "take_single_picture": MachineTransition{ to: "single_picture", }, }, }, "single_picture": MachineState{ on: TransitionMap{ "single_picture_taken": MachineTransition{ to: "idle", }, }, }, }, api: make(chan string), state_listeners: make([]*(chan string), 0), hook: runCameraHooks, }, } } func runCameraHooks(last string, next string, m *Machine) { if last == "idle" && next == "single_picture" { go singlePicture(m) } } func singlePicture(m *Machine) { // create command var cmd *exec.Cmd if !config.Flag.Debug { cmd = exec.Command("python3", "/usr/lib/python3.9/site-packages/birdscan/") } else { cmd = exec.Command("python3", "../python/birdscan", "--debug") // FIXME relative paths do not work in exec.Command! } // connect stdout of python process stdout,err := cmd.StdoutPipe() if err != nil { log.Print(err) } defer stdout.Close() // run command err = cmd.Start() if err != nil { log.Print(err) } _,err = io.ReadAll(stdout) if err != nil { log.Print(err) } err = cmd.Wait() // wait until command execution and io is complete if err != nil { log.Print(err) } // process result m.SendEvent("single_picture_taken") } func (cam *Camera) run() { cam.statemachine.Run() }