package config import ( "bytes" "encoding/json" "fmt" "io" "text/tabwriter" "github.com/satori/go.uuid" "git.cryptic.systems/fh-trier/go-flucky-server/pkg/types" ) // FluckyConfig dasd type FluckyConfig struct { Device *types.Device `json:"device"` Sensors []*types.Sensor `json:"sensors"` Remotes []*Remote `json:"remotes"` } // AddSensor add a new sensor func (fc *FluckyConfig) AddSensor(sensor *types.Sensor) error { // check if sensorID is a valid UUID string if !validUUID.MatchString(sensor.SensorID) { sensor.SensorID = uuid.NewV4().String() } // check if sensor name and sensor uuid already exists for _, s := range fc.Sensors { if s.SensorName == sensor.SensorName { return fmt.Errorf("Sensor %v already exists", s.SensorName) } if s.SensorID == sensor.SensorID { return fmt.Errorf("Sensor %v with UUID %v already exists", s.SensorName, s.SensorID) } if sensor.WireID != nil && s.WireID == sensor.WireID { return fmt.Errorf("Sensor with 1wire-id %v already exists as %v", s.WireID, s.SensorName) } } fc.Sensors = append(fc.Sensors, sensor) return nil } // AddRemote add a new remote address func (fc *FluckyConfig) AddRemote(remote *Remote) error { // check if remoteID is a valid UUID string if !validUUID.MatchString(remote.RemoteID) { remote.RemoteID = uuid.NewV4().String() } // check if remote name or remiteid already exists for _, r := range fc.Remotes { if r.Name == remote.Name { return fmt.Errorf("Remote %v -> %v already exists", r.Name, r.Address) } if r.RemoteID == remote.RemoteID { return fmt.Errorf("Remote %v with UUID %v already exists", r.Name, r.RemoteID) } } fc.Remotes = append(fc.Remotes, remote) return nil } // DisableRemote disables a remote address by its name or its unique UUID func (fc *FluckyConfig) DisableRemote(nameOrUUID string) error { found := false for _, remote := range fc.Remotes { // disable sensor matched after name if !validUUID.MatchString(nameOrUUID) && remote.Name == nameOrUUID { remote.Enabled = false found = true break } // remove machted uuid if validUUID.MatchString(nameOrUUID) && remote.RemoteID == nameOrUUID { remote.Enabled = false found = true break } } if !found { return fmt.Errorf("Can not found remote name %v", nameOrUUID) } return nil } // DisableSensor disables a sensor by its name or its unique UUID func (fc *FluckyConfig) DisableSensor(nameOrUUID string) error { found := false for _, sensor := range fc.Sensors { // disable sensor matched after name if !validUUID.MatchString(nameOrUUID) && *sensor.SensorName == nameOrUUID { *sensor.SensorEnabled = false found = true break } // remove machted uuid if validUUID.MatchString(nameOrUUID) && sensor.SensorID == nameOrUUID { *sensor.SensorEnabled = false found = true break } } if !found { return fmt.Errorf("Can not found sensor %v", nameOrUUID) } return nil } // EnableRemote enable a remote address by its name or its unique UUID func (fc *FluckyConfig) EnableRemote(nameOrUUID string) error { found := false for _, remote := range fc.Remotes { // disable sensor matched after name if !validUUID.MatchString(nameOrUUID) && remote.Name == nameOrUUID { remote.Enabled = true found = true break } // remove machted uuid if validUUID.MatchString(nameOrUUID) && remote.RemoteID == nameOrUUID { remote.Enabled = true found = true break } } if !found { return fmt.Errorf("Can not found sensor %v", nameOrUUID) } return nil } // EnableSensor enables a sensor by its name or its unique UUID func (fc *FluckyConfig) EnableSensor(nameOrUUID string) error { found := false for _, sensor := range fc.Sensors { // disable sensor matched after name if !validUUID.MatchString(nameOrUUID) && *sensor.SensorName == nameOrUUID { *sensor.SensorEnabled = true found = true break } // remove machted uuid if validUUID.MatchString(nameOrUUID) && sensor.SensorID == nameOrUUID { *sensor.SensorEnabled = true found = true break } } if !found { return fmt.Errorf("Can not found sensor %v", nameOrUUID) } return nil } // JSONDecoder decode a JSON string from a reader into a struct func (fc *FluckyConfig) JSONDecoder(r io.Reader) error { jsonDecoder := json.NewDecoder(r) if err := jsonDecoder.Decode(&fc); err != nil { return fmt.Errorf("Can not unmarshal JSON: %v", err) } return nil } // JSONWriter needs a writer to write the struct into JSON string func (fc *FluckyConfig) JSONWriter(w io.Writer) error { encoder := json.NewEncoder(w) encoder.SetIndent("", " ") err := encoder.Encode(&fc) if err != nil { return fmt.Errorf("Error in encoding struct to json: %v", err) } return nil } // PrintRemotes displays a list with all configured remote addresses func (fc *FluckyConfig) PrintRemotes(w io.Writer) error { tw := tabwriter.NewWriter(w, 0, 0, 3, ' ', 0) fmt.Fprint(tw, "name\taddress\tenabled\tregistered\n") for _, remote := range fc.Remotes { fmt.Fprintf(tw, "%v\t%v\t%v\t%v\n", remote.Name, remote.Address, remote.Enabled, remote.Registered) } tw.Flush() return nil } // PrintSensors displays a list with all configured sensors func (fc *FluckyConfig) PrintSensors(w io.Writer) error { // declar tabwriter tw := tabwriter.NewWriter(w, 0, 0, 3, ' ', 0) fmt.Fprint(tw, "id\tname\tlocation\ttype\twire-id\tgpio\tenabled\n") for _, sensor := range fc.Sensors { fmt.Fprintf(tw, "%v\t%v\t%v\t%v\t%v\t%v\t%v\n", sensor.SensorID, *sensor.SensorName, *sensor.SensorLocation, *sensor.SensorType, *sensor.WireID, *sensor.GPIONumber, *sensor.SensorEnabled) } tw.Flush() return nil } // RemoveSensor deletes a sensor by its name or its unique UUID func (fc *FluckyConfig) RemoveSensor(nameOrUUID string) error { found := false for i, sensor := range fc.Sensors { // remove machted name if !validUUID.MatchString(nameOrUUID) && *sensor.SensorName == nameOrUUID { fc.Sensors = append(fc.Sensors[:i], fc.Sensors[i+1:]...) found = true break } // remove machted uuid if validUUID.MatchString(nameOrUUID) && sensor.SensorID == nameOrUUID { fc.Sensors = append(fc.Sensors[:i], fc.Sensors[i+1:]...) found = true break } } if !found { return fmt.Errorf("Can not find remote %v", nameOrUUID) } return nil } // RemoveRemote deletes a remote address by its name or its unique UUID func (fc *FluckyConfig) RemoveRemote(nameOrUUID string) error { found := false for i, remote := range fc.Remotes { // remove machted name if !validUUID.MatchString(nameOrUUID) && remote.Name == nameOrUUID { fc.Remotes = append(fc.Remotes[:i], fc.Remotes[i+1:]...) found = true } // remove machted uuid if validUUID.MatchString(nameOrUUID) && remote.RemoteID == nameOrUUID { fc.Remotes = append(fc.Remotes[:i], fc.Remotes[i+1:]...) found = true } } if !found { return fmt.Errorf("Can not find remote %v", nameOrUUID) } return nil } // ToJSON returns the struct as JSON string func (fc *FluckyConfig) ToJSON() (string, error) { var b bytes.Buffer err := fc.JSONWriter(&b) if err != nil { return "", err } return b.String(), nil }