|!Punctuation|!Location|!Function|\n|{{{@@...@@}}}|surrounding text|@@highlighted text@@|\n|{{{//...//}}}|surrounding text|//italicized text//|\n|{{{==...==}}}|surrounding text|==strikethrough text==|\n|{{{''...''}}}|surrounding text|''boldfaced text''|\n|{{{__...__}}}|surrounding text|__underlined text__|\n|{{{[[text|url]]}}}|around text/url pair|[[text|http://gri.gallaudet.edu/]] link to url|\n|{{{ {...} }}}|''__tripled__'' surrounding text|{{{in-line literal text}}}|\n|{{{ {...} }}}|''__tripled__'' surrounding ''__lines__''|literal block|\n|{{{<<<}}}|surrounding ''__lines__''|blockquotes|\n|{{{!}}}|at start of line|subheading|\n|{{{|...|...|}}}|line sectioned by vertical bars|table row|\n|{{{!}}}|in a table|!table heading|\n|{{{----}}}|alone on line|horizontal rule|\n|{{{*}}}|at start of line|bulleted list item|\n|{{{#}}}|at start of line|numbered list item|\nsource: Kevin Cole, January 2007
TTiddlyWiki uses Wiki style markup, a way of lightly "tagging" plain text so it can be transformed into HTML. Edit this Tiddler to see samples.\n\n! Header Samples\n!Header 1\n!!Header 2\n!!!Header 3\n!!!!Header 4\n!!!!!Header 5\n\n! Unordered Lists:\n* Lists are where it's at\n* Just use an asterisk and you're set\n** To nest lists just add more asterisks...\n***...like this\n* The circle makes a great bullet because once you've printed a list you can mark off completed items\n* You can also nest mixed list types\n## Like this\n\n! Ordered Lists\n# Ordered lists are pretty neat too\n# If you're handy with HTML and CSS you could customize the [[numbering scheme|http://www.w3schools.com/css/pr_list-style-type.asp]]\n## To nest, just add more octothorpes (pound signs)...\n### Like this\n* You can also\n** Mix list types\n*** like this\n# Pretty neat don't you think?\n\n! Tiddler links\nTo create a Tiddler link, just use mixed-case WikiWord, or use [[brackets]] for NonWikiWordLinks. This is how the GTD style [[@Action]] lists are created. \n\nNote that existing Tiddlers are in bold and empty Tiddlers are in italics. See CreatingTiddlers for details.\n\n! External Links\nYou can link to [[external sites|http://google.com]] with brackets. You can also LinkToFolders on your machine or network shares.\n\n! Images\nEdit this tiddler to see how it's done.\n[img[http://img110.echo.cx/img110/139/gorilla8nw.jpg]]\n\n!Tables\n|!th1111111111|!th2222222222|\n|>| colspan |\n| rowspan |left|\n|~| right|\n|colored| center |\n|caption|c\n\nFor a complex table example, see PeriodicTable.\n\n! Horizontal Rules\nYou can divide a tiddler into\n----\nsections by typing four dashes on a line by themselves.\n\n! Blockquotes\n<<<\nThis is how you do an extended, wrapped blockquote so you don't have to put angle quotes on every line.\n<<<\n>level 1\n>level 1\n>>level 2\n>>level 2\n>>>level 3\n>>>level 3\n>>level 2\n>level 1\n\n! Other Formatting\n''Bold''\n==Strike==\n__Underline__\n//Italic//\nSuperscript: 2^^3^^=8\nSubscript: a~~ij~~ = -a~~ji~~\n@@highlight@@\n@@color(green):green colored@@\n@@bgcolor(#ff0000):color(#ffffff):red colored@@\n
[[furmon|http://docbox.flint.com:8081/furmon/]]
the site devoted to the furnace monitoring project in conjunction with Pellergy
AMTEL AVR \n\n|!Reference HTML|! Description|\n|[[AMTEL AVR |https://www.google.com/search?client=ubuntu&channel=fs&q=avr+microcontroller&ie=utf-8&oe=utf-8]]||\n|[[AMTEL AVR |http://www.atmel.com/products/microcontrollers/avr/default.aspx]]||\n|[[AMTEL AVR |http://www.atmel.com/products/microcontrollers/avr/tinyavr.aspx]]||\n|[[AMTEL AVR |http://en.wikipedia.org/wiki/Atmel_AVR]]||\n|[[AMTEL AVR JTAG |http://en.wikipedia.org/wiki/JTAG]]||\n|[[AMTEL AVR SPI |http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus]]||\n|[[AVRDUDE |https://www.google.com/search?client=ubuntu&channel=fs&q=AVRDUDE&ie=utf-8&oe=utf-8]]||\n|[[AMTEL AVR AVRDUDE |http://www.nongnu.org/avrdude/]]||\n|[[AMTEL AVR AVRDUDE |http://www.ladyada.net/learn/avr/avrdude.html]]||
[[Pellergy Stove Installation Manual (password protected)|http://docbox.flint.com:8081/furmon/PB-1525%20Installation%20Manual%20V1_0%20%281%29.pdf]]\n[[Current Project Email Dialog|http://docbox.flint.com/~flint/furmon/furmon]]\n[[New Haven Display information|http://docbox.flint.com/~flint/furmon/NHD-0420D3Z-FL-GBW.pdf]]\n
[[overview]]\n[[FurmonSystem]]
Type the text for 'New Tiddler'\n\n|!Reference HTML|! Description|\n|[[reference|http://www.google.com/search?ie=UTF-8&sa=Search&channel=fe&client=browser-ubuntu&q=arduino+ubuntu&hl=en]]||\n|[[reference|http://arduino.cc/playground/Linux/Ubuntu]]||\n|[[reference|http://arduino.cc/en/Main/Software]]||\n|[[reference|http://arduino.cc/en/Guide/HomePage]]||\n|[[reference|http://www.arduino.cc/playground/Learning/Linux]]||\n|[[reference|http://arduino.cc/playground/Linux/Ubuntu]]||\n|[[reference|http://arduino.cc/playground/]]||\n
sudo apt-get install lighttpd
sudo apt-get install sqlite
[[uptimescript]]
after Lighttpd and PHP are installed then save this file as /var/www/uptime.php and goto [[http://localhost/uptime.php|http://localhost/uptime.php]]\n\n@@\n<meta http-equiv="refresh" content="1">\n<?php\nfunction linuxUptime() {\n $ut = strtok( exec( "cat /proc/uptime" ), "." );\n $days = sprintf( "%2d", ($ut/(3600*24)) );\n $hours = sprintf( "%2d", ( ($ut % (3600*24)) / 3600) );\n $min = sprintf( "%2d", ($ut % (3600*24) % 3600)/60 );\n $sec = sprintf( "%2d", ($ut % (3600*24) % 3600)%60 );\n return array( $days, $hours, $min, $sec );\n}\n\n$ut = linuxUptime();\n\necho "Time since last reboot: $ut[0] days, $ut[1] hours, $ut[2] minutes, $ut[3] seconds";\n?>\n@@
{{{sudo apt-get install php5 php5-sqlite php5-auth-pam}}}
''login.php''\n@@\n<form name="input" action="auth.php" method="post">\n\n Username: <input type="text" name="uname" /><br />\n\n Password: <input type="password" name="pswd" />\n\n <input type="submit" value="Submit" />\n\n</form>\n@@\n\n\n''auth.php''\n\n@@\n\n<?php\n\n$uname = $_POST['uname'];\n\n$pswd = $_POST['pswd'];\n\nif ( pam_auth( $uname, $pswd, &$error ) ) {\n\n echo "You are authenticated!";\n\n} \n\nelse {\n\n echo $error;\n\n}\n\n?>\n@@\n\nbe sure to do a \n{{{sudo chgrp www-data /etc/shadow}}}\n\nor else authentication WILL fail.
!The USB Pinout:\n|!Pin|!Name|!Cable color|!Description|\n|1|VCC|Red|+5 VDC|\n|2|D-|White |Data -|\n|3|D+|Green|Data +|\n|4|GND|Black|Ground|
[[AVR]]
Christopher P. Yarger\n(802) 839-5270\ncpyarger@gmail.com
Using BASH to make repetitive tasks easier\n\n[[Bash Scripting Guide|http://tldp.org/LDP/abs/html/]]
''DEFINITION''\nThose attributes or characteristics of a system that are considered critical or essential to the development of an effective military capability. A KPP normally has a threshold, representing the required value, and an objective, representing the desired value. KPPs are contained in the Capability Development Document (CDD) and the Capability Production Document (CPD) and are included verbatim in the Acquisition Program Baseline (APB). Certain KPPs may be "mandatory" or "selectively applied," depending on the system. See Validation Authority, Capability Development Document, Capability Production Document, Mandatory Key Performance Parameters (KPPs), Selectively Applied KPPs, threshold value, objective value, and Joint Potential Designator.\n\n\nsource:[[https://acc.dau.mil/ILC_KPP|https://acc.dau.mil/ILC_KPP]]
http://oss.oetiker.ch/rrdtool/
\n*input Voltage - 20V DC -->DC2DC transformer --> 5vDC\n\n''WARNING: --- DO NOT SEND ANY VOLTAGE TO THE AM-TEL CHIP, IT IS PROGRAMMED TO AUTOMATICALLY WIPE ITSELF CLEAN''
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
So the furmon is as old as some children.\n\nWhen you start ''fm.py -s'' you get this:\n{{{\nstarting bin/fm.py at 2015-02-18 07:49:54 \nYou are at the serial routine\nUsing serial data from /dev/ttyUSB0 at 9600 bits per second, with a 6 second time out factor\nGot past open. Press Ctrl+C to interrupt block read\nPress Ctrl+C for interrupt\nyou are in dofile routine about to read the file\n}}}\n\nThe output we need suppress is:\n{{{\ndfscript function is done\nchmod +x start ./test.sh\nexecute script start\n0 is bin/outpcp.sh\nNumber of Arguments are 6\nopstate:Status=shuttingdown Resets:Resets=0000 stack_temp:System=186 stack_temp:Stack=613 state_counter:countdown=000 Call:Call=\nThis starts the changes arguments must be in pairs, target:change\nopstate:Status=shuttingdown Resets:Resets=0000 stack_temp:System=186 stack_temp:Stack=613 state_counter:countdown=000 Call:Call=\nNext change opstate Status=shuttingdown\nNext change Resets Resets=0000\nNext change stack_temp System=186\nNext change stack_temp Stack=613\nNext change state_counter countdown=000\nNext change Call Call=\nthe difference between these strings is\n}}}\n\nThe latest change involves the way we are reading data. Yarger says to use read() function as opposed to the readline() function. The code involves the following:\n(start around line 350)\n{{{\n#\ndef rfdl(dfile):\n ''' read data line'''\n dataline=dfile.readline()\n line=re.split("\sxfeE",dataline)\n # print line\n # out = open(options.filename,'a')\n if dataline == '': \n dataline = "EOF"\n return line\n#\n}}}\n\nThis is a bit more to the point\n(around line 453)\n{{{\n#\ndef dorserial():\n ''' loop display of raw serial data '''\n mser=otrs()\n # print 'Press Ctrl+C for interrupt'\n i = 0\n while True:\n i += 1\n tada=rsdl(mser) # using rdsl with a pointer to otrs to read data into tada\n if (len(tada) > 30):\n print tada \n # dfout(tada)\n # print(systmp(tada))\n # print(timest(tada))\n else:\n # print len(tada) \n 'Block %d is and underrun with only %d elements. Press Ctrl+C to interrupt ' % (i,len(tada) )\n print 'At %s Block %d is %d elements long. Press Ctrl+C to interrupt ' % (timest(tada),i,len(tada) )\n#\n#\ndef doserial():\n ''' load serial data into attributes '''\n mser=otrs()\n print 'Press Ctrl+C for interrupt'\n print "you are in dofile routine about to read the file"\n status="undefined"\n i = 0\n #d while ( i < 8 ): # for run limit in debug mode...\n while True:\n i += 1 # count for run limit\n b = 1\n dataline=rsdl(mser) # assumes open file with pointer to dline \n #d print dataline\n while ( b < len(dataline)):\n os.system('clear')\n if ( len(dataline[b]) < 50 ): # sets allowable element length\n l=dataline[b] \n serial.system_temp = systmp(l)\n # print systmp(l)\n starts(l)\n serial.stack_temp = stacktmp(l)\n serial.hours = ophours(l)\n serial.opstate = opstate(l) \n serial.thstcall = thstcall(l) \n resets(l) \n serial.recno = i\n # outfile1() \n # outfile() \n print 'in line %d' % (b)\n # expose(frfile) #really good object dumpter\n # dfout()\n # dfdisk()\n # dfscript()\n dfscript("test.sh") #cpy grabbed from dofile\n os.system('sleep 0.25s')\n # os.system('clear')\n b += 1\n\n i += 1\n tada=rsdl(mser) # using rdsl with a pointer to otrs to read data into tada\n if (len(tada) > 30):\n print tada \n # dfout(tada)\n # print(systmp(tada))\n # print(timest(tada))\n else:\n # print len(tada) \n 'Block %d is and underrun with only %d elements. Press Ctrl+C to interrupt ' % (i,len(tada) )\n print 'At %s Block %d is %d elements long. Press Ctrl+C to interrupt ' % (timest(tada),i,len(tada) )\n#\n}}}
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Type the text for 'New Tiddler'
Introduction\nI own a Pellergy Pellet furnace system and while I have not disassembled by burner (it has been cold :^). I am interested in monitoring the system which uses an AMTEL AVR system as the processing platform. \nThink of this web monitor project as manifest in two pieces:\n1. A special cable maybe USB on one end and a 2.5 mm audio jack \n2. A bootable CD that contains all you need to access Pellergy data and \n Display it via the web (think MRTG).\n\nTo install, you get a comodity PC (possibly from a junk pile) put the CD in, plug the cable between the Pellergy system and the PC apply power and walk away.\n\nThis project should be an open source project. \n\nImplementation \nI am very happy with the open provenance of the AMTEL line, and their relationship with the Arduino movement. However, rather than burden the system with additional code, Andy Boutin and I discussed the possibility of attaching a spare buffer to the line driving the display. In the initial concept, we would "wiretap" the serial data going to the display and feed this into a ring buffer on an external Intel box running some OS'ix variant. This external system and buffer would be responsible to programmatic-ally acquire data from the serial connection. \nIn the case of a JTAG interface, I would suppose that monitoring TDO (Test Data Out) \n\nThe Wiretap Concept\nThe goal is to listen to your controller as it transmits data going to the LCD display process and reflect this data onto the web. A simple "wiretap therefore would get me access to all the system data I need. \n\nDeveloping the use of the JTAG or SPI adapters would be good, but this approcah could require a new development and test cycle on the Pellergy platform. \n\nIf such a 'wiretap' of the data being transmitted from the AVR to the LCD is a reasonable approach. Several factors are of concern: \n1. The TDO is a synchronous serial data stream Andy estimated at 9600 bps.\n How can I reliably capture this data stream and direct it to a DE9 or a\n USB port? \n2. How opaque is the display protocol that places the information on the display? \n3. What is the make model and serial number of the LCD display?\n4. How can I electrically buffer this interface such that any outside signal would \n merely damage some open drain NAND gate and not whack either the AVR or the LCD?\n\nThis cheap vision involves adding the following:\n1. An extra open drain buffer for the serial out \n2. A small hole in the bezel area for the 2.5 mm audio plug.\n\nDevelopment \nSince the signal going to the [[New Haven Display]] is Serial Asynchronous, 9600. \nbut this signal is at (0-+5) TTL levels ("RS-232 like"), the goal would be to try \nthe DE-9 currently hanging off the back a "Junk" class computerwhich are often capable of \nAsynchronous communications at 0-+5 logic level signaling, and are, by nature, very\nhigh impedance inputs. Thus a test of this concept could be done as a wiretap bridge\n\noff the line at the display from the following pins:\nIntroduction\nI own a Pellergy Pellet furnace system and while I have not disassembled by burner (it has been cold :^). I am interested in monitoring the system which uses an AMTEL AVR system as the processing platform. \nThink of this web monitor project as manifest in two pieces:\n1. A special cable maybe USB on one end and a 2.5 mm audio jack \n2. A bootable CD that contains all you need to access Pellergy data and \n Display it via the web (think MRTG).\n\nTo install, you get a comodity PC (possibly from a junk pile) put the CD in, plug the cable between the Pellergy system and the PC apply power and walk away.\n\nThis project should be an open source project. \n\nImplementation \nI am very happy with the open provenance of the AMTEL line, and their relationship with the Arduino movement. However, rather than burden the system with additional code, Andy Boutin and I discussed the possibility of attaching a spare buffer to the line driving the display. In the initial concept, we would "wiretap" the serial data going to the display and feed this into a ring buffer on an external Intel box running some OS'ix variant. This external system and buffer would be responsible to programmatic-ally acquire data from the serial connection. \nIn the case of a JTAG interface, I would suppose that monitoring TDO (Test Data Out) \n\nThe Wiretap Concept\nThe goal is to listen to your controller as it transmits data going to the LCD display process and reflect this data onto the web. A simple "wiretap therefore would get me access to all the system data I need. \n\nDeveloping the use of the JTAG or SPI adapters would be good, but this approcah could require a new development and test cycle on the Pellergy platform. \n\nIf such a 'wiretap' of the data being transmitted from the AVR to the LCD is a reasonable approach. Several factors are of concern: \n1. The TDO is a synchronous serial data stream Andy estimated at 9600 bps.\n How can I reliably capture this data stream and direct it to a DE9 or a\n USB port? \n2. How opaque is the display protocol that places the information on the display? \n3. What is the make model and serial number of the LCD display?\n4. How can I electrically buffer this interface such that any outside signal would \n merely damage some open drain NAND gate and not whack either the AVR or the LCD?\n\nThis cheap vision involves adding the following:\n1. An extra open drain buffer for the serial out \n2. A small hole in the bezel area for the 2.5 mm audio plug.\n\nDevelopment \nSince the signal going to the [[New Haven Display]] is Serial Asynchronous, 9600. \nbut this signal is at (0-+5) TTL levels ("RS-232 like"), the goal would be to try \nthe DE-9 currently hanging off the back a "Junk" class computerwhich are often capable of \nAsynchronous communications at 0-+5 logic level signaling, and are, by nature, very\nhigh impedance inputs. Thus a test of this concept could be done as a wiretap bridge\n\noff the line at the display from the following pins:\n\nPin 1 RS232 Serial input port\nPin 2 Ground\n \nThese would be wired to a DE9 Female Connector on the following pins: \nPin 2 Serial input \nPin 5 Ground\n\nPlease see this diagram as a reference... \nhttp://docbox.flint.com:8081/tsp/#RS232connector\nNote that this is to the TSP project, and I will modify it to this project\ndirectly.\n\nOur first shot out of the box would be to run minicom in Linux or\nHpyerterm in Window$ and see what we get.\n\nIn the production version of this I would simply add a gate of some type\nas a line buffer, especially if there are any spares on the board.\n\n\n\nPin 1 RS232 Serial input port\nPin 2 Ground\n \nThese would be wired to a DE9 Female Connector on the following pins: \nPin 2 Serial input \nPin 5 Ground\n\nPlease see this diagram as a reference... \nhttp://docbox.flint.com:8081/tsp/#RS232connector\nNote that this is to the TSP project, and I will modify it to this project\ndirectly.\n\nOur first shot out of the box would be to run minicom in Linux or\nHpyerterm in Window$ and see what we get.\n\nIn the production version of this I would simply add a gate of some type\nas a line buffer, especially if there are any spares on the board.\n\n\n
! Furmon\n# [[Development|furmonDevel]]\n# [[Test|furmonTest]]\n# [[Production|furmonProd]]\n\nYarger under Flint and Boutin's direction and supervision, has been working on Pellergy's furnace monitoring project, \nthe system shall be comprised of the following software elements:\n\n* A copy of Ubuntu server installed via the Ubuntu mini.iso minimal net install CD.\n*[[Lighttpd]] \n* Apache2 web server.\n*[[MRTG|http://oss.oetiker.ch/mrtg/]]\n**Takes data and graphs it.\n*** Uptime\n*** Burn time\n*** Usage\n*** Stack Temp\n*** Ambient Temp\n*** ...\n** Uses [[RRDtool|http://oss.oetiker.ch/rrdtool/]] as a database\n***RRDtool is the Open Source industry standard, high performance data logging and graphing system for time series data. RRDtool can be easily integrated in shell scripts, perl, python, ruby, lua or tcl applications.\nkeep an eye on http://oss.oetiker.ch/ for further updates to the two above tools\n\nThe product works by [[Tap]]ping into the data flowing from the amtel chip to the New Haven Data display. This is a serial stream, and eventually will be available initially as an [[RS-232|http://en.wikipedia.org/wiki/RS-232]] signal and ultimately as a [[USB interface|FurmonUSB]]\n\n[[Pellergy|http://www,pellergy.com]] [[ISO interface model|http://en.wikipedia.org/wiki/OSI_model]] \nspecifics:\n[[Layer 1: physical layer|furmon1]]\n[[Layer 2: data link layer|furmon2]]\n[[Layer 3: network layer|furmon3]]\n[[Layer 4: transport layer|furmon4]]\n[[Layer 5: session layer|furmon5]]\n[[Layer 6: presentation layer|furmon6]]\n[[Layer 7: application layer|furmon7]]\n
[[Furmon Project managment|https://launchpad.net/furmon]]\n\n*Key Performance Parameters(KPPs)\n**Work by Winter\n**Display graphs of furnace data\n**Minimal Downtime
[[Sample of current information panel|http://docbox.flint.com/~flint/furmon/Pellergy_Control_For_Furmon_Site.html]]\n\nIntroduction\nI own a Pellergy Pellet furnace system and I am interested in monitoring the system which uses an AMTEL AVR system as the processing platform, and a New Haven Display Liquid Crystal Display (LCS) for status output display.\n \nThink of this web monitor project as manifest in two pieces:\n1. A special serial cable (maybe USB) on one end and a 2.5 mm audio jack on the other that plugs into a mating 2.5 mm plug on the modified controller module. \n2. A bootable CD that contains all you need to access Pellergy data and \n Display it via the web (think [[MRTG|http://oss.oetiker.ch/mrtg/]]).\n\nTo install, you get a commodity PC (possibly from a junk pile). Put the CD in, plug the cable between the Pellergy system and the PC apply power and walk away.\n\nThis project shall be an open source project. \n\nImplementation \nI am very happy with the open provenance of the AMTEL line, and their relationship with the Arduino movement. However, rather than burden the system with additional code, Andy Boutin of Pellergy and I discussed the possibility of attaching a spare buffer to the line driving the display. In the initial concept, we would "wiretap" the serial data going to the display and feed this into a ring buffer on an external Intel box running some OS'ix variant. This external system and buffer would be responsible to programmatic-ally acquire data from the serial connection. \nIn the case of a "JTAG" interface, I would suppose that monitoring TDO (Test Data Out) \n\nThe Wiretap Concept\nThe goal is to listen to your controller as it transmits data going to the LCD display process and reflect this data onto the web. A simple "wiretap therefore would get me access to all the system data I need. \n\n[img[http://docbox.flint.com/~flint/furmon/furmon1.gif]]\n\nDeveloping the use of the JTAG or SPI adapters would be good, but this approcah could require a new development and test cycle on the Pellergy platform. \n\nIf such a 'wiretap' of the data being transmitted from the AVR to the LCD is a reasonable approach. Several factors are of concern: \n1. The TDO is a synchronous serial data stream Andy estimated at 9600 bps.\n How can I reliably capture this data stream and direct it to a DE9 or a\n USB port? \n2. How opaque is the display protocol that places the information on the display? \n3. What is the make model and serial number of the LCD display?\n4. How can I electrically buffer this interface such that any outside signal would \n merely damage some open drain NAND gate and not whack either the AVR or the LCD?\n\nThis cheap vision involves adding the following:\n1. An extra open drain buffer for the serial out \n2. A small hole in the bezel area for the 2.5 mm audio plug.\n\nDevelopment \nSince the signal going to the [[New Haven Display]] is Serial Asynchronous, 9600. \nbut this signal is at (0-+5) TTL levels ("RS-232 like"), the goal would be to try \nthe DE-9 currently hanging off the back a "Junk" class computerwhich are often capable of \nAsynchronous communications at 0-+5 logic level signaling, and are, by nature, very\nhigh impedance inputs. Thus a test of this concept could be done as a wiretap bridge\n\noff the line at the display from the following pins:\nIntroduction\nI own a Pellergy Pellet furnace system and while I have not disassembled by burner (it has been cold :^). I am interested in monitoring the system which uses an AMTEL AVR system as the processing platform. \nThink of this web monitor project as manifest in two pieces:\n1. A special cable maybe USB on one end and a 2.5 mm audio jack \n2. A bootable CD that contains all you need to access Pellergy data and \n Display it via the web (think MRTG).\n\nTo install, you get a comodity PC (possibly from a junk pile) put the CD in, plug the cable between the Pellergy system and the PC apply power and walk away.\n\nThis project should be an open source project. \n\nImplementation \nI am very happy with the open provenance of the AMTEL line, and their relationship with the Arduino movement. However, rather than burden the system with additional code, Andy Boutin and I discussed the possibility of attaching a spare buffer to the line driving the display. In the initial concept, we would "wiretap" the serial data going to the display and feed this into a ring buffer on an external Intel box running some OS'ix variant. This external system and buffer would be responsible to programmatic-ally acquire data from the serial connection. \nIn the case of a JTAG interface, I would suppose that monitoring TDO (Test Data Out) \n\nThe Wiretap Concept\nThe goal is to listen to your controller as it transmits data going to the LCD display process and reflect this data onto the web. A simple "wiretap therefore would get me access to all the system data I need. \n\nDeveloping the use of the JTAG or SPI adapters would be good, but this approcah could require a new development and test cycle on the Pellergy platform. \n\nIf such a 'wiretap' of the data being transmitted from the AVR to the LCD is a reasonable approach. Several factors are of concern: \n1. The TDO is a synchronous serial data stream Andy estimated at 9600 bps.\n How can I reliably capture this data stream and direct it to a DE9 or a\n USB port? \n2. How opaque is the display protocol that places the information on the display? \n3. What is the make model and serial number of the LCD display?\n4. How can I electrically buffer this interface such that any outside signal would \n merely damage some open drain NAND gate and not whack either the AVR or the LCD?\n\nThis cheap vision involves adding the following:\n1. An extra open drain buffer for the serial out \n2. A small hole in the bezel area for the 2.5 mm audio plug.\n\nDevelopment \nSince the signal going to the [[New Haven Display]] is Serial Asynchronous, 9600. \nbut this signal is at (0-+5) TTL levels ("RS-232 like"), the goal would be to try \nthe DE-9 currently hanging off the back a "Junk" class computerwhich are often capable of \nAsynchronous communications at 0-+5 logic level signaling, and are, by nature, very\nhigh impedance inputs. Thus a test of this concept could be done as a wiretap bridge\n\noff the line at the display from the following pins:\n\nPin 1 RS232 Serial input port\nPin 2 Ground\n \nThese would be wired to a DE9 Female Connector on the following pins: \nPin 2 Serial input \nPin 5 Ground\n\nPlease see this diagram as a reference... \nhttp://docbox.flint.com:8081/tsp/#RS232connector\nNote that this is to the TSP project, and I will modify it to this project\ndirectly.\n\nOur first shot out of the box would be to run minicom in Linux or\nHpyerterm in Window$ and see what we get.\n\nIn the production version of this I would simply add a gate of some type\nas a line buffer, especially if there are any spares on the board.\n\n\n\nPin 1 RS232 Serial input port\nPin 2 Ground\n \nThese would be wired to a DE9 Female Connector on the following pins: \nPin 2 Serial input \nPin 5 Ground\n\nPlease see this diagram as a reference... \nhttp://docbox.flint.com:8081/tsp/#RS232connector\nNote that this is to the TSP project, and I will modify it to this project\ndirectly.\n\nOur first shot out of the box would be to run minicom in Linux or\nHpyerterm in Window$ and see what we get.\n\nIn the production version of this I would simply add a gate of some type\nas a line buffer, especially if there are any spares on the board.\n\n\n
! Furmon\n# [[Development|furmonDevel]]\n# [[Test|furmonTest]]\n# [[Production|furmonProd]]\n\nYarger under Flint and Boutin's direction and supervision, has been working on Pellergy's furnace monitoring project, \nthe system shall be comprised of the following software elements:\n\n* A copy of Ubuntu server installed via the Ubuntu mini.iso minimal net install CD.\n*[[Lighttpd]] \n* Apache2 web server.\n*[[MRTG|http://oss.oetiker.ch/mrtg/]]\n**Takes data and graphs it.\n*** Uptime\n*** Burn time\n*** Usage\n*** Stack Temp\n*** Ambient Temp\n*** ...\n** Uses [[RRDtool|http://oss.oetiker.ch/rrdtool/]] as a database\n***RRDtool is the Open Source industry standard, high performance data logging and graphing system for time series data. RRDtool can be easily integrated in shell scripts, perl, python, ruby, lua or tcl applications.\nkeep an eye on http://oss.oetiker.ch/ for further updates to the two above tools\n\nThe product works by [[Tap]]ping into the data flowing from the amtel chip to the New Haven Data display. This is a serial stream, and eventually will be available initially as an [[RS-232|http://en.wikipedia.org/wiki/RS-232]] signal and ultimately as a [[USB interface|FurmonUSB]]\n\n[[Pellergy|http://www,pellergy.com]] [[ISO interface model|http://en.wikipedia.org/wiki/OSI_model]] \nspecifics:\n[[Layer 1: physical layer|furmon1]]\n[[Layer 2: data link layer|furmon2]]\n[[Layer 3: network layer|furmon3]]\n[[Layer 4: transport layer|furmon4]]\n[[Layer 5: session layer|furmon5]]\n[[Layer 6: presentation layer|furmon6]]\n[[Layer 7: application layer|furmon7]]\n
|!Pin No. | !Symbol | !Function Description|\n|1 | RX| RS232 Serial input port|\n|2 | VSS| Ground |\n|3 | VDD| Power supply for logic (+5.0V) |\n\n\n\n \n\n
Flint wants to hook the NHD to the Arduino, I can take a look into hooking it into the serial recieve port and having the serial receive send the data back to the computer, basically an echo, after that It will be possible to take that data, filter out the unnecessary bits and log it, until I learn multiplexing this will cut off the ability to send data to the Arduino from the computer. \n\neventually I want to send a single line of CSV Data back to the computer from the Arduino, \n
Here is the Python code so far for the furmon\n\n{{{\n#!/usr/bin/python\n# -*- coding: utf-8 -*-\nimport time\nimport os\nimport serial\nimport io\nimport csv\nimport sys\nimport MySQLdb\nfrom subprocess import call\n\n# Connect to Mysql DB\n\n\nportread = os.system("dmesg |grep ttyACM |tail -n 1|cut -d : -f3")\n\n# Open connection to the arduino, \nport = "/dev/ttyACM" + str(portread)\n #now = datetime.datetime.now()\nser = serial.Serial(port, 9600, timeout=5) \n\n#open connection to the arduino\n#sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser)) # clear buffering get the data out *now*\n#sio.flush()\ntime.sleep(.75) # Give the buffer time to clear \n#line3 = ser.readline()\nclearline = ser.readline() # read a '\sn' terminated line1 usually the one line with misformatted text\ndataline = ser.readline() # read a '\sn' terminated line4\nser.close() \n#print (line1), ('line1')\n\nfilewrite = open("test.cap", "rw+")\nline = filewrite.write( dataline )\nline2 = filewrite.write( clearline )\n\nfilewrite.close()\n\nstrings = os.system("strings test.cap > strings.a")\ntemp = os.system("")\nfileread = open ("strings.a", "r")\n\nprint (fileread.read())\nfileread.close()\n\ntemp = os.system("cat strings.a |grep EF |cut -c 3- > temp ")\nstarts = os.system("cat strings.a |grep Starts > starts ")\nidle = os.system("cat strings.a |grep Idle > Idle ")\nhours = os.system("cat strings.a |grep Hours > Hours")\nresets = os.system("cat strings.a |grep Resets > resets ")\n}}}\nMore will follow later
Here is the last revision of my python code for the day\n\n{{{\n#!/usr/bin/python\n# -*- coding: utf-8 -*-\nimport time\nimport os\nimport serial\nimport io\nimport csv\nimport sys\nimport MySQLdb\nfrom subprocess import call\n\n# Connect to Mysql DB\n\n\nportread = os.system("dmesg |grep ttyACM |tail -n 1|cut -d : -f3")\n\n# Open connection to the arduino, \nport = "/dev/ttyACM" + str(portread)\n #now = datetime.datetime.now()\nser = serial.Serial(port, 9600, timeout=5) \n\n#open connection to the arduino\n#sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser)) # clear buffering get the data out *now*\n#sio.flush()\ntime.sleep(.75) # Give the buffer time to clear \n#line3 = ser.readline()\nclearline = ser.readline() # read a '\sn' terminated line1 usually the one line with misformatted text\ndataline = ser.readline() # read a '\sn' terminated line4\nline3 = ser.readline() # read a '\sn' terminated line4\nline4 = ser.readline() # read a '\sn' terminated line4\nline5 = ser.readline() # read a '\sn' terminated line4\n\n\nser.close() \n#print (line1), ('line1')\n\nfilewrite = open("test.cap", "rw+")\nline = filewrite.write( dataline )\nline2 = filewrite.write( clearline )\nline3 = filewrite.write( line3 )\nline4 = filewrite.write( line4 )\nline5 = filewrite.write( line5 )\nfilewrite.close()\n\nstrings = os.system("strings test.cap > strings.a")\ntemp = os.system("")\nfileread = open ("strings.a", "r")\n\nprint (fileread.read())\nfileread.close()\n\ntemp = os.system("cat strings.a |grep EF |cut -c 3- > ./data/temperature ")\nstarts = os.system("cat strings.a |grep Starts > ./data/starts ")\nidle = os.system("cat strings.a |grep Idle > ./data/idle ")\nhours = os.system("cat strings.a |grep Hours > ./data/hours")\nresets = os.system("cat strings.a |grep Resets > ./data/resets ")\nthh = os.system("cat strings.a |grep THH |cut -c 6- > ./data/thh ")\ntht = os.system("cat strings.a |grep THT |cut -c 6- > ./data/tht ")\n}}}\n\nMore tomorrow
{{{\n\n#!/usr/bin/python\n# -*- coding: utf-8 -*-\nimport time\nimport os\nimport serial\nimport io\nimport csv\nimport sys\nimport MySQLdb\nfrom subprocess import call\n\n# Connect to Mysql DB\n\n\nportread = os.system("dmesg |grep ttyACM |tail -n 1|cut -d : -f3")\n\n# Open connection to the arduino, \nport = "/dev/ttyACM" + str(portread)\n #now = datetime.datetime.now()\nser = serial.Serial(port, 9600, timeout=5) \n\n#open connection to the arduino\n#sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser)) # clear buffering get the data out *now*\n#sio.flush()\ntime.sleep(.75) # Give the buffer time to clear \n#line3 = ser.readline()\nclearline = ser.readline() # read a '\sn' terminated line1 usually the one line with misformatted text\ndataline = ser.readline() # read a '\sn' terminated line4\nline3 = ser.readline() # read a '\sn' terminated line4\nline4 = ser.readline() # read a '\sn' terminated line4\nline5 = ser.readline() # read a '\sn' terminated line4\n\n\nser.close() \n#print (line1), ('line1')\n\nfilewrite = open("load.cap", "rw+")\nline = filewrite.write( dataline )\nline2 = filewrite.write( clearline )\nline3 = filewrite.write( line3 )\nline4 = filewrite.write( line4 )\nline5 = filewrite.write( line5 )\nfilewrite.close()\n\nstrings = os.system("strings load.cap > strings.a")\ntemp = os.system("")\nfileread = open ("strings.a", "r")\n\nprint (fileread.read())\nfileread.close()\n\ntemp = os.system("cat strings.a |grep EF |cut -c 3-8|tail -n1 |tr -d '\sn'> ./data/temperature ")\nstarts = os.system("cat strings.a |grep Starts |cut -c 9-13 |tail -n1|tr -d '\sn'> ./data/starts ")\nidle = os.system("cat strings.a |grep Idle |tail -n1 |tr -d '\sn'> ./data/idle ")\nhours = os.system("cat strings.a |grep Hours |tail -n1 |cut -c 9-13|tr -d '\sn'> ./data/hours")\nresets = os.system("cat strings.a |grep Resets |tail -n1| cut -c 9-13|tr -d '\sn'> ./data/resets ")\nthh = os.system("cat strings.a |grep THH |tail -n1|cut -c 6-11 |tr -d '\sn'> data/thh")\ntht = os.system("cat strings.a |grep THT |cut -c 6-11 |tail -n1 |tr -d '\sn' > ./data/tht ")\n\nthh2 = open("data/thh", "r")\ntht2 = open("data/tht", "r")\nstarts2 = open("data/starts", "r")\ntemp2 = open("data/temperature", "r")\nidle2 = open("data/idle", "r")\nhours2 = open("data/hours", "r")\nresets2 = open("data/resets", "r")\n\ncosm = open("cosm2.json", "rw+")\ncline1 = cosm.write("{ \sn") \ncline2 = cosm.write(' "version":"1.0.0", \sn')\ncline3 = cosm.write(' "datastreams":[\sn') \ncline4 = cosm.write(' {"id":"temp", "current_value":"'+temp2.read()+'"},\sn') \ncline5 = cosm.write(' {"id":"starts", "current_value":"'+starts2.read()+'"},\sn') \ncline6 = cosm.write(' {"id":"idle", "current_value":"'+idle2.read()+'"},\sn') \ncline7 = cosm.write(' {"id":"hours", "current_value":"'+hours2.read()+'"},\sn')\ncline8 = cosm.write(' {"id":"resets", "current_value":"'+resets2.read()+'"},\sn') \ncline9 = cosm.write(' {"id":"thh", "current_value":"'+thh2.read()+'"},\sn') \ncline10 = cosm.write(' {"id":"tht", "current_value":"'+tht2.read()+'"}\sn') \ncline11 = cosm.write(' ]\sn') \ncline12 = cosm.write('}\sn')\n}}}
Furmon Arduino Code\n\n{{{\n/*\n Software serial multple serial test\n \n Receives from the hardware serial, sends to software serial.\n Receives from software serial, sends to hardware serial.\n \n The circuit: \n * RX is digital pin 2 (connect to TX of other device)\n * TX is digital pin 3 (connect to RX of other device)\n \n created back in the mists of time\n modified 9 Apr 2012\n by Tom Igoe\n based on Mikal Hart's example\n \n This example code is in the public domain.\n \n */\n\n\n#include "DHT.h"\n\n#define DHTPIN 2 // what pin we're connected to\n\n// Uncomment whatever type you're using!\n//#define DHTTYPE DHT11 // DHT 11 \n#define DHTTYPE DHT22 // DHT 22 (AM2302)\n//#define DHTTYPE DHT21 // DHT 21 (AM2301)\n\n// Connect pin 1 (on the left) of the sensor to +5V\n// Connect pin 2 of the sensor to whatever your DHTPIN is\n// Connect pin 4 (on the right) of the sensor to GROUND\n// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor\n\nDHT dht(DHTPIN, DHTTYPE);\nvoid setup() \n{\n // Open serial communications and wait for port to open:\n Serial.begin(9600);\n\n \n dht.begin();\n} \n\n\nvoid loop() // run over and over\n{\n float h = dht.readHumidity();\n float t = dht.readTemperature();\n\n // check if returns are valid, if they are NaN (not a number) then something went wrong!\n if (isnan(t) || isnan(h)) {\n Serial.println("Failed to read from DHT");\n } else {\n Serial.print("THH: "); \n Serial.print(h);\n Serial.println(" %\st");\n Serial.print("THT: "); \n Serial.print(t);\n Serial.println(" *C");\n }\n\n\n String content = "";\n char character;\n\n while(Serial.available()) {\n character = Serial.read();\n content.concat(character);\n }\n\n if (content != "") {\n\n Serial.println(content);\n delay(1000);\n }\n\n}\n}}}
1freadscript.py is the current version of the way to read the Arduino board via the usb.\n\n{{{\n#!/usr/bin/python\n# -*- coding: utf-8 -*-\nimport time\nimport os\nimport re\nimport serial\nimport io\nimport csv\nimport sys\nimport MySQLdb\nfrom subprocess import call\n\n# Connect to Mysql DB\n\n\nportread = os.system("dmesg |grep ttyACM |tail -n 1|cut -d : -f3")\n\n# Open connection to the arduino, \nport = "/dev/ttyACM" + str(portread)\n #now = datetime.datetime.now()\nser = serial.Serial(port, 9600, timeout=5) \n\n#open connection to the arduino\n#sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser)) # clear buffering get the data out *now*\n#sio.flush()\ntime.sleep(.75) # Give the buffer time to clear \n#line3 = ser.readline()\nclearline = ser.readline() # read a '\sn' terminated line1 usually the one line with misformatted text\ndataline = ser.readline() # read a '\sn' terminated line4\nser.close() \n# print (line1), ('line1')\n# print (clearline)\n# print (clearline.strip())\nrx = re.compile('\sW+')\nres = rx.sub(' ', clearline).strip()\nprint res\nrx = re.compile('\sW+')\nres = rx.sub(' ', dataline).strip()\nprint res\n# print (dataline)\n\n# print (os.system("dmesg |grep ttyACM |tail -n 1|cut -d : -f3"))\n\n\n\n\nfilewrite = open("test.cap", "rw+")\nline = filewrite.write( dataline )\nline2 = filewrite.write( clearline )\n\nfilewrite.close()\n\n\nstrings = os.system("strings test.cap > strings.a")\ntemp = os.system("")\nfileread = open ("strings.a", "r")\n\nprint (fileread.read())\nfileread.close()\n\ntemp = os.system("cat strings.a |grep EF |cut -c 3- > temp ")\nstarts = os.system("cat strings.a |grep Starts > starts ")\nidle = os.system("cat strings.a |grep Idle > Idle ")\nhours = os.system("cat strings.a |grep Hours > Hours")\nreets = os.system("cat strings.a |grep Resets > resets ")\n}}}
This code will allow you to read a DHT11 from a remote raspberry pi\n\n{{{\n\n#!/usr/bin/python\n# Read temperature / humidity data and print it out from the DHT11 on pin 4\n# Prints only the temperature and humidity data\n\nimport subprocess\nimport re\nimport sys\nimport time\nimport datetime\n\n\n# Continuously append data\nwhile(True):\n\n # Run the DHT program to get the humidity and temperature readings!\n\n output = subprocess.check_output( "ssh root@10.0.1.243 '/usr/bin/Adafruit_DHT 11 4' ", shell=True);\n #print output # For Debugging only\n matches = re.search("Temp =\ss+([0-9.]+)", output)\n if (not matches):\n time.sleep(3)\n continue\n temp = float(matches.group(1))\n \n # search for humidity printout\n matches = re.search("Hum =\ss+([0-9.]+)", output)\n if (not matches):\n time.sleep(3)\n continue\n humidity = float(matches.group(1))\n\n print "Temperature: %.1f C" % temp\n print "Humidity: %.1f %%" % humidity\n \n}}}
This will print out the current temp or humidity of the garage\n\n{{{\n\n#!/bin/bash\n# furmon.sh\n#\n# Prints out the current temp or humidity of flint's garage\n# By Christopher Yarger, cpyarger.com\n# Licensed under GPLv3\n#\n# cpyarger Tue Mar 5 21:17:03 EST 2013 - Started program Design\n\n# Pulls and cleans Humidity from cosm\nversion="0.01"\n#\n# hold environment\nexport S=$PWD\n#* move to the appropriate directorygrep '^\s#\s*' tparse.sh\n# cd ??\nfunction help(){\nclear;\necho "This is "$0" "$version\ncat $0 | grep '^## ' | sed -e 's/##//'\n# echo "This is the help function"\n## *****DOCUMENTATION*****\n## You get this documentation when you put in the wrong number of arguments...\n## The name of this program is furmon.sh, a box of tools\n## This is released under GPLv3\n## The syntax is:\n## furmon.sh -t Prints current garage temperature\n## furmon.sh temp Prints current garage temperature\n## furmon.sh -h Prints current garage humidity\n## furmon.sh hum Prints current garage humidity\n}\n\nfunction hum (){\ncurl -s --request GET --header X-ApiKey:Zj5MqWdMj6K1HzOQrQ8sA0y9ePmSAKxCRStkOC9pYmxOaz0g http://api.cosm.com/v2/feeds/116703 | cut -d , -f 19-20 |tr "," "\sn"|cut -d: -f2- |sed s/\s"//g|tr "T" " "|cut -d. -f1\n}\n\n# pulls and cleans temp from cosm\n\nfunction temp (){\ncurl -s --request GET --header X-ApiKey:Zj5MqWdMj6K1HzOQrQ8sA0y9ePmSAKxCRStkOC9pYmxOaz0g http://api.cosm.com/v2/feeds/116703 | cut -d , -f 25-26 |tr "," "\sn"|cut -d: -f2- |sed s/\s"//g|tr "T" " "|cut -d. -f1\n}\n\n\nif [ "$1" = "" ]; then help; fi\nif [ "$1" = "-t" ] || [ "$1" = "temp" ]; then temp; fi\nif [ "$1" = "-h" ] || [ "$1" = "hum" ]; then hum; fi\n\n\n}}}
Type the text for 'New Tiddler'\n\n{{{\ndevice="/dev/ttyUSB0";miniterm.py -p $device |strings -n12\n}}}
Basic furmon object class\n\n{{{\n# Mon 18 Mar 2013 02:50:39 PM EDT \n# This is the base class for the furmon object\n# ref http://www.youtube.com/watch?v=CtzVNCmysFs\nclass furmon:\n def alarm(self):\n print "Alarm-type Date-time"\n def state(self):\n print "State-type State-counter Date-time"\n def stacktmp(self):\n print "stacktmp Date-time"\n def flamesns(self):\n print "flamesns Date-time"\n def ophours(self):\n print "Hours-operating Date-time"\n def thstcall(self):\n print "Thermostat-call Date-time"\n def ignind(self):\n print "Ignition-indicator Ignition-count Date-time"\n def alarm(self):\n print "ding ding Date-time"\n def starts(self):\n print "Number-starts Date-time"\n def blower(self):\n print "Blower-value Date-time"\n def button1(self):\n print "Button1-pressed Date-time"\n def button2(self):\n print "Button2-pressed Date-time"\n}}}
gfd.py\n\nversion 0.001\n\n{{{\n#!/usr/bin/python\n# -*- coding: utf-8 -*-\nimport signal\nimport time\nimport os\nimport re\nimport serial\nimport io\nimport csv\nimport sys\nfrom subprocess import call\nfrom serial import Serial\n# import MySQLdb\n#\n# note that this works from a linux command line:\n# device="/dev/ttyUSB0";miniterm.py -p $device |strings -n12\n# Connect to Mysql DB\n#\nFILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)])\n\ndef dump(src, length=8):\n N=0; result=''\n while src:\n s,src = src[:length],src[length:]\n hexa = ' '.join(["%02X"%ord(x) for x in s])\n s = s.translate(FILTER)\n result += "%04X %-*s %s\sn" % (N, length*3, hexa, s)\n N+=length\n return result\n\n"""\n# this is an example which works if you uncomment this block\ns=("This 10 line function is just a sample of pyhton power "\n "for string manipulations.\sn"\n "The code is \sx07even\sx08 quite readable!")\n\nprint dump(s)\n"""\n#\n\n# portread = os.system("dmesg |grep ttyACM |tail -n 1|cut -d : -f3")\n# Open connection to the arduino, \n# port = "/dev/ttyUSB0" + str(portread)\ndef main():\n out = open('furmon.data','a')\n port = "/dev/ttyUSB0"\n # ser = Serial(port="/dev/ttyUSB0", baudrate=9600 ) # set the parameters to what you want\n ser = Serial(port="/dev/ttyUSB0", baudrate=9600, timeout=6) # set the parameters to what you want 5 is good as well\n # dataline="the quick brown fox" # sample data\n def signal_handler(signal, frame):\n print " - You pressed Ctrl+C! "\n print time.time() - start_time, "seconds"\n sys.exit(0)\n signal.signal(signal.SIGINT, signal_handler)\n print 'Press Ctrl+C for interrupt'\n while True:\n pac_start=time.time()\n if ser.inWaiting():\n dataline = ser.readline()\n out.write(dataline)\n now=time.time()\n print 'At %d, after %d seconds the length of the data is: %d' % ( time.time(), ( time.time() - pac_start ), len(dataline))\n # print 'At %(now)d, after %(done)d seconds the length of the data is: %(length)d' % ('now':time.time(), 'done':( time.time() - pac_start ), 'lentgh':len(dataline))\n # print 'At %(time.time())d, after %( time.time() - pac_start )d seconds the length of the data is:',len(dataline)\n # print 'After %d seconds the length of the data is:' % ( time.time() - pac_start ), len(dataline)\n #\n#\n\n"""\nJunk\n#now = datetime.datetime.now()\n# ser = serial.Serial(port, 9600, timeout=5) \n#open connection to the arduino\n#sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser)) # clear buffering get the data out *now*\n#sio.flush()\n#t time.sleep(.75) # Give the buffer time to clear \n#line3 = ser.readline()\n#t clearline = ser.readline() # read a '\sn' terminated line1 usually the one line with misformatted text\n# dataline = ser.readline() # read a '\sn' terminated line4\n# print (line1), ('line1')\n# print (clearline)\n# print (dataline)\n#\n\nif __name__ == "__main__":\n main()\n"""\nstart_time = time.time()\nmain()\nser.close() \nout.close()\nprint time.time() - start_time, "seconds"\n\n}}}\n
\nThe [[New Haven Display Manual|http://docbox.flint.com/~flint/furmon/NHD-0420D3Z-FL-GBW.pdf]], [[page 9|http://docbox.flint.com/~flint/furmon/NHD-0420D3Z-FL-GBW.pdf#page=9]] has the key to the position variables.
Characteristics:\n\n[[Updates every 30 seconds|http://www.dynamicdrive.com/forums/showthread.php?18995-Refresh-webpage-automatically-without-clicking-refresh-button]]. [[This is the working example on docbox. Note passsword|http://docbox.flint.com:8081/test/index_html/pt_editForm]]
outpcp.sh generates out.html. Sample arguments are placed in couplets in "target:change" format.\n\nThe next version of this program will likely follow the [[Visual Bash|http://docbox.flint.com:8081/visual.bash]] template.\n\nExample working command line is as follows:\n{{{\n bin/outpcp8.sh opstate:Status=Running state_counter:countdown=100 Call:Call=T Resets:Resets=120 stack_temp:Stack=345 system_temp:System=330 Blower:Blower=10\n}}}\n\noutpcp9.sh\n{{{\n#!/bin/bash\n# pflint Fri 17 May 2013 07:49:14 AM EDT \n# packs html into String and makes changes at the end...\n# \n# this is the origin point:\norigin="http://www.w3.org/TR/html4/strict.dtd"\n#\n# the following evaluates the string... go to line 54 for more stuff...\nread -d '' String <<"EOF"\n<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n<html><head>\n<meta http-equiv="refresh" content="10;url=http://10.0.1.45/furmon/out.html">\n<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>Pellergy Control For Furmon Site</title>\n\n</head>\n<body>\n<img style="width: 847px; height: 642px;" alt="Drawing of control plate should be here" src="http://docbox.flint.com/%7Eflint/furmon/Pellergy_Control_blank_plate.png">\n<table style="position: relative; z-index: 1; left: 120px; top: -500px; width: 606px; height: 215px;" cellpadding="2" cellspacing="2">\n<tbody>\n<tr>\n<td colspan="2" rowspan="1" style="position: relative; width: 305px;"><big>\nopstate </big><br>\n</td>\n<td colspan="3" rowspan="1" style="position: relative; width: 257px;"><big>\nstate_counter </big><br>\n</td>\n</tr>\n<tr>\n<td colspan="2" rowspan="1" style="position: relative; width: 103px;">No Alarm<br>\n</td>\n<td colspan="3" rowspan="1" style="position: relative; width: 257px;">All is well<br>\n</td>\n</tr>\n<tr>\n<td style="position: relative; width: 100px;">Call <br>\n</td>\n<td style="position: relative; width: 100px;">Resets\n<br>\n</td>\n<td style="position: relative; width: 140px;">stack_temp\n&#8457; <br>\n</td>\n<td style="position: relative; width: 150px;">system_temp\n&#8457; <br>\n</td>\n<td style="position: relative; width: 140px;">Blower<br>\n</td>\n</tr>\n<tr>\n<td style="position: relative; width: 120px;">\n<br>\n</td>\n<td style="position: relative; width: 130px;">Button1\n<br>\n</td>\n<td style="position: relative; width: 140px;">Button2\n<br>\n</td>\n<td style="position: relative; width: 140px;">Button3<br>\n</td>\n<td style="position: relative; width: 140px;">Button4<br>\n</td>\n</tr>\n<tr>\n<td style="position: absolute; top: 542px; left: 190px;">Param<br>\n</td>\n<td style="position: absolute; top: 542px; left: 343px;">Test<br>\n</td>\n<td style="position: absolute; top: 542px; left: 491px;">Enabl<br>\n</td>\n<td style="position: absolute; top: 541px; left: 643px;">Feed</td>\n</tr>\n</tbody>\n</table>\n<br>\n<br>\n</body></html>\nEOF\n# echo "this is the string"\necho "$String" > in.html\nrm -rf outpcp.html\nnewrd1=$1\nnewrd2=$2\nt11="test 1,1"\nt12="test 1,2"\n#\n# very last line erases all extra test files\necho "0 is $0"\necho "Number of Arguments are $#"\necho $@\necho "This starts the changes arguments must be in pairs, target:change"\necho $@\nfor f in $@; \ndo \n target=${f%:*}; \n change=${f#*:}; \n echo "Next change $target $change"; \n changed=${String/$target/$change}; String=$changed \ndone\necho "$String" > out.html\necho "the difference between these strings is"\n# diff -y in.html out.html | less -S\ndiff in.html out.html | less -NS\n# sleep 5\necho "Type cntrl -c to stop firefox now"\nfirefox 2>/dev/null out.html\n}}}
''Statement of the problem''\n* Must capture serial content periodically and\n* * Date time stamp it and\n* Parse content via the furmon class\n* output the furmon class based data\n\nVersion 1 reads sample data\n{{{\n#!/usr/bin/env python\nimport os\nimport re\nimport sys\nimport optparse\nimport subprocess\nimport signal\nimport time\nimport serial\nimport io\nimport csv\nimport string\nfrom subprocess import call\nfrom serial import Serial\n#\nclass furmon:\n# def __init__(self):\n def alarm(self):\n '''This determines if there is an alarm, this also reports the reason '''\n alarm="No Alarm "\n reason=" no reason " \n target="\sx00ALARM"\n for item in L:\n if item.find(target) != -1:\n index=L.index(item)\n alarm=(item[1:])\n reason=L[index+1]\n return printme( alarm+reason )\n def resets(self):\n '''This is the number of resets '''\n norst=""\n type="Resets"\n target="\sx14"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 19 <= len(item) < 22: \n if item.find(type) != -1:\n norst=(item[1:])\n return printme( norst )\n#\n def state(self):\n '''This is the purging state.'''\n purg=""\n type="Purging"\n target="\sx00"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 14 <= len(item) < 25: \n if item.find(type) != -1:\n purg=(item[1:])+"\st"\n return printme( purg )\n#\n def systmp(self):\n # get system temprature\n temp=""\n target="B"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 5 <= len(item) < 6: \n temp="System Temp: "+(item[1:])\n return printme( temp )\n#\n def stacktmp(self):\n '''this gets the stack temprature'''\n stemp=""\n target="\sx0f"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 5 <= len(item) < 6: \n stemp="Stack Temp: "+(item[1:])\n return printme( stemp )\n # return printme( "flamesns Date-time" )\n#\n def flamesns(self):\n ''' Is the sensor sensing flame?'''\n return printme( "flame sensor?" )\n#\n def ophours(self):\n '''This is the hours the system has been operating'''\n hours=""\n type="Hours"\n target="\sx14"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 19 <= len(item) < 22: \n if item.find(type) != -1:\n hours=(item[1:])\n return printme( hours )\n#\n def thstcall(self):\n '''This is the thermostat call, it is either on or off.'''\n tcall=""\n target="@T"\n # L=re.split("\sxfeE", dataline)\n for item in L:\n if item.find(target) != -1:\n tcall="Last "+(item[1:])+"-call at \st"\n return printme( tcall )\n#\n def ignind(self):\n '''Ignition-indicator Ignition-count Date-time'''\n print "input string is %s" % L\n return printme( "Ignition-indicator Ignition-count Date-time")\n#\n def starts(self):\n strts=""\n type="Starts"\n target="\sx14"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 19 <= len(item) < 22: \n if item.find(type) != -1:\n strts=(item[1:])\n return printme( strts )\n def blower(self):\n return printme( "Blower-value Date-time")\n def button1(self):\n return printme( "Button1-pressed Date-time")\n def button2(self):\n return printme( "Button2-pressed Date-time")\n#\n# inserts time nearly everywhere...\ndef cfltime(fd):\n cflout=""\n type="Time"\n target="pf"\n #\n for item in fd:\n if item.find(target) != -1:\n if item.find(type) != -1:\n rawtime=(item[9:22])\n cflout=(item[3:22])\n cflout=time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(time.time(rawtime))\n # cflout=time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(time.time())\n print rawtime \n # print cflout \n return cflout\n\n\ndef printme( str ):\n '''This time stamps a string passed into this function'''\n out=str+"\st\st"+cfltime(L)\n return out\n\n#\nFILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)])\n\ndef dump(src, length=8):\n N=0; result=''\n while src:\n s,src = src[:length],src[length:]\n hexa = ' '.join(["%02X"%ord(x) for x in s])\n s = s.translate(FILTER)\n result += "%04X %-*s %s\sn" % (N, length*3, hexa, s)\n N+=length\n return result\n#\ndef FileCheck(fn):\n ''' Not using this routine yet'''\n try:\n open(fn, "r")\n return 1\n except IOError:\n print "Error: File does not appear to exist."\n return 0\n#\n# reference\n# http://www.alexonlinux.com/pythons-optparse-for-human-beings\n\ndef main():\n ''' \n This is the main subroutine, any detail about this program belongs here.\n This program has two basic parts:\n 1. data gathering from at pellergy furnace with a furmon installed and\n 2. display of this data via mrtg.\n '''\n#\n# establish the globals\n global L\n inf=""\n # L="banana" # is this global now?\n ver="0.20130328"\n filename="furmon.data"\n#\n# parse options and act\n parser = optparse.OptionParser(description='Furmon Software Support Package',\n prog=os.path.basename(__file__),\n version='This is version %s. This code, %s is copyright 2013 by fits and licensed under GPLI ' % ( ver,os.path.basename(__file__) ),\n usage= '%prog [option]')\n parser.add_option('--query', '-?', dest='bool',default=False, action='store_true',\n help='print document string with extensive result',)\n # parser.add_option('--functs', '-s', help='starts operational functions', dest='function', action='store')\n parser.add_option('--person', '-p', dest="person", default="world")\n parser.add_option('-n', '--new', help='creates a new object')\n parser.add_option("-f", "--file", dest="filename", default="file", \n help="read test data from a file", metavar="FILE")\n # parser.add_option("-s", "--serial", dest="filename", default="file",\n#\n options, arguments = parser.parse_args() # evaluate options\n print 'file name %s' % options.filename\n print 'Hello %s' % options.person\n if options.bool: \n print '%s documentation' % os.path.basename(__file__)\n print main.__doc__\n print "for operating information type '%s -h'" % __file__\n sys.exit() \n#\n# open the information for reading\n # print options.filename\n if options.filename != "file":\n try:\n inf = open(options.filename, "rb")\n except IOError: \n print "The file does not exist, exiting gracefully"\n sys.exit() \n#\n# read data line\n dataline=inf.readline()\n#\n L=re.split("\sxfeE",dataline)\n # print L\n # out = open(options.filename,'a')\n# display \n c=furmon()\n # output of objects test point\n # print c.alarm.__doc__ ," The value is",(c.alarm())\n # print c.state.__doc__ ," The value is",(c.state())\n print(c.alarm())\n print(c.state())\n print(c.ophours())\n print(c.resets())\n print(c.starts())\n print(c.systmp())\n print(c.stacktmp())\n print(c.thstcall())\n # print c.thstcall.__doc__ ," The value is",(c.thstcall())\n # print c.ignind.__doc__ ," The value is",(c.ignind()) # currently dumps L\n print "tada"\n\nif __name__ == '__main__':\n print "starting %s" % __file__\n if len(sys.argv) == 1:\n print "for operating information type '%s -h'" % __file__\n sys.exit()\n main()\n print "that's it"\n\n\n}}}\n\nVersion 0 The skeleton:\n{{{\n#!/usr/bin/env python\nimport optparse\nimport subprocess\n\n\ndef main():\n p = optparse.OptionParser(description='A unix testbox',\n prog='ibmfr1.py',\n version='fits 0.1',\n usage= '%prog [option]')\n # p = optparse.OptionParser()\n p.add_option('--verbose', '-v',\n action = 'store_true',\n help='prints verbosely',\n default=False)\n p.add_option('--person', '-p', default="world")\n # p.add_option('--query', '-?', default="world")\n print "starting"\n options, arguments = p.parse_args()\n print 'Hello %s' % options.person\n print "that's it"\n\nif __name__ == '__main__':\n main()\n}}}\n\nReferences:\nhttp://www.ibm.com/developerworks/aix/library/au-pythocli/\nhttp://magazine.redhat.com/2008/02/07/python-for-bash-scripters-a-well-kept-secret/\nhttp://www.alexonlinux.com/pythons-optparse-for-human-beings\n\nMaybe one the way to use [[ipython|http://showmedo.com/videotutorials/video?name=1000010&fromSeriesID=100]]
http://hutgrip.com/
Flint Has an Elster smart meter on the side of his house... We should be able to read it without an issue. Within it contains an 900MHz Xbee radio module. \n\nhere is a link to the teardown\n\n[[http://www.ifixit.com/Teardown/Elster+REX2+Smart+Meter+Teardown/5710/1|http://www.ifixit.com/Teardown/Elster+REX2+Smart+Meter+Teardown/5710/1]]\n\nhere is the NIST site \n\n[[http://collaborate.nist.gov/twiki-sggrid/bin/view/SmartGrid/WebHome|http://collaborate.nist.gov/twiki-sggrid/bin/view/SmartGrid/WebHome]]\n\nthe xbee site info\n\n[[http://www.zigbee.org/DesktopModules/ZigbeeDisplayCategoryProducts/ProductDetails.aspx?ProductID=368&Ctrl=ViewProducts|http://www.zigbee.org/DesktopModules/ZigbeeDisplayCategoryProducts/ProductDetails.aspx?ProductID=368&Ctrl=ViewProducts]] \n\n
Type the text for 'New Tiddler'\n\n{{{\ngrep -vi at furmon.display.data_v1 | grep -vi tada |sed 's|\st||g' |grep -e "^$" -v\n}}}\n\nhttp://www.panix.com/~elflord/unix/bash-tute.html\n\n[[Guide|http://docbox.flint.com/~flint/furmon/PB-1525%20Installation%20Manual%20V1_0%20%281%29.pdf#page=27]]
Eric Howard is right, the method based class is not acceptable.\n\nthe refactoring of this requires the use of a class based upon attributes that is instantiated many times.\n\nto do this consider the following simple example from this [[source|http://stackoverflow.com/questions/223559/using-variables-for-class-names-in-python#]].\n* Create a simple class with an attribute...\n{{{\n>>> class conflict:\n... name="the Weasel"\n... \n>>> \n}}}\n\nnow test this class \n{{{\n>>> eric=conflict\n>>> print eric.name\nthe Weasel\n>>> \n}}}\n\nOr instantiate the new object "eric" in this fashion:\n{{{\n>>> eric = className()\n>>> print eric.name\nthe Weasel\n}}}\n\nOne way to do this is with the copy module...\n{{{\n>>> import copy\n>>> flint=copy.deepcopy(eric)\n>>> print flint.name\nthe Weasel\n}}}\n\nThe trick is can "flint" be called by value?
The development environment we use is based upon screen.\n\nThe way it looks is as follows:\n{{{\nNum Name Flags\n\n 1 python $\n 2 ipython $\n 3 test3 $\n 4 test4 $\n 5 test5 $\n\n}}}\n\nHow you get there is you run bin/fdbg.sh from furmon directory. Note this automatically requires root.\n{{{\n#!/bin/bash\n# pflint Tue 19 Feb 2013 07:46:49 AM EST \n# pbug debug environment\n# sudo bash\n# sudo ~flint/bin/fdbg.sh\n# Make sure only root can run our script\nsudo cd /var/www/furmon\nchmod 777 ~/.screenrc\n# echo "Welcome to fdbg.sh"; sleep 1s\ncp /home/flint/furmon/bin/fdbg.screen ~/.screenrc\nsudo screen\n}}}\n\nThe settings for /home/flint/furmon/bin/fdbg.screen are below, note there is plenty of chaff:\n{{{\n# $Id: screenrc,v 1.15 2003/10/08 11:39:03 zal Exp $\n#\n# /etc/screenrc\n#\n# This is the flint screenrc.\n#\n# You can use this file to change the default behavior of screen system wide\n# or copy it to ~/.screenrc and use it as a starting point for your own\n# settings.\n#\n# Commands in this file are used to set options, bind screen functions to\n# keys, redefine terminal capabilities, and to automatically establish one or\n# more windows at the beginning of your screen session.\n#\n# This is not a comprehensive list of options, look at the screen manual for\n# details on everything that you can put in this file.\n#\n\n# ------------------------------------------------------------------------------\n# SCREEN SETTINGS\n# ------------------------------------------------------------------------------\n\n#startup_message off\n#nethack on\n\n#defflow on # will force screen to process ^S/^Q\ndeflogin on\n#autodetach off\n\n# turn visual bell on\nvbell on\nvbell_msg " Wuff ---- Wuff!! "\n\n# define a bigger scrollback, default is 100 lines\ndefscrollback 1024\n\n# ------------------------------------------------------------------------------\n# SCREEN KEYBINDINGS\n# ------------------------------------------------------------------------------\n\n# Remove some stupid / dangerous key bindings\nbind ^k\n#bind L\nbind ^\s\n# Make them better\nbind \s\s quit\nbind K kill\nbind I login on\nbind O login off\nbind } history\n\n# An example of a "screen scraper" which will launch urlview on the current\n# screen window\n#\n#bind ^B eval "hardcopy_append off" "hardcopy -h $HOME/.screen-urlview" "screen urlview $HOME/.screen-urlview"\n\n# ------------------------------------------------------------------------------\n# TERMINAL SETTINGS\n# ------------------------------------------------------------------------------\n\n# The vt100 description does not mention "dl". *sigh*\ntermcapinfo vt100 dl=5\sE[M\n\n# turn sending of screen messages to hardstatus off\nhardstatus off\n# Set the hardstatus prop on gui terms to set the titlebar/icon title\ntermcapinfo xterm*|rxvt*|kterm*|Eterm* hs:ts=\sE]0;:fs=\s007:ds=\sE]0;\s007\n# use this for the hard status string\nhardstatus string "%h%? users: %u%?"\n\n# An alternative hardstatus to display a bar at the bottom listing the\n# windownames and highlighting the current windowname in blue. (This is only\n# enabled if there is no hardstatus setting for your terminal)\n#\n#hardstatus lastline "%-Lw%{= BW}%50>%n%f* %t%{-}%+Lw%<"\n\n# set these terminals up to be 'optimal' instead of vt100\ntermcapinfo xterm*|linux*|rxvt*|Eterm* OP\n\n# Change the xterm initialization string from is2=\sE[!p\sE[?3;4l\sE[4l\sE>\n# (This fixes the "Aborted because of window size change" konsole symptoms found\n# in bug #134198)\ntermcapinfo xterm 'is=\sE[r\sE[m\sE[2J\sE[H\sE[?7h\sE[?1;4;6l'\n\n# To get screen to add lines to xterm's scrollback buffer, uncomment the\n# following termcapinfo line which tells xterm to use the normal screen buffer\n# (which has scrollback), not the alternate screen buffer.\n#\n#termcapinfo xterm|xterms|xs|rxvt ti@:te@\n\n# ------------------------------------------------------------------------------\n# STARTUP SCREENS\n# ------------------------------------------------------------------------------\n\n# Example of automatically running some programs in windows on screen startup.\n#\n# The following will open top in the first window, an ssh session to monkey\n# in the next window, and then open mutt and tail in windows 8 and 9\n# respectively.\n#\n# screen top\n# screen -t monkey ssh monkey\n# screen -t mail 8 mutt\n# screen -t daemon 9 tail -f /var/log/daemon.log\n#\n# pflint \n# Thu Feb 9 23:24:52 EST 2006\n# added so pine will live...\nbindkey -k k; stuff ";a"\nbindkey -k F1 stuff "as"\nbindkey -k F2 stuff ";cn"\n# the new spam key...\nbindkey -k F3 stuff "d"\n# \n# Sat Mar 4 22:25:07 EST 2006\n#\n# screen top\n# screen -t monkey ssh monkey\nscreen -t python 1 python\nscreen -t ipython 2 ipython\nscreen -t test3 3\nscreen -t test4 4\nscreen -t test5 5\n# screen -t itemp 2 watch 'echo $(date +%s);head -20 /var/www/itemp/itemp.log'\n# screen -t otemp 3 watch 'echo $(date +%s);head -20 /var/www/otemp/otemp.log'\n# screen -t itemp 4 watch 'tail -20 /var/www/itemp/logs/itemp.log'\n# screen -t otemp 5 watch 'tail -20 /var/www/otemp/logs/otemp.log'\n# screen -t itemp.data 4 watch 'echo $(date +%F);echo $(date +%s); tail -20 /var/www/itemp/itemp.data'\n# screen -t otemp.data 5 watch 'echo $(date +%F);echo $(date +%s); tail -20 /var/www/otemp/otemp.data'\n# screen -t itemp.log 6 watch "echo $(date +%F);echo $(date +%s); tail -20 /var/www/itemp/logs/itemp.log"\n# screen -t otemp.log 7 watch "echo $(date +%F);echo $(date +%s); tail -20 /var/www/otemp/logs/otemp.log"\n# screen -t temp.log 8 watch "echo $(date +%F);echo $(date +%s); tail -20 /var/www/temp.log"\n# screen 9 # 'gedit /var/www/bin/mtsp.sh &'\n# screen -t mail 8 pine\n# screen -t daemon 9 tail -f /var/log/daemon.log\n#\n# pflint \n}}}\n
Current state of the furmon data gathering code...\n\nNote much filtering is going on...\n\n{{{\n#!/usr/bin/env python\n#\n# pflint Mon 01 Apr 2013 07:29:56 AM EDT have methods evaluate attributes\n# once all the attributes are evaluated then reaport...\nimport os\nimport re\nimport sys\nimport optparse\nimport subprocess\nimport signal\nimport time\nimport serial\nimport io\nimport csv\nimport string\nfrom subprocess import call\nfrom serial import Serial\n#\n#\n# establish the dreaded globals\n# global L\n# global inf\nver="0.20130329"\n# filename="furmon.data"\nfilename="/home/flint/furmon/furmon.data"\n# \ndef intro():\n ''' Prints the main story about this program and tries to warn you.'''\n print '\st %s documentation: A tale of woe and intrigue' % os.path.basename(__file__)\n print main.__doc__\n print "for operating information type '%s -h'" % __file__\n\n#\n# This is the base class for the furmon object\n# ref http://www.youtube.com/watch?v=CtzVNCmysFs\nclass furmon:\n hours="0000" \n tonoff="Off"\n fsensor="00" \n fmotor="off" \n blowsp="00"\n alarm="No Alarm" \n reason="All is well" \n state="Purging"\n state_counter="0000" \n resets="0000" \n stack_temp="000"\n starts="00000" \n system_temp="000"\n butn1="Param"\n butn2="Test"\n butn3="Enabl"\n butn4="Feed"\n# The goal of this program is to fill in as many attributes of the object as you can.\n# These are the basic functions\n#\n# Here are the tests\ndef alarm(L):\n '''This determines if there is an alarm, this also reports the reason '''\n alarm="No Alarm "\n reason=" no reason " \n target="\sx00ALARM"\n for item in L:\n if item.find(target) != -1:\n index=L.index(item)\n alarm=(item[1:])\n reason=L[index+1]\n return printme( alarm+reason )\n#\ndef resets(L):\n '''This is the number of resets '''\n norst=""\n type="Resets"\n target="\sx14"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 19 <= len(item) < 22: \n if item.find(type) != -1:\n norst=(item[1:])\n return printme( norst )\n#\ndef state(L):\n '''This is the purging state.'''\n purg=""\n type="Purging"\n target="\sx00"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 14 <= len(item) < 25: \n if item.find(type) != -1:\n purg=(item[1:])+"\st"\n return printme( purg )\n#\ndef systmp(L):\n ''' get system temprature '''\n temp=""\n # target="B"\n # target="\sxdfF" \n target="F"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 5 <= len(item) < 7: \n temp="System Temp: "+(item[1:4])\n return printme( temp )\n#\ndef stacktmp(L):\n '''this gets the stack temprature'''\n stemp=""\n target="\sx0f"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 5 <= len(item) < 7: \n stemp="Stack Temp: "+(item[1:4])\n return printme( stemp )\n # return printme( "flamesns Date-time" )\n\n#\ndef flamesns(L):\n ''' Is the sensor sensing flame?'''\n return printme( "flame sensor?" )\n#\ndef ophours(L):\n '''This is the hours the system has been operating'''\n hours=""\n type="Hours"\n target="\sx14"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 19 <= len(item) < 22: \n if item.find(type) != -1:\n hours=(item[1:])\n return printme( hours )\n#\ndef thstcall(L):\n '''This is the thermostat call, it is either on or off.'''\n tcall=""\n target="@T"\n # L=re.split("\sxfeE", dataline)\n for item in L:\n if item.find(target) != -1:\n tcall="Last "+(item[1:])+"-call at \st"\n return printme( tcall )\n#\ndef ignind(L):\n '''Ignition-indicator Ignition-count Date-time'''\n print "input string is %s" % L\n return printme( "Ignition-indicator Ignition-count Date-time")\n#\ndef starts(L):\n strts=""\n type="Starts"\n target="\sx14"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 19 <= len(item) < 22: \n if item.find(type) != -1:\n# strts=(item[1:])\n return printme( strts )\n#\ndef blower(L):\n return printme( "Blower-value Date-time")\n#\ndef button1(L):\n return printme( "Button1-pressed Date-time")\n#\ndef button2(L):\n return printme( "Button2-pressed Date-time")\n#\ndef button3(L):\n return printme( "Button3-pressed Date-time")\n#\ndef button4(L):\n return printme( "Button4-pressed Date-time")\n#\n#\ndef printme( str ):\n '''This time stamps a string passed into this function'''\n out=str+"\st\st"+cfltime(L)\n return out\n#\n# inserts time nearly everywhere...\ndef cfltime(fd):\n '''inserts time nearly everywhere...'''\n cflout=""\n type="Time"\n target="pf"\n #\n for item in fd:\n if item.find(target) != -1:\n if item.find(type) != -1:\n rawtime=float(item[9:21]) # must be float to work in time machine\n cflout=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(rawtime))\n return cflout\n#\n#\n# open the information for reading\n# print options.filename\n# class test:\n# filename="furmon.data"\n# optioins=test\n# print options.filename\ndef otrf():\n ''' open to read file'''\n try:\n inf = open(options.filename, "rb")\n except IOError: \n print "The file '%s' does not exist, please correct and retry..." % options.filename\n sys.exit()\n return inf\n# \n#\ndef rfdl(dfile):\n ''' read data line'''\n dataline=dfile.readline()\n line=re.split("\sxfeE",dataline)\n # print line\n # out = open(options.filename,'a')\n return line\n# \ndef otrs():\n print "Using serial data from %s at %s bits per second, with a %s second time out factor" \s\n % (options.serial_port, options.port_baud, options.timeout)\n serp = Serial(port=options.serial_port, baudrate=options.port_baud, timeout=6)\n print "Got past open"\n return serp\n#\ndef rsdl(ser):\n ''' read serial data Line '''\n def signal_handler(signal, frame):\n print " - You pressed Ctrl+C! "\n print time.time() - start_time, "seconds"\n sys.exit(0)\n signal.signal(signal.SIGINT, signal_handler)\n # ser=""\n print 'Press Ctrl+C for interrupt'\n while True:\n pac_start=time.time()\n if ser.inWaiting():\n now=str(time.time())\n dataline = ser.readline()\n outline = dataline+"\sxfeEpf Time: "+now\n # print(outline)\n # out.write(outline)\n L=re.split("\sxfeE", dataline)\n return L\n#\ndef getL():\n done_time=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))\n print 'At %s, after %d seconds the length of the data is: %d' \s\n % ( done_time, ( time.time() - pac_start ), len(dataline))\n # print 'At %(now)d, after %(done)d seconds the length of the data is: %(length)d' % ('now':time.time(), 'done':( time.time() - pac_start ), 'lentgh':len(dataline))\n # print 'At %(time.time())d, after %( time.time() - pac_start )d seconds the length of the data is:',len(dataline)\n # print 'After %d seconds the length of the data is:' % ( time.time() - pac_start ), len(dataline)\n #\n # sys.exit()\n c=furmon()\n # output of objects test point\n # print c.alarm.__doc__ ," The value is",(c.alarm())\n # print c.state.__doc__ ," The value is",(c.state())\n print(c.alarm())\n print(c.state())\n print(c.ophours())\n print(c.resets())\n print(c.starts())\n print(c.systmp())\n print(c.stacktmp())\n print(c.thstcall())\n # print c.thstcall.__doc__ ," The value is",(c.thstcall())\n # print c.ignind.__doc__ ," The value is",(c.ignind()) # currently dumps L\n print "tada" \n#\n# display \n c=furmon()\n # output of objects test point\n # print c.alarm.__doc__ ," The value is",(c.alarm())\n # print c.state.__doc__ ," The value is",(c.state())\n print(c.alarm())\n print(c.state())\n print(c.ophours())\n print(c.resets())\n print(c.starts())\n print(c.systmp())\n print(c.stacktmp())\n print(c.thstcall())\n # print c.thstcall.__doc__ ," The value is",(c.thstcall())\n # print c.ignind.__doc__ ," The value is",(c.ignind()) # currently dumps L\n print "tada display"\n\n\ndef main():\n ''' \n This is the main subroutine, any detail about this program belongs here.\n This program has two basic parts:\n 1. data gathering from at pellergy furnace with a furmon installed and\n 2. display of this data via mrtg.\nTue 02 Apr 2013 02:52:07 PM EDT this is the rewrite with the object right.\nFri 29 Mar 2013 07:02:36 AM EDT at this point the program depends on sample data\n This data is in the "New Haven Display" format and is basically binary.\nThu 04 Apr 2013 08:16:33 AM EDT new version of fm.py trying to clean up this code.\nMon 08 Apr 2013 02:17:18 PM EDT Continuing cleanup...\n '''\nstart_time = time.time()\n# print "starting %s at %s " % (__file__, \s\ngo_time=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(start_time))\nprint "starting %s at %s " % (__file__, go_time)\nif len(sys.argv) == 1:\n print "for operating information type '%s -h'" % __file__\n sys.exit()\n# Above handles no arguments\n#\nelse:\n# parse options and act\n parser = optparse.OptionParser(description='Furmon Software Support Package',\n prog=os.path.basename(__file__),\n version='This code is version %s, and the code, %s is copyright 2013 by fits and licensed under GPLI ' % ( ver,os.path.basename(__file__) ),\n usage= '%prog [option]')\n parser.add_option('--query', '-?', dest='bool',default=False, action='store_true',\n help='print document string with extensive result',)\n parser.add_option('--serial', '-s', dest='serialp',default=False, action='store_true',\n help='gather data from serial port',)\n parser.add_option("-f", "--file", dest="filename", default="USB", \n help="read test data from a file", metavar="FILE")\n parser.add_option("-p", "--port", dest="serial_port", default="/dev/ttyUSB0",\n help="set serial port; default=\s"/dev/ttyUSB0\s"", metavar="STRING")\n parser.add_option("-b", "--baud", dest="port_baud", default="9600",\n help="set port speed; default=\s"9600\s"", metavar="STRING")\n parser.add_option("-t", "--timeout", dest="timeout", default="6",\n help="set timeout value; default=\s"6\s"", metavar="INT")\n#\n# Evaluates inbound arguments\n options, arguments = parser.parse_args() # evaluate options\n if options.bool: \n print len(sys.argv)\n intro()\n sys.exit() \n elif options.serialp:\n print "You are at serial routines"\n mser=otrs()\n # print mser.__doc__\n # print dir(mser)\n print rsdl(mser) \n sys.exit() \n elif options.filename != "USB":\n print "You are at file routines"\n dline=otrf() # open file\n print "you opened the file"\n # print dline.__doc__\n # print dir(dline)\n # print dline.readline()\n # print re.split("\sxfeE",dline.readline())\n # print inf.__doc__\n # print dir(inf)\n # print rfdl() # read line from file\n print rfdl(dline) # read line from file\n sys.exit() \n elif options.serial_port != "/dev/ttyUSB0":\n print "You are at port selection"\n sys.exit()\n elif options.port_baud != "9600":\n print "You are at port selection"\n sys.exit() \n elif options.timeout != "6":\n print "You are at timeout selection"\n sys.exit() \n# More junk\n # print 'file name %s' % options.filename\n # print 'Hello %s' % options.person\n\n\nif __name__ == '__main__':\n main()\n print "that's it"\n\n\n}}}
{{{\n#!/usr/bin/env python\n#\n# pflint Mon 01 Apr 2013 07:29:56 AM EDT have methods evaluate attributes\n# once all the attributes are evaluated then reaport...\nimport os\nimport re\nimport sys\nimport optparse\nimport subprocess\nimport signal\nimport time\nimport serial\nimport io\nimport csv\nimport string\nfrom subprocess import call\nfrom serial import Serial\nfrom string import digits\n#\n#\n# establish the dreaded globals\n# global L\n# global inf\nver="0.20130403"\n# filename="furmon.data"\nfilename="/home/flint/furmon/furmon.data"\n# \ndef intro():\n ''' Prints the main story about this program and tries to warn you.'''\n print '\st %s documentation: A tale of woe and intrigue' % os.path.basename(__file__)\n print main.__doc__\n print "for operating information type '%s -h'" % __file__\n\n#\n# This is the base class for the furmon object\n# ref http://www.youtube.com/watch?v=CtzVNCmysFs\nclass furmon:\n hours="0000" \n tonoff="Off"\n fsensor="00" \n fmotor="off" \n blowsp="00"\n alarm="No Alarm" \n reason="All is well" \n state="Purging"\n state_counter="0000" \n resets="0000" \n stack_temp="000"\n starts="00000" \n system_temp="000"\n butn1="Param"\n butn2="Test"\n butn3="Enabl"\n butn4="Feed"\n# The goal of this program is to fill in as many attributes of the object as you can.\n# These are the basic functions\n#\n# Here are the tests\ndef alarm(L):\n '''This determines if there is an alarm, this also reports the reason '''\n alarm="No Alarm "\n reason=" no reason " \n target="\sx00ALARM"\n for item in L:\n if item.find(target) != -1:\n index=L.index(item)\n alarm=(item[1:])\n reason=L[index+1]\n return printme( alarm+reason )\n#\ndef resets(L):\n '''This is the number of resets '''\n norst=""\n type="Resets"\n target="\sx14"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 19 <= len(item) < 22: \n if item.find(type) != -1:\n norst=(item[1:])\n return printme( norst )\n#\ndef state(L):\n '''This is the purging state.'''\n purg=""\n type="Purging"\n target="\sx00"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 14 <= len(item) < 25: \n if item.find(type) != -1:\n purg=(item[1:])+"\st"\n return printme( purg )\n#\ndef systmp(L):\n ''' get system temprature '''\n temp=""\n # target="B"\n # target="\sxdfF" \n target="F"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 5 <= len(item) < 7: \n temp="System Temp: "+(item[1:4])\n # return printme( temp )\n return temp \n#\ndef stacktmp(L):\n '''this gets the stack temprature'''\n stemp=""\n target="\sx0f"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 5 <= len(item) < 7: \n stemp="Stack Temp: "+(item[1:4])\n return printme( stemp )\n # return printme( "flamesns Date-time" )\n\n#\ndef flamesns(L):\n ''' Is the sensor sensing flame?'''\n return printme( "flame sensor?" )\n#\ndef ophours(L):\n '''This is the hours the system has been operating'''\n hours=""\n type="Hours"\n target="\sx14"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 19 <= len(item) < 22: \n if item.find(type) != -1:\n hours=(item[1:])\n return printme( hours )\n#\ndef thstcall(L):\n '''This is the thermostat call, it is either on or off.'''\n tcall=""\n target="@T"\n # L=re.split("\sxfeE", dataline)\n for item in L:\n if item.find(target) != -1:\n tcall="Last "+(item[1:])+"-call at \st"\n return printme( tcall )\n#\ndef ignind(L):\n '''Ignition-indicator Ignition-count Date-time'''\n print "input string is %s" % L\n return printme( "Ignition-indicator Ignition-count Date-time")\n#\ndef starts(L):\n strts=""\n type="Starts"\n target="\sx14"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n if 19 <= len(item) < 22: \n if item.find(type) != -1:\n# strts=(item[1:])\n return printme( strts )\n#\ndef blower(L):\n return printme( "Blower-value Date-time")\n#\ndef button1(L):\n return printme( "Button1-pressed Date-time")\n#\ndef button2(L):\n return printme( "Button2-pressed Date-time")\n#\ndef button3(L):\n return printme( "Button3-pressed Date-time")\n#\ndef button4(L):\n return printme( "Button4-pressed Date-time")\n#\n#\ndef printme( str ):\n '''This time stamps a string passed into this function'''\n out=str+"\st\st"+cfltime(tada)\n return out\n#\ndef timest(L):\n '''This pulls the timestamp out of the data string'''\n type="Time"\n target="pf"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n # if 19 <= len(item) < 22: \n # if item.find(type) != -1:\n rawtime=float(item[9:]) # must be float to work in time machine\n # print rawtime\n # print time.localtime(rawtime)\n tm=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(rawtime))\n # tm=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(1367590968.24)))\n # time=(item[8:])\n # return printme( hours )\n return tm\n#\n# inserts time nearly everywhere...\ndef cfltime(fd):\n '''inserts time nearly everywhere...'''\n cflout=""\n type="Time"\n target="pf"\n #\n for item in fd:\n if item.find(target) != -1:\n if item.find(type) != -1:\n rawtime=float(item[9:21]) # must be float to work in time machine\n cflout=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(rawtime))\n return cflout\n#\n#\n# open the information for reading\n# print options.filename\n# class test:\n# filename="furmon.data"\n# optioins=test\n# print options.filename\ndef otrf():\n ''' open to read file'''\n try:\n inf = open(options.filename, "rb")\n except IOError: \n print "The file '%s' does not exist, please correct and retry..." % options.filename\n sys.exit()\n print "you opened the file"\n return inf\n# \n#\ndef rfdl(dfile):\n ''' read data line'''\n dataline=dfile.readline()\n line=re.split("\sxfeE",dataline)\n # print line\n # out = open(options.filename,'a')\n return line\n#\n#\ndef dofile():\n ''' loop display of raw serial data '''\n dline=otrf() # open file\n print "you are about to read the file"\n burner="burner"\n flue="flue"\n i = 0\n print '%s\st\st\st%s' % (burner,flue)\n # print '%i\st%s\st\st\st%s' % (i,burner,flue)\n # while ( i < 8 ):\n while True:\n i += 1\n b = 1\n dataline=rfdl(dline)\n while ( b < len(dataline)):\n if ( len(dataline[b]) < 10 ):\n l=dataline[b] \n if ( str(''.join([c for c in l if l.startswith('B')]))[0:] ):\n # burner = (str(''.join([c for c in l if l.startswith('B')]))[1:4])\n burner = re.sub(r'[^\sw]', '',(str(''.join([c for c in l if l.startswith('B')]))[1:4]))\n if ( str(''.join([c for c in l if l.startswith('F')]))[0:] ):\n # flue = (str(''.join([c for c in l if l.startswith('F')]))[1:4])\n flue = re.sub(r'[^\sw]', '',(str(''.join([c for c in l if l.startswith('F')]))[1:4]))\n if ( burner != "burner" and flue != "flue"):\n # out1 = ''.join(c for c in burner if c in digits)\n # out2 = ''.join(c for c in flue if c in digits)\n # print '%s\st\st\st%s' % ((re.sub("[A-Z]", "", "burner)),(re.sub("[A-Z]", "", "flue)) )\n # print '%s\st\st\st%s' % ((re.sub("[^0-9]", "", "burner)),(re.sub("[^0-9]", "", "flue)) )\n # print '%s\st\st\st%s' % (burner,flue)\n # print '%s\st\st\st%s' % (out1,out2)\n print '%s\st\st\st%s' % (''.join(c for c in burner if c in digits),''.join(c for c in flue if c in digits))\n b += 1\n#\ndef dofilter():\n ''' read data line'''\n\n#\ndef doofus():\n# # print 'Press Ctrl+C for interrupt'\n# if (len(tada) > 30):\n if (19 <= len(tada) < 120) :\n print 'Block %d not right with %d elements.' % (i,len(tada) )\n else:\n print tada \n #'Block %d is and underrun with only %d elements. Press Ctrl+C to interrupt ' % (i,len(tada) )\n # print 'At %s Block %d is %d elements long. Press Ctrl+C to interrupt ' % (timest(tada),i,len(tada) )\n # print 'Block %d is %d elements long. Press Ctrl+C to interrupt ' % (i,len(tada) )\n#\n# \ndef otrs():\n print "Using serial data from %s at %s bits per second, with a %s second time out factor" \s\n % (options.serial_port, options.port_baud, options.timeout)\n serp = Serial(port=options.serial_port, baudrate=options.port_baud, timeout=6)\n print "Got past open. Press Ctrl+C to interrupt block read"\n return serp\n#\ndef rsdl(ser):\n ''' read serial data Line '''\n def signal_handler(signal, frame):\n print " - You pressed Ctrl+C! in block read"\n print time.time() - start_time, "seconds"\n sys.exit(0)\n signal.signal(signal.SIGINT, signal_handler)\n # ser=""\n # print 'Press Ctrl+C to interrupt block read'\n while True:\n pac_start=time.time()\n if ser.inWaiting():\n now=str(time.time())\n dataline = ser.readline()\n outline = dataline+"\sxfeEpf Time: "+now\n # print(outline)\n # out.write(outline)\n L=re.split("\sxfeE", outline)\n return L\n#\ndef doserial():\n ''' loop display of raw serial data '''\n mser=otrs()\n # print 'Press Ctrl+C for interrupt'\n i = 0\n while True:\n i += 1\n tada=rsdl(mser)\n if (len(tada) > 30):\n print tada \n # dfout(tada)\n # print(systmp(tada))\n # print(timest(tada))\n else:\n # print len(tada) \n 'Block %d is and underrun with only %d elements. Press Ctrl+C to interrupt ' % (i,len(tada) )\n print 'At %s Block %d is %d elements long. Press Ctrl+C to interrupt ' % (timest(tada),i,len(tada) )\n#\n# display \n # output of objects test point\n # print c.alarm.__doc__ ," The value is",(c.alarm())\n # print c.state.__doc__ ," The value is",(c.state())\n print(c.alarm())\n print(c.state())\n print(c.ophours())\n print(c.resets())\n print(c.starts())\n print(c.systmp())\n print(c.stacktmp())\n print(c.thstcall())\n # print c.thstcall.__doc__ ," The value is",(c.thstcall())\n # print c.ignind.__doc__ ," The value is",(c.ignind()) # currently dumps L\n print "tada display"\n\n#\ndef dcycle():\n ''' display filtered output '''\n global L\n while 1:\n L=rfdl(dline)\n if not L:\n break\n pass\n#\ndef dfout(L):\n ''' display filtered output '''\n # global L\n counter = 0\n while 1:\n # L=rfdl(dline)\n # output of objects test point\n # print c.alarm.__doc__ ," The value is",(alarm(L))\n # print c.state.__doc__ ," The value is",(state(L))\n print(alarm(L))\n print(state(L))\n print(ophours(L))\n print(resets(L))\n print(starts(L))\n print(systmp(L))\n print(stacktmp(L))\n print(thstcall(L))\n # print c.thstcall.__doc__ ," The value is",(thstcall(L))\n # print c.ignind.__doc__ ," The value is",(ignind(L)) # currently dumps L\n counter = counter + 1\n print "tada display line %s" % (counter)\n os.system('clear')\n if not L:\n break\n pass\ndef main():\n ''' \n This is the main subroutine, any detail about this program belongs here.\n This program has two basic parts:\n 1. data gathering from at pellergy furnace with a furmon installed and\n 2. display of this data via mrtg.\nTue 02 Apr 2013 02:52:07 PM EDT this is the rewrite with the object right.\nFri 29 Mar 2013 07:02:36 AM EDT at this point the program depends on sample data\n This data is in the "New Haven Display" format and is basically binary.\nThu 04 Apr 2013 08:16:33 AM EDT new version of fm.py trying to clean up this code.\nMon 08 Apr 2013 02:17:18 PM EDT Continuing cleanup...\nFri 03 May 2013 08:46:50 AM EDT clean up serial routine\n '''\nstart_time = time.time()\n# print "starting %s at %s " % (__file__, \s\ngo_time=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(start_time))\nprint "starting %s at %s " % (__file__, go_time)\nif len(sys.argv) == 1:\n print "for operating information type '%s -h'" % __file__\n sys.exit()\n# Above handles no arguments\n#\nelse:\n# parse options and act\n parser = optparse.OptionParser(description='Furmon Software Support Package',\n prog=os.path.basename(__file__),\n version='This code is version %s, and the code, %s is copyright 2013 by fits and licensed under GPLI ' % ( ver,os.path.basename(__file__) ),\n usage= '%prog [option]')\n parser.add_option('--query', '-?', dest='bool',default=False, action='store_true',\n help='print document string with extensive result',)\n parser.add_option('--serial', '-s', dest='serialp',default=False, action='store_true',\n help='gather data from serial port',)\n parser.add_option("-f", "--file", dest="filename", default="USB", \n help="read test data from a file", metavar="FILE")\n parser.add_option("-p", "--port", dest="serial_port", default="/dev/ttyUSB0",\n help="set serial port; default=\s"/dev/ttyUSB0\s"", metavar="STRING")\n parser.add_option("-b", "--baud", dest="port_baud", default="9600",\n help="set port speed; default=\s"9600\s"", metavar="STRING")\n parser.add_option("-t", "--timeout", dest="timeout", default="6",\n help="set timeout value; default=\s"6\s"", metavar="INT")\n#\n# Evaluates inbound arguments\n options, arguments = parser.parse_args() # evaluate options\n if options.bool: \n print len(sys.argv)\n intro()\n sys.exit() \n elif options.serialp:\n print "You are at the serial routine"\n # mser=otrs()\n # print mser.__doc__rsdl(mser)\n # print dir(mser)\n #d print rsdl(mser) \n doserial()\n sys.exit() \n elif options.filename != "USB":\n print "You are at file routines"\n dline=otrf() # open file\n # print "you opened the file"\n # print dline.__doc__\n # print dir(dline)\n # print dline.readline()\n # print re.split("\sxfeE",dline.readline())\n # print inf.__doc__\n # print dir(inf)\n # print rfdl(L) # read line from file\n # print rfdl(dline) # read line from file to out\n dofile()\n sys.exit() \n elif options.serial_port != "/dev/ttyUSB0":\n print "You are at port selection"\n sys.exit()\n elif options.port_baud != "9600":\n print "You are at port selection"\n sys.exit() \n elif options.timeout != "6":\n print "You are at timeout selection"\n sys.exit() \n# More junk\n # print 'file name %s' % options.filename\n # print 'Hello %s' % options.person\n\n\nif __name__ == '__main__':\n main()\n print "that's it"\n\n}}}
Code drop for furmon data acquisition:\n\n{{{\n#!/usr/bin/env python\n#\n# pflint Mon 01 Apr 2013 07:29:56 AM EDT have methods evaluate attributes\n# once all the attributes are evaluated then reaport...\nimport os\nimport re\nimport sys\nimport optparse\nimport subprocess\nimport signal\nimport time\nimport serial\nimport io\nimport csv\nimport string\nfrom subprocess import call\nfrom serial import Serial\nfrom string import digits\n#\n#\n# establish the dreaded globals\n# global L\n# global inf\nver="0.20130403"\n# filename="furmon.data"\nfilename="/home/flint/furmon/furmon.data"\n# \ndef intro():\n ''' Prints the main story about this program and tries to warn you.'''\n print '\st %s documentation: A tale of woe and intrigue' % os.path.basename(__file__)\n print main.__doc__\n print "for operating information type '%s -h'" % __file__\n\n#\n# This is the base class for the furmon object\n# ref http://www.youtube.com/watch?v=CtzVNCmysFs\nclass furmon:\n def __init__(self):\n self.thstcall="Call"\n self.recno="#"\n self.hours="Hours Used" \n self.tonoff="Off"\n self.fsensor="00" \n self.fmotor="off" \n self.blowsp="00"\n self.alarm="No Alarm" \n self.reason="All is well" \n self.opstate="Operational State"\n self.state_counter="0000" \n self.resets="0000" \n self.stack_temp="Flue Temp"\n self.starts="000" \n self.system_temp="System Temp"\n self.butn1="Param"\n self.butn2="Test"\n self.butn3="Enabl"\n self.butn4="Feed"\n# The goal of this program is to fill in as many attributes of the object as you can.\n# These are the basic methods\n #d def expose(self):\n # ''' prints all the attributes of this object '''\n # note this is an example from \n # http://www.saltycrane.com/blog/2008/09/how-iterate-over-instance-objects-data-attributes-python/\n #d for attr, value in a.__dict__.iteritems(): \n #d print attr, value\n\n#\n# exposes attributes and values in an object\ndef expose(obj):\n ''' prints all the attributes of this object '''\n # note this is based on an example from \n # http://www.saltycrane.com/blog/2008/09/how-iterate-over-instance-objects-data-attributes-python/\n #d a=obj()\n for attr, value in obj.__dict__.iteritems(): \n if len(attr) >=8:\n print '%s\st%s' % (attr, value)\n else:\n print '%s\st\st%s' % (attr, value)\n # print '%d\st%s\st\st%s' % (len(attr),attr, value)\n\n# Here are the tests\ndef alarm(L):\n '''This determines if there is an alarm, this also reports the reason '''\n alarm="No Alarm "\n reason=" no reason " \n target="\sx00ALARM"\n for item in L:\n if item.find(target) != -1:\n index=L.index(item)\n alarm=(item[1:])\n reason=L[index+1]\n return printme( alarm+reason )\n#\ndef resets(input):\n '''This is the number of resets '''\n resets=""\n target="Resets:"\n # type="Resets:"\n # target="\sx14"\n s=re.sub(r'[^\sw]', '',input)\n if (string.find(input, target) > 0):\n # print "Got One in"\n # print s\n beg=(string.find(s, target)+len(target))\n # print beg\n resets=s[(beg):(beg+6)]\n # print "new resets =", resets\n # resets=''.join(c for c in (s[5:9]) if c in digits)\n # print "length of resets",len(resets)\n # print "length of out.resets",len(out.resets)\n if (len(resets) > len(out.resets)) or (cleann(resets) > out.resets):\n out.resets=cleann(resets)\n return cleann(resets)\n # return out.resets\n#\ndef cstate(input):\n '''This is the countdown of the current state.'''\n ''' get system temprature '''\n state_counter=""\n # target="O"\n # target="E"\n # target="dE"\n target="ZE"\n s=re.sub(r'[^\sw]', '',input)\n if (string.find(s, target) > 0):\n # print s\n beg=(string.find(s, target)+len(target))\n # print beg\n # print s[(beg):(beg+6)]\n # if (len(cleann(s[(beg):(beg+6)])) = 4):\n state_counter = cleann(s[(beg):(beg+6)])\n # print "\stgot a state count ",state_counter\n if (len(state_counter) == 4):\n out.state_counter=state_counter\n # print "got an object count ",out.state_counter\n # return printme( temp )\n return state_counter \n\n#\ndef systmp(input):\n ''' get system temprature '''\n temperature=""\n target="B"\n if ( str(''.join([c for c in input if input.startswith(target)]))[0:] ): # if the element starts with the target\n temperature = cleanv(input,target)\n # print "got a good temp"\n else: \n temperature=out.system_temp\n # return printme( temp )\n return temperature \n#\ndef stacktmp(input):\n ''' get system temprature '''\n temperature=""\n target="F"\n if ( str(''.join([c for c in input if input.startswith(target)]))[0:] ): # if the element starts with the target\n temperature = cleanv(input,target)\n else: \n temperature=out.stack_temp\n # return printme( temp )\n return temperature \n#\ndef flamesns(L):\n ''' Is the sensor sensing flame?'''\n return ( "flame sensor?" )\n#\ndef ophours(input):\n '''This is the hours the system has been operating'''\n hours=""\n # type="Hours"\n # target="\sx14"\n target="Hours"\n s=re.sub(r'[^\sw]', '',input)\n # print s\n # print string.find(s, target) \n if (string.find(s, target) == 0):\n # hours=(s[5:9])\n hours=''.join(c for c in (s[5:9]) if c in digits)\n if len(cleann(out.hours)) >= len(cleann(hours)) :\n hours=out.hours\n # hours="" \n # return printme( hours )\n return cleann(hours)\n # return hours\n#\n#\ndef opstate(input):\n '''This is the state the system is operating in'''\n # http://www.pythonforbeginners.com/strings/\n state=""\n target="\sx00"\n # print input\n # print s\n # print string.find(s, target) \n if (string.find(input, target) == 0):\n # state=(s[0:])\n state=re.sub(r'[^\sw]', '',input[0:])\n # state=''.join(c for c in (s[5:9]) if c in digits)\n else:\n state=out.opstate \n # return printme( state )\n # print state \n x=0\n statepairs = [ ('IDL','idle') , \n ('I','idle') , \n ('IGN','igniting') , \n ('FEE','feedstart'),\n ('FIR','firing'),\n ('STA','stabilizing'),\n ('SH','shuttingdown'), # test for comments in line...\n ('S','shuttingdown'), # this appears to work.\n ('PU','purging'),\n ('ALA','alarm') ]\n for s in statepairs:\n tart=len(statepairs[x][0])\n if (state.upper()[0:tart] == statepairs[x][0] ):\n state = statepairs[x][1]\n x += 1\n # return cleann(state)\n if (state.isupper() or state.isdigit()):\n state = out.opstate\n return state\n#\ndef thstcall(input):\n '''This is the thermostat call, it is either on or off.'''\n tcall=""\n target="@T"\n # L=re.split("\sxfeE", dataline)\n if (string.find(input, target) == 0):\n # state=(s[0:])\n state=re.sub(r'[^\sw]', '',input[0:])\n # state=''.join(c for c in (s[5:9]) if c in digits)\n else:\n state="" \n return state[0:1]\n#\ndef ignind(L):\n '''Ignition-indicator Ignition-count Date-time'''\n print "input string is %s" % L\n return printme( "Ignition-indicator Ignition-count Date-time")\n#\ndef starts(input):\n # print "entering starts function"\n starts=""\n beg=0\n target="Starts:"\n s=re.sub(r'[^\sw]', '',input)\n if (string.find(input, target) > 0):\n # print "Got One in"\n # print s\n beg=(string.find(s, target)+len(target))\n # print beg\n starts=s[(beg):(beg+5)]\n # print "new starts =", starts\n # starts=''.join(c for c in (s[5:9]) if c in digits)\n # print "length of starts",len(starts)\n # print "length of out.starts",len(out.starts)\n if (len(starts) > len(out.starts)) or (cleann(starts) > out.starts):\n out.starts=cleann(starts)\n return cleann(starts)\n # return out.starts\n#\ndef blower(L):\n return printme( "Blower-value Date-time")\n#\ndef button1(L):\n return printme( "Button1-pressed Date-time")\n#\ndef button2(L):\n return printme( "Button2-pressed Date-time")\n#\ndef button3(L):\n return printme( "Button3-pressed Date-time")\n#\ndef button4(L):\n return printme( "Button4-pressed Date-time")\n#\n#\ndef printme( str ):\n '''This time stamps a string passed into this function'''\n out=str+"\st\st"+cfltime(tada)\n return out\n#\ndef timest(L):\n '''This pulls the timestamp out of the data string'''\n type="Time"\n target="pf"\n for item in L:\n if item.find(target) != -1:\n # print len(item)," ",(item[1:])\n # if 19 <= len(item) < 22: \n # if item.find(type) != -1:\n rawtime=float(item[9:]) # must be float to work in time machine\n # print rawtime\n # print time.localtime(rawtime)\n tm=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(rawtime))\n # tm=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(1367590968.24)))\n # time=(item[8:])\n # return printme( hours )\n return tm\n#\n # inserts time nearly everywhere...\ndef cfltime(fd):\n '''inserts time nearly everywhere...'''\n cflout=""\n type="Time"\n target="pf"\n #\n for item in fd:\n if item.find(target) != -1:\n if item.find(type) != -1:\n rawtime=float(item[9:21]) # must be float to work in time machine\n cflout=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(rawtime))\n return cflout\n#\n#\ndef cleann(thing):\n ''' cleans up a variable returns a number no matter what'''\n # mid = re.sub(r'[^\sw]', '',thing)\n out = ''.join(c for c in thing if c in digits)\n if out == "":\n out="0"\n return out\n\n#\n#\ndef cleanv(thing,trigger):\n ''' cleans up a variable starting with a number no matter what'''\n mid = re.sub(r'[^\sw]', '',(str(''.join([c for c in thing if thing.startswith(trigger)]))[1:4]))\n out = ''.join(c for c in mid if c in digits)\n if out == "":\n out="0"\n return out\n\n#\n#\n# open file information for reading\ndef otrf():\n ''' open to read file'''\n try:\n inf = open(options.filename, "rb")\n except IOError: \n print "The file '%s' does not exist, please correct and retry..." % options.filename\n sys.exit()\n print "you opened the file from otrf"\n return inf\n #\n# \n#\ndef rfdl(dfile):\n ''' read data line'''\n dataline=dfile.readline()\n line=re.split("\sxfeE",dataline)\n # print line\n # out = open(options.filename,'a')\n if dataline == '': \n dataline = "EOF"\n return line\n#\n#\ndef dofile():\n ''' loop display of data from a file '''\n print "you are in dofile routine about to read the file"\n status="undefined"\n i = 0\n #d while ( i < 8 ): # for run limit in debug mode...\n while True:\n i += 1 # count for run limit\n b = 1\n dataline=rfdl(dline) # assumes open file with pointer to dline \n #d print dataline\n while ( b < len(dataline)):\n os.system('clear')\n if ( len(dataline[b]) < 50 ): # sets allowable element length\n l=dataline[b] \n out.system_temp = systmp(l)\n # print systmp(l)\n starts(l)\n out.state_counter = cstate(l)\n out.stack_temp = stacktmp(l)\n out.hours = ophours(l)\n out.opstate = opstate(l) \n out.thstcall = thstcall(l) \n resets(l) \n out.recno = i\n # outfile1() \n # outfile() \n print 'in line %d' % (b)\n expose(frfile) #really good object dumpter\n # print "output of ",out\n # dftest()\n # dfout()\n os.system('sleep 0.25s')\n # os.system('clear')\n b += 1\n#\ndef tfile():\n ''' test loop display of data from a file '''\n # dline=otrf() # open file do this from main routine...\n print "using tfile to read the file"\n # system_temp="System Temp"\n # out.stack_temp="Flue Temp"\n status="test"\n i = 0\n # print '%s\st%i\st\st\st\st%s' % (status,i,out.opstate)\n #t while ( i < 8 ):\n while True:\n #t i += 1 # count for run limit\n b = 1\n dataline=rfdl(dline)\n #d print dataline\n while ( b < len(dataline)):\n if ( len(dataline[b]) < 50 ): # sets allowable element length\n l=dataline[b] \n cstate(l)\n b += 1\n#\n#\ndef Sfile():\n ''' test loop display of data from a file '''\n # dline=otrf() # open file do this from main routine...\n print "using tfile to read the file"\n # system_temp="System Temp"\n # frfile.stack_temp="Flue Temp"\n status="test"\n i = 0\n # print '%s\st\st%s' % (status,status)\n print '%s\st%i\st\st\st\st%s' % (status,i,frfile.state)\n while ( i < 8 ):\n #d while True:\n i += 1 # count for run limit\n b = 1\n dataline=rfdl(dline)\n #d print dataline\n while ( b < len(dataline)):\n if ( len(dataline[b]) < 50 ): # sets allowable element length\n l=dataline[b] \n # print "record = %s entering opstate sub" % b\n frfile.state=opstate(l)\n if ( frfile.state != "" ):\n print "leaving tfile record = %s current state = %s" % (b,frfile.state) \n b += 1\n# \ndef otrs():\n print "Using serial data from %s at %s bits per second, with a %s second time out factor" \s\n % (options.serial_port, options.port_baud, options.timeout)\n serp = Serial(port=options.serial_port, baudrate=options.port_baud, timeout=6)\n print "Got past open. Press Ctrl+C to interrupt block read"\n return serp\n#\ndef rsdl(ser):\n ''' read serial data Line '''\n def signal_handler(signal, frame):\n print " - You pressed Ctrl+C! in block read"\n print time.time() - start_time, "seconds"\n sys.exit(0)\n signal.signal(signal.SIGINT, signal_handler)\n # ser=""\n # print 'Press Ctrl+C to interrupt block read'\n while True:\n pac_start=time.time()\n if ser.inWaiting():\n now=str(time.time())\n dataline = ser.readline()\n outline = dataline+"\sxfeEpf Time: "+now\n # print(outline)\n # out.write(outline)\n l=re.split("\sxfeE", outline)\n return l\n#\ndef dorserial():\n ''' loop display of raw serial data '''\n mser=otrs()\n # print 'Press Ctrl+C for interrupt'\n i = 0\n while True:\n i += 1\n tada=rsdl(mser) # using rdsl with a pointer to otrs to read data into tada\n if (len(tada) > 30):\n print tada \n # dfout(tada)\n # print(systmp(tada))\n # print(timest(tada))\n else:\n # print len(tada) \n 'Block %d is and underrun with only %d elements. Press Ctrl+C to interrupt ' % (i,len(tada) )\n print 'At %s Block %d is %d elements long. Press Ctrl+C to interrupt ' % (timest(tada),i,len(tada) )\n#\n#\ndef doserial():\n ''' load serial data into attributes '''\n mser=otrs()\n print 'Press Ctrl+C for interrupt'\n print "you are in dofile routine about to read the file"\n status="undefined"\n i = 0\n #d while ( i < 8 ): # for run limit in debug mode...\n while True:\n i += 1 # count for run limit\n b = 1\n dataline=rsdl(mser) # assumes open file with pointer to dline \n #d print dataline\n while ( b < len(dataline)):\n os.system('clear')\n if ( len(dataline[b]) < 50 ): # sets allowable element length\n l=dataline[b] \n serial.system_temp = systmp(l)\n # print systmp(l)\n starts(l)\n serial.stack_temp = stacktmp(l)\n serial.hours = ophours(l)\n serial.opstate = opstate(l) \n serial.thstcall = thstcall(l) \n resets(l) \n serial.recno = i\n # outfile1() \n # outfile() \n print 'in line %d' % (b)\n # expose(frfile) #really good object dumpter\n dfout()\n os.system('sleep 0.25s')\n # os.system('clear')\n b += 1\n\n i += 1\n tada=rsdl(mser) # using rdsl with a pointer to otrs to read data into tada\n if (len(tada) > 30):\n print tada \n # dfout(tada)\n # print(systmp(tada))\n # print(timest(tada))\n else:\n # print len(tada) \n 'Block %d is and underrun with only %d elements. Press Ctrl+C to interrupt ' % (i,len(tada) )\n print 'At %s Block %d is %d elements long. Press Ctrl+C to interrupt ' % (timest(tada),i,len(tada) )\n#\n#\ndef dcycle():\n ''' display filtered output '''\n # global l\n while 1:\n l=rfdl(dline)\n if not L:\n break\n pass\n#\ndef serdis():\n '''display of raw serial data'''\n # output of objects test point\n # print serial.alarm.__doc__ ," The value is",(serial.alarm())\n # print serial.state.__doc__ ," The value is",(serial.state())\n print(serial.alarm())\n print(serial.state())\n print(serial.ophours())\n print(serial.resets())\n print(serial.starts())\n print(serial.systmp())\n print(serial.stacktmp())\n print(serial.thstcall())\n # print serial.thstcall.__doc__ ," The value is",(serial.thstcall())\n # print serial.ignind.__doc__ ," The value is",(serial.ignind()) # currently dumps L\n print "tada display"\n#\ndef dfout():\n ''' display object instance based output '''\n # note that out must be set to an object instance name\n print(out.alarm)\n print(out.opstate)\n print(out.hours)\n print(out.resets)\n print(out.starts)\n print(out.system_temp)\n print(out.stack_temp)\n print(out.thstcall)\n#\ndef dffile():\n ''' display file based output '''\n print(frfile.alarm)\n print(frfile.opstate)\n print(frfile.hours)\n print(frfile.resets)\n print(frfile.starts)\n print(frfile.system_temp)\n print(frfile.stack_temp)\n print(frfile.thstcall)\n#\n\ndef main():\n ''' \n This is the main subroutine, any detail about this program belongs here.\n This program has two basic parts:\n 1. data gathering from at pellergy furnace with a furmon installed and\n 2. display of this data via mrtg.\nTue 02 Apr 2013 02:52:07 PM EDT this is the rewrite with the object right.\nFri 29 Mar 2013 07:02:36 AM EDT at this point the program depends on sample data\n This data is in the "New Haven Display" format and is basically binary.\nThu 04 Apr 2013 08:16:33 AM EDT new version of fm.py trying to clean up this code.\nMon 08 Apr 2013 02:17:18 PM EDT Continuing cleanup...\nFri 03 May 2013 08:46:50 AM EDT clean up serial routine\nTue 11 Jun 2013 01:48:23 PM EDT working on the file based system\nWed 12 Jun 2013 08:46:56 AM EDT cleaning up file and testing serial based system...\n '''\nstart_time = time.time()\n# frfile = furmon() # instantiate the furmon class to frfile\n# print "starting %s at %s " % (__file__, \s\ngo_time=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(start_time))\nprint "starting %s at %s " % (__file__, go_time)\nif len(sys.argv) == 1:\n print "Welcome to the Furmon Support Package, fm.py. For operating information type '%s -h'" % __file__\n sys.exit()\n# Above handles no arguments\n#\nelse:\n# parse options and act\n parser = optparse.OptionParser(description='Furmon Software Support Package',\n prog=os.path.basename(__file__),\n version='This code is version %s, and the code, %s is copyright 2013 by fits and licensed under GPLI ' % ( ver,os.path.basename(__file__) ),\n usage= '%prog [option]')\n #\n parser.add_option('-?', '--query', dest='bool',default=False, action='store_true',help='print document string with extensive result',)\n parser.add_option('-s', '--serial', dest='serialp',default=False, action='store_true',help='gather data from serial port',)\n parser.add_option("-f", "--file", dest="filename", default="USB",help="read test data from a file", metavar="FILE")\n parser.add_option("-p", "--port", dest="serial_port", default="/dev/ttyUSB0",help="set serial port; \stdefault=\s"/dev/ttyUSB0\s"", metavar="STRING")\n parser.add_option("-b", "--baud", dest="port_baud", default="9600",help="set port speed; \stdefault=\s"9600\s"", metavar="STRING")\n parser.add_option("-t", "--timeout", dest="timeout", default="6",help="set timeout value; \stdefault=\s"6\s"", metavar="INT")\n#\n# Evaluates inbound arguments\n options, arguments = parser.parse_args() # evaluate options\n if options.bool: \n print len(sys.argv)\n intro()\n sys.exit() \n elif options.serialp:\n print "You are at the serial routine"\n # serial = furmon() # instantiate the furmon class to serial\n # mser=otrs()\n # print mser.__doc__rsdl(mser)\n # print dir(mser)\n #d print rsdl(mser) \n doserial()\n sys.exit() \n elif options.filename != "USB":\n print "You are at file routines"\n dline=otrf() # open file\n print "this is the end of opening"\n frfile = furmon() # instantiate the furmon class to frfile\n out=frfile\n # print frfile.system_temp\n # print dline.__doc__\n # print dir(dline)\n # print dline.readline()\n # print re.split("\sxfeE",dline.readline())\n # print inf.__doc__\n # print dir(inf)\n # print rfdl(L) # read line from file\n # print rfdl(dline) # read line from file to out\n # print rfdl(dline) # read line from file to out\n dofile() # code to use for all object elements\n # tfile() # test individual object elements\n # expose(furmon)\n # expose(frfile)\n sys.exit() \n elif options.serial_port != "/dev/ttyUSB0":\n print "You are at port selection"\n sys.exit()\n elif options.port_baud != "9600":\n print "You are at port selection"\n sys.exit() \n elif options.timeout != "6":\n print "You are at timeout selection"\n sys.exit() \n# More junk\n # print 'file name %s' % options.filename\n # print 'Hello %s' % options.person\n\n\nif __name__ == '__main__':\n main()\n print "that's it"\n\n\n}}}
|!Reference HTML|! Description|\n|[[tekscan|http://www.tekscan.com/flexiforce/load-cell.html?utm_source=google&utm_medium=cpc&utm_term=load+cell&utm_content=ad1&utm_campaign=load+cell&gclid=COe0yvOutb0CFaVQOgodiCAAKA]]||\n|[[tekscan|http://www.tekscan.com/flexible-force-sensors#specifications]]|specifications|\n|[[tekscan|http://www.tekscan.com/flexiforce-sample-circuit]]|sample circuit|\n|[[tekscan|http://www.tekscan.com/pressureSensors]]|pressure sensors|\n|[[tekscan|http://www.tekscan.com/store/flexiforce-sensors.html]]| flexiforce sensors|
Logstash?\n\nGraphite?\n\nelastic search\n\ngrok\n\nkabana\n\n
Wonder Boy recommends:\n* change serial input routing\n* add a jmake function that puts out json\n* report the last time the object was seen
GettingStarted\n[[Chris GitHub Repo|https://github.com/cpyarger/furmon-1]]\n[[Flint GitHub Repo|https://github.com/flintiii/furmon]]