Exemple #1
0
func (w *WeatherStation) getDataWithCRC16(numBytes int64, prompt string) ([]byte, error) {
	var err error

	buf := new(bytes.Buffer)

	if prompt != "" {
		// We'll write to a Buffer and then dump it to the device
		_, err = buf.WriteString(prompt)
		if err != nil {
			return nil, err
		}

		// Write the buffer to the device
		_, err = buf.WriteTo(w.RW)
		if err != nil {
			return nil, err
		}
		w.RW.Flush()

	}

	// We're going to try reading data from the device maxTries times...
	for i := 1; i <= maxTries; i++ {

		// If it's not our first attempt at reading from the console, we send a RESEND command
		// to goad the console into responding.
		if i > 1 {
			_, err = buf.Write([]byte(RESEND))
			if err != nil {
				log.Println("Could not write RESEND command to buffer")
				return nil, err
			}
			// Write the buffer to the console
			_, err = buf.WriteTo(w.RW)
			if err != nil {
				log.Println("Could not write buffer to console")
				return nil, err
			}

			checkBytes := make([]byte, numBytes)

			_, err := w.RW.Read(checkBytes)
			if err != nil {
				return nil, err
			}

			// Do a CRC16 check on data we read and return data if it passes
			if crc16.Crc16(checkBytes) == uint16(0) {
				return checkBytes, nil
			}

			// We didn't pass the CRC check so we loop again.
			log.Println("The data read did not pass the CRC16 check")
		}
	}

	// We failed at reading data from the console
	return nil, fmt.Errorf("Failed to read any data from the console after %v attempts.", maxTries)
}
Exemple #2
0
func (w *WeatherStation) sendDataWithCRC16(d []byte) error {
	var resp []byte

	// We'll write to a Buffer and then dump the buffer to the device
	buf := new(bytes.Buffer)

	check := crc16.Crc16(d)

	// First, write the data
	_, err := buf.Write(d)
	if err != nil {
		return err
	}

	// Next, write the CRC in big-endian order
	err = binary.Write(buf, binary.BigEndian, check)
	if err != nil {
		return err
	}

	for i := 0; i <= maxTries; i++ {
		_, err := buf.WriteTo(w.RW)
		if err != nil {
			return err
		}

		_, err = w.RW.Read(resp)
		if err != nil {
			log.Println("Error reading response:", err)
			return err
		}

		if resp[0] != ACK[0] {
			log.Println("No <ACK> was received from console")
			return nil
		}
	}

	return fmt.Errorf("I/O error writing data with CRC to device.")
}
Exemple #3
0
// GetDavisLoopPackets attempts to initiate a LOOP command against the station and retrieve some packets
func (w *WeatherStation) GetDavisLoopPackets(n int, packetChan chan<- Reading) error {
	// Make a slice of loop packet maps, n elements long.
	//var loopPackets []*LoopPacketWithTrend

	log.Println("Initiating LOOP mode for", n, "packets.")
	// Request n packets
	w.sendData([]byte(fmt.Sprintf("LOOP %v\n", n)))
	w.RW.Flush()

	time.Sleep(1 * time.Second)

	tries := 1

	for l := 0; l < n; l++ {

		time.Sleep(1 * time.Second)

		if tries > maxTries {
			log.Println("Max retries exeeded while getting loop data")
			return nil
		}

		err := w.C.SetReadDeadline(time.Now().Add(5 * time.Second))
		if err != nil {
			log.Println("Error setting read deadline:", err)
		}

		// Read 99 bytes from the console
		buf := make([]byte, 99)
		_, err = w.RW.Read(buf)
		//_, err = io.ReadAtLeast(w.C, buf, 99)
		if err != nil {
			tries++
			log.Printf("Error while reading from console, LOOP %v: %v", l, err)
			return nil
		}

		if buf[95] != 0x0A && buf[96] != 0x0D {
			log.Println("End-of-packet signature not found; rejecting.")
		} else {

			if crc16.Crc16(buf) != 0 {
				log.Printf("LOOP %v CRC error.  Try #%v", l, tries)
				tries++
				continue
			}

			unpacked, err := w.unpackLoopPacket(buf)
			if err != nil {
				tries++
				log.Printf("Error unpacking loop packet: %v.  Try %v", err, tries)
				continue
			}

			tries = 1

			r := convValues(unpacked)

			// Set the timestamp on our reading to the current system time
			r.Timestamp = time.Now()
			r.StationName = w.Config.Device.Name

			packetChan <- r
			//loopPackets = append(loopPackets, unpacked)
		}
	}
	return nil
}