func main() { log.Println("Started Meter Receiver Server") //Listen to the TCP port for connections from meter readers updatechan := make(chan *MeterReader.CounterUpdate) settingschan := make(chan *MeterReader.Settings) go func() { // drain the channel for settings which we won't need for range settingschan { } }() log.Println("Listening to port 2110 for meter events") listener, err := net.Listen("tcp", "127.0.0.1:2110") if err != nil { log.Fatal(err) } go func() { for { if conn, err := listener.Accept(); err == nil { //If err is nil then that means that data is available for us so we take up this data and pass it to a new goroutine go MeterReader.HandleProtoClient(conn, updatechan, settingschan) } else { continue } } }() // Listen to the serial port go func() { for { serialPorts, err := filepath.Glob("/dev/ttyUSB*") if err == nil { for i := range serialPorts { config := &serial.Config{Name: serialPorts[i], Baud: 57600} ser, err := serial.OpenPort(config) if err != nil { // ok, try the next port } else { log.Printf("Opened port %s", serialPorts[i]) MeterReader.HandleProtoClient(ser, updatechan, settingschan) } } } time.Sleep(time.Second) // try to open again in a second } }() // translate the events from the meters to meter state messages msh := MeterReader.NewMeterStateHandler() tch := msh.Handle(updatechan) // socket.io server log.Println("Starting socket.io server") server, err := socketio.NewServer(nil) if err != nil { log.Fatal(err) } server.On("connection", func(so socketio.Socket) { log.Println("on connection") so.Join("updates") so.On("disconnection", func() { log.Println("on disconnect") }) }) server.On("error", func(so socketio.Socket, err error) { log.Println("error:", err) }) go func() { for msg := range tch { log.Println("JSON to UI:", msg) server.BroadcastTo("updates", "meter update", msg) } }() // serve the user log.Println("Preparing json api") api := MeterReader.MakeAPI() http.Handle("/api/", http.StripPrefix("/api", api.MakeHandler())) http.Handle("/socket.io/", server) http.Handle("/static/", http.StripPrefix("/static", http.FileServer(http.Dir("src/MeterReader/static")))) go func() { log.Println("Listening on port 2111 for http traffic") log.Fatal(http.ListenAndServe(":2111", nil)) }() // stop on SIGINT and SIGTERM ch := make(chan os.Signal) signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) log.Println(<-ch) }
func main() { var serialport = flag.String("serial", "/dev/ttyUSB0", "The serial port to use to connect") var id = flag.Uint("id", math.MaxUint32, "Set the meter id") var seriesId = flag.Uint("series", 0, "Set the series id") var calibrate = flag.Bool("calibrate", false, "Start calibration") var uncalibrate = flag.Bool("uncalibrate", false, "Reset calibration values") var serialProtocol = flag.Bool("serialproto", false, "Use serial communication to transfer updates") var wirelessProtocol = flag.Bool("wirelessproto", false, "Use wireless to transfer updates") var risingEdgeAmounts edgeAmounts var fallingEdgeAmounts edgeAmounts flag.Var(&risingEdgeAmounts, "rising", "Rising edge amount") flag.Var(&fallingEdgeAmounts, "falling", "Falling edge amount") flag.Parse() config := &serial.Config{Name: *serialport, Baud: 57600} // Opening the port resets the device. First the bootloader runs for half a second, then the actual application loads. // Wait for this to happen before attempting to talk to the device. time.Sleep(1 * time.Second) updatechan := make(chan *MeterReader.CounterUpdate) settingschan := make(chan *MeterReader.Settings) go func() { // drain the channel for updates which we won't need for range updatechan { } }() ser, err := serial.OpenPort(config) if err != nil { log.Fatal(err) } go MeterReader.HandleProtoClient(ser, updatechan, settingschan) log.Print("Waiting for current settings") settings := <-settingschan log.Print("Got current settings") MeterReader.PrintSettings(settings) log.Print("id=", *id) changedSettings := false expectSettingsResponse := false if *calibrate { expectSettingsResponse = true MeterReader.SendStartCalibration(ser) } if *id != math.MaxUint32 { changedSettings = true var _id = uint32(*id) settings.MeterId = &_id } if *seriesId != 0 { changedSettings = true var _id = uint32(*seriesId) settings.SeriesId = &_id } if fallingEdgeAmounts.changed || risingEdgeAmounts.changed { if fallingEdgeAmounts.sensors != risingEdgeAmounts.sensors { log.Fatal("Number of rising and falling edge amounts must be the same.") } if fallingEdgeAmounts.sensors > 6 { log.Fatal("Maximum 6 edges allowed.") } settings.FallingEdgeAmounts = fallingEdgeAmounts.amounts settings.RisingEdgeAmounts = risingEdgeAmounts.amounts changedSettings = true } if *uncalibrate { settings.FallingEdgeAmounts = []uint32{0, 0, 0, 0, 0, 0} settings.RisingEdgeAmounts = []uint32{0, 0, 0, 0, 0, 0} changedSettings = true } if *serialProtocol || *wirelessProtocol { if *serialProtocol && *wirelessProtocol { log.Fatal("Can't use both serial and wireless communication protocol.") } var mode MeterReader.Settings_CommunicationChannel if *serialProtocol { mode = MeterReader.Settings_SERIAL } else { mode = MeterReader.Settings_WIRELESS } settings.CommunicationChannel = &mode changedSettings = true } if changedSettings { MeterReader.PrintSettings(settings) MeterReader.SendSettings(ser, settings) expectSettingsResponse = true } if expectSettingsResponse { MeterReader.PrintSettings(<-settingschan) } }