Class: PWN::SDR::Decoder::RTL433::AcuriteIQ

Inherits:
Object
  • Object
show all
Defined in:
lib/pwn/sdr/decoder/rtl433.rb

Overview

Native Acurite 609TXC OOK/PPM only. Protocol timing and checksum: https://github.com/merbanan/rtl_433/blob/master/src/devices/acurite.c This is NOT a binding to rtl_433 or support for its entire device catalogue.

Instance Method Summary collapse

Constructor Details

#initialize(rate:, threshold: 0.5) ⇒ AcuriteIQ

Returns a new instance of AcuriteIQ.

Raises:

  • (ArgumentError)


93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/pwn/sdr/decoder/rtl433.rb', line 93

def initialize(rate:, threshold: 0.5)
  @rate = Float(rate)
  raise ArgumentError, 'Acurite requires sample_rate >= 20000' unless @rate.finite? && @rate >= 20_000

  @threshold = Float(threshold)**2
  @smooth = 0.0
  @alpha = 1.0 / [(@rate * 0.000032).round, 1].max
  @level = false
  @run = 0
  @bits = []
  @pulse_valid = false
end

Instance Method Details

#feed_iq(samples, rate: nil) ⇒ Object

Raises:

  • (ArgumentError)


106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/pwn/sdr/decoder/rtl433.rb', line 106

def feed_iq(samples, rate: nil)
  raise ArgumentError, 'sample rate changed midstream' if rate && (rate.to_f - @rate).abs.positive?
  raise ArgumentError, 'interleaved IQ pairs required' unless samples.length.even?

  samples.each_slice(2) do |i, q|
    @smooth += @alpha * (((i * i) + (q * q)) - @smooth)
    level = @smooth >= @threshold * (@level ? 0.8 : 1.2)
    if level != @level
      duration = @run / @rate
      if @level
        @pulse_valid = duration.between?(0.00015, 0.001)
        @bits.clear unless @pulse_valid
      elsif @pulse_valid && duration.between?(0.00065, 0.0025)
        @bits << (duration < 0.0015 ? 0 : 1)
        @bits.clear if @bits.length > 40
      else
        @bits.clear
      end
      @level = level
      @run = 0
    end
    @run += 1
    next if @level || @run != (@rate * 0.003).ceil

    frame = RTL433.parse_frame(bits: @bits)
    yield frame if frame && block_given?
    @bits.clear
    @pulse_valid = false
  end
end

#flushObject



137
138
139
# File 'lib/pwn/sdr/decoder/rtl433.rb', line 137

def flush
  @bits.clear
end