116 lines
2.0 KiB
Go
116 lines
2.0 KiB
Go
package printer
|
|
|
|
import "time"
|
|
|
|
type PrintState int
|
|
|
|
const (
|
|
StateIdle PrintState = iota
|
|
StateSDPrinting
|
|
StateHostPrinting
|
|
StatePaused
|
|
StateError
|
|
)
|
|
|
|
func (p PrintState) String() string {
|
|
switch p {
|
|
case StateIdle:
|
|
return "IDLE"
|
|
case StateSDPrinting:
|
|
return "SD PRINTING"
|
|
case StateHostPrinting:
|
|
return "PRINTING"
|
|
case StatePaused:
|
|
return "PAUSED"
|
|
case StateError:
|
|
return "ERROR"
|
|
default:
|
|
return "?"
|
|
}
|
|
}
|
|
|
|
type TempPair struct {
|
|
Current float64
|
|
Target float64
|
|
}
|
|
|
|
type SDFile struct {
|
|
Name string // 8.3 short filename, what M23 takes
|
|
LongName string // long filename if firmware reports one
|
|
Size int64
|
|
}
|
|
|
|
type State struct {
|
|
Connected bool
|
|
Online bool
|
|
Firmware string
|
|
Port string
|
|
Baud int
|
|
|
|
PrintState PrintState
|
|
ErrorMsg string
|
|
|
|
Temps map[string]TempPair
|
|
|
|
SDByte int64
|
|
SDTotal int64
|
|
SDFilename string
|
|
SDStart time.Time
|
|
|
|
FeedratePct int
|
|
FlowPct int
|
|
FanPct int
|
|
BabystepZ float64
|
|
|
|
// SD card listing. SDListing is true while M20 output is being
|
|
// collected; SDFiles is the most recently completed listing.
|
|
SDFiles []SDFile
|
|
SDListing bool
|
|
}
|
|
|
|
func NewState() State {
|
|
return State{
|
|
Temps: map[string]TempPair{},
|
|
FeedratePct: 100,
|
|
FlowPct: 100,
|
|
FanPct: 0,
|
|
PrintState: StateIdle,
|
|
}
|
|
}
|
|
|
|
func (s *State) Progress() float64 {
|
|
if s.SDTotal <= 0 {
|
|
return 0
|
|
}
|
|
p := float64(s.SDByte) / float64(s.SDTotal)
|
|
if p > 1 {
|
|
return 1
|
|
}
|
|
return p
|
|
}
|
|
|
|
func (s *State) ETA() (time.Duration, bool) {
|
|
if s.PrintState != StateSDPrinting || s.SDByte <= 0 || s.SDStart.IsZero() {
|
|
return 0, false
|
|
}
|
|
elapsed := nowFn().Sub(s.SDStart)
|
|
if elapsed < 5*time.Second {
|
|
return 0, false
|
|
}
|
|
rate := float64(s.SDByte) / elapsed.Seconds()
|
|
if rate <= 0 {
|
|
return 0, false
|
|
}
|
|
remaining := float64(s.SDTotal - s.SDByte)
|
|
if remaining < 0 {
|
|
remaining = 0
|
|
}
|
|
return time.Duration(remaining/rate) * time.Second, true
|
|
}
|
|
|
|
// indirection so tests can fix time
|
|
var (
|
|
nowFn = time.Now
|
|
zeroTime = time.Time{}
|
|
)
|