(ITP 4-in-4 day 4+1, or how i learned to stop worrying and love blowing deadlines)
to complete the signal to noise meter previously posted i wrote up an apple script which calculates a ratio of messages in my mail inbox to the junk messages which have been caught. the apple script then sends that ratio via serial to the signal to noise meter. i’ve set up a rule in mail.app to trigger the script every time a message comes in. the serial output (ascii only, it seems) is thanks to SerialPort X.
it’s certainly not perfect…having a lot of read messages stagnating in the inbox brings the ratio down…but i’m posting the code below so maybe someone can figure a better way.
also, the script wasn’t triggering when called directly from mail’s rules…my workaround was to have a launcher script run ‘do shell script “osascript ” signalToNoise.scpt’. for some reason this worked when the launcher script was triggered by mail – YMMV.
oh! it just when off as i was writing this entry…the light came on, and the needle swung high….i need to clean out the junk mail!
code after the break (i always wanted to write “after the break”)
Apple Script Code
Make a new script and copy it to your ~/Library/Scripts folder.
tell application "Mail" set junkCount to unread count of junk mailbox as number set inboxCount to unread count of inbox as number (* this returns a count of all the messages in the inbox *) set inboxMsgs to count messages of inbox (* this returns only the unread count of the inbox *) set total to 0 repeat with mb in mailboxes set total to total + (unread count of mb) as number end repeat (* this will count all the messages *) (* set mailboxMsgs to 0 repeat with mb in mailboxes set mailboxMsgs to mailboxMsgs + (count messages of mb) end repeat *) if inboxMsgs > 0 then set sn to junkCount / (inboxMsgs + junkCount) as number else set sn to 0 end if (* establish the baseline value for the meter *) if sn < 0.3 then set sn to 0.3 end if (* display dialog ("Signal to Noise - " & sn) *) end tell set portName to (item 1 of (serialport list)) set portRef to serialport open portName bps rate 9600 if portRef is equal to -1 then display dialog "Could not open Serial Port: " & portName else delay 2 set sendVal to 10 * sn as integer serialport write sendVal to portRef (* sn should be a ratio *) delay 3 serialport close portRef end if (* this will list all the serial ports available *) (* serialport list *) [/sourcecode] <h3>Arduino code</h3> This is for the meter, specifically, but could be easily updated for other output devices. /* Signal / noise meter 2009 Robert Carlsen // robertcarlsen.net driving a mechanical decibel meter with PWM via Arduino raw analogWrite values: 3 : -4 (bottom of scale) 9 : +6 (top of scale) draws about 1mA at top of scale running through an LED and 220ohm resistor to provide more load and to protect the Arduino from (possible) reverse current as the springs pull the needle past the electromagnet when it's turned off */ int meterPin = 3; byte val; int maxVal = 40; // this is adjusted for the load of the meter, resistor and led int inputMode = 0; int numModes = 3; void setup() { pinMode(meterPin, OUTPUT); Serial.begin(9600); } void loop(){ if(Serial.available()){ val = Serial.read(); Serial.flush(); // change modes if(val == 255){ inputMode = (inputMode + 1) % numModes; val = 0; return; } // allow mode switching. default is to accept ascii 0-9 // second mode is to accept raw bytes 0-254 // third mode echos the received values for testing switch(inputMode){ case 0: // direct input from Serial Monitor // converting ascii values to int for math val = constrain(val,48,57) - 48; // mapping to a useable range val = map(val,0,9,0,maxVal); break; case 1: // input bytes // reserve 255 for changing mode val = map(val,0,254,0,maxVal); break; case 2: // monitor input values Serial.print(val , DEC); break; } } // send value: if(inputMode != 2) analogWrite(meterPin, (int)val); delay(100); }
Leave a Reply
You must be logged in to post a comment.