3 PyAudio example: Record a few seconds of audio and save to a WAVE
14 FORMAT = pyaudio.paInt32 # Format
15 STRUCTFORMAT = 'i' # Format for python struct module
16 DEVICE = 3 # which alsa decive to read
20 VOLUME_CONSTANT = 132360.98315789475
23 # numid=23,iface=MIXER,name='Capture Volume'
24 # ; type=INTEGER,access=rw---R--,values=2,min=0,max=46,step=0
26 # | dBscale-min=-16.00dB,step=1.00dB,mute=0
29 # https://www.actutem.com/valeur-crete-moyenne-et-efficace-dune-tension-ac/
30 # math.pi/math.sqrt(2)/2 = 1.1107207345395915
32 # Pour 30 A à 230V ( 6900 W )
33 # abs(Sndmax) = 2147483520
34 # Sndavg = 2147483520/math.pi = 683565234.8327662
35 # Sndeff = 683565234.8327662 * 1.1107207345395915 = 759250079.7391784
37 # https://fr.wikipedia.org/wiki/Compteur_%C3%A9lectrique
38 # Mon compteur tourne à une vitesse proportionnelle à la puissance instantanée
40 # https://fr.wikipedia.org/wiki/%C3%89lectricit%C3%A9_domestique#Tension
41 # En france, ERDF fourni 230V EFFICACES (=> 207.0727527161344 moyenne)
43 #raw average: 636207384.4738322 - min: -2147483648 - max: 2147483392
46 def loop(optrecord, optstats):
50 NSAMPLE = int(RATE * RECORD_SECONDS)
51 stream = p.open(format=FORMAT,
52 channels=1, # Our ampmeter always returns 0 on the second channel
55 input_device_index=DEVICE)
57 structformat = '<' + STRUCTFORMAT * NSAMPLE
63 data = stream.read(NSAMPLE, exception_on_overflow=False)
64 values = struct.unpack(structformat, data)
66 #for x in range(100): print('**{:04x}**{}**'.format(values[x], values[x]))
76 avg = float(total) / NSAMPLE
78 print("raw average: {} - min: {} - max: {}".format(avg, minvalue, maxvalue))
79 watts = avg / VOLUME_CONSTANT
80 print("average {:.1f}W ".format(watts), end='\r')
82 #os.system("rrdtool update --daemon /var/run/rrdcached.sock power.rrd N:{}".format(watts))
83 os.system("rrdtool update --daemon /var/run/rrdcached.sock /var/lib/rrdcached/db/power.rrd {}:{}".format(time.time(), watts))
84 except KeyboardInterrupt:
85 print("Received KeyboardInterrupt: exiting")
95 parser = argparse.ArgumentParser(description='Ampemeter processing')
100 help='Dump recording level stats for every chunk',
104 action='store_false',
106 help='Disable recording in RRD file',
109 args = parser.parse_args()
112 print('Recording disabled.')
114 loop(optrecord=args.record, optstats=args.stats)
116 if __name__ == '__main__':