Merge pull request #4 from indihub-space/run-without-manager-option

new optional param --indi-server added
This commit is contained in:
dencoded 2020-03-19 00:11:47 -04:00 committed by GitHub
commit 21ac961491
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 82 additions and 87 deletions

118
main.go
View file

@ -34,6 +34,7 @@ const (
var (
flagINDIServerManagerAddr string
flagPHD2ServerAddr string
flagINDIServerAddr string
flagINDIProfile string
flagToken string
flagConfFile string
@ -58,6 +59,12 @@ func init() {
"raspberrypi.local:8624",
"INDI-server Manager address (host:port)",
)
flag.StringVar(
&flagINDIServerAddr,
"indi-server",
"",
"INDI-server address (host:port) to connect without Web Manager",
)
flag.StringVar(
&flagMode,
"mode",
@ -130,17 +137,65 @@ func main() {
indiHubAddr = "localhost:7667" // TODO: change this to optional DEV server
}
if flagINDIServerManagerAddr == "" {
log.Fatal("'indi-server-manager' parameter is missing, the 'host:port' format is expected")
}
indiServerAddr := ""
indiDrivers := []*lib.INDIDriver{}
indiProfile := &lib.INDIProfile{}
if flagINDIServerAddr != "" {
// connect to INDI-server directly without Web Manager
if _, _, err := net.SplitHostPort(flagINDIServerAddr); err != nil {
log.Fatal("Bad syntax for 'indi-server' parameter, the 'host:port' format is expected")
}
log.Println("Will try to connect directly to INDI-server (Web Manager is not used)")
indiProfile.Name = flagINDIServerAddr // to let backend know that no Web Manager was used
indiServerAddr = flagINDIServerAddr
} else {
// connect to INDI-server using info from Web Manager
indiHost, _, err := net.SplitHostPort(flagINDIServerManagerAddr)
if err != nil {
log.Fatal("Bad syntax for 'indi-server-manager' parameter, the 'host:port' format is expected")
}
if flagINDIProfile == "" {
log.Fatal("'indi-profile' parameter is required")
}
indiHost, _, err := net.SplitHostPort(flagINDIServerManagerAddr)
if err != nil {
log.Fatal("Bad syntax for 'indi-server-manager' parameter, the 'host:port' format is expected")
}
// connect to INDI-server Manager
log.Printf("Connection to local INDI-Server Manager on %s...\n", flagINDIServerManagerAddr)
managerClient := manager.NewClient(flagINDIServerManagerAddr)
running, currINDIProfile, err := managerClient.GetStatus()
if err != nil {
log.Fatal(err)
}
log.Println("...OK")
if flagINDIProfile == "" {
log.Fatal("'indi-profile' parameter is required")
// start required profile if it is not active and running
if !running || currINDIProfile != flagINDIProfile {
log.Printf("Setting active INDI-profile to '%s'\n", flagINDIProfile)
if err := managerClient.StopServer(); err != nil {
log.Fatal(err)
}
if err := managerClient.StartProfile(flagINDIProfile); err != nil {
log.Fatal(err)
}
} else {
log.Printf("INDI-server is running with active INDI-profile '%s'\n", flagINDIProfile)
}
// get profile connect data
indiProfile, err = managerClient.GetProfile(flagINDIProfile)
if err != nil {
log.Fatalf("could not get INDI-profile from INDI-server manager: %s", err)
}
indiServerAddr = fmt.Sprintf("%s:%d", indiHost, indiProfile.Port)
// get profile drivers data
indiDrivers, err = managerClient.GetDrivers()
if err != nil {
log.Fatalf("could not get INDI-drivers info from INDI-server manager: %s", err)
}
log.Println("INDIDrivers:")
for _, d := range indiDrivers {
log.Printf("%+v", *d)
}
}
// read token from flag or from config file if exists
@ -151,45 +206,6 @@ func main() {
}
}
// connect to INDI-server Manager
log.Printf("Connection to local INDI-Server Manager on %s...\n", flagINDIServerManagerAddr)
managerClient := manager.NewClient(flagINDIServerManagerAddr)
running, currINDIProfile, err := managerClient.GetStatus()
if err != nil {
log.Fatal(err)
}
log.Println("...OK")
// start required profile if it is not active and running
if !running || currINDIProfile != flagINDIProfile {
log.Printf("Setting active INDI-profile to '%s'\n", flagINDIProfile)
if err := managerClient.StopServer(); err != nil {
log.Fatal(err)
}
if err := managerClient.StartProfile(flagINDIProfile); err != nil {
log.Fatal(err)
}
} else {
log.Printf("INDI-server is running with active INDI-profile '%s'\n", flagINDIProfile)
}
// get profile connect data
indiProfile, err := managerClient.GetProfile(flagINDIProfile)
if err != nil {
log.Fatalf("could not get INDI-profile from INDI-server manager: %s", err)
}
indiServerAddr = fmt.Sprintf("%s:%d", indiHost, indiProfile.Port)
// get profile drivers data
indiDrivers, err := managerClient.GetDrivers()
if err != nil {
log.Fatalf("could not get INDI-drivers info from INDI-server manager: %s", err)
}
log.Println("INDIDrivers:")
for _, d := range indiDrivers {
log.Printf("%+v", *d)
}
// test connect to local INDI-server
log.Printf("Test connection to local INDI-Server on %s...\n", indiServerAddr)
indiConn, err := net.Dial("tcp", indiServerAddr)
@ -228,11 +244,7 @@ func main() {
Os: runtime.GOOS,
Arch: runtime.GOARCH,
}
ccdDrivers := []string{}
for i, driver := range indiDrivers {
if driver.Family == "CCDs" {
ccdDrivers = append(ccdDrivers, driver.Binary)
}
indiHubHost.Drivers[i] = &indihub.INDIDriver{
Binary: driver.Binary,
Family: driver.Family,
@ -295,7 +307,7 @@ func main() {
}
// prepare all modes
soloMode := solo.NewMode(indiHubClient, regInfo, indiServerAddr, ccdDrivers)
soloMode := solo.NewMode(indiHubClient, regInfo, indiServerAddr)
shareMode := share.NewMode(indiHubClient, regInfo, indiServerAddr, flagPHD2ServerAddr, lib.ModeShare)
roboticMode := share.NewMode(indiHubClient, regInfo, indiServerAddr, flagPHD2ServerAddr, lib.ModeRobotic)

View file

@ -11,18 +11,16 @@ type Mode struct {
indiServerAddr string
indiHubClient indihub.INDIHubClient
regInfo *indihub.RegisterInfo
ccdDrivers []string
stopCh chan struct{}
status string
}
func NewMode(indiHubClient indihub.INDIHubClient, regInfo *indihub.RegisterInfo, indiServerAddr string, ccdDrivers []string) *Mode {
func NewMode(indiHubClient indihub.INDIHubClient, regInfo *indihub.RegisterInfo, indiServerAddr string) *Mode {
return &Mode{
indiServerAddr: indiServerAddr,
indiHubClient: indiHubClient,
regInfo: regInfo,
ccdDrivers: ccdDrivers,
stopCh: make(chan struct{}, 1),
}
}
@ -40,7 +38,6 @@ func (s *Mode) Start() {
soloAgent := New(
s.indiServerAddr,
soloClient,
s.ccdDrivers,
)
go func() {

View file

@ -18,8 +18,8 @@ var (
getProperties = []byte("<getProperties version='1.7'/>")
enableBLOB = "<enableBLOB device='%s'>Also</enableBLOB>"
setBLOBVector = []byte("<setBLOBVector")
defTextVector = []byte("<defTextVector")
setBLOBVector = []byte("<setBLOBVector")
defNumberVector = []byte("<defNumberVector")
)
type INDIHubSoloTunnel interface {
@ -31,20 +31,13 @@ type Agent struct {
indiServerAddr string
indiConn net.Conn
tunnel INDIHubSoloTunnel
ccdDrivers map[string]bool
shouldExit bool
}
func New(indiServerAddr string, tunnel INDIHubSoloTunnel, ccdDrivers []string) *Agent {
ccdDriversMap := make(map[string]bool)
for _, d := range ccdDrivers {
ccdDriversMap[d] = true
}
func New(indiServerAddr string, tunnel INDIHubSoloTunnel) *Agent {
return &Agent{
indiServerAddr: indiServerAddr,
tunnel: tunnel,
ccdDrivers: ccdDriversMap,
}
}
@ -67,6 +60,7 @@ func (p *Agent) Start(sessionID uint64, sessionToken string) error {
// listen INDI-server for data
buf := make([]byte, lib.INDIServerMaxSendMsgSize, lib.INDIServerMaxSendMsgSize)
xmlFlattener := lib.NewXmlFlattener()
subscribedCCDs := map[string]bool{}
for {
if p.shouldExit {
break
@ -91,8 +85,8 @@ func (p *Agent) Start(sessionID uint64, sessionToken string) error {
continue
}
// subscribe to BLOBs from CCDs
if !bytes.HasPrefix(xmlCmd, defTextVector) {
// subscribe to BLOBs from CCDs by catching defNumberVector property with name="CCD_EXPOSURE"
if !bytes.HasPrefix(xmlCmd, defNumberVector) {
continue
}
@ -101,28 +95,20 @@ func (p *Agent) Start(sessionID uint64, sessionToken string) error {
log.Println("could not parse XML chunk in solo-mode:", err)
continue
}
defTextVectorMap, _ := mapVal.ValueForKey("defTextVector")
if defTextVectorMap == nil {
defNumberVectorMap, _ := mapVal.ValueForKey("defNumberVector")
if defNumberVectorMap == nil {
continue
}
defTextVectorVal := defTextVectorMap.(map[string]interface{})
defNumberVectorVal := defNumberVectorMap.(map[string]interface{})
if nameStr, ok := defTextVectorVal["attr_name"].(string); ok && nameStr == "DRIVER_INFO" {
if defTextVal, ok := defTextVectorVal["defText"].([]interface{}); ok {
for _, driverInfo := range defTextVal {
driverInfoVal := driverInfo.(map[string]interface{})
if driverNameStr, ok := driverInfoVal["attr_name"].(string); ok && driverNameStr == "DRIVER_EXEC" {
if execText, ok := driverInfoVal["#text"].(string); ok && p.ccdDrivers[execText] {
if deviceStr, ok := defTextVectorVal["attr_device"].(string); ok {
_, err := p.indiConn.Write([]byte(fmt.Sprintf(enableBLOB, deviceStr)))
if err != nil {
log.Printf("could not write to INDI-server in solo-mode: %s\n", err)
}
break
}
}
}
if nameStr, ok := defNumberVectorVal["attr_name"].(string); ok && nameStr == "CCD_EXPOSURE" {
if deviceStr, ok := defNumberVectorVal["attr_device"].(string); ok && !subscribedCCDs[deviceStr] {
_, err := p.indiConn.Write([]byte(fmt.Sprintf(enableBLOB, deviceStr)))
if err != nil {
log.Printf("could not write to INDI-server in solo-mode: %s\n", err)
}
subscribedCCDs[deviceStr] = true
break
}
}
}