pax_global_header00006660000000000000000000000064133746042150014517gustar00rootroot0000000000000052 comment=a162e63aad35358aab325388f3d5e88121606419 digitemp-3.7.2/000077500000000000000000000000001337460421500133325ustar00rootroot00000000000000digitemp-3.7.2/.gitignore000066400000000000000000000000041337460421500153140ustar00rootroot00000000000000*.o digitemp-3.7.2/COPYING000066400000000000000000000354251337460421500143760ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for non-commercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS digitemp-3.7.2/COPYRIGHT000066400000000000000000000016061337460421500146300ustar00rootroot00000000000000 DigiTemp v3.7.2 Dallas Semiconductor one-wire temperature sensor interface http://www.digitemp.com Copyright (c) 1996-2018 by Brian C. Lane http://www.brianlane.com All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA digitemp-3.7.2/CREDITS000066400000000000000000000011671337460421500143570ustar00rootroot00000000000000Brian C. Lane Original DigiTemp code, and editor of submitted patches Erik Rigtorp Developed the ds9097 code for the owpd kit. Jesus Roncero Debian package maintainer Hub search fixes Manpage Eric Wilde DS2438 Humidity support Sven Geggus -n0 infinite loop Ewan Leith AIX Support Roland Roberts DS1822 and DS18B20 changes Ted Frohling 1-wire hub loan John Stoffel Solaris, AIX, FreeBSD patches Erik Rigtorp userial driver for passive DS9097 adapter Kevin Pedigo Makefile cleanup Peter Enderborg sleep change Måns Nilsson OpenBSD (need to add more names here) digitemp-3.7.2/ChangeLog000066400000000000000000000464511337460421500151160ustar00rootroot0000000000000008/27/2008 Gathering up patches for a v3.6.0 release. Changes Include: - Releasing new version with these changes: - Updated to the .spec file from Fedora9 - DS2490 now suppresses the 'Found usb ...' output - Support for compiling under DARWIN - Current reading added to DS2438 - DS28EA00 support added - Tabbed output of 0.00 on CRC errors with log type -o2 or -o3 - New manpage from Debian digitemp maintainer 01/01/2007 Released v3.5.0 12/26/2006 Adding DS1923 Hygrosens Logger support from Tomasz Nowak Moved all of the history to ChangeLog 12/25/2006 Added Cygwin support Fixing ambiguous error messages (eg. blank config file or blank serial device). 06/25/2005 Logging output for DS2438 is not consistent with the other outputs. When -o2 and -o3 are used the temperatures for the DS2438 devices are output. The -H option can still be used to customize the DS2438 output when not using the -o options. 02/03/2004 Broke DS9097 support with my owWriteBytePower() return code check in digitemp.c in v3.3.1, so I applied the new DS9097 performance patch from Erik Rigtorp and changed owLevel in the ds9097 code to return the value called with to fake out the higher level code. Added FREEBSD to the typedef section of ownet.h, maybe this will fix some of those problems. 02/01/2004 Fixed DS2490 USB adapter support. Fixed Makefile so that it doesn't need to be edited for USB support. 01/25/2004 A user reported a bug in the humidity temperature, it wasn't converting negative temperatures correctly. I also see a potential problem with the DS18B20 and DS1822 which use a short int type and depend on it being 16 bits so that the sign comes out correct. But can we count on a short int always being 16 bits? I need to look into it. 01/10/2004 I'm trying to wrap up all the patches I've received int a new release v3.3.0 with humidity and DS2438 support. Added code from Eric Wilde to do humidity calculations for the AAG TAI-8540 humidity sensor. Adding patches for OpenBSD from Mns Nilsson. Changing the binary names that are generated to differentiate between DS9097, DS9097U and DS2490 (usb) adapter support. The USB support still doesn't work right. It searches the LAN ok, but needs to be root to do so, and doesn't read properly. I'll deal with it in the next release I guess. Added lockfiles. This requires either setting the binary to group lock (chmod g+s;chown .lock digitemp_*) or adding the user who will be running it to the lock group. 11/29/2003 Trying to get a first pass at DS2438 (A/D & Battery monitor) support up and running. Found a bug, init wouldn't record counters found on branches of a hub. 10/27/2003 Added patch from Sven Geggus to allow -n0 to make it run in an infinite loop. Need to check for exit conditions and clean up logfile, serial port, etc. in a nice manner. 08/13/2003 Adding DS2490 USB to 1-wire adapter support. Bumping the version number to 3.3.0 without a release of 3.2.1 06/14/2003 Made change to hub search from Jess Roncero, it wouldn't work right if run with -q (a owFirst was inside the quiet check). Also adding the manpage created by Jes. Version changed to 3.2.1 05/24/2003 Adding a banner that reports what library the binary was compiled for (DS9097 or DS9097U). Adjusted the makefile a bit, change the dist to be one of dist-9097 or dist-9097u to build for the right target. 05/23/2003 Adding kludges for USB to Serial adapter. Added a loop of 10 tries to the DS2480Detect routine. Added DEBUG_USERIAL compile time wrappers for diagnostic information about the ReadCOM routine. Part of the key to this is the delay used in ReadCOM, its just too short for use with the USB to serial adapter. I've changed it to 1 second + 10-15mS -- I'm not sure that the global_msec is really needed with the longer timeout time, its a fail-safe anyway; the character ought to come back a long time before the timeout. Changed version to v3.2.0 02/14/2003 Adding logging of read values. Need to change the way it handles building the output string. It works, but the counter really needs its own format string. Kinda hard to automatically integrate it into the current temperature oriented format string. 02/12/2003 Adding more code... Needs more work, the family code may be buried in the coupler linked list. I may need to move the decision as to how to read it to after it finds the coupler and turns it on. Change read_temp to read_sensor. device selection is common to all devices, then switch based on the serial number finally selected (saved as it is selected). 02/06/2003 Changed version number to v3.1.0 Adding support for counters Happy 92nd Birthday to Ronald Reagan! 01/10/2003 Finally, humidity is working, thanks in large part to work by Eric Wilde. Need to add logging of DS2438. I think it will be hard-coded, if it needs to be in another format it can be parsed with perl or python or whatever. Fixed a bug that wasn't allowing %% to be embedded in the format specifier. Adding lockfile support using the lockdev library under Linux. Wrapping it in LINUX checks until other systems indicate that they can use it. Lockfiles are working, but - the binary has to be sgid to the lock group so that it can access /var/lock, adding the user to the lock group would also accomplish this. 01/08/2003 Still trying to get DS2438 and Humidity support working Also changing strcpy to strncpy, dunno why they weren't already using it. 01/04/2003 Adding DS2438 based humidity support from Eric Wilde. 11/21/2002 Changed sleep method to use less CPU cycles, thanks to peter enderborg for pointing it out. 11/19/2002 Reviewing massive changes from Erik Rigtorp, he has added a userial compatible version of the passive adapter code. I am creating a new Makefile that will work for all systems and allow selection of the adapter at build time. Thanks for this version go to Erik Rigtorp for adding the userial compatible passive code. His webpage can be found at http://erkki.g0ds.org/ Thanks also go out to Kevin Pedigo for his help in getting the new Makefile up and running. Kevin is the current President of KPLUG (www.kplug.org/~kevinp) Improved the sleep method when reading sensors multiple times so that it doesn't use 100 CPU while waiting. Thanks to peter enderborg for pointing this out. Changed version # to v3.0.0 08/21/2002 Small bug with -i crept in, it wants another command to be present, it won't just initialize. 08/18/2002 Added %N token to allow the time in seconds since Epoch to be selected in the output. Added module for NetSaint/Nagios to perl directory, it is named check_digitemp.pl Added a MySQL logging script to perl directory, it is named digitemp_mysql.pl Added check for serial port permissions and nice error output if the user doesn't have +rw on the selected port. Removed limitation on -i being the only command. It can be combined with other commands again. Changed to v2.6 08/16/2002 Adding %N token to output seconds since Epoch, which is masked by my use of %s for the sensor number. I don't want to remove %s, because that would break old code. So %N now maps to %s in the strftime format. The check for commands is too strict, it isn't allowing -i to be combined with any of the other commands. Added permission checking on the serial device with a clean exit if the user doesn't have access to the serial device. 06/23/2002 Releasing new version today. Really! Making -q turn off the extra output I added for initializing the 1-wire lan. 06/08/2002 Adding patches from John. exit() codes are now #defines and .digitemprc now outputs the serial numbers as hex instead of decimal. But maintains backwards compatibility until a new .digitemprc is written. Output format string now includes an option to output the Sensor's serial number in hex (%R). 06/08/2002 Made changes suggested by John Stoffel. Consisting mostly of code reorganizations. The one new feature is the %R format specifier for the log output string which inserts the hex serial number of the sensor into the output. We changed the way command line arguments are processed, so getopt is only called once, and added a check to make sure only 1 of the action commands is specified and complain otherwise. Changed to v2.5 05/11/2002 Adding more changes from John Stoffel 05/08/2002 Integrating changes for Solaris, AIX, FreeBSD from John Stoffel. Changes to getopt initial settings, Makefile and include files. 05/06/2002 Adding changes and fixes from DT v2.5 for Windows. Family code for DS1822 was wrong, it is really 0x22 Lots of changes to the read_temp routine, added a better scratchpad dump routine (previous one only worked for the DS1820). Quite a bit needs to be changed, I have switched to using a structure to store the sensor and coupler lists. I updated the core temperature read routine, the lan walk and device search routines. Reading when using a hub is now faster when reading multiple devices on the same hub segment. 01/15/2002 Cleaning up, preparing for release 01/15/2002 Added support for DS2409 one-wire couplers like those used in Simon Atkin's hub. www.simat.enta.net Converted to Dallas Semi's userial v3.00 one-wire library. Version changed to v2.3 Added a -w command to walk the entire one-wire LAN and show all device serial numbers with a descriptive family type. Thanks to Ted Frohling for the loan of the one-wire Hub. 01/14/2002 Adding support for reading sensors on DS2409 couplers. 01/13/2002 Walking the tree now works -- after changing the swt1f.c routine to use the Smart-On Main command while searching for devices (otherwise it only finds the first). Adding support for Coupler to the main program. Init now works, writing .digitemprc now works. Read .digitemprc appears to work. Need to add reading of specified sensors and of all sensors. 01/12/2002 Adding a diagnostic walk of the attached network, working on DS2409 MicroLAN Coupler support. Added release1WireNet calls before all exit calls. Switching to the userial library v3.0.0, I seem to have run into a problem with the old library and I cannot read either of my DS9097U adapters with v2.2 digitemp code. 05/26/2001 The 18B20 and 1822 patch didn't work. It was reading the wrong scratchpad registers. (2,1 instead of 1,0). Changed version to v2.2 03/16/2001 Integrating the AIX patch from Ewan Leith It amounts to return value checking on getopt and changes in the wirelnk.c file. Adding DS1822 and DS18B20 changes from Roland Roberts 03/16/2001 Integrated the AIX changes Integrated the DS1822 and DS18B20 patch Added the patch for DS1822 and DS18B20 support. 03/13/2001 Version 2.1 release Added detection of a temperature glitch in the DS1820 Added detection of the DS18S20's 85 degree C error state Added output of error conditions to stderr Bad reads will now insert zeros instead of skipping the sensor If a read fails it is retried 3 times before giving up on that sensor. The remainder of the sensors are still attempted. Added a command line option (-c) to allow the configuration file to be specified. Added a couple more scripts to the rrdb directory. 03/05/2001 Adding a command line option to specify the configuration file to use. -c config_file will override the default of .digitemprc 02/17/2001 If there is an error with strong pullup on/off it shouldn't abort the conversion! Just log an error to stderr. 01/31/2001 Added a dummy temperature output when a sensor cannot be read. It outputs a 0 so that scripts like my grapher don't get confused and log the wrong sensor in the wrong place. An error message is also output to stderr. 01/29/2001 Oops. It seems that I missed the line in the DS1820 datasheet that says Vdd needs to be tied to GND for Parasite power to work correctly. Various curses come to mind. The DS1820 works better than the DS18S20 with Vdd floating but this probably explains the infrequent glitches I saw before adding the DS18S20s. 01/15/2001 Still getting glitches. Adding a reset and delay before retry 01/14/2001 Changed Version number to 2.1 I now have 2 DS18S20 sensors which supposedly fix the Temperature accuracy problems of the DS1820 (see the ds1820-report.pdf from Dallas). But now I get a huge number of glitches in the DS18S20's readings. The DS18S20 has an error condition, but it is +85C and the glitches I am seeing are because DigiTemp doesn't output anything at all for the DS18S20's reading. Adding a check for the DS18S20's error condition: LSB = 0xAA MSB = 0x00 COUNT_REMAIN = 0x0C COUNT_PER_C = 0x10 If this error case is encountered, the reading should be repeated. If it comes up again, use it. There is also a glitch possible in the DS1820 that exhibits itself by COUNT_PER_C - COUNT_REMAIN = 1, this should be checked for, and the reading repeated and the next result used. The problem with no reading from the device seems to happen when MLanAccess is called. There is no good way to tell what the problem is, so I will change the code to try 3 times before failing. Changes are in read_temp. 01/04/2000 Changing the default read timeout to 1000mS. I had problems with it set to 500mS and a 30' sensor wire (the reading was low by about 10 degrees). 01/04/2000 Version 2.0 release Adding support for the DS9097-U adapter for the Linux version. The Solaris version will need changes to be able to support the DS9097-U. Changed license to GNU General Public License v2.0 Added the -q option to make the banner disappear. 01/01/2000 Well, no release last year. Adding -q to make the banner dissapear for batchfiles that want to get the output directly. 12/28/1999 Changed Version number to 2.0 Adding GNU public license Changing this code to use the DS9097-U adapter 06/03/1999 Finishing this thing up. 06/02/1999 Use 2 logging routines, log_time to log a single line per sensor with optional time data and log_str to log a single line for multiple sensors with elapsed time at the beginning of the line. 05/29/1999 Added 2 new init file tags, LOG_FORMAT and LOG_TYPE New formatting works, need to clean up the logic now. 05/27/1999 Adding user specified format string. To use it, first parse out the digitemp specific stuff and create a new string to feed into strftime, with the sensor, temperature already set. 05/24/1999 Adding a output specifier string, this will allow users to configure the output to look however they want it to. The format string uses strftime tokens plus 3 special ones for digitemp - %s for sensor #, %C for centigrade, %F for fahrenheit 05/23/1999 Adding Solaris support via -DSOLARIS define Fixing the time problems once and for all, using localtime in the log_line routine. The user should have TZ set correctly for their timezone. This has been tested and works correctly. Changed version number to v1.3 05/23/1999 Adding Solaris changes, donated by a user. Removing libc5 binaries, I no longer have a libc5 system Fixing the time problems with logging 01/14/1999 A user in Sweden (and another in Finland) discovered a long standing bug. In do_temp I should have been using 0x100 instead of 0xFF for the subtraction. This caused temperatures below 0 degrees C to jump up 1 degree as it decreased. This is fixed. Changed version number to v1.2 10/20/1998 Adding new features from DOS version to keep things consistent. Removing the debug command, not used anyway. Added a free() to error condition edit from read_rcfile() Set some cases of freeing to = NULL, also freed the rom list before doing a search rom (searchROM checks too, but this is the right place for it). 08/31/1998 Adding a check for family 0x10 so that we can read DS1820s while they are on a network that includes other 1-wire devices. Fixed a problem with freeing uninitialized rom_list when starting a SearchROM. Not sure why this never appeared before. 03/06/1998 Adding a -d debug level to help figure out why this thing is no longer working. 03/13/1997 Error in CRC calculation. Wrong # of bytes. Error with 3 sensors. Sometimes doesn't store correct ROM data to .digitemprc -- need to malloc more memory dummy! 03/08/1997 Adding user defined timeouts for failure and for the read delay. 01/24/1997 Changed over to correct baud rate and 6 bits @ 115.2k ROM search function is now working. All low level code is functioning except for Alarm Search. Starting to move into a seperate object file with API for users to write their own code with. 01/22/97 Working on ROM search routine, double cannot handle a full 64 bits for some reason, converting to 64 byte array for each bit. 01/19/1997 Rewriting for new interface. This programs handles all the low level communications with the temperature sensor using the 115200k serial adapter. 01/02/1996 Rewriting this code to be more user friendly digitemp-3.7.2/DS9097_Schematic.gif000066400000000000000000000176701337460421500166530ustar00rootroot00000000000000GIF89aj""" !!!200888A@@GGGQPPVVVa``oooqpp!Created with The GIMP,j"@pH,Ȥrl:ШtJZجvzxL.zn|N~XZGV[h;T &d谢:R0Fhc9P@f$8NP$i6L`d鲦5JpƤig4H(3F%j1D&e괪0`ժWX[f"YUaR='i7KݹxݒU7Y1ʋ:+߉ EAO ;tgvwD%a{[ceՑsC<@qlLYAM(vt=6!]Z%~_',a] |&#E`eUdCα߉iMYZ!P[g%AwyYErf`vg6h}xibրvZ7{#Ц<~'#Ǟw:*wF*ꪥfu魀ʪk a8F*l'Fl&ȂE-+$w,N#mn+n#-[Hb ֻϹ>K h' 7/5Uov ,$l(wc̆,kSXf΄܈9c#@ "pADMUK4QL 4M5D8ML]Hg\sqC0"`wC  - jpqKMxAm7Fd^P(0D x#A0D~9U/M +9߳A~{@-^'1;޷K$|0_4 Ak8 Ncwr@|WA Нx0¦|c!uAܖ!H HY6/X30E&"rb .vъdҀ>x gD#7\W3Sΐ+qƦ wc/1Ρ,@V<`\9{(Rt"8t&yi"0> Ӥw=O (&(f$B&d:&CC~DЀ!6{R|O]89 e:$ Jd @ D`$IBp] lz=g8됳 A"JҒ(MJW0LgJӚ46ͩIqӞf% L* 71VjQ~sRXp|B@P C & k!)9B`jDU|ǨŐ>Œp&9b p逪JDux+0ʆ&`%E: V*,6T^H'(VBE8@qDݴAu\ FF$ X3w @FV*={]kn'L}wU4Pq' Sk^W @ 0< AHu /`5CbKXRdjS\ŕxh[;dEc2 >Ń sbch+1+,%Ax2!"Fc Le9pY^n! ypl5Orwxs.9d&C,$c h\Ɔ&G>+m eä θǦ-\qE@4F-6ǡҷtS-UKdh[T-t=0ߚ2ς3> 64mnw@|_l18Ɉ!C|[BJމEpn:V;s7{"@x:ކ;C p b`;=u31\M~ƨ8yk:%42e`_\P86ЈcY19S | &BMFZXo$QЀ{=:υ'qRǁ j;Rp۽F:[J*BgT.lG|)z;~vg&@rKJ/Cѫj;MB.z$GE 'hoR,*a`ɞ'ѻ== |"Pė$JP 427LEHJ$Ё/;(Bg5}G"zL4wHAWH pϷ BU`{{{w`}(ir*g$t('t"T,xx0^npdyqX!6{LMUgTE%PyMxB Px#G}F+xagLzPJF3&4LD4j^&ߔ7|DT?xXC(;-tH8*t5L4cETTxTNLh&T@g[jO' pWu$$`ᆉ( `0IE\faLJav|E^J {#{Dp pUXH]WQ"@O fs0yV\GƤHX+hWh sy 0]b\] |.HRsx#DXCOGXYL@xa#&U0BK`Tt%HMs8GIŏAqX|s yWq9 PeW@G(D7(|uCuqW IXOu2;1n| b"v;I02)@T§{ѷ/u}+HHwhH{^ {Д}%Q}c}~X2ܤuxǔɀ){,n?#&'{@a`ejMt9)XxAWMcTyAT0 uGDŽNx7bxx([wiTy *I7hGmOǨ Az2h@oQP,9Sy ڶY(n oqyllPHG&p#&`x{W %_u DQ.2iIã6Tpضbwvgz@ʁZLGsr1Zx0s*@PЛvOn \*o2o=8=~hLڤF|3 dlTTPV%:zbJ ZZr6`wmu|ߐ~hjP pY pÚwР9W(j@&s]:J Fwë՚_JWp߂ [npJHh`HpzTz#;Sy_ԪxTEH0CVN`$9` ky{1BhfF*j2Hiˆs<HX" [z!Ѵ㈩f-3hABQAtpjPu^ɱq"V5!U8`BQ}n۶~{XK+|U/#6x q{";k$ы'"|`"OQ*81 ̔E躄kz&+ZL Ň?a{&FmJ"j1"z!1ɠ qʮuٻtF 8ȓ)b}7POLA~@hQzV[t{ (=gY&c`j~E|~H\aA<ۚu*hXJ&hl+w@*PLMHQOwYLAwM+- OsAcG;4g⻛K ]Z0YP ÖpxeX*naj>:\ü[vΐ\,M ؊i)Ω̪Ҽ;pLVPчrՆ*^=iŤy0 L09<0<!eL+ *oէdzDž}PiG:C@APD;dA:pVԕiˠȮr|\R: rVm7#C=C8cϹfkbnfqQM(N"MZ-9zL3:R(5ڤ]ڦ}ڨڪ}Qxj;Vmræ^n$5fٚ-`op9uܧF<&~ BQC]"PM09(GB}XJ+seOw}5O3?{N`6[ ȠP#mr[fSGZೌWtʜ O!L`x[.s(n ]<QKব }wiĐ<#Falшà(kVnX~R~\_~0 {4a Z@e^i kNm.,6 #ųjb yu @T7"[&N)(Vby9RLPB$0O64v%E"Tˆ IuTJwg $ UMtMO0@BwS9>|Ŋ$dNTt"LTMn3%:]<~Ӑ{, 7PGqT%;[T^+I%KL+zGCn$ MTHM됤拜M!p6H[LH=|p:NP9nf԰4#9X< wxy56^IS@1T4MW`5MP2?!mmd ϟ_5;>Pk ~p / \@ E>MNUn]7#c|lctu}si#0C2Rr/1R@4TT5U55tҳt8ՋCQ9#bY3ɓW;[{Ԙb\ko]9!77Ox 4ް: \u-@%Vx1C+7RJ @WhP cJ+'qq:$Y3(BJ)  OSVB ֬"|b#'$DimZD6i6C|{kyH\´Ӓ u 3 !l f thn.hR#] \䳐_lfۢyc-eGi{F5"*$]L/0wvw$Wוzȃ·|8B~pA7fj^Nl戠J{B)SJbb-f]R;v$_.Xy(eg{Ъl%6n}[3}B\;^u#>0|t&" X\-*3,uUߎ} وKd$] XUċD=- &eR8脏h%8^:{ϻTry>#y>n6X F&HLLqo./{.Y `D"Jў `5o.B |+M_fh)c6ޥ 7/!2p0 dvZf٨h`,"ߋbܵpؖ[a!dDOq OYok p۷?ݻOPF@׵ȉuAk*#69- `X0HQ]:B(ьq uu`c*:Qr$*;kP^D / )iE4$"S:DqZ@2V $h99ouK^sT޲) Uyף]sR\_To.VVeL\Ɔ}d}ԓoz`48rS 9 x,O tgtّLf_b*O|9de7I<“g /U ^^ą-`’hL:ɗΡ3IART$eDcrU\"_8@|)S%sn(Q'C_t 8[)!ՃxT&5*QZsTn\QKU&uFʩfA<ԭjt'Yljի$R|bE8Hfz(@5eTs-H] Xh_ظ5e*RA3 `@$s @P0.guQ BŊZ.ME]{6F#I@aT xȍ*88WsnVzuT_eijMPvEÚ7%D!H \(P$EerA_H1}0̜{$Bh1ea PA\d#q8&r+a\`11۫vxQ@$TaUf7q\g;y's$1%;/vYJrd5_ wp|C]iy P6ud3b]Ez+ֵpU]l` {V6e?[^ͮ#/v moj]nsVwmwa]o{-o ^p Wp?)^q_9q!I^r)WYr1i^s9΋;digitemp-3.7.2/FAQ000066400000000000000000000157601337460421500136750ustar00rootroot00000000000000DigiTemp Frequently Asked Questions Copyright 1996-2018 by Brian C. Lane http://www.brianlane.com http://www.digitemp.com Q. Where Do I buy Parts? From www.ibuttonlink.com I have discontinued my hardware products so that I can spend more time on software. ibuttonLink makes a great serial adapter, and they have picked up production of my DT1A sensors. www.aagelectronica.com produces a full line of 1-wire products at a very reasonable proce, including temperature sensors, humidity and pressure, weather stations, hubs, etc. Places to avoid are www.buffalorun.com, all I see are numerous complaints on the mailing lists about how he doesn't deliver and doesn't communicate. If you want to build them yourself you can get parts from either www.maximic.com or www.digikey.com for sensors. For serial port adapters I now recommend using iButtonLink instead of DS9097U's -- Maxim raised the proce so much that the little extra you spend for the Link is well worth it. I order my temperature sensors directly from Dallas Semiconductor at 1-800-336-6933 (http://www.dalsemi.com/sales/credit_card.html) DigiKey (http://www.digikey.com) now has DS18S20 sensors in stock as well. Q. How do I connect it to the RJ-11 of the DS9097U Take a look at the DS9097U data sheet at http://pdfserv.maxim-ic.com/arpdf/DS9097U-009-DS9097U-S09.pdf Ground is the pin on the right and data is the pin on the left (using the two center pins of the RJ-11). Even with this information you will probably get it backwards the first time so make a temporary connection the first time and confirm that you have the correct polarity. Holding the RJ-11 plug so that it is facing you (as if you were going to plug it into your mouth), with the clip on the top. ____ --| |-- | 4321 | -------- 1 = NC 2 = Ground 3 = Data 4 = NC The same applies for the RJ-45 connectors. Q. How many can I connect? Read the Dallas Semiconductor Tech. Brief on the One Wire Network. http://www.maxim-ic.com/appnotes.cfm/appnote_number/570 It covers everything you want to know and more. The limit comes down to wiring, how much you have and how good it is. Other than that you can connect as many as you need. www.pointsix.com also has some very good app notes on network length and ringing problems. Having a 1-wire hub for complicated netowrks and supplying +5v instead of using the sensors in parasite mode will also help you create larger and more reliable networks. Q. How long can the wire be? Again, read the Tech. Brief above. This depends on the cable. Using better cable will allow you to extend the cable longer distances. CAT5 is the recommended cable for networks of almost any length. You can get away with other cable but be prepared to rip it all up and replace it with CAT5 if it doesn't work. Having a hub and supplying +5v to the sensors will increase the liklihood of your long network operating properly. I have had reports of people using CAT5 and a passive network up to 200m long. Q. I get a result of 85C when reading temperatures 85C is the error state of the DS18S20 sensor, and it usually indicates that one of 2 things are wrong: 1. If you are using parasite powered sensors you forgot to ground the +5v pin to put the sensor into parasite mode. 2. You are trying to read the sensor too quickly. The DS18S20 needs about 750mS of delay in order to properly convert the temperature. Q. I have glitches in my data, what do I do? The first solution is to check all of your connections to make sure they are soldered or well connected. Next, is your cable decent quality? Cat-5 is the best, with twisted telephone cable coming in second. If you are still having problems you should try Using a Schottky diode across the cable's end. Connect the diode reverse-biased with the cathode (the stripe) on the data line and anode on the return. I used a 1N5818 across my attic sensor -- before adding this I was getting multiple glitches per hour. Now I have seen 1 glitch in about 2 weeks. You can also buy pre-assembled sensors that include a 1N5817 diode from my DigiTemp Hardware page at http://www.brianlane.com/dthardware.php Q. What is the difference between the DS9097-U and the App. Note 74 type of adapter. The DS9097-U adapter uses a serial port to 1-wire conversion chip that makes talking to the 1-wire network easier. DigiTemp v2.x uses this type of adapter (the DS9097U-009 and -S09 both work fine). The old style of adapter (sometimes called passive or App. Note #74) used only diodes and resistors to convert the serial port voltages to the one-wire voltages. Dallas still sells adapters of this type, part number DS9097 and DS9097E that is built on this design. DigiTemp v1.x supports this type of adapter, and include a HOWTO document with instructions for building your own. As of DigiTemp v3.0.0 support for both style adapters has been integrated into the same code tree. You no longer need to use v1.x for the DS9097 passive adapter and v2.x for the DS9097U adapter. Q. When will digitemp support the one-wire hub? It does! As of v2.3 it scand for the DS2409 couplers used in the hubs and keeps track of which branch it finds the sensors on. It doesn't support cascaded hubs (hubs connected behind a hub), only multiple hubs on the main 1-wire lan. Q. When will Digitemp support the one-wire Weather Station? Probably never. DigiTemp has 1 purpose - to read temperatures. Weather station support is more complicated and requires a dedicated program to be watching the station and recording events like weather vane movement and wind-speed calculations. I may add support for humidity and barometric pressure, especially if someone were to donate a unit for me to use. I have found a possible source for Humidity, Barometer and Lightning sensors at http://www.jjware.com/index2.htm I do have plans to write my own weather station software though. No release date as of yet, but it is being worked on. Q. When will it support 1-wire device X? The quick answer is "When someone sends me one". DigiTemp v3.3.0 now has support for the DS2438 battery monitor which is used in many of the more complicated sensors, like humidity and pressure. It also has native support for humidity using the AAD TI-8540 humidity sensor. Q. Will the DS2490 USB to 1-wire adapter work? Maybe. I have reports of varying levels of success with it. On my Debian Sarge system using libusb 1.4 it does not work. On my Fedora Core 3 laptop it worked sometimes. On OSX it does not work. Some people report that it works fine for them, others are like me and have mixed results. Version 3.7.0 may improve this, a usb buffer was not being cleared before being used. Running the new code on my Fedora 23 system overnight worked without any errors. digitemp-3.7.2/Makefile000066400000000000000000000125161337460421500147770ustar00rootroot00000000000000# # Makefile for DigiTemp # # Copyright 1996-2018 by Brian C. Lane # See COPYING for GNU General Public License # # Please note that this Makefile *needs* GNU make. BSD make won't do. # VERSION=$(shell awk '/Version:/ { print $$2 }' digitemp.spec) SRCDIR = $(CURDIR) VPATH = $(SRCDIR) # May be overridden by the command line CFLAGS ?= -O2 -Wall # -g # Mandatory additions to CFLAGS EXTRACFLAGS = -I$(SRCDIR)/src -I$(SRCDIR)/userial override CFLAGS += $(EXTRACFLAGS) OBJS = src/digitemp.o src/device_name.o src/ds2438.o HDRS = src/digitemp.h src/device_name.h # Common userial header/source HDRS += userial/ownet.h userial/owproto.h userial/ad26.h \ src/device_name.h src/digitemp.h OBJS += userial/crcutil.o userial/ioutil.o userial/swt1f.o \ userial/owerr.o userial/cnt1d.o userial/ad26.o # DS9097 passive adapter support source DS9097OBJS = userial/ds9097/ownet.o userial/ds9097/linuxlnk.o \ userial/ds9097/linuxses.o userial/ds9097/owtran.o \ src/ds9097.o # DS9097-U adapter support source DS9097UOBJS = userial/ds9097u/ds2480ut.o userial/ds9097u/ownetu.o \ userial/ds9097u/owllu.o userial/ds9097u/owsesu.o \ userial/ds9097u/owtrnu.o userial/ds9097u/linuxlnk.o \ src/ds9097u.o # DS2490 adapter support DS2490OBJS = userial/ds2490/ownet.o userial/ds2490/owtran.o \ userial/ds2490/usblnk.o userial/ds2490/usbses.o \ src/ds2490.o # ----------------------------------------------------------------------- # Sort out what operating system is being run and modify CFLAGS and LIBS # # If you add a new OSTYPE here please email it to me so that I can add # it to the distribution in the next release # ----------------------------------------------------------------------- SYSTYPE := $(shell uname -s) ifneq (, $(findstring CYGWIN,$(SYSTYPE))) EXTRACFLAGS += -DCYGWIN LIBS += -static -static-libgcc endif ifeq ($(SYSTYPE), SunOS) EXTRACFLAGS += -DSOLARIS LIBS += -lposix4 endif ifeq ($(SYSTYPE), FreeBSD) EXTRACFLAGS += -DFREEBSD endif ifeq ($(SYSTYPE), Darwin) EXTRACFLAGS += -DDARWIN endif ifeq ($(SYSTYPE), AIX) EXTRACFLAGS += -DAIX endif # USB specific flags ds2490: EXTRACFLAGS += -DOWUSB ds2490: LIBS += -lusb help: @echo " SYSTYPE = $(SYSTYPE)" @echo " CFLAGS = $(CFLAGS)" @echo " LIBS = $(LIBS)" @echo "" @echo "Pick one of the following targets:" @echo -e "\tmake ds9097\t- Build version for DS9097 (passive)" @echo -e "\tmake ds9097u\t- Build version for DS9097U" @echo -e "\tmake ds2490\t- Build version for DS2490 (USB) (edit Makefile) (BROKEN)" @echo " " @echo "" @echo "Please note: You must use GNU make to compile digitemp" @echo "" all: help # Build the Linux executable ds9097: $(OBJS) $(HDRS) $(ONEWIREOBJS) $(ONEWIREHDRS) $(DS9097OBJS) $(CC) $(OBJS) $(ONEWIREOBJS) $(DS9097OBJS) -o digitemp_DS9097 $(LDFLAGS) $(LIBS) ds9097u: $(OBJS) $(HDRS) $(ONEWIREOBJS) $(ONEWIREHDRS) $(DS9097UOBJS) $(CC) $(OBJS) $(ONEWIREOBJS) $(DS9097UOBJS) -o digitemp_DS9097U $(LDFLAGS) $(LIBS) ds2490: $(OBJS) $(HDRS) $(ONEWIREOBJS) $(ONEWIREHDRS) $(DS2490OBJS) $(CC) $(OBJS) $(ONEWIREOBJS) $(DS2490OBJS) -o digitemp_DS2490 $(LDFLAGS) $(LIBS) # Clean up the object files and the sub-directory for distributions clean: rm -f *~ src/*~ userial/*~ userial/ds9097/*~ userial/ds9097u/*~ userial/ds2490/*~ rm -f $(OBJS) $(ONEWIREOBJS) $(DS9097OBJS) $(DS9097UOBJS) $(DS2490OBJS) rm -f core *.asc rm -f perl/*~ rrdb/*~ .digitemprc digitemp-$(VERSION)-1.spec rm -rf digitemp-$(VERSION) # Sign the binaries using gpg (www.gnupg.org) # My key is available from the keyservers or # https://www.brianlane.com/0xD29845A70F5017DE.txt sign: gpg -ba digitemp_DS* echo tag: git tag -s -u 0x3085CEE24BECD24B -m "Tag as v$(VERSION)" v$(VERSION) # Install digitemp into /usr/local/bin install: digitemp install -b -o root -g bin digitemp /usr/local/bin # Build the archive of everything archive: clean git archive --format=tar --prefix=digitemp-$(VERSION)/ v$(VERSION) > v$(VERSION).tar gzip -9 v$(VERSION).tar @echo "The archive is in v$(VERSION).tar.gz" rpmlog: @git log --pretty="format:- %s (%ae)" v$(VERSION).. |sed -e 's/@.*)/)/' | grep -v "Merge pull request" bumpver: @NEWSUBVER=$$((`echo $(VERSION) |cut -d . -f 3` + 1)) ; \ NEWVERSION=`echo $(VERSION).$$NEWSUBVER |cut -d . -f 1,2,4` ; \ DATELINE="* `date "+%a %b %d %Y"` `git config user.name` <`git config user.email`> - $$NEWVERSION-1" ; \ cl=`grep -n %changelog digitemp.spec |cut -d : -f 1` ; \ tail --lines=+$$(($$cl + 1)) digitemp.spec > speclog ; \ (head -n $$cl digitemp.spec ; echo "$$DATELINE" ; make --quiet rpmlog 2>/dev/null ; echo ""; cat speclog) > digitemp.spec.new ; \ mv digitemp.spec.new digitemp.spec ; rm -f speclog ; \ sed -i "s/Version:.*$(VERSION)/Version: $$NEWVERSION/" digitemp.spec ; \ sed -i "s/$(VERSION)/$$NEWVERSION/" README ; \ sed -i "s/$(VERSION)/$$NEWVERSION/" COPYRIGHT ; \ sed -i "s/$(VERSION)/$$NEWVERSION/" ./src/digitemp.h # Build the source distribution source: archive dist: ds9097 ds9097u ds2490 sign archive dist_ds9097: ds9097 sign archive cd .. && mv digitemp-$(VERSION).tar.gz digitemp-$(VERSION)-ds9097.tar.gz dist_ds9097u: ds9097u sign archive cd .. && mv digitemp-$(VERSION).tar.gz digitemp-$(VERSION)-ds9097u.tar.gz dist_ds2490: ds2490 sign archive cd .. && mv digitemp-$(VERSION).tar.gz digitemp-$(VERSION)-ds2490.tar.gz digitemp-3.7.2/README000066400000000000000000000477121337460421500142250ustar00rootroot00000000000000---------------------------------------------------------------------------- DigiTemp v3.7.2 for Linux (c)1996-2018 by Brian C. Lane ============================================================================ Thank you for using DigiTemp for Linux. If you have any problems or suggestions please feel free to contact me at bcl@brianlane.com You can get the latest information by pointing your web browser at http://www.digitemp.com/ and look at the Software page for the latest release, or use the forums to talk to other DigiTemp users. There is a DigiTemp support mailing list available from https://lists.brianlane.com/mailman/listinfo/ Quick Setup ----------- DigiTemp requires very little setup in order to work. Basically there are 3 requirements: 1. Permission to access the serial port you will be using. 2. A 1-wire serial port adapter 3. A 1-wire sensor connected to the adapter If you think you have all of these taken care of you can try the following to see if it 'Just Works': 1. Initialize the ./.digitemprc file with the following command: digitemp -s/dev/ttyS2 -i If you had my 1-wire setup (hub and sensors) you would see this: DigiTemp v3.3.0 Copyright 1996-2004 by Brian C. Lane GNU General Public License v2.0 - http://www.brianlane.com Turning off all DS2409 Couplers ... Searching the 1-Wire LAN 1F404301000000E4 : DS2409 MicroLAN Coupler 1FB03001000000B5 : DS2409 MicroLAN Coupler 1F881D01000000ED : DS2409 MicroLAN Coupler 22B9B20500000049 : DS1822 Econo-Temperature Sensor 286D1D2D000000EA : DS18B20 Temperature Sensor 104C4D55000800D9 : DS1820/DS18S20/DS1920 Temperature Sensor 1092B9330008002E : DS1820/DS18S20/DS1920 Temperature Sensor 1009212E0008004B : DS1820/DS18S20/DS1920 Temperature Sensor 1067FF33000800C2 : DS1820/DS18S20/DS1920 Temperature Sensor 26E22C1500000046 : DS2438 Temperature, A/D Battery Monior ROM #0 : 22B9B20500000049 ROM #1 : 286D1D2D000000EA ROM #2 : 104C4D55000800D9 ROM #3 : 1092B9330008002E ROM #4 : 1009212E0008004B ROM #5 : 1067FF33000800C2 ROM #6 : 26E22C1500000046 Wrote .digitemprc Your network will be different, but the output should look similar, with it listing the recognized devices, their serial numbers, and ROM numbers. 4. Read all the temperatures with this command: digitemp -a Again, if you were using the same 1-wire lan as I am you would see: DigiTemp v3.3.0 Copyright 1996-2004 by Brian C. Lane GNU General Public License v2.0 - http://www.brianlane.com Jan 11 08:33:41 Sensor 0 C: 22.50 F: 72.50 Jan 11 08:33:42 Sensor 1 C: 31.44 F: 88.59 Jan 11 08:33:43 Sensor 2 C: 21.56 F: 70.81 Jan 11 08:33:44 Sensor 3 C: 12.19 F: 53.94 Jan 11 08:33:46 Sensor 4 C: 21.00 F: 69.80 Jan 11 08:33:47 Sensor 5 C: 4.38 F: 39.88 Jan 11 08:33:48 Sensor 6 C: 27.53 F: 81.56 H: 23% 5. If it doesn't work, try running the initialization again. Make sure you have the right serial port and that it works, try plugging an external modem into the port and check that it works by using a terminal program such as minicom. If all else fails, email me! On older Linux kernels there was a problem with serial port support being a loadable module. With newer (v2.2.x and later) Linux kernels I have not noticed any problems with loadable modules. The problems that people usually run into are: a. Permission problems. DigiTemp will complain if you don't have +rw permission on the serial port specified so this is a pretty easy one to catch. b. Wrong serial port. Make sure you know which port the adapter is plugged into. If you are using a DS2480 based adapter DigiTemp will complain when it cannot find the DS2480. c. Bad connections. Make sure your wiring is correct. This is usually only a problem with home built passive adapters. d. Bad serial port. Test the port with an external modem to make sure it really does work. e. If you are seeing a temperature reading of 85C then you probably built your own sensors and didn't connect the sensor's +5v pin to GND to enable parasite power mode (assuming that you are not using an external +5v power supply). It can also be caused by not enough read time, the DS18S20 needs about 750mS to do a temperature conversion. This time can be adjusted with the -r X argument, but the default is 1000mS which should be fine for most applications. 6. Read the rest of this document to learn how to log data to a file, how to upload include files to a remote web server, and how to setup different logfile format strings. DigiTemp Overview ----------------- DigiTemp is a command line application used for reading 1-wire sensors like the DS18S20 temperature sensor, or DS2438 battery monitor. DigiTemp supports the following devices: DS18S20 (and older DS1820) Temperature Sensor DS18B20 Temperature Sensor DS1822 Temperature Sensor DS2438 Battery monitor DS2409 1-wire coupler (used in 1-wire hubs) DS2422 Counter DS2423 Counter The output format can be customized and all settings are stored in a configuration file (.digitemprc) in the current directory. DigiTemp can repeatedly read the sensors and output to stdout and/or to a logfile. I include a variety of scripts in Perl and Python for processing the output of DigiTemp and doing various things with the data. Like logging to a Round Robin database for easy graph generation, logging to a MySQL database, or using GNU Plot to plot graphs from logfiles. Initialization -------------- Before you can read the sensors you need to initialize the list of serial numbers (each 1-wire sensor has a unique 64 bit serial number used to address it on the bus). When you add sensors to your lan you need to rerun the initialization process -- be aware that the order that they are detected in depends on their number, so when you add new sensors it may change the order of your sensors. When you specify the -i option to initialize the .digitemprc file the program will store the serial port, serial numbers of the attached sensors, the read delay time, log format type, and the log specifier string. The .digitemprc file is written into the current directory. The .digitemprc file is read before the command line arguments are read, this way the configuration can be temporarily overridden by passing arguments to the digitemp program. Digitemp needs at least the -w, -a or -t option to tell it to walk the lan, read all sensors, or read 1 sensor. This is after you have initialized the system with the -i command of course. You need to make sure you have permission to access the serial port. To allow access to the serial port, add the user that will be running DigiTemp to the uucp group (or whatever group owns the serial port device). Tree Walking ------------ No acrobatics here, but if you run ./digitemp -w -s/dev/ttySx the program will show all devices on the one-wire network and traverse all couplers connected to the main LAN. The only thing it doesn't support is nested couplers (couplers connected to the branch of another coupler). The output will identify each device connected, even if it isn't a sensor that DigiTemp supports. DigiTemp v3.3.0 Copyright 1996-2003 by Brian C. Lane GNU General Public License v2.0 - http://www.brianlane.com Turning off all DS2409 Couplers Devices on the Main LAN 1F404301000000E4 : DS2409 MicroLAN Coupler 1FB03001000000B5 : DS2409 MicroLAN Coupler 1F881D01000000ED : DS2409 MicroLAN Coupler Devices on Main Branch of Coupler : 1F404301000000E4 Devices on Aux Branch of Coupler : 1F404301000000E4 Devices on Main Branch of Coupler : 1FB03001000000B5 22B9B20500000049 : DS1822 Econo-Temperature Sensor Devices on Aux Branch of Coupler : 1FB03001000000B5 286D1D2D000000EA : DS18B20 Temperature Sensor Devices on Main Branch of Coupler : 1F881D01000000ED 104C4D55000800D9 : DS1820/DS18S20/DS1920 Temperature Sensor 1092B9330008002E : DS1820/DS18S20/DS1920 Temperature Sensor 1009212E0008004B : DS1820/DS18S20/DS1920 Temperature Sensor 1067FF33000800C2 : DS1820/DS18S20/DS1920 Temperature Sensor Devices on Aux Branch of Coupler : 1F881D01000000ED 26E22C1500000046 : DS2438 Temperature, A/D Battery Monior Temperature Logging ------------------- To log temperatures to a logfile instead of to the console you use the -l command line option. The logfile name may use strftime format to generate the filename. I have a cron job that runs every 30 minutes and logs the temperatures to a file called /var/log/temperature. The cron entry look like this: 0,30 * * * * /usr/local/bin/digitemp -a -l/var/log/temperature This can be added to your crontab using the crontab -e command from the user's account that you want to run digitemp from. The format of the data to be written to the logfile can be controlled in several ways. The default is to use a format specifier string that outputs a line of data like: Dec 29 20:52:29 Sensor 1 C: 1.70 F: 35.06 The -o argument is used to change this. Using -o2 or -o3 will output all the sensor readings on a single line like: 0 23.22 1.33 12.69 The first number is the elapsed time (see timing, below) and the rest are the sensor readings, separated by tabs. This makes it easy to import the data into a spreadsheet program. The data is output in Centigrade when -o2 is used and Fahrenheit when -o3 is used. Using -o4 or -o5 will output all the sensor readings on a single line like: 1476177670 23.22 1.33 12.69 Like -o2 and -o3 except the first number is the elapsed time since 1970-01-01 00:00:00 (unixtime). The other option is to use a format specifier string. To do this you pass the string as the argument to -o, like this: -o"%b %d %H:%M:%S Sensor %s C: %.2C F: %.2F" The specifiers are the same as those used for strftime with the addition of five special ones. %s for the sensor number, %C for the temperature in Centigrade and %F for the temperature in Fahrenheit. %R outputs the sensor's serial number in HEX, and %N output the number of seconds since Epoch (this is because DigiTemp's %s masks the %s which normally does this in strftime. See the strftime manpage for the rest of the specifiers that are supported. The new counter specifier string has 2 special specifiers: %n is the number of the counter %C is the count for that counter The counter log format is specified by the -O command line argument, it is stored in the configuration file when executed with a -i command. Humidity support adds the %h specifier for humidity from 0-100%, and the format is specified by the -H command line argument. It too is saved to the configuration file when executed with a -i command. The %C and %F in the humidity specifier will display the temperature of the humidity sensor. If the -A command is passed then the humidity sensor data will be output as raw voltages from the DS2438. The format string for this is hard-coded and the output looks like this: DigiTemp v3.3.0 Copyright 1996-2003 by Brian C. Lane GNU General Public License v2.0 - http://www.brianlane.com Jan 11 16:56:00 Sensor 6 VDD: 4.70 AD: 1.46 C: 27.94 In the rrdb directory you will find a collection of scripts that I use to generate the graphs at www.brianlane.com/digitemp.php, they create a RRDB database and log data to it every 5 minutes. The web server dynamically generates a graph when a page update is requested. RRDB is the Round Robin Database Tool, and it is available for free from its website at http://ee-staff.ethz.ch/~oetiker/webtools/rrdtool/ you will also find a collection of other useful scripts, written in Perl and in Python in the perl and python directories. All of these scripts will need some tweaking to work with your unique setup. Timing ------ The Read timeout is the amount of time for DigiTemp to pause after issuing a temperature conversion command before it reads the temperature (it takes the DS1820 a few milliseconds to do the conversion and make the temperature available to DigiTemp). The default value for this is 1000mS. The Read timeout can be set by issuing the following command: digitemp -r500 Set Read timeout to 500mS digitemp -i -r500 Set Read timeout to 500mS and save to .digitemprc If Read timeout is set too short the temperature will not be read correctly. The shortest I can set it with my sensors is 300mS before they fail. You may have other problems if the delay is set too short, depending on the temperature being read. I currently have mine set to 1000mS. The older DS1820 sensors would work with a read timing of about 500mS, but the new (and greatly improved IMHO) DS18S20 takes a little longer, between 750mS and 1S, so I have set the default to 1S. Repeated Temperature Sampling ----------------------------- You can setup a script to repeatedly call DigiTemp and process its output, or you can setup DigiTemp to repeatedly sample the sensors and output the data in one of the logfile formats specified in the 'Temperature Logging' section of this document. -dx This sets the sample interval. x is a number in seconds. -d5 will sample at 5 second intervals. The number of sensors that you have attached will determine the minimum interval that you can use. It can take as long as 1/2 second to sample each sensor attached, so if you have 6 sensors you will probably have a minimum sample interval of 3 seconds. The program will tell you when the sampling process has taken longer than the interval you have specified so that you can adjust it accordingly. -nx This sets the number of times to sample all the specified sensors. -n10 will sample 10 times. Setting -n0 will make it loop forever. The output can be sent to a file by using the -lfilename.txt options. So to log data every 10 seconds for 30 minutes you would run DigiTemp to sample every 10 seconds for a count of 180 (10 x 180 = 1800 seconds = 3 minutes) like this: digitemp -a -d10 -n180 -o2 -ldata1.txt This outputs the data as tab separated Centigrade readings to a file named data1.txt in the current directory. To log continously every 10 seconds into files named with current date: digitemp -a -d10 -n0 -o4 -ltemperature-%Y%m%d.txt This outputs the data as tab separated Centigrade readings to files named temperature-20161011.txt, temperature-20161011.txt, ... in the current directory. Web scripts ----------- I have written some Perl scripts for use with local or remote web pages: web_temp This can be used as a CGI binary and will show the last two entries from the /var/log/temperature file inc_temp This can be called from a cron job to create a server side include file that can be included from your webpage. rem_temp This is the script I use to update my webpage at www.brianlane.com/digitemp.php every hour (or whenever the script can get through the busy signals). It creates a shtml file in the /tmp/ directory and then uses the Perl ftp functions to upload it to the remote site. The script lists the modules that need to be added to Perl to enable ftp. You need to have a connection script working for this script to work correctly. Or if you have diald just comment out the ppp-on and off lines. Please consult the various Linux howto FAQs for information on how to construct the connect scripts if you don't already have them set up. maxplot This perl script generates the temperature graph that you can use on your webpage. They require the GD module for perl, which is available from - http://www.perl.com/CPAN-local//modules/by-module/GD/ It generates a .gif file, and move the file to the final location, so it will need some small changes in the paths and ownership at the end of the scripts to customize it for your setup. RRD tool I have also written several scripts to manipulate data with RRD (Round Robin Database) tool databases. RRD tool is available from - http://ee-staff.ethz.ch/~oetiker/webtools/rrdtool/ There are several scripts, one to add data to the database, and one to retrieve data as a .png image. NetSaint I have written a Net Saint/Nagios (http://www.nagios.com) plugin. It is named check_digitemp.pl and it located in the perl directory. Installation instructions are in the top of the file's comments. MySQL I have written a perl script to log temperature readings to a MySQL database. It is named digitemp_mysql.pl and is in the perl directory. Instructions for setup and use are in the README file in the perl directory. The scripts have been commented so that you can change them easily (I hope! Email any changes you have). There are several variables that need to be setup for your system before they will run. If you have any comments, questions, or scripts that you would like to donate, drop me an email, and I'll set up a ftp directory for user contributions. Have Fun! And when you get your sensors up on your website send me the URL and I will add it to the list at http://www.digitemp.com/users.shtml Brian C. Lane bcl@brianlane.com http://www.brianlane.com Release notes ------------- Version 3.6.0 adds ... Version 3.5.0 adds DS1923 Hygrochron support, fixes some small bugs in the userial driver. A lockdev bug was fixed (wasn't unlocking when done), a crash in free_couplers() was fixed, better error reporting when trying to access serial ports that don't exist, compiled for Windows with cygiwn. DS2490/9490 support still doesn't work well for me, although others have had success with it. Version 3.4.0 fixes temperature output using -o2 and -o3 log formats with the DS2438 sensor. Version 3.3.2 fixes the broken DS9097 support that I hosed in v3.3.1 and adds a performance patch to DS9097 from Erik Rigtorp that should speed up passive adapter operations. Version 3.3.1 works with the DS9490R USB adapter using the DS2490 USB to 1-wire adapter chip. It needs to be run as root, and your version of libusb may need to be patched using the patch in the ./contrib directory Version 3.3.0 adds support for the DS2490 USB adapter, DS2438 battery monitor and AAG TAI-8540 humidity sensor module. Additional format string specifiers have been added to handle the humidity reading. See the Initialization section below. The binary generated when building from source is now digitemp_DS9097, digitemp_DS9097U, or digitemp_DS2490 depending on which build you do. You can then make a symlink to 'digitemp' for whichever adapter you need to use. I now recommend use of the iButtonLink from www.ibuttonlink.com, it is 100% compatible with the DS9097U, but has been engineered to work with longer networks more reliably. Version 3.1.0 adds support for the DS2406 counters. A new output format specifier has been added, using the -O option (capital Oh, not lower case). I have included my first pass at a python script to log to MySQL and RRD. Version 3.0.0 adds support for both the DS9097 passive adapter, and the newer DS9097U adapter. It also introduces a better makefile and less CPU usage when repeatedly reading multiple sensors. Version 2.5 adds compilation under Solaris. A new log option of %R has been added to output the serial number in hex in the logging output string. The quiet -q option now quiets down the 1-Wire walk and initialize routine so that only the important information is output. Version 2.4 fixes the problems (finally!) with the DS18B20 and DS1822 sensors. I have also modified the search and read algorithms so that they will work faster when used with a 1-wire hub. Version 2.3 adds support for one wire hubs like Simon Atkin's hub that can be found at www.simat.enta.net Version 2.x.x removes support for the old adapter (based on the one described in App. Note 74 from Dallas Semiconductor. Version 1.3 still supports the older adapters and is now also released under the GNU General Public License). This new version uses the DS9097-U adapter available from Dallas Semiconductor. You can order them from their iButton webpage at www.ibutton.com This adapter is more expensive but is easier to program and support higher current capability so that it should work at higher temperatures than the previous adapter. digitemp-3.7.2/TODO000066400000000000000000000036201337460421500140230ustar00rootroot00000000000000 1. Reduce cpu usage in the loop when doing multiple conversions 2. Catch TERM to exit the loop cleanly 3. Add global variables for the slew rate and re/write timing adjustments in the ds2840ut.c file. Add control of these to the digitemp.c code. 4. Update support for rpm building X 5. Fix problems using the USB serial port. Not sure what's happening. It will sometimes work, most of the time fail. Extending VTIME didn't make any noticable difference. I changed global_msec_max (controls the time delay for characters in the ReadCOM routine). It might be a slight improvement, but still fails a considerable percentage of the time. Sometimes the DS2480 detection fails, sometimes the search fails. It will also sometimes run fine (and quickly). Getting somewhere: Fails: 17 45 5B 0F 91 Works: 16 44 5A 00 93 Sent : 17 45 5B 0F 91 Once : C1 17 45 5B 0F I added a wrapper for DS2480Detect that retries up to 10 times before giving up. Extending the maximum time to 1.800 or so (1sec + 800mS) also helps it run better. Without that it doesn't read the data very well. Without the loop on DS2480Detect it doesn't work consistently with the dongle. I need to add the delays back in, and see how they effect normal operation. The problem, it appears, was the usb buffer wasn't being zered before being used and an unknown number of bytes can be returned so it wasn't actually checking a bit that was set by the data. See commit 33422c748e28dc550e31eda63487135537838d00 6. Add long-argument switches to the program so that counter and switch results can be turned on/off. Temperature as well. 7. Update and review all documents and directions to make sure they are current and match the command line. 8. Update or remove the various helper scripts. Remove hard-coded paths, etc. digitemp-3.7.2/contrib/000077500000000000000000000000001337460421500147725ustar00rootroot00000000000000digitemp-3.7.2/contrib/digitemp-freebsd.patch000066400000000000000000000044051337460421500212300ustar00rootroot00000000000000diff -urN digitemp-3.2.0-org/userial/cnt1d.c digitemp-3.2.0/userial/cnt1d.c --- digitemp-3.2.0-org/userial/cnt1d.c Thu May 22 03:50:21 2003 +++ digitemp-3.2.0/userial/cnt1d.c Sat Oct 25 18:17:41 2003 @@ -30,6 +30,8 @@ // // #include "ownet.h" +#include +typedef unsigned long ulong; // external One Wire functions from nework layer extern SMALLINT owAccess(int); diff -urN digitemp-3.2.0-org/userial/crcutil.c digitemp-3.2.0/userial/crcutil.c --- digitemp-3.2.0-org/userial/crcutil.c Thu May 22 03:50:20 2003 +++ digitemp-3.2.0/userial/crcutil.c Sat Oct 25 18:17:41 2003 @@ -29,6 +29,7 @@ // Include files #include "ownet.h" +#include // Local subroutines void setcrc16(int,ushort); diff -urN digitemp-3.2.0-org/userial/ds9097/owtran.c digitemp-3.2.0/userial/ds9097/owtran.c --- digitemp-3.2.0-org/userial/ds9097/owtran.c Thu May 22 03:50:19 2003 +++ digitemp-3.2.0/userial/ds9097/owtran.c Sat Oct 25 18:17:41 2003 @@ -34,6 +34,7 @@ // #include "ownet.h" +#include //-------------------------------------------------------------------------- // The 'owBlock' transfers a block of data to and from the diff -urN digitemp-3.2.0-org/userial/ds9097u/owtrnu.c digitemp-3.2.0/userial/ds9097u/owtrnu.c --- digitemp-3.2.0-org/userial/ds9097u/owtrnu.c Thu May 22 03:50:20 2003 +++ digitemp-3.2.0/userial/ds9097u/owtrnu.c Sat Oct 25 18:17:41 2003 @@ -41,6 +41,7 @@ #include "ownet.h" #include "ds2480.h" +#include // external functions defined in owllu.c extern SMALLINT owTouchReset(int); diff -urN digitemp-3.2.0-org/userial/ioutil.c digitemp-3.2.0/userial/ioutil.c --- digitemp-3.2.0-org/userial/ioutil.c Thu May 22 03:50:21 2003 +++ digitemp-3.2.0/userial/ioutil.c Sat Oct 25 18:17:41 2003 @@ -37,6 +37,8 @@ #include #include "ownet.h" +typedef unsigned long ulong; + #ifdef __MC68K__ #include #include diff -urN digitemp-3.2.0-org/userial/owproto.h digitemp-3.2.0/userial/owproto.h --- digitemp-3.2.0-org/userial/owproto.h Thu May 22 03:50:21 2003 +++ digitemp-3.2.0/userial/owproto.h Sat Oct 25 18:17:41 2003 @@ -29,7 +29,7 @@ char *owGetErrorMsg(int); #endif - +typedef unsigned long ulong; /* From ioutil.c */ int EnterString(char *, char *, int, int); digitemp-3.7.2/contrib/libusb.patch.txt000066400000000000000000000061761337460421500201230ustar00rootroot00000000000000--------------070507070300030101020103 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit I've successfully used the driver found in main PDK archive (owpd300b2.zip) under generic library using usblnk.c and usbses.lnk. This driver in turn uses libusb library found on the internet. I've found libusb v0.1.7, which contained a small bug in linux.c file. The fixed routine is below. int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) { struct usb_bulktransfer bulk; int ret, retrieved = 0, requested; /* Ensure the endpoint address is correct */ ep |= USB_ENDPOINT_IN; do { bulk.ep = ep; requested = size - retrieved; if (requested > MAX_READ_WRITE) requested = MAX_READ_WRITE; bulk.len = requested; bulk.timeout = timeout; bulk.data = (unsigned char *)bytes + retrieved; ret = ioctl(dev->fd, IOCTL_USB_BULK, &bulk); if (ret < 0) USB_ERROR_STR(ret, "error reading from bulk endpoint 0x%x: %s", ep, strerror(errno)); retrieved += ret; } while (ret > 0 && retrieved < size); /* Yefim: && ret == requested */ return retrieved; } Best regards, Mike. bcl wrote: >On Wed, Jul 23, 2003 at 05:57:50AM -0400, Paul Alfille wrote: > > >>Has anyone written a driver for the DS9490 USB master for Linux? >> >>I will try if it hasn't been done, but it's not my area of expertise. >> >> >> > >Not yet (to my knowledge), although I am trying to make the time to get >started on the project. > >Brian > > > --------------070507070300030101020103 Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: 7bit I've successfully used the driver found in main PDK archive (owpd300b2.zip) under generic library using usblnk.c and usbses.lnk. This driver in turn uses libusb library found on the internet. I've found libusb v0.1.7, which contained a small bug in linux.c file. The fixed routine is below. int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) { struct usb_bulktransfer bulk; int ret, retrieved = 0, requested; /* Ensure the endpoint address is correct */ ep |= USB_ENDPOINT_IN; do { bulk.ep = ep; requested = size - retrieved; if (requested > MAX_READ_WRITE) requested = MAX_READ_WRITE; bulk.len = requested; bulk.timeout = timeout; bulk.data = (unsigned char *)bytes + retrieved; ret = ioctl(dev->fd, IOCTL_USB_BULK, &bulk); if (ret < 0) USB_ERROR_STR(ret, "error reading from bulk endpoint 0x%x: %s", ep, strerror(errno)); retrieved += ret; } while (ret > 0 && retrieved < size); /* Yefim: && ret == requested */ return retrieved; } Best regards, Mike. bcl wrote: >On Wed, Jul 23, 2003 at 05:57:50AM -0400, Paul Alfille wrote: > > >>Has anyone written a driver for the DS9490 USB master for Linux? >> >>I will try if it hasn't been done, but it's not my area of expertise. >> >> >> > >Not yet (to my knowledge), although I am trying to make the time to get >started on the project. > >Brian > > > digitemp-3.7.2/digitemp.1000066400000000000000000000110461337460421500152200ustar00rootroot00000000000000.TH DIGITEMP 1 "August 2008" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME digitemp \- program to read from 1-wire temperature sensors. .SH SYNOPSIS .B digitemp .RI [ options ] .SH DESCRIPTION DigiTemp uses the Dallas 1-wire bus to read temperatures from digital sensors attached to a serial port adapter. It handles initializing the bus, searching for attached devices, reading devices and custom log strings. It supports the following temperature devices: DS1820, DS18S20, DS18B20, DS1822 .PP It also handles the DS2406 1-wire hub switches, and DS2422 and DS2423 counters. .PP DigiTemp uses either the DS9097 passive serial port adapter, or the DS2480B based DS9097U adapter. 1-wire adapters from ibuttonlink.com, such as the Link45 are also supported. .SH OPTIONS At least 1 action must be given, along with some optional arguments. Actions are one (and only on) of the .B \-w \-t \-a \-w options .TP .B \-h, \-? Show summary of options. .TP .B \-v Show verbose output. .TP .B \-i Initialize .digitemprc file, search the bus for all supported devices. .TP .B \-I Initialize .digitemprc file, search the bus for all supported devices, store devices in sorted serial # order. .TP .B \-w Walk the full device tree and display the serial number and type of all devices detected on the bus. .TP .B \-s /dev/ttyS0 Set serial port to use. Make sure you have permission to access this port. For USB operation pass USB instead of /dev/ttySX .TP .B \-l /var/log/temperature Send output to logfile, the output format is defined by the .B \-o command .TP .B \-c digitemp.conf Set digitemp configuration file. The default is .digitemprc in the current directory. .TP .B \-r 1000 Read delay in ms. This sets the amount of time to wait between sending the temperature conversion command and reading the result. The DS18S20 takes about 750mS to do the temperature conversion. Default is 1000mS (1 sec). .TP .B \-t # Read sensor number #, the # depends on the order of the sensors in the \&.digitemprc file. .TP .B \-q Quiet output, no copyright banner. .TP .B \-a Read all sensors. .TP .B \-A Treat DS2438 as A/D converter, output raw voltages and currents. .TP .B \-d 5 Delay between samples (in seconds). .TP .B \-n 50 Number of times to repeat the command. .TP .B \-O"counter format string" See Counter Format below. .TP .B \-o [1..3] ["output format string"] See Temperature Format below. .TP .B \-H"Humidity format string" See Humidity Format below. .PP .SH Temperature Format .PP The temperature format can be either a numeric value, or a string. The numeric values select pre-configured output formats: .PP 1 = One line per sensor, time, C, F (default) 2 = One line per sample, elapsed time, temperature in C 3 = Same as #2, except temperature is in F .PP #2 and #3 have the data separated by tabs, suitable for import into a spreadsheet or other graphing software. .PP The format string uses strftime tokens plus 5 special ones for DigiTemp: .TP .B %s for sensor # .TP .B %C for centigrade .TP .B %F for fahrenheit .TP .B %R to output the hex serial number .TP .B %N for seconds since Epoch. .PP The case of the token is important! The default format string is: "%b %d %H:%M:%S Sensor %s C: %.2C F: %.2F" which gives you an output of: May 24 21:25:43 Sensor 0 C: 23.66 F: 74.59 .PP The DS2438 sensor can be used for a variety of things. It includes a temperature sensor and A/D converter. DigiTemp defaults to using it as a humidity sensor. The raw voltages and currents can be displayed by passing the \-A argument .PP When the \-o2 or \-o3 log options are used the attached DS2438's temperatures will be output without the humidity. .PP .SH Counter Format String .PP The counter format string is similar, adding these tokens: .TP .B %n is the counter #, which depends on its position in the .digitemprc file .TP .B %C is the count in decimal. .PP .SH Humidity Format String .PP The Humidity format string is the same as the temperature format string with the addition of this format specifier: .TP .B %h is the humidity in 0-100% .PP .SH AUTHOR This manual page was written by Jes\['u]s Roncero , for the Debian project (but may be used by others). Modifications by Brian C. Lane .SH UPDATES DigiTemp updates can be found on the http://www.digitemp.com website. digitemp-3.7.2/digitemp.spec000066400000000000000000000071611337460421500160150ustar00rootroot00000000000000%global with_libusb 1 Summary: Dallas Semiconductor 1-wire device reading console application Name: digitemp Version: 3.7.2 Release: 1%{?dist} License: GPLv2+ Group: Applications/System URL: http://www.digitemp.com/ Source0: https://github.com/bcl/%{name}/archive/v%{version}.tar.gz %if %{with_libusb} BuildRequires: libusb-devel %endif BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %description DigiTemp is a simple to use console application for reading values from Dallas Semiconductor 1-wire devices. Its main use is for reading temperature sensors, but it also reads counters and understands the 1-wire hubs with devices on different branches of the network. DigiTemp now supports the following 1-wire temperature sensors: DS18S20 (and DS1820), DS18B20, DS1822, the DS2438 Smart Battery Monitor, DS2422 and DS2423 Counters, DS2409 MicroLAN Coupler (used in 1-wire hubs) and the AAG TAI-8540 humidity sensor. %prep %setup -q %build CFLAGS="$RPM_OPT_FLAGS -fPIE -DPIC"; export CFLAGS make ds9097 %{?_smp_mflags} make clean make ds9097u %{?_smp_mflags} %if %{with_libusb} make clean make ds2490 %{?_smp_mflags} %endif %install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT{%{_bindir},%{_mandir}/man1} install -m 755 digitemp_DS9097 digitemp_DS9097U $RPM_BUILD_ROOT%{_bindir} %if %{with_libusb} install -m 755 digitemp_DS2490 $RPM_BUILD_ROOT%{_bindir} %endif install -p -m 644 %{name}.1 $RPM_BUILD_ROOT%{_mandir}/man1/%{name}.1 # Convert everything to UTF-8 iconv -f iso-8859-1 -t utf-8 -o ChangeLog.utf8 ChangeLog touch -c -r ChangeLog ChangeLog.utf8; mv -f ChangeLog.utf8 ChangeLog %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %doc ChangeLog COPYING COPYRIGHT CREDITS FAQ README TODO %doc dthowto.txt DS9097_Schematic.gif %{_bindir}/%{name}* %{_mandir}/man1/%{name}.* %changelog * Mon Nov 19 2018 Brian C. Lane - 3.7.2-1 - Fix digitemp.spec Version in bumpver target (bcl) - Make sure strncpy uses are null-terminated (bcl) - Add a check for ROM number vs. SENSORS count (bcl) - Log the scratchpad diagnostics (bcl) - Bump Copyright Year to 2018 (bcl) - Fix strftime use of log_file (bcl) - Add strftime formating to logfile name (peje) - Clean up the start_time switch statement usage (bcl) - Add log_type 4 & 5 (peje) - Check for bad Get_Temperature result (bcl) - Fix the return value of Get_Temperature in ad26.c (bcl) - Display DS2438 temperature even if humidity calculation fails. (bcl) - Always include types.h and time.h (bcl) - Bump copyright year to 2016 (bcl) - Add bumpver target (bcl) - Spelling corrections (ryan) * Sat Dec 12 2015 Brian C. Lane 3.7.1-1 - Update version to 3.7.1 - Fix version in digitemp.h * Sat Dec 12 2015 Brian C. Lane 3.7.0-1 - Updating to v3.7.0 - New upstream location at GitHub * Thu Aug 28 2008 Brian C. Lane 3.6.0-1 - Releasing new version with these changes: - Updated to the .spec file from Fedora9 - DS2490 now suppresses the 'Found usb ...' output - Support for compiling under DARWIN - Current reading added to DS2438 - DS28EA00 support added - Tabbed output of 0.00 on CRC errors with log type -o2 or -o3 - New manpage from Debian digitemp maintainer * Sun Feb 10 2008 Robert Scheck 3.5.0-3 - Rebuilt against gcc 4.3 * Tue Aug 28 2007 Robert Scheck 3.5.0-2 - Updated the license tag according to the guidelines * Sun Jan 07 2007 Robert Scheck 3.5.0-1 - Upgrade to 3.5.0 - Initial spec file for Fedora and Red Hat Enterprise Linux digitemp-3.7.2/dthowto.txt000066400000000000000000000074701337460421500155730ustar00rootroot00000000000000 Howto build a Serial Adapter for Dallas DS1820 temperature sensors Copyright (c) 2001 by Brian C. Lane All Rights Reserved The DigiTemp program for Linux, DOS and Windows 95 uses a simple serial port adapter to communicate with the Dallas DS1820 digital temperature sensors. These sensors use a protocol called One-Wire or Micro LAN (depending on which Dallas documentation you are reading). This protocol requires only a ground and a data wire to the device. All power is derived from the data line while it is idle. The protocol is NOT RS232! The adapter converts the RS232 voltages into the +5v needed to communicate with the DS1820. Each byte sent to the serial port represents one data bit to the DS1820. See Dallas Semiconductor App Note #74 for more information, or the sourcecode for DigiTemp. How To build an adapter ----------------------- If you want a schematic diagram you need to look at page 20 of App. Note #74 from Dallas Semiconductor ( ) Parts List ---------- 1 DB-25 connector or DB-9 connector 1 1.5k ohm resistor 2 1N5818 Schottky Diode 1 1N5228 3.9v Zener Diode 1 1N5234 6.2v Zener Diode 1 2 position terminal block (for connecting the sensors to adapter) Wire cutters and a soldering iron. In this document I will refer to the pin functions. The pin numbers for DB-25 and DB-9 are as follows: Name DB-25 DB-9 ---- ----- ---- DTR 20 4 RXD 3 2 TXD 2 3 GND 1,7 5 NOTE: I have not built a DB-9 version myself. Please let me know if you successfully build one or have problems with it. On the DB-25 pins 1 and 7 must BOTH be connected together. Step Description ------------------------------------------------------------------------ 1. Solder the 1N5228 3.9v Zener between GND and DTR with the Cathode(the stripe) towards DTR. 2. Solder the 1.5k ohm resistor between RXD and TXD. 3. Solder one of the 1N5818 diodes between RXD and TXD with the Cathode(the stripe) towards RXD. 4. Solder the other 1N5818 diode between RXD and DTR with the Cathode(the stripe) towsrds DTR. 5. Solder the 1N5234 6.2v Zener between RXD and DTR with the Cathode(the stripe) towards DTR. 6. Solder RXD to one pin of the terminal block and paint it black. This is the GND connection for the sensors. 7. Solder DTR to the other pin of the terminal block and paint it red. This is the DATA connection for the sensors. There! Now you have an adapter. Connecting the sensors ---------------------- You need to connect to wires to the sensor to attach to the terminal block. If you look at the sensor so that the label is towards you, with the pins facing down the pins are from left to right: 1. GND 2. DATA 3. +5v Solder your wires to GND and DATA and connect them to the terminal block and you're done! Be careful not to overheat the sensor while soldering to it. My method is to tin the legs quickly and let them cool off (while tinning the others) and then to tin the wires, then attach them quickly with a minimum of heat applied. One additional note: Because of the voltage(and current) drop across the resistor this adapter isn't capable of providing enough current to read temperatures above about +70C. This is a limitation of the design, not an error with the DS1820 or the software. If you have any questions or comments, email me at bcl@brianlane.com or subscribe to the digitemp mailing list by sending a blank email to digitemp-subscribe@brianlane.com Brian Lane bcl@brianlane.com http://www.brianlane.com March 13, 2001 digitemp-3.7.2/perl/000077500000000000000000000000001337460421500142745ustar00rootroot00000000000000digitemp-3.7.2/perl/README000066400000000000000000000046441337460421500151640ustar00rootroot00000000000000Digitemp v2.6 Copyright 1996-2002 by Brian C. Lane Here are a few useful perl scripts for you to use with DigiTemp. Most of them need customization for your specific circumstances. Some these scripts are old, as I now use the RRD tool to graph and log data. The digitemp_sql.pl script is new, and has not been tested extensivly yet, but should work for users familiar with the MySQL database system. inc_temp Build a file suitable for including into a server side include webpage (or modify it to create the whole webpage. This script operates on a logfile output from digitemp when running with the -l option. rem_temp Create an include file as in inc_temp and then send it to a server via FTP. This script operates on a logfile output from digitemp when running with the -l option. maxplot Create a GIF image of the temperature graph. This script operates on a logfile output from digitemp when running with the -l option. check_digitemp.pl This is a NetSaint/Nagios (www.nagios.com) script that uses DigiTemp to check temperatures on monitored machines. digitemp_sql.pl MySQL database logging of temperatures. This is a new script, it logs the serial number and temperature in Fahrenheit to a MySQL database. I assume that you are familiar with the care and feeding of your database so that I can skip over the simple stuff and get to the point: Create a new database named digitemp: mysqladmin create digitemp -u root -p Edit the grant_mysql.sql file and change the password and optionally the username. Grant access to the new database: mysql mysql -u root -p < mysql_grant.sql Create the database table: mysql digitemp -u root -p < make_mysql.sql Edit the digitemp_mysql.pl script. Change the password to the one you used above, optionally change the username. Point the digitemp_rcfile variable to the DigiTemp config file that you have previously created using digitemp -i -c rcfile I recommend using one other than .digitemprc so that it isn't accidently erased when you run digitemp -i from your home directory. Make sure the path to the digitemp binary is correct. It is specified by the $digitemp_binary variable. Setup a cron job to log temperatures to the database at regular intervals: */5 * * * * /home/brian/bin/digitemp_mysql.pl At this time I have not written any logging or graphing scripts to deal with the MySQL temperature data. digitemp-3.7.2/perl/check_digitemp.pl000077500000000000000000000177671337460421500176150ustar00rootroot00000000000000#!/usr/bin/perl -w # check_digitemp.pl Copyright (C) 2002 by Brian C. Lane # # This is a NetSaint plugin script to check the temperature on a local # machine. Remote usage may be possible with SSH # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # # =========================================================================== # Howto Install in NetSaint (tested with v0.0.7) # # 1. Copy this script to /usr/local/netsaint/libexec/ or wherever you have # placed your NetSaint plugins # # 2. Create a digitemp config file in /usr/local/netsaint/etc/ # eg. digitemp -i -s/dev/ttyS0 -c /usr/local/netsaint/etc/digitemp.conf # # 3. Make sure that the webserver user has permission to access the serial # port being used. # # 4. Add a command to /usr/local/netsaint/etc/commands.cfg like this: # command[check-temp]=$USER1$/check_digitemp.pl -w $ARG1$ -c $ARG2$ \ # -t $ARG3$ -f $ARG4$ # (fold into one line) # # 5. Tell NetSaint to monitor the temperature by adding a service line like # this to your hosts.cfg file: # service[kermit]=Temperature;0;24x7;3;5;1;home-admins;120;24x7;1;1;1;; \ # check-temp!65!75!1!/usr/local/netsaint/etc/digitemp.conf # (fold into one line) # 65 is the warning temperature # 75 is the critical temperature # 1 is the sensor # (as reported by digitemp -a) to monitor # digitemp.conf is the path to the config file # # 6. If you use Centigrade instead of Fahrenheit, change the commands.cfg # line to include the -C argument. You can then pass temperature limits in # Centigrade in the service line. # # =========================================================================== # Howto Install in Nagios (tested with v1.0b4) # # 1. Copy this script to /usr/local/nagios/libexec/ or wherever you have # placed your Nagios plugins # # 2. Create a digitemp config file in /usr/local/nagios/etc/ # eg. digitemp -i -s/dev/ttyS0 -c /usr/local/nagios/etc/digitemp.conf # # 3. Make sure that the webserver user has permission to access the serial # port being used. # # 4. Add a command to /usr/local/nagios/etc/checkcommands.cfg like this: # # #DigiTemp temperature check command # define command{ # command_name check_temperature # command_line $USER1$/check_digitemp.pl -w $ARG1$ -c $ARG2$ \ # -t $ARG3$ -f $ARG4$ # (fold above into one line) # } # # 5. Tell NetSaint to monitor the temperature by adding a service line like # this to your service.cfg file: # # #DigiTemp Temperature check Service definition # define service{ # use generic-service # host_name kermit # service_description Temperature # is_volatile 0 # check_period 24x7 # max_check_attempts 3 # normal_check_interval 5 # retry_check_interval 2 # contact_groups home-admins # notification_interval 240 # notification_period 24x7 # notification_options w,u,c,r # check_command check_temperature!65!75!1! \ # /usr/local/nagios/etc/digitemp.conf # (fold into one line) # } # # 65 is the warning temperature # 75 is the critical temperature # 1 is the sensor # (as reported by digitemp -a) to monitor # digitemp.conf is the path to the config file # # 6. If you use Centigrade instead of Fahrenheit, change the checkcommands.cfg # line to include the -C argument. You can then pass temperature limits in # Centigrade in the service line. # # =========================================================================== # Modules to use use strict; use Getopt::Std; # Define all our variable usage use vars qw($opt_c $opt_f $opt_t $opt_w $opt_F $opt_C $temperature $conf_file $sensor $temp_fmt $crit_level $warn_level $null %exit_codes $percent $fmt_pct $verb_err $command_line); # Predefined exit codes for NetSaint %exit_codes = ( 'OK' , 0, 'WARNING' , 1, 'CRITICAL', 2, 'UNKNOWN' ,3,); # Default to Fahrenheit input and result (use -C to change this) $temp_fmt = 3; # Get the options if ($#ARGV le 0) { &usage; } else { getopts('f:t:FCc:w:'); } # Shortcircuit the switches if (!$opt_w or $opt_w == 0 or !$opt_c or $opt_c == 0) { print "*** You must define WARN and CRITICAL levels!"; &usage; } # Check if levels are sane if ($opt_w >= $opt_c) { print "*** WARN level must not be greater than CRITICAL when checking temperature!"; &usage; } $warn_level = $opt_w; $crit_level = $opt_c; # Default sensor to read is #0 if(!$opt_t) { $sensor = 0; } else { $sensor = $opt_t; } # Default config file is /etc/digitemp.conf if(!$opt_f) { $conf_file = "/etc/digitemp.conf"; } else { $conf_file = $opt_f; } # Check for config file if( !-f $conf_file ) { print "*** You must have a digitemp.conf file\n"; &usage; } if($opt_C) { $temp_fmt = 2; } # Read the output from digitemp # Output in form 0\troom\tattic\tdrink open( DIGITEMP, "/usr/local/bin/digitemp -c $conf_file -t $sensor -q -o $temp_fmt |" ); # Process the output from the command while( ) { # print "$_\n"; chomp; if( $_ =~ /^nanosleep/i ) { print "Error reading sensor #$sensor\n"; close(DIGITEMP); exit $exit_codes{'UNKNOWN'}; } else { # Check for an error from digitemp, and report it instead if( $_ =~ /^Error.*/i ) { print $_; close(DIGITEMP); exit $exit_codes{'UNKNOWN'}; } else { ($null,$temperature) = split(/\t/); } } } close( DIGITEMP ); if( $temperature and $temperature >= $crit_level ) { print "Temperature CRITICAL - Sensor #$sensor = $temperature "; if( $temp_fmt == 3 ) { print "F\n"; } else { print "C\n"; } exit $exit_codes{'CRITICAL'}; } elsif ($temperature and $temperature >= $warn_level ) { print "Temperature WARNING - Sensor #$sensor = $temperature "; if( $temp_fmt == 3 ) { print "F\n"; } else { print "C\n"; } exit $exit_codes{'WARNING'}; } elsif( $temperature ) { print "Temperature OK - Sensor #$sensor = $temperature "; if( $temp_fmt == 3 ) { print "F\n"; } else { print "C\n"; } exit $exit_codes{'OK'}; } else { print "Error parsing result for sensor #$sensor\n"; exit $exit_codes{'UNKNOWN'}; } # Show usage sub usage() { print "\ncheck_digitemp.pl v1.0 - NetSaint Plugin\n"; print "Copyright 2002 by Brian C. Lane \n"; print "See source for License\n"; print "usage:\n"; print " check_digitemp.pl -t -f -w -c \n\n"; print "options:\n"; print " -f DigiTemp Config File\n"; print " -t DigiTemp Sensor #\n"; print " -F Temperature in Fahrenheit\n"; print " -C Temperature in Centigrade\n"; print " -w temperature temperature >= to warn\n"; print " -c temperature temperature >= when critical\n"; exit $exit_codes{'UNKNOWN'}; } digitemp-3.7.2/perl/digitemp_mysql.pl000077500000000000000000000053401337460421500176650ustar00rootroot00000000000000#!/usr/bin/perl -W # DigiTemp MySQL logging script # Copyright 2002 by Brian C. Lane # All Rights Reserved # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # -------------------------[ HISTORY ]------------------------------------- # 01/08/2004 The storage definition should have been decimal(6,2) instead # bcl of decimal(3,2). # See http://www.mysql.com/doc/en/Numeric_types.html for a # good description of how decimal(a,b) works. # # 08/18/2002 Putting together this MySQL logging script for the new # bcl release of DigiTemp. # # ------------------------------------------------------------------------- # CREATE table digitemp ( # dtKey int(11) NOT NULL auto_increment, # time timestamp NOT NULL, # SerialNumber varchar(17) NOT NULL, # Fahrenheit decimal(6,2) NOT NULL, # PRIMARY KEY (dtKey), # KEY serial_key (SerialNumber), # KEY time_key (time) # ); # # GRANT SELECT,INSERT ON digitemp.* TO dt_logger@localhost # IDENTIFIED BY 'TopSekRet'; # # ------------------------------------------------------------------------- use DBI; # Database info my $db_name = "digitemp"; my $db_user = "dt_logger"; my $db_pass = "TopSekRet"; # The DigiTemp Configuration file to use my $digitemp_rcfile = "/home/brian/digitemp.cfg"; my $digitemp_binary = "/home/brian/bin/digitemp"; my $debug = 0; # Connect to the database my $dbh = DBI->connect("dbi:mysql:$db_name","$db_user","$db_pass") or die "I cannot connect to dbi:mysql:$db_name as $db_user - $DBI::errstr\n"; # Gather information from DigiTemp # Read the output from digitemp # Output in form SerialNumberTemperature in Fahrenheit open( DIGITEMP, "$digitemp_binary -q -a -o\"%R %.2F\" -c $digitemp_rcfile |" ); while( ) { print "$_\n" if($debug); chomp; ($serialnumber,$temperature) = split(/ /); my $sql="INSERT INTO digitemp SET SerialNumber='$serialnumber',Fahrenheit=$temperature"; print "SQL: $sql\n" if($debug); $dbh->do($sql) or die "Can't execute statement $sql because: $DBI::errstr"; } close( DIGITEMP ); $dbh->disconnect; digitemp-3.7.2/perl/grant_mysql.sql000066400000000000000000000001241337460421500173520ustar00rootroot00000000000000GRANT SELECT,INSERT ON digitemp.* TO dt_logger@localhost IDENTIFIED BY 'TopSekRet'; digitemp-3.7.2/perl/inc_temp000077500000000000000000000054221337460421500160230ustar00rootroot00000000000000#!/usr/bin/perl -w # # DigiTemp webpage include script # Copyright 1997-2001 by Brian C. Lane www.brianlane.com # All Rights Reserved # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # # Read the temperature logfile, write an include file for the webpage. # # Sensor #0 is the Window # Sensor #1 is the inside of the Linux box # # Dec 18 21:46:47 Sensor 0 C: 8.81 F: 47.86 # Dec 18 21:46:47 Sensor 1 C: 26.41 F: 79.54 # # Directory and filename of the webpage include file to create $ftp_src_dir = "/tmp/"; $ftp_src_file = "nexus_temp.inc"; # Open the file for output open( INCFILE, ">$ftp_src_dir$ftp_src_file") || die "Can't open $ftp_src_dir$ftp_src_file"; # Write the temperatures to the file print INCFILE "
\n"; print INCFILE "
\n"; print INCFILE "The current temperatures are:

\n"; # Run tail -2 /var/log/temperature and parse the output # The -2 depends on the number of sensors that you have. open( TEMPLOG, "tail -2 /var/log/temperature |") || die "Can't fork: $!"; while( ) { # Get the time and date, sensor number, temperature in c and f ($month,$day,$time,$d1,$sensor,$d1,$centigrade,$d1,$fahrenheight) = split( " ", $_ ); # Print sensor specific messages # The \xB0 is supposed to be a degree symbol. It seems to work for some # systems but not for others if( $sensor eq '0' ) { print INCFILE "The modems are $fahrenheight\xB0 F ($centigrade\xB0 C)
\n"; } if( $sensor eq '1' ) { print INCFILE "The room is a "; if( $fahrenheight < 40.0 ) { print INCFILE "Freezing"; } if( $fahrenheight >= 40.0 and $fahrenheight < 70.0 ) { print INCFILE "Chilly"; } if( $fahrenheight >= 70.0 and $fahrenheight < 80.0 ) { print INCFILE "Comfortable"; } if( $fahrenheight >= 80.0 and $fahrenheight < 100.0 ) { print INCFILE "Balmy"; } if( $fahrenheight >= 100.0 ) { print INCFILE "Blistering"; } print INCFILE " $fahrenheight\xB0 F ($centigrade\xB0 C)
\n"; } } print INCFILE "Last updated: $month $day $time
\n"; print INCFILE "

\n"; close( TEMPLOG ); close( INCFILE ); # done! digitemp-3.7.2/perl/make_mysql.sql000066400000000000000000000003671337460421500171650ustar00rootroot00000000000000CREATE table digitemp ( dtKey int(11) NOT NULL auto_increment, time timestamp NOT NULL, SerialNumber varchar(17) NOT NULL, Fahrenheit decimal(6,2) NOT NULL, PRIMARY KEY (dtKey), KEY serial_key (SerialNumber), KEY time_key (time) ); digitemp-3.7.2/perl/maxplot000077500000000000000000000201061337460421500157050ustar00rootroot00000000000000#!/usr/bin/perl # -*- Perl -*- # # DigiTemp v2.1 gnuplot script # Modified by Brian C. Lane www.brianlane.com # # Modified plot script from Russell Nelson # for use with the GD module for Perl # # The GD module can be found at: # http://www.perl.com/CPAN-local//modules/by-module/GD/ # # More mods to add maximum and minimum temp display for each day # NOTE: You will need to change the commands at the bottom that tell # where to store and move the final .gif file to. # use GD; # Transform the temperature into graph coordinates. Convert to Farenheit # I already have fahrenheight data, so no conversion is needed. sub ytransform { $temp = shift; # $temp = $temp * 9 / 5 + 32; return int(250 - 2*$temp); } # You will need to customize these values for your setup $height = 350; $hmargin = 40; $middlex = 300; # display them all! $dx=2.0/1.0; # # of temperatures per sample (number of sensors) $sensors = 3; $samples_per_hour = 2; # 5 Days, 24 hours a day, 2 samples per hour $samples = 5*24* $samples_per_hour; $width = $hmargin + $samples*$dx + $hmargin; # print PLOT "create plot $width $height\n"; $im = new GD::Image( $width, $height ); # Allocate a bunch of colors ($white,$black,$red,$green,$orange,$lightgreen,$blue,$skyblue) = ( $im->colorAllocate(255, 255, 255), $im->colorAllocate(0, 0, 0), $im->colorAllocate(255, 0, 0), $im->colorAllocate(0,255,0), $im->colorAllocate(255,0,255), $im->colorAllocate(0,128,0), $im->colorAllocate(0,0,255), $im->colorAllocate(100,100,255) ); # Grayscale -- Not currently used. I'll skip for now #for ($i=0; $i<128; $i++) { # print PLOT "colorallocate plot gray$i ".$i*2 ." ".$i*2 ." ".$i*2 ."\n"; #} #sub dogray { # ($light) = @_; # # if ($light < -70) { # $gray = int(0.5 + 32 * ($light - -92) / (-70 - -92)); # } elsif ($light < 265) { # $gray = int(32.5 + 32 * ($light - -70) / (265 - -70)); # } else { # $gray = int(64.5 + 64 * ($light - 265) / (290 - 265)); # } # $gray = 0 if ($gray < 0); # $gray = 127 if ($gray > 127); # print PLOT "filledrectangle plot "; # print PLOT "$x 20 "; # print PLOT $x+$dx." ".($height-20)." gray$gray\n"; #} # Draw a Horizontal line at a temperature point sub hline { ($y,$color) = @_; $color = $skyblue unless $color; $yname = $y; $y = &ytransform($y); $ychar = $y-6; $numleft = 10; $lineleft = 26; $lineright = $width - 24; $numright = $width - 20; # print PLOT "string plot gdFont6x13 $numleft $ychar \"$yname\" $color\n"; $im->string(gdSmallFont,$numleft,$ychar,$yname,$color); # print PLOT "line plot $lineleft $y $lineright $y $color\n"; $im->line($lineleft,$y,$lineright,$y,$color); # print PLOT "string plot gdFont6x13 $numright $ychar \"$yname\" $color\n"; $im->string(gdSmallFont,$numright,$ychar,$yname,$color); } # Draw the temperature reference lines #&hline(-20); &hline(0 ); &hline(20 ); &hline(32, $lightgreen ); &hline(40 ); &hline(60 ); &hline(80 ); &hline(100 ); sub xtransform { return $hmargin + $dx * shift; } # Draw a vertical line sub vline { ($x,$label,$color) = @_; $color = $skyblue unless $color; $x = &xtransform($x); $linetop = &ytransform(100); $linebot = &ytransform(-20); $ychar = &ytransform(107); # print PLOT "string plot gdFont6x13 $x $ychar \"$label\" $color\n"; $im->string(gdSmallFont,$x-5,$ychar,$label,$color); # print PLOT "line plot $x $linetop $x $linebot $color\n"; $im->line($x,$linetop,$x,$linebot,$color); } # See if the min or max data for the current day should be changed # This function has been tested and works sub minmax { ($sample,$temp,$sensor) = @_; $day = int($sample / (24 * $samples_per_hour ) ); if( $temp > $max_temp[$day][$sensor] ) { #print "oldmax[$day][$sensor] = $max_temp[$day][$sensor]\n"; $max_temp[$day][$sensor] = $temp; #print "newmax[$day][$sensor] = $max_temp[$day][$sensor]\n"; } if( $temp < $min_temp[$day][$sensor] ) { #print "oldmin[$day][$sensor] = $min_temp[$day][$sensor]\n"; $min_temp[$day][$sensor] = $temp; #print "newmin[$day][$sensor] = $min_temp[$day][$sensor]\n"; } } # --------------------------------[ MAIN CODE ]---------------------------- # Draw the vertical day lines &vline(0*24*$samples_per_hour," -5d"); &vline(1*24*$samples_per_hour," -4d"); &vline(2*24*$samples_per_hour," -3d"); &vline(3*24*$samples_per_hour," -2d"); &vline(4*24*$samples_per_hour," yesterday"); &vline(5*24*$samples_per_hour," now"); # Here we read in all the samples. I have 3 temps for every # 30 minutes within the day. $lines = $sensors * $samples; open(DOTTEMP, "tail -$lines /gonzo/var/log/temperatures|"); @dottemp = ; close(DOTTEMP); # Now all the temps are in dottemp -- it might be better to read it line # by line for bigger files? # Initialize the initial variables - I should use a list for this $x = $hmargin; $_= $dottemp[0]; @_ = split( " ", $_ ); $lasty0 = &ytransform($_[8]); $_= $dottemp[1]; @_ = split( " ", $_ ); $lasty1 = &ytransform($_[8]); $_= $dottemp[2]; @_ = split( " ", $_ ); $lasty2 = &ytransform($_[8]); # Init the max and min temps and their points on the graph # Keep track of data for all of the last 5 days for( 0 .. 4 ) { $day = $_; for( 0 .. 2 ) { $max_temp[$day][$_] = -50; $min_temp[$day][$_] = 200; } } $sample = 0; # Plot each of the datapoints. foreach (@dottemp) { # Get the time and date, sensor number, temperature in c and f ($month,$day,$time,$d1,$sensor,$d1,$centigrade,$d1,$fahrenheight) = split(" ", $_ ); # Plot the next line for each sensor # 0 - Harddrive #1 in gonzo # 2 - Room Temperature # 1 - Outside temperature if( $sensor eq '0' ) { $color = $red; $y0 = &ytransform($fahrenheight); $im->line(int($x),$lasty0,int($x+$dx),$y0,$color); $lasty0 = $y0; # Run minmax for the current day and sensor &minmax( $sample, $fahrenheight, 0 ); } if( $sensor eq '1' ) { $color = $green; $y1 = &ytransform($fahrenheight); $im->line(int($x),$lasty1,int($x+$dx),$y1,$color); $lasty1 = $y1; # Run minmax for the current day and sensor &minmax( $sample, $fahrenheight, 1 ); } if( $sensor eq '2' ) { $color = $orange; $y2 = &ytransform($fahrenheight); $im->line(int($x),$lasty2,int($x+$dx),$y2,$color); $lasty2 = $y2; # Run minmax for the current day and sensor &minmax( $sample, $fahrenheight, 2 ); # Count the number of samples so we can figure out what day it is $sample++; # move to next position $x += $dx; } } # Print the Header for the Min/Max data for each day for( 0 .. 4 ) { $im->string(gdSmallFont,3+&xtransform($_*24*$samples_per_hour),&ytransform(-1),"Min Max",$black); } # Print the min and max temperatures # Print the min/max for each day and sensor for( 0 .. 4 ) { $im->string(gdSmallFont,3+&xtransform($_*24*$samples_per_hour),&ytransform(-6),sprintf("%-6s %s",$min_temp[$_][0],$max_temp[$_][0]),$red); $im->string(gdSmallFont,3+&xtransform($_*24*$samples_per_hour),&ytransform(-11),sprintf("%-6s %s",$min_temp[$_][1],$max_temp[$_][1]),$green); $im->string(gdSmallFont,3+&xtransform($_*24*$samples_per_hour),&ytransform(-16),sprintf("%-6s %s",$min_temp[$_][2],$max_temp[$_][2]),$orange); } # Add the Date and time $date = `date "+Generated at %H:%M on %a, %b %d %Y"`; chop $date; $im->string(gdSmallFont,$middlex-5,&ytransform(-30),$date,$black); # Advertise! $im->string(gdSmallFont,$middlex-5,&ytransform(-35),"with DigiTemp - http://www.brianlane.com",$black); # Print the Color Key $im->string(gdSmallFont,$hmargin,&ytransform(-30),"Harddrive #1",$red); $im->string(gdSmallFont,$hmargin,&ytransform(-35),"Room Temperature",$green); $im->string(gdSmallFont,$hmargin,&ytransform(-40),"Outside Temperature",$orange); # Output it to a .gif image file open( PLOT, ">/tmp/tempplot.gif"); print PLOT $im->gif; close(PLOT); # copy the image to its final destination and make sure it is owned # by the right person. system "cp /tmp/tempplot.gif /home/nexus/.public_html/tempplot.gif"; system "chown nexus.users /home/nexus/.public_html/tempplot.gif"; system "chmod 0644 /home/nexus/.public_html/tempplot.gif"; digitemp-3.7.2/perl/rem_temp000077500000000000000000000102241337460421500160310ustar00rootroot00000000000000#!/usr/bin/perl -w # # DigiTemp remote system update script # Copyright 1997-2001 by Brian C. Lane www.brianlane.com # All Rights Reserved # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # # Read the temperature logfile, write it to an include file for the webpage, # then ftp the files to the destination server. # # The following perl extensions are required : # libnet package from http://www.perl.com/CPAN-local/modules/by-module/Net/ # I used libnet-1.0506.tar.gz # # Data-Dumper package from: CPAN/modules/by-module/Data/Data-Dumper-x.x.tar.gz # I used Data-Dumper-2.07.tar.gz # # Sensor #0 is the Window # Sensor #1 is the inside of the Linux box # # Dec 18 21:46:47 Sensor 0 C: 8.81 F: 47.86 # Dec 18 21:46:47 Sensor 1 C: 26.41 F: 79.54 # use Net::FTP; # Include file for the webpage (included from the main page) $inc_file = "/tmp/temp.inc"; # Temperature logfile updated by seperate DigiTemp daemon $log_file = "/var/log/temperature"; # Script to run to bring up the link # I use diald, you probably use something different. $ip_up = "/usr/sbin/dialdc up"; # Your username for the destination ftp server $ftp_user = "username"; # Your password for the destination ftp server $ftp_pass = "password"; # Destination ftp server's address $ftp_host = "ftp.host.com"; # Directory on the destination ftp server to place $inc_file $dest_dir = "/home/login/public_html"; # Create a new include file, overwrite the old one open( INCFILE, ">$inc_file") || die "Can't open $inc_file"; # Include a break line and center the text print INCFILE "
\n"; print INCFILE "
\n"; # You should customize this! print INCFILE "The current temperatures are

\n"; # Run tail -2 /var/log/temperature and parse the output # The -2 is the number of sensors you have (last 2 lines from logfile) open( TEMPLOG, "tail -2 $log_file |") || die "Can't fork: $!"; # Parse the output of the tail program while( ) { # Get the time and date, sensor number, temperature in c and f ($month,$day,$time,$d1,$sensor,$d1,$centigrade,$d1,$fahrenheight) = split( " ", $_ ); # Print some custom messages for the sensors # The \xB0 is supposed to be a degree symbol. This works on some systems # but not on others. if( $sensor eq '0' ) { print INCFILE "The modems are at $fahrenheight\xB0 F ($centigrade\xB0 C)
\n"; } if( $sensor eq '1' ) { print INCFILE "The room is a "; if( $fahrenheight < 40.0 ) { print INCFILE "freezing"; } if( $fahrenheight >= 40.0 and $fahrenheight < 70.0 ) { print INCFILE "chilly"; } if( $fahrenheight >= 70.0 and $fahrenheight < 80.0 ) { print INCFILE "comfortable"; } if( $fahrenheight >= 80.0 and $fahrenheight < 100.0 ) { print INCFILE "balmy"; } if( $fahrenheight >= 100.0 ) { print INCFILE "blistering"; } print INCFILE " $fahrenheight\xB0 F ($centigrade\xB0 C)
\n"; } } print INCFILE "Last updated: $month $day $time
\n"; # Blantant advertisement print INCFILE "

These temperatures generated with ";
print INCFILE "";
print INCFILE "DigiTemp

\n"; print INCFILE "
\n"; close( TEMPLOG ); close( INCFILE ); # Send it to the server # Fire up the link system $ip_up; # Wait a little bit to let ppp0 come up sleep 60; # Send it to the server $ftp = Net::FTP->new($ftp_host); $ftp->login($ftp_user,$ftp_pass); $ftp->cwd($dest_dir); $ftp->binary(); $ftp->put($inc_file); $ftp->quit; # Shut down the link system $ip_down; # done! digitemp-3.7.2/python/000077500000000000000000000000001337460421500146535ustar00rootroot00000000000000digitemp-3.7.2/python/mysql/000077500000000000000000000000001337460421500160205ustar00rootroot00000000000000digitemp-3.7.2/python/mysql/README000066400000000000000000000014011337460421500166740ustar00rootroot00000000000000This script is pretty rough at the moment. I haven't made any attempt to clean it up and make it more user friendly yet. But it does work if you're willing to take the time to tweak it. It reads temps, logs them to a MySQL database named weather as a user named weather, logs the data to a RRD and writes a new sigfile. Requirements are: DigiTemp v3.1.x+ http://www.digitemp.com MySQL database http://www.mysql.org Round Robin Database http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/ Python MySQLdb module http://www.mysql.com/downloads/api-python.html If you find any problems, let me know. I may have forgotten something. The windspeed calculation isn't correct. I'm still working on graphs that are based on the MySQL database data. digitemp-3.7.2/python/mysql/home_weather.py000077500000000000000000000127151337460421500210520ustar00rootroot00000000000000#!/usr/bin/env python # # DigiTemp temperature and q-wire home weather station logging # Copyright 2003 by Brian C. Lane # http://www.digitemp.com # # Requires DigiTemp v3.1.0 or later for counter support # Requires Python MySQLdb module and Round Robin Database binaries # # Logs data to a MySQL database and to a RRDb graph log # # Create a MySQL database called weather and give a weather user permission # to access it. # GRANT SELECT,INSERT,CREATE ON weather.* TO weather@localhost IDENTIFIED BY 'password'; # # CREATE TABLE temperature ( # TemperatureKey bigint UNSIGNED NOT NULL auto_increment, # SerialNumber varchar(20) NOT NULL, # RecTime timestamp NOT NULL, # C float NOT NULL, # PRIMARY KEY(SerialNumber), # KEY(TemperatureKey) # ); # # CREATE TABLE counter ( # CounterKey bigint UNSIGNED NOT NULL auto_increment, # SerialNumber varchar(20) NOT NULL, # RecTime timestamp NOT NULL, # CounterNum tinyint UNSIGNED NOT NULL, # CounterValue mediumint UNSIGNED NOT NULL, # PRIMARY KEY(SerialNumber), # KEY(CounterKey) # ); # import string, os, sys, time import MySQLdb timefmt = '%Y-%m-%d %H:%M:%S' # Connect to the database try: mydb = MySQLdb.Connect(host='localhost',user='weather',passwd='password',db='weather') except DatabaseError: print "Problem connecting to database" sys.exit(-1) cursor=mydb.cursor() # 1. Read the output of DigiTemp cmd = '/home/brian/temperature/digitemp -c/home/brian/temperature/digitemp.cfg -a -q' for outline in os.popen(cmd).readlines(): outline = outline[:-1] # print outline if outline[0:1] == 'T': # Parse the temperature sensor line S = string.split(outline, " ") # print S # Add the reading to the database sql = "INSERT INTO temperature VALUES(NULL, %s, %s, %s)" sqltime = time.strftime( timefmt, time.localtime(int(S[2]))) cursor.execute( sql, (S[1], sqltime, S[3]) ); if outline[0:1] == 'C': # Parse the counter line S = string.split(outline, " ") # print S # Add the reading to the database sql = "INSERT INTO counter VALUES(NULL, %s, %s, %s, %s)" sqltime = time.strftime( timefmt, time.localtime(int(S[2]))) cursor.execute( sql, (S[1], sqltime, S[3], S[4]) ); # ----------------------------------------------------------------------- # Do interesting things with the just-logged information # ======================================================================= # Brian's Sensor Map: # #10E8A00E00000055 Room (grey wire) #10B95E05000800AA Attic #10575A050008008F Desk #22B9B20500000049 DS1822 #286D1D2D000000EA DS18B20 (kermit) #1092B9330008002E Drink #1D9CB900000000B3 Rain Gauge #1DFA15010000005F Wind Speed #1009212E0008004B DT-1A passive sensor # # Dict of serial numbers and what to name them sensors = {'10E8A00E00000055':'Office', '10B95E05000800AA':'Attic', '10575A050008008F':'Desk', '22B9B20500000049':'DS1822', '286D1D2D000000EA':'DS18B20', '1092B9330008002E':'Drink', '1009212E0008004B':'DT1A' } counters= {'1D9CB900000000B3':'Rain', '1DFA15010000005F':'Wind' } rrdtool_path = "/usr/local/rrdtool/bin/rrdtool" rrd_path = "/home/brian/temperature/" def c2f( c ): f = 32.0 + ((c * 9.0) / 5.0) return f rrd_sensors = {} # grab the latest readings for the sensors for skey in sensors.keys(): sql = "SELECT UNIX_TIMESTAMP(rectime), C from temperature where serialnumber='"+skey+"' ORDER BY rectime DESC LIMIT 1" # print sql cursor.execute(sql) result = cursor.fetchone() # print result rrd_sensors[sensors[skey]] = result # grab the counters rrd_counters = {} # grab the latest readings for the sensors for ckey in counters.keys(): sql = "SELECT UNIX_TIMESTAMP(rectime), countervalue from counter where serialnumber='"+ckey+"' AND counternum=0 ORDER BY rectime DESC LIMIT 1" # print sql cursor.execute(sql) result = cursor.fetchone() # print result rrd_counters[counters[ckey]] = result # Log the temperatures to the RRD # rrdtool update drink.rrd time:value rrd = "%s update %s/drink.rrd %ld:%0.2f" % (rrdtool_path, rrd_path, rrd_sensors['Drink'][0], rrd_sensors['Drink'][1]) os.system(rrd) #print rrd # rrdtool update outside.rrd time:value rrd = "%s update %s/outside.rrd %ld:%0.2f" % (rrdtool_path, rrd_path, rrd_sensors['Attic'][0], rrd_sensors['Attic'][1]) os.system(rrd) #print rrd # rrdtool update room.rrd time:value rrd = "%s update %s/room.rrd %ld:%0.2f" % (rrdtool_path, rrd_path, rrd_sensors['Office'][0], rrd_sensors['Office'][1]) os.system(rrd) #print rrd # rrdtool update room.rrd time:value rrd = "%s update %s/kermit.rrd %ld:%0.2f" % (rrdtool_path, rrd_path, rrd_sensors['DS1822'][0], rrd_sensors['DS1822'][1]) os.system(rrd) #print rrd # Log the counter values # rrdtool update rain.rrd time:value rrd = "%s update %s/rain.rrd %ld:%ld" % (rrdtool_path, rrd_path, rrd_counters['Rain'][0], rrd_counters['Rain'][1]) os.system(rrd) #print rrd # rrdtool update wind.rrd rime:value rrd = "%s update %s/wind.rrd %ld:%ld" % (rrdtool_path, rrd_path, rrd_counters['Wind'][0], rrd_counters['Wind'][1]) os.system(rrd) #print rrd # Write a new .signature file outfile = open('/home/user/.signature','w') sig = "--[Inside %0.1fF]--[Outside %0.1fF]--[Kermit %0.1fF]--[Coaster %0.1fF]--\n" % (c2f(rrd_sensors['Office'][1]),c2f(rrd_sensors['Attic'][1]),c2f(rrd_sensors['DS1822'][1]),c2f(rrd_sensors['Drink'][1])) outfile.write(sig) outfile.close() mydb.close() digitemp-3.7.2/python/mysql/make_rain_rrd000077500000000000000000000005661337460421500205520ustar00rootroot00000000000000#!/bin/sh /usr/local/rrdtool/bin/rrdtool create rain.rrd \ DS:Rain:COUNTER:600:U:U \ RRA:AVERAGE:0.5:1:600 \ RRA:AVERAGE:0.5:6:700 \ RRA:AVERAGE:0.5:24:775 \ RRA:AVERAGE:0.5:288:797 \ RRA:MAX:0.5:1:600 \ RRA:MAX:0.5:6:700 \ RRA:MAX:0.5:24:775 \ RRA:MAX:0.5:288:797 digitemp-3.7.2/python/mysql/make_sensor_rrd000077500000000000000000000010101337460421500211130ustar00rootroot00000000000000#!/bin/sh /usr/local/rrdtool/bin/rrdtool create sensor.rrd \ DS:Temperature:GAUGE:600:U:U \ RRA:AVERAGE:0.5:1:600 \ RRA:AVERAGE:0.5:6:700 \ RRA:AVERAGE:0.5:24:775 \ RRA:AVERAGE:0.5:288:797 \ RRA:MAX:0.5:1:600 \ RRA:MAX:0.5:6:700 \ RRA:MAX:0.5:24:775 \ RRA:MAX:0.5:288:797 \ RRA:MIN:0.5:1:600 \ RRA:MIN:0.5:6:700 \ RRA:MIN:0.5:24:775 \ RRA:MIN:0.5:288:797 digitemp-3.7.2/python/mysql/make_wind_rrd000077500000000000000000000005701337460421500205550ustar00rootroot00000000000000#!/bin/sh /usr/local/rrdtool/bin/rrdtool create wind.rrd \ DS:WindSpeed:DERIVE:600:0:U \ RRA:AVERAGE:0.5:1:600 \ RRA:AVERAGE:0.5:6:700 \ RRA:AVERAGE:0.5:24:775 \ RRA:AVERAGE:0.5:288:797 \ RRA:MAX:0.5:1:600 \ RRA:MAX:0.5:6:700 \ RRA:MAX:0.5:24:775 \ RRA:MAX:0.5:288:797 digitemp-3.7.2/rrdb/000077500000000000000000000000001337460421500142635ustar00rootroot00000000000000digitemp-3.7.2/rrdb/README000066400000000000000000000021751337460421500151500ustar00rootroot00000000000000 DigiTemp v2.4 rrdb scripts Copyright 1999-2002 by Brian C. Lane www.brianlane.com All Rights Reserved The Round Robin Database is a great way to store data that you want to graph. You can get it from: http://ee-staff.ethz.ch/~oetiker/webtools/rrdtool/ log_temps calls digitemp and adds the current temperature readings to the RRD database. It should be called from a crontab at regular intervals. log-temperature.pl is a Perl script that runs digitemp and inserts the new samples into the RRDB, optionally it can create a text file for use in an email signature. make_temps creates a RRD database suitable for logging 3 sensors of data. temp-all.cgi temp-one.cgi are scripts to generate .png graphs of temperature data. Insert them into your webpage with: temp-minmax.cgi generates a graph with minimum and maximum printed on the graph. The suggested initialization sets up digitemp to output the temperature in Centigrade and the conversion to Fahrenheit. The -o option passed to digitemp when it is initialized controls how the temperature is output. digitemp-3.7.2/rrdb/log-temperature.pl000077500000000000000000000052511337460421500177420ustar00rootroot00000000000000#!/usr/bin/perl -w # # DigiTemp v2.3 RRDB Temperature logger # # Copyright 1997-2002 by Brian C. Lane www.brianlane.com # All Rights Reserved # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # This require the RRDB pipe module for Perl, available with the RRDB source # from http://ee-staff.ethz.ch/~oetiker/webtools/rrdtool/ use RRDp; # Convert centigrade to fahrenheit sub ctof { ($temp_c) = @_; return 32 + (($temp_c * 9)/5); } # Find the RRD executable, look in the standard locations # If your rrdtool is installed someplace else, fill in the proper location # below: if ( -x "/usr/bin/rrdtool") { RRDp::start "/usr/bin/rrdtool"; } elsif ( -x "/usr/local/bin/rrdtool") { RRDp::start "/usr/local/bin/rrdtool"; } elsif ( -x "/usr/local/rrdtool/bin/rrdtool" ) { RRDp::start "/usr/local/rrdtool/bin/rrdtool"; } else { die "Could not find rrdtool binary\n"; } # The RRD database to put the data into $wx_rrd = "/tmp/digitemp.rrd"; # Read the output from digitemp # Output in form 0\troom\tattic\tdrink open( DIGITEMP, "digitemp -a -q -o2 |" ); while( ) { # print "$_\n"; chomp; if( $_ =~ /^nanosleep/i ) { $now = localtime; open( ERRLOG, ">>/tmp/dt-error") or die "Error opening dt-error"; print ERRLOG "nanosleep error at $now\n"; close( ERRLOG ); die "nanosleep error"; } else { ($null,$desk_DS18S20,$attic_DS18S20,$room) = split(/\t/); } } close( DIGITEMP ); # Put the info into the weather rrd database room:drink:attic RRDp::cmd "update $wx_rrd N:$room:$attic_DS18S20:$desk_DS18S20"; #$answer=RRDp::read; # This section was used to create up to date email signature files # Create the email header in Fahrenheit #open( HEADER, ">/tmp/.header") or die "Error opening .header"; #$now = localtime; #print HEADER "[$now]--[Inside "; #printf HEADER "%0.2f",ctof( $room ); #print HEADER "F]--[Outside "; #printf HEADER "%0.2f",ctof( $attic_DS18S20 ); #print HEADER"F]--[Drink "; #printf HEADER "%0.2f",ctof( $desk_DS18S20 ); #print HEADER "F]--\n"; #close( HEADER ); exit; digitemp-3.7.2/rrdb/log_temp000077500000000000000000000027741337460421500160310ustar00rootroot00000000000000#!/bin/bash # DigiTemp RRD logging script # Copyright 1997-2002 by Brian C. Lane www.brianlane.com # All Rights Reserved # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Call this from crontab every 5 minutes. Make sure the .digitemprc is in # your root directory or specify the configuration file using -c filename # on the digitemp command line in the reading variable below. # Get the current temperatures, digitemp has been previously initialized with # digitemp -i -s /dev/ttyS0 -o2 -a # Run it in quiet mode, output is 0\tsensor#1\tsensor#2\tsensor#3 reading=`/usr/local/bin/digitemp -a -q` # Diagnostic output room=`echo $reading | gawk '{print $2}'` attic=`echo $reading | gawk '{print $3}'` drink=`echo $reading | gawk '{print $4}'` # Update the database /usr/local/rrdtool/bin/rrdtool update /root/rrdb/digitemp.rrd N:$room:$drink:$attic digitemp-3.7.2/rrdb/make_temps000077500000000000000000000026711337460421500163440ustar00rootroot00000000000000#!/usr/bin/perl -w # # DigiTemp v2.1 RRDB database Creation # # Copyright 1997-2001 by Brian C. Lane www.brianlane.com # All Rights Reserved # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA use Time::Local; use RRDp; RRDp::start "/usr/local/rrdtool/bin/rrdtool"; # Create the database RRDp::cmd "create digitemp.rrd \ DS:room:GAUGE:600:U:U \ DS:attic:GAUGE:600:U:U \ DS:desk:GAUGE:600:U:U \ RRA:AVERAGE:0.5:1:600 \ RRA:AVERAGE:0.5:6:700 \ RRA:AVERAGE:0.5:24:775 \ RRA:AVERAGE:0.5:288:797 \ RRA:MIN:0.5:1:600 \ RRA:MIN:0.5:6:700 \ RRA:MIN:0.5:24:775 \ RRA:MIN:0.5:288:797 \ RRA:MAX:0.5:1:600 \ RRA:MAX:0.5:6:700 \ RRA:MAX:0.5:24:775 \ RRA:MAX:0.5:288:797"; $answer = RRDp::read; #print $$answer; RRDp::end; digitemp-3.7.2/rrdb/temp-all.cgi000077500000000000000000000056331337460421500164740ustar00rootroot00000000000000#!/usr/bin/perl -w # # DigiTemp v2.1 RRDB Temperature Graph # # Copyright 1997-2001 by Brian C. Lane www.brianlane.com # All Rights Reserved # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # REQUIRES: # RRD tool binary # CGI (comes with perl5) use RRDp; use CGI; $cgi = new CGI; # Load the CGI routines # Find the RRD executable, look in the standard locations # If your rrdtool is installed someplace else, fill in the proper location # below: if ( -x "/usr/bin/rrdtool") { RRDp::start "/usr/bin/rrdtool"; } elsif ( -x "/usr/local/bin/rrdtool") { RRDp::start "/usr/local/bin/rrdtool"; } elsif ( -x "/usr/local/rrdtool/bin/rrdtool" ) { RRDp::start "/usr/local/rrdtool/bin/rrdtool"; } else { die "Could not find rrdtool binary\n"; } # The RRD database to get the data from $rrd = "/tmp/digitemp.rrd"; # Make the variables easier to use and assign defaults if not set if( !$cgi->param('starttime') ) { $starttime = "-1day"; } else { $starttime = $cgi->param('starttime'); } if( !$cgi->param('endtime') ) { $endtime = time; } else { $endtime = $cgi->param('endtime'); } if( !$cgi->param('width') ) { $width = "400"; } else { $width = $cgi->param('width'); } if( !$cgi->param('height') ) { $height = "100"; } else { $height = $cgi->param('height'); } if( !$cgi->param('label') ) { $label=""; } else { $label = $cgi->param('label'); } $var = $cgi->param('var'); # Diagnostic output #print STDERR "start = $starttime\n"; #print STDERR "end = $endtime\n"; #print STDERR "width = $width\n"; #print STDERR "height = $height\n"; #print STDERR "var = $var\n"; #print STDERR "label = $label\n"; # Output a HTML header for the PNG image to follow print $cgi->header('image/png'); # Generate the graph RRDp::cmd "graph - --imgformat PNG", "--start '$starttime' --end '$endtime'", "--width $width --height $height", "DEF:room_c=$rrd:room:AVERAGE", "DEF:attic_c=$rrd:attic:AVERAGE", "DEF:desk_c=$rrd:desk:AVERAGE", "CDEF:room_f=room_c,9,*,5,/,32,+", "CDEF:attic_f=attic_c,9,*,5,/,32,+", "CDEF:desk_f=drink_c,9,*,5,/,32,+", "LINE1:room_f#00FF00:'Computer Room'", "LINE1:attic_f#FF0000:'Attic'", "LINE1:desk_f#0000FF:'Desk'"; $answer=RRDp::read; print $$answer; RRDp::end; digitemp-3.7.2/rrdb/temp-minmax.cgi000077500000000000000000000073751337460421500172220ustar00rootroot00000000000000#!/usr/bin/perl -w # # DigiTemp v2.1 RRDB Temperature Graph with Min/Max # # Copyright 1997-2001 by Brian C. Lane www.brianlane.com # All Rights Reserved # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # REQUIRES: # RRD tool binary # CGI (comes with perl5) use RRDp; use CGI; $cgi = new CGI; # Load the CGI routines # Find the RRD executable, look in the standard locations # If your rrdtool is installed someplace else, fill in the proper location # below: if ( -x "/usr/bin/rrdtool") { RRDp::start "/usr/bin/rrdtool"; } elsif ( -x "/usr/local/bin/rrdtool") { RRDp::start "/usr/local/bin/rrdtool"; } elsif ( -x "/usr/local/rrdtool/bin/rrdtool" ) { RRDp::start "/usr/local/rrdtool/bin/rrdtool"; } else { die "Could not find rrdtool binary\n"; } # The RRD database to get the data from $rrd = "/tmp/digitemp.rrd"; # Make the variables easier to use and assign defaults if not set if( !$cgi->param('starttime') ) { $starttime = "-1day"; } else { $starttime = $cgi->param('starttime'); } if( !$cgi->param('endtime') ) { $endtime = time; } else { $endtime = $cgi->param('endtime'); } if( !$cgi->param('width') ) { $width = "400"; } else { $width = $cgi->param('width'); } if( !$cgi->param('height') ) { $height = "100"; } else { $height = $cgi->param('height'); } if( !$cgi->param('label') ) { $label=""; } else { $label = $cgi->param('label'); } $var = $cgi->param('var'); # Diagnostic output #print STDERR "start = $starttime\n"; #print STDERR "end = $endtime\n"; #print STDERR "width = $width\n"; #print STDERR "height = $height\n"; #print STDERR "var = $var\n"; #print STDERR "label = $label\n"; RRDp::cmd "last $rrd"; $lastupdate = RRDp::read; # Output a HTML header for the PNG image to follow print $cgi->header('image/png'); # Generate the graph RRDp::cmd "graph - --imgformat PNG", "--start '$starttime' --end '$endtime'", "--width $width --height $height", "DEF:room_c=$rrd:room:AVERAGE", "DEF:attic_c=$rrd:attic:AVERAGE", "DEF:desk__c=$rrd:desk:AVERAGE", "CDEF:room_f=room_c,9,*,5,/,32,+", "CDEF:attic_f=attic_c,9,*,5,/,32,+", "CDEF:desk_f=desk_c,9,*,5,/,32,+", "COMMENT:\" \"", "COMMENT:\" Min Max Avg Last\\n\"", "COMMENT:\" \"", "GPRINT:attic_f:MIN:\"Attic %5.2lf F\"", "GPRINT:attic_f:MAX:\" %5.2lf F\"", "GPRINT:attic_f:AVERAGE:\" %5.2lf F\"", "GPRINT:attic_f:LAST:\" %5.2lf F\\n\"", "COMMENT:\" \"", "GPRINT:room_f:MIN:\"Room %5.2lf F\"", "GPRINT:room_f:MAX:\" %5.2lf F\"", "GPRINT:room_f:AVERAGE:\" %5.2lf F\"", "GPRINT:room_f:LAST:\" %5.2lf F\\n\"", "COMMENT:\" \"", "GPRINT:desk_f:MIN:\"Desk %5.2lf F\"", "GPRINT:desk_f:MAX:\" %5.2lf F\"", "GPRINT:desk_f:AVERAGE:\" %5.2lf F\"", "GPRINT:desk_f:LAST:\" %5.2lf F\\n\"", "COMMENT:\"\\s\"", "LINE1:room_f#FF8000:'Computer Room'", "LINE1:attic_DS18S20_f#8080F0:'Attic'", "LINE2:desk_DS18S20_f#008000:'Desk\\c'", "COMMENT:\"Last Updated ". localtime($$lastupdate) . "\\c\""; $answer=RRDp::read; print $$answer; RRDp::end; digitemp-3.7.2/rrdb/temp-one.cgi000077500000000000000000000055051337460421500165030ustar00rootroot00000000000000#!/usr/bin/perl -w # # DigiTemp v2.1 RRDB Temperature Graph (single sensor) # # Copyright 1997-2001 by Brian C. Lane www.brianlane.com # All Rights Reserved # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # REQUIRES: # RRD tool binary # CGI (comes with perl5) use RRDp; use CGI; $cgi = new CGI; # Load the CGI routines # Find the RRD executable, look in the standard locations # If your rrdtool is installed someplace else, fill in the proper location # below: if ( -x "/usr/bin/rrdtool") { RRDp::start "/usr/bin/rrdtool"; } elsif ( -x "/usr/local/bin/rrdtool") { RRDp::start "/usr/local/bin/rrdtool"; } elsif ( -x "/usr/local/rrdtool/bin/rrdtool" ) { RRDp::start "/usr/local/rrdtool/bin/rrdtool"; } else { die "Could not find rrdtool binary\n"; } # The RRD database to get the data from $rrd = "/tmp/digitemp.rrd"; # Make the variables easier to use and assign defaults if not set if( !$cgi->param('starttime') ) { $starttime = "-1day"; } else { $starttime = $cgi->param('starttime'); } if( !$cgi->param('endtime') ) { $endtime = time; } else { $endtime = $cgi->param('endtime'); } if( !$cgi->param('width') ) { $width = "400"; } else { $width = $cgi->param('width'); } if( !$cgi->param('height') ) { $height = "100"; } else { $height = $cgi->param('height'); } if( !$cgi->param('label') ) { $label=""; } else { $label = $cgi->param('label'); } $var = $cgi->param('var'); if( !$cgi->param('color') ) { $color = "#000000"; } else { $color = $cgi->param('color'); } # Diagnostic output #print STDERR "start = $starttime\n"; #print STDERR "end = $endtime\n"; #print STDERR "width = $width\n"; #print STDERR "height = $height\n"; #print STDERR "var = $var\n"; #print STDERR "label = $label\n"; #print STDERR "color = $color\n"; # Output a HTML header for the PNG image to follow print $cgi->header('image/png'); # Generate the graph RRDp::cmd "graph - --imgformat PNG", "--start '$starttime' --end '$endtime'", "--width $width --height $height", "DEF:temp_c=$rrd:$var:AVERAGE", "CDEF:temp_f=temp_c,9,*,5,/,32,+", "LINE1:temp_f$color:'$label'"; $answer=RRDp::read; print $$answer; RRDp::end; digitemp-3.7.2/src/000077500000000000000000000000001337460421500141215ustar00rootroot00000000000000digitemp-3.7.2/src/device_name.c000066400000000000000000000103401337460421500165220ustar00rootroot00000000000000/* ----------------------------------------------------------------------- DigiTemp Copyright 1996-2003 by Brian C. Lane All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ----------------------------------------------------------------------- */ /* Return the family name passed to it */ char *device_name( unsigned int family ) { switch( family ) { case 0x01: return "DS2401/DS1990A Serial Number iButton"; case 0x02: return "DS1425/DS1991 MultiKey iButton"; case 0x04: return "DS2402/DS1994 4K NVRAM memory, clock, timer"; case 0x05: return "DS2405 Addressable Switch"; case 0x06: return "DS1993 4K NVRAM Memory"; case 0x08: return "DS1992 1K NVRAM Memory"; case 0x09: return "DS2502/DS1982 1Kbit Add only memory"; case 0x0A: return "DS1995 16K NVRAM Memory"; case 0x0B: return "DS2505/DS1985 16K EPROM Memory"; case 0x0C: return "DS1996/x2/x4 64K to 256K NVRAM Memory"; case 0x0F: return "DS2506/DS1986 64K EEPROM Memory"; case 0x10: return "DS1820/DS18S20/DS1920 Temperature Sensor"; case 0x12: return "DS2406/2407 Dual Addressable Switch + 1Kbit memory"; case 0x14: return "DS2430A/DS1971 256bit EEPROM iButton"; case 0x18: return "DS1963S SHA iButton"; case 0x1A: return "DS1963L 4kBit MONETARY iButton"; case 0x1C: return "DS2422 1Kbit RAM + Counter"; case 0x1D: return "DS2423 4Kbit RAM + Counter"; case 0x1F: return "DS2409 MicroLAN Coupler"; case 0x20: return "DS2450 Quad A/D Converter"; case 0x21: return "DS1921/H/Z Thermochron iButton"; case 0x22: return "DS1822 Econo-Temperature Sensor"; case 0x23: return "DS2433/DS1973 4K EEPROM Memory"; case 0x24: return "DS1425/DS1904 Real Time Clock"; case 0x26: return "DS2438 Temperature, A/D Battery Monitor"; case 0x27: return "DS2417 Real Time Clock with Interrupt"; case 0x28: return "DS18B20 Temperature Sensor"; case 0x29: return "DS2408 8-Channel Addressable Switch"; case 0x2C: return "DS2890 Single Channel Digital Potentiometer"; case 0x30: return "DS2760 Temperature, Current, A/D"; case 0x33: return "DS2432/DS1961S 1K EEPROM with SHA-1 Engine"; case 0x3A: return "DS2413 Dual Channel Addressable Switch"; case 0x41: return "DS1923 Hygrochron Temperature/Humidity Logger with 8kB Data Log Memory"; case 0x42: return "DS28EA00 Temperature Sensor with Sequence Detect and PIO"; case 0x81: return "DS2401 Serial Number (DS9490R/DS9490B)"; case 0x82: return "DS1425 Multi iButton"; case 0x84: return "DS1427 TIME iButton"; case 0x89: return "DS2502/1982 1024bit UniqueWare Add Only Memory"; case 0x8B: return "DS2505/1985 16Kbit UniqueWare Add Only Memory"; case 0x8F: return "DS2506/1986 64Kbit UniqueWare Add Only Memory"; case 0x91: return "DS1981 512-bit EEPROM Memory UniqueWare Only"; case 0x96: return "DS1955/DS1957B Java Cryptographic iButton"; case 0xEE: return "Hobby Boards with Temperature Sensor"; case 0xEF: return "Hobby Boards"; default: return "Unknown Family Code"; } } /* Local Variables: */ /* mode: C */ /* compile-command: "cd ..; make -k" */ /* End: */ digitemp-3.7.2/src/device_name.h000066400000000000000000000017661337460421500165430ustar00rootroot00000000000000/* ------------------------------------------------------------------------ DigiTemp Copyright 1996-2005 by Brian C. Lane All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ------------------------------------------------------------------------ */ char *device_name( unsigned int family ); digitemp-3.7.2/src/digitemp.c000066400000000000000000002441211337460421500160730ustar00rootroot00000000000000/* ----------------------------------------------------------------------- DigiTemp Copyright 1996-2018 by Brian C. Lane All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA digitemp -w Walk the LAN & show all digitemp -i Initialize .digitemprc file digitemp -I Initialize .digitemprc w/sorted serial #s digitemp -s/dev/ttyS0 Set serial port (required) digitemp -cdigitemp.conf Configuration File digitemp -r1000 Set Read timeout to 1000mS digitemp -l/var/log/temperature Send output to logfile digitemp -v Verbose mode digitemp -t0 Read Temperature digitemp -q Quiet, no copyright banner digitemp -a Read all Temperatures digitemp -d5 Delay between samples (in sec.) digitemp -n50 Number of times to repeat. 0=forever digitemp -A Treat DS2438 as A/D converter digitemp -o1 Output format for logfile See description below digitemp -o"output format string" See description below digitemp -O"counter format" See description below digitemp -H"Humidity format" See description below Logfile formats: 1 = (default) - 1 line per sensor, time, C, F 1 line for each sample, elapsed time, sensor #1, #2, ... tab seperated 2 = (seconds since start of measurement) & Reading in C 3 = (seconds since start of measurement) & Reading in F 4 = Unixtime(seconds since 1970-01-01 00:00:00) & Reading in C 5 = Unixtime(seconds since 1970-01-01 00:00:00) & Reading in F The format string uses strftime tokens plus 6 special ones for digitemp - %s for sensor #, %C for centigrade, %F for fahrenheit, %R for hex serial number, %N for seconds since Epoch Humidity uses %h for the relative humidity in percent The counter format uses %n for the counter # and %C for the count in decimal Remember the case of the token is important! ======================================================================= See ChangeLog file for history of changes -----------------------------------------------------------------------*/ #include #include #include #include #if !defined(AIX) && !defined(SOLARIS) && !defined(FREEBSD) && !defined(DARWIN) #include #endif /* !AIX and !SOLARIS and !FREEBSD and !DARWIN */ #include #include #include #include #include #include #include "ad26.h" #include "digitemp.h" #include "device_name.h" #include "ownet.h" #include "owproto.h" /* For tracking down strange errors */ #undef BCL_DEBUG extern char *optarg; extern int optind, opterr, optopt; extern const char dtlib[]; /* Library Used */ char serial_port[1024], /* Path to the serial port */ tmp_serial_port[1024], serial_dev[1024], /* Device name without /dev/ */ log_file[1024], /* Path to the log file */ tmp_log_file[1024], temp_format[80], /* Format for temperature readings */ tmp_temp_format[80], counter_format[80], /* Format for counter readings */ tmp_counter_format[80], humidity_format[80], /* Format for Humidity readings */ tmp_humidity_format[80], conf_file[1024], /* Configuration File */ option_list[40]; int read_time, /* Pause during read */ tmp_read_time, log_type, /* output format type */ tmp_log_type, num_cs = 0, /* Number of sensors on cplr */ opts = 0; /* Bitmask of flags */ struct _coupler *coupler_top = NULL; /* Linked list of couplers */ unsigned char Last2409[9]; /* Last selected coupler */ int global_msec = 10; /* For ReadCOM delay */ int global_msec_max = 15; /* ----------------------------------------------------------------------- * Print out the program usage * ----------------------------------------------------------------------- */ void usage() { printf(BANNER_1); printf(BANNER_2); printf(BANNER_3, dtlib ); /* Report Library version */ printf("\nUsage: digitemp [-s -i -I -U -l -r -v -t -a -d -n -o -c]\n"); printf(" -i Initialize .digitemprc file\n"); printf(" -I Initialize .digitemprc file w/sorted serial #s\n"); printf(" -w Walk the full device tree\n"); printf(" -s /dev/ttyS0 Set serial port\n"); printf(" -l /var/log/temperature Send output to logfile\n"); printf(" -c digitemp.conf Configuration File\n"); printf(" -r 1000 Read delay in mS\n"); printf(" -v Verbose output\n"); printf(" -t 0 Read Sensor #\n"); printf(" -q No Copyright notice\n"); printf(" -a Read all Sensors\n"); printf(" -d 5 Delay between samples (in sec.)\n"); printf(" -n 50 Number of times to repeat\n"); printf(" 0=loop forever\n"); printf(" -A Treat DS2438 as A/D converter\n"); printf(" -O\"counter format string\" See description below\n"); printf(" -o 2 Output format for logfile\n"); printf(" -o\"output format string\" See description below\n"); printf(" -H\"Humidity format string\" See description below\n"); printf("\nLogfile formats: 1 = One line per sensor, time, C, F (default)\n"); printf(" 2 = One line per sample, elapsed time, temperature in C\n"); printf(" 3 = Same as #2, except temperature is in F\n"); printf(" 4 = Same as #2, except elapsed time since (1970-01-01 00:00:00)\n"); printf(" 5 = Same as #4, except temperature is in F\n"); printf(" #2 and #3 have the data separated by tabs, suitable for import\n"); printf(" into a spreadsheet or other graphing software.\n"); printf("\n The format string uses strftime tokens plus 5 special ones for\n"); printf(" digitemp - %%s for sensor #, %%C for centigrade, %%F for fahrenheit,\n"); printf(" %%R to output the hex serial number, and %%N for seconds since Epoch.\n"); printf(" The case of the token is important! The default format string is:\n"); printf(" \"%%b %%d %%H:%%M:%%S Sensor %%s C: %%.2C F: %%.2F\" which gives you an\n"); printf(" output of: May 24 21:25:43 Sensor 0 C: 23.66 F: 74.59\n\n"); printf(" The counter format string has 2 special specifiers:\n"); printf(" %%n is the counter # and %%C is the count in decimal.\n"); printf(" The humidity format uses %%h for the humidity in percent\n\n"); printf(" The logfile may contain strftime pattern to format the filename\n"); } /* ----------------------------------------------------------------------- * Free up all memory used by the coupler list * ----------------------------------------------------------------------- */ void free_coupler( int free_only ) { unsigned char a[3]; struct _coupler *c; c = coupler_top; while(c) { /* Turn off the Coupler */ if ( !free_only ) SetSwitch1F(0, c->SN, ALL_LINES_OFF, 0, a, TRUE); /* Free up the serial number lists */ if( c->num_main > 0 ) free( c->main ); if( c->num_aux > 0 ) free( c->aux ); /* Point to the next in the list */ coupler_top = c->next; /* Free up the current entry */ free( c ); c = coupler_top; } /* Coupler free loop */ /* Make sure its null */ coupler_top = NULL; } /* ----------------------------------------------------------------------- Convert degrees C to degrees F ----------------------------------------------------------------------- */ float c2f( float temp ) { return 32 + ((temp*9)/5); } /* ----------------------------------------------------------------------- Take the log_format string and parse out the digitemp tags (%*s %*C and %*F) including any format specifiers to pass to sprintf. Build a new string with the strftime tokens and the temperatures mixed together If humidity is <0 then it is invalid ----------------------------------------------------------------------- */ int build_tf( char *time_format, char *format, int sensor, float temp_c, int humidity, unsigned char *sn ) { char *tf_ptr, *lf_ptr, *tk_ptr, token[80], temp[80]; if( !time_format || !format ) return 0; tf_ptr = time_format; lf_ptr = format; while( *lf_ptr ) { if( *lf_ptr != '%' ) { *tf_ptr++ = *lf_ptr++; } else { /* Found a token, decide if its one of ours... */ /* save initial pointer, grab everything up to... */ tk_ptr = token; /* At this point it has a potential format specifier, copy it over to the token variable, up to the alpha-numeric specifier. It needs to stop copying after it gets the alpha character */ while( isalnum( *lf_ptr ) || (*lf_ptr == '.') || (*lf_ptr == '*') || (*lf_ptr == '%') ) { *tk_ptr++ = *lf_ptr++; *tk_ptr = 0; /* Break out when the alpha character is copied over */ if( isalpha( *(lf_ptr-1) ) ) break; } /* see if the format specifier is digitemp or strftime */ switch( *(tk_ptr-1) ) { case 's' : /* Sensor number */ /* Change the specifier to a d */ *(tk_ptr-1) = 'd'; /* Pass it through sprintf */ sprintf( temp, token, sensor ); /* Insert this into the time format string */ tk_ptr = temp; while( *tk_ptr ) *tf_ptr++ = *tk_ptr++; break; case 'h' : /* Relative humidity % */ /* Change the specifier to a d */ *(tk_ptr-1) = 'd'; /* Pass it through sprintf */ sprintf( temp, token, humidity ); /* Insert this into the time format string */ tk_ptr = temp; while( *tk_ptr ) *tf_ptr++ = *tk_ptr++; break; case 'F' : /* Degrees Fahrenheit */ /* Change the specifier to a f */ *(tk_ptr-1) = 'f'; /* Pass it through sprintf */ sprintf( temp, token, c2f(temp_c) ); /* Insert this into the time format string */ tk_ptr = temp; while( *tk_ptr ) *tf_ptr++ = *tk_ptr++; break; case 'C' : /* Degrees Centigrade */ /* Change the specifier to a f */ *(tk_ptr-1) = 'f'; /* Pass it through sprintf */ sprintf( temp, token, temp_c ); /* Insert this into the time format string */ tk_ptr = temp; while( *tk_ptr ) *tf_ptr++ = *tk_ptr++; break; case 'R' : /* ROM Serial Number */ /* Change the specifier to a hex (x) */ *(tk_ptr-1) = 'X'; /* Insert the serial number in HEX, yes its ugly, but it works and saves using another temporary location and variable. */ sprintf( temp, "%02X%02X%02X%02X%02X%02X%02X%02X", sn[0],sn[1],sn[2],sn[3],sn[4],sn[5],sn[6],sn[7]); /* Insert this into the time format string */ tk_ptr = temp; while( *tk_ptr ) *tf_ptr++ = *tk_ptr++; break; case 'N' : /* Seconds since Epoch */ /* Change the specifier to a s and pass to time */ *(tk_ptr-1) = 's'; /* Intentional fall through */ default: /* Not something for us, copy it into the time format */ tk_ptr = token; while( *tk_ptr ) *tf_ptr++ = *tk_ptr++; break; } } } /* Terminate the string */ *tf_ptr = 0; return 1; } /* ----------------------------------------------------------------------- Take the log_format string and parse out the digitemp tags (%*s %*C and %*F) including any format specifiers to pass to sprintf. Build a new string with the strftime tokens and the temperatures mixed together ----------------------------------------------------------------------- */ int build_cf( char *time_format, char *format, int sensor, int page, unsigned long count, unsigned char *sn ) { char *tf_ptr, *lf_ptr, *tk_ptr, token[80], temp[80]; if( !time_format || !format ) return 0; tf_ptr = time_format; lf_ptr = format; while( *lf_ptr ) { if( *lf_ptr != '%' ) { *tf_ptr++ = *lf_ptr++; } else { /* Found a token, decide if its one of ours... */ /* save initial pointer, grab everything up to... */ tk_ptr = token; /* Take numbers, astrix, period and letters */ while( isalnum( *lf_ptr ) || (*lf_ptr == '.') || (*lf_ptr == '*') || (*lf_ptr == '%') ) { *tk_ptr++ = *lf_ptr++; *tk_ptr = 0; } /* see if the format specifier is digitemp or strftime */ switch( *(tk_ptr-1) ) { case 's' : /* Sensor number */ /* Change the specifier to a d */ *(tk_ptr-1) = 'd'; /* Pass it through sprintf */ sprintf( temp, token, sensor ); /* Insert this into the time format string */ tk_ptr = temp; while( *tk_ptr ) *tf_ptr++ = *tk_ptr++; break; case 'F' : break; case 'n' : /* Show the page/counter # (0 or 1) */ /* Change the specifier to a d */ *(tk_ptr-1) = 'd'; /* Pass it through sprintf */ sprintf( temp, token, page ); /* Insert this into the time format string */ tk_ptr = temp; while( *tk_ptr ) *tf_ptr++ = *tk_ptr++; break; case 'C' : /* Counter reading, 32 bit value */ /* Change the specifier to a ld */ *(tk_ptr-1) = 'l'; *(tk_ptr) = 'd'; *(tk_ptr+1) = 0; /* Pass it through sprintf */ sprintf( temp, token, count ); /* Insert this into the time format string */ tk_ptr = temp; while( *tk_ptr ) *tf_ptr++ = *tk_ptr++; break; case 'R' : /* ROM Serial Number */ /* Change the specifier to a hex (x) */ *(tk_ptr-1) = 'X'; /* Insert the serial number in HEX, yes its ugly, but it works and saves using another temporary location and variable. */ sprintf( temp, "%02X%02X%02X%02X%02X%02X%02X%02X", sn[0],sn[1],sn[2],sn[3],sn[4],sn[5],sn[6],sn[7]); /* Insert this into the time format string */ tk_ptr = temp; while( *tk_ptr ) *tf_ptr++ = *tk_ptr++; break; case 'N' : /* Seconds since Epoch */ /* Change the specifier to a s and pass to time */ *(tk_ptr-1) = 's'; /* Intentional fall through */ default: /* Not something for us, copy it into the time format */ tk_ptr = token; while( *tk_ptr ) *tf_ptr++ = *tk_ptr++; break; } } } /* Terminate the string */ *tf_ptr = 0; return 1; } /* ----------------------------------------------------------------------- Print a string to the console or the logfile ----------------------------------------------------------------------- */ int log_string( char *line ) { int fd=0; char time_log_file[1024]; if( log_file[0] != 0 ) { time_t now = time(NULL); /* Update time_log_file name according to current time and logfile format */ strftime(time_log_file, sizeof(log_file) - 1, log_file, gmtime(&now)); if( (fd = open( time_log_file, O_CREAT | O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ) ) == -1 ) { printf("Error opening logfile: %s\n", time_log_file ); return -1; } if( write( fd, line, strlen( line ) ) == -1) perror("Error loging to logfile"); close( fd ); } else { printf( "%s", line ); fflush( stdout ); } return 0; } /* ----------------------------------------------------------------------- Log one line of text to the logfile with the current date and time Used with temperatures ----------------------------------------------------------------------- */ int log_temp( int sensor, float temp_c, unsigned char *sn ) { char temp[1024], time_format[160]; time_t mytime; mytime = time(NULL); if( mytime ) { /* Build the time format string from log_format */ build_tf( time_format, temp_format, sensor, temp_c, -1, sn ); /* Handle the time format tokens */ strftime( temp, 1024, time_format, localtime( &mytime ) ); strcat( temp, "\n" ); } else { sprintf( temp, "Time Error\n" ); } /* Log it to stdout, logfile or both */ log_string( temp ); return 0; } /* ----------------------------------------------------------------------- Log one line of text to the logfile with the current date and time Used with counters ----------------------------------------------------------------------- */ int log_counter( int sensor, int page, unsigned long counter, unsigned char *sn ) { char temp[1024], time_format[160]; time_t mytime; mytime = time(NULL); if( mytime ) { /* Build the time format string from counter_format */ build_cf( time_format, counter_format, sensor, page, counter, sn ); /* Handle the time format tokens */ strftime( temp, 1024, time_format, localtime( &mytime ) ); strcat( temp, "\n" ); } else { sprintf( temp, "Time Error\n" ); } /* Log it to stdout, logfile or both */ log_string( temp ); return 0; } /* ----------------------------------------------------------------------- Log one line of text to the logfile with the current date and time Used with temperatures ----------------------------------------------------------------------- */ int log_humidity( int sensor, double temp_c, int humidity, unsigned char *sn ) { char temp[1024], time_format[160]; time_t mytime; mytime = time(NULL); if( mytime ) { /* Log the temperature */ switch( log_type ) { /* Multiple Centigrade temps per line */ case 2: case 4: sprintf( temp, "\t%3.2f", temp_c ); break; /* Multiple Fahrenheit temps per line */ case 3: case 5: sprintf( temp, "\t%3.2f", c2f(temp_c) ); break; default: /* Build the time format string from log_format */ build_tf( time_format, humidity_format, sensor, temp_c, humidity, sn ); /* Handle the time format tokens */ strftime( temp, 1024, time_format, localtime( &mytime ) ); strcat( temp, "\n" ); break; } } else { sprintf( temp, "Time Error\n" ); } /* Log it to stdout, logfile or both */ log_string( temp ); return 0; } /* ----------------------------------------------------------------------- Compare two serial numbers and return 1 of they match The second one has an additional byte indicating the main (0) or aux (1) branch. ----------------------------------------------------------------------- */ int cmpSN( unsigned char *sn1, unsigned char *sn2, int branch ) { int i; for(i = 0; i < 8; i++ ) { if( sn1[i] != sn2[i] ) { return 0; } } if( branch != sn2[8] ) { return 0; } /* Everything Matches */ return 1; } /* ----------------------------------------------------------------------- Show the verbose contents of the scratchpad ----------------------------------------------------------------------- */ void show_scratchpad( unsigned char *scratchpad, int sensor_family ) { char temp[80]; int i; /* Log and/or print the scratchpad diagnostics */ switch( sensor_family ) { case DS1820_FAMILY: sprintf( temp, " Temperature : 0x%02X\n", scratchpad[1] ); log_string( temp ); sprintf( temp, " Sign : 0x%02X\n", scratchpad[2] ); log_string( temp ); sprintf( temp, " TH : 0x%02X\n", scratchpad[3] ); log_string( temp ); sprintf( temp, " TL : 0x%02X\n", scratchpad[4] ); log_string( temp ); sprintf( temp, " Remain : 0x%02X\n", scratchpad[7] ); log_string( temp ); sprintf( temp, " Count Per C : 0x%02X\n", scratchpad[8] ); log_string( temp ); sprintf( temp, " CRC : 0x%02X\n", scratchpad[9] ); log_string( temp ); break; case DS18B20_FAMILY: case DS1822_FAMILY: case DS28EA00_FAMILY: sprintf( temp, " Temp. LSB : 0x%02X\n", scratchpad[1] ); log_string( temp ); sprintf( temp, " Temp. MSB : 0x%02X\n", scratchpad[2] ); log_string( temp ); sprintf( temp, " TH : 0x%02X\n", scratchpad[3] ); log_string( temp ); sprintf( temp, " TL : 0x%02X\n", scratchpad[4] ); log_string( temp ); sprintf( temp, " Config Reg. : 0x%02X\n", scratchpad[5] ); log_string( temp ); sprintf( temp, " CRC : 0x%02X\n", scratchpad[9] ); log_string( temp ); break; case DS2422_FAMILY: case DS2423_FAMILY: break; } /* sensor_family switch */ /* Dump the complete contents of the scratchpad */ for( i = 0; i < 10; i++ ) { printf( "scratchpad[%d] = 0x%02X\n", i, scratchpad[i] ); } } /* ----------------------------------------------------------------------- Read the temperature from one sensor Return the high-precision temperature value Calculated using formula from DS1820 datasheet Temperature = scratchpad[1] Sign = scratchpad[2] TH = scratchpad[3] TL = scratchpad[4] Count Remain = scratchpad[7] Count Per C = scratchpad[8] CRC = scratchpad[9] count_per_C - count_remain (temp - 0.25) * -------------------------- count_per_C If Sign is not 0x00 then it is a negative (Centigrade) number, and the temperature must be subtracted from 0x100 and multiplied by -1 ----------------------------------------------------------------------- */ int read_temperature( int sensor_family, int sensor ) { char temp[1024]; /* For output string */ unsigned char lastcrc8, scratchpad[30], /* Scratchpad block from the sensor */ TempSN[8]; int j, try, /* Number of tries at reading device */ ds1820_try, /* Allow ds1820 glitch 1 time */ ds18s20_try; /* Allow DS18S20 error 1 time */ float temp_c, /* Calculated temperature in Centigrade */ hi_precision; ds1820_try = 0; ds18s20_try = 0; temp_c = 0; for( try = 0; try < MAX_READ_TRIES; try++ ) { if( owAccess(0) ) { /* Convert Temperature */ if( !owWriteBytePower( 0, 0x44 ) ) { return FALSE; } /* Sleep for conversion second */ msDelay( read_time ); /* Turn off the strong pullup */ owLevel( 0, MODE_NORMAL ); /* Now read the scratchpad from the device */ if( owAccess(0) ) { /* Use Read_Scratchpad instead? */ /* Build a block for the Scratchpad read */ scratchpad[0] = 0xBE; for( j = 1; j < 10; j++ ) scratchpad[j] = 0xFF; /* Send the block */ if( owBlock( 0, FALSE, scratchpad, 10 ) ) { /* Calculate the CRC 8 checksum on the received data */ setcrc8(0, 0); for( j = 1; j < 10; j++ ) lastcrc8 = docrc8( 0, scratchpad[j] ); /* If the CRC8 is valid then calculate the temperature */ if( lastcrc8 == 0x00 ) { /* DS1822 and DS18B20 use a different calculation */ if( (sensor_family == DS18B20_FAMILY) || (sensor_family == DS1822_FAMILY) || (sensor_family == DS28EA00_FAMILY) || (sensor_family == DS1923_FAMILY) ) { short int temp2 = (scratchpad[2] << 8) | scratchpad[1]; temp_c = temp2 / 16.0; } /* Handle the DS1820 and DS18S20 */ if( sensor_family == DS1820_FAMILY ) { /* Check for DS1820 glitch condition */ /* COUNT_PER_C - COUNT_REMAIN == 1 */ if( ds1820_try == 0 ) { if( (scratchpad[7] - scratchpad[6]) == 1 ) { ds1820_try = 1; continue; } /* DS1820 error */ } /* ds1820_try */ /* Check for DS18S20 Error condition */ /* LSB = 0xAA MSB = 0x00 COUNT_REMAIN = 0x0C COUNT_PER_C = 0x10 */ if( ds18s20_try == 0 ) { if( (scratchpad[4]==0xAA) && (scratchpad[3]==0x00) && (scratchpad[7]==0x0C) && (scratchpad[8]==0x10) ) { ds18s20_try = 1; continue; } /* DS18S20 error condition */ } /* ds18s20_try */ /* Convert data to temperature */ if( scratchpad[2] == 0 ) { temp_c = (int) scratchpad[1] >> 1; } else { temp_c = -1 * (int) (0x100-scratchpad[1]) >> 1; } /* Negative temp calculation */ temp_c -= 0.25; hi_precision = (int) scratchpad[8] - (int) scratchpad[7]; hi_precision = hi_precision / (int) scratchpad[8]; temp_c = temp_c + hi_precision; } /* DS1820_FAMILY */ /* Log the temperature */ switch( log_type ) { /* Multiple Centigrade temps per line */ case 2: case 4: sprintf( temp, "\t%3.2f", temp_c ); log_string( temp ); break; /* Multiple Fahrenheit temps per line */ case 3: case 5: sprintf( temp, "\t%3.2f", c2f(temp_c) ); log_string( temp ); break; default: owSerialNum( 0, &TempSN[0], TRUE ); log_temp( sensor, temp_c, TempSN ); break; } /* switch( log_type ) */ /* Show the scratchpad if verbose is seelcted */ if( opts & OPT_VERBOSE ) { show_scratchpad( scratchpad, sensor_family ); } /* if OPT_VERBOSE */ /* Good conversion finished */ return TRUE; } else { fprintf( stderr, "CRC Failed. CRC is %02X instead of 0x00\n", lastcrc8 ); if (try == MAX_READ_TRIES - 1) { /* need to output something (0,-,NaN?) to keep columns consistent */ switch( log_type ) { /* Multiple Centigrade temps per line */ case 2: case 4: /* Multiple Fahrenheit temps per line */ case 3: case 5: sprintf( temp, "\t%3.2f", (double) 0 ); log_string( temp ); break; default: break; } /* switch( log_type ) */ } /* if tries == max_read_tries */ if( opts & OPT_VERBOSE ) { show_scratchpad( scratchpad, sensor_family ); } /* if OPT_VERBOSE */ } /* CRC 8 is OK */ } /* Scratchpad Read */ } /* owAccess failed */ } /* owAccess failed */ /* Failed to read, rest the network, delay and try again */ owTouchReset(0); msDelay( read_time ); } /* for try < 3 */ /* Failed, no good reads after MAX_READ_TRIES */ return FALSE; } /* ----------------------------------------------------------------------- Read the current counter values ----------------------------------------------------------------------- */ int read_counter( int sensor_family, int sensor ) { char temp[1024]; /* For output string */ unsigned char TempSN[8]; int page; unsigned long counter_value; if( sensor_family == DS2422_FAMILY ) { /* Read Pages 2, 3 */ for( page=2; page<=3; page++ ) { if( ReadCounter( 0, page, &counter_value ) ) { /* Log the counter */ switch( log_type ) { /* Multiple Centigrade temps per line */ case 2: case 3: case 4: case 5: sprintf( temp, "\t%ld", counter_value ); log_string( temp ); break; default: owSerialNum( 0, &TempSN[0], TRUE ); log_counter( sensor, page-2, counter_value, TempSN ); break; } /* switch( log_type ) */ } } } else if( sensor_family == DS2423_FAMILY ) { /* Read Pages 14, 15 */ for( page=14; page<=15; page++ ) { if( ReadCounter( 0, page, &counter_value ) ) { /* Log the counter */ switch( log_type ) { /* Multiple Centigrade temps per line */ case 2: case 3: case 4: case 5: sprintf( temp, "\t%ld", counter_value ); log_string( temp ); break; default: owSerialNum( 0, &TempSN[0], TRUE ); log_counter( sensor, page-14, counter_value, TempSN ); break; } /* switch( log_type ) */ } } } return FALSE; } /* ----------------------------------------------------------------------- Read the DS2406 General Purpose PIO by Tomasz R. Surmacz (tsurmacz@ict.pwr.wroc.pl) !!!! Not finished !!!! Needs an output format string system. Hard-coded for the moment. ----------------------------------------------------------------------- */ int read_ds2406( int sensor_family, int sensor ) { int pio; char temp[1024], time_format[160]; time_t mytime; if( sensor_family == DS2406_FAMILY ) { /* Read Vdd */ pio = PIO_Reading(0, 0); if (pio==-1) { printf(" PIO DS2406 sensor %d CRC failed\n", sensor); return FALSE; } mytime = time(NULL); if( mytime ) { /* Log the temperature */ switch( log_type ) { /* Multiple Centigrade temps per line */ case 2: case 4: sprintf( temp, "\t%02x,%02x", pio>>8, pio&0xff ); break; /* Multiple Fahrenheit temps per line */ case 3: case 5: sprintf( temp, "\t%02x,%02x", pio>>8, pio&0xff); break; default: sprintf( time_format, "%%b %%d %%H:%%M:%%S Sensor %d PIO: %02x,%02x, PIO-A: %s%s", sensor, pio>>8, pio&0xff, ((pio&0x1000)!=0)? // Port A latch: there was a change (((pio&0x0400)!=0)? "ON" // and the current state is ON :"on") :"off", // the current state is off, no change ((pio&0x4000)!=0)? // we have 2 ports if bit is 1 ( ((pio&0x2000)!=0)? (((pio&0x0800)!=0)? // the latch says 1 " PIO-B: ON" // and state too :" PIO-B: on") :" PIO-B: off") // the latch said no : "") ; /* Handle the time format tokens */ strftime( temp, 1024, time_format, localtime( &mytime ) ); strcat( temp, "\n" ); break; } /* switch( log_type ) */ } else { sprintf( temp, "Time Error\n" ); } /* Log it to stdout, logfile or both */ log_string( temp ); } return TRUE; } /* ----------------------------------------------------------------------- Read the DS2438 General Purpose A/D VDD Temperature ... !!!! Not finished !!!! Needs an output format string system. Hard-coded for the moment. ----------------------------------------------------------------------- */ int read_ds2438( int sensor_family, int sensor ) { double temp_c; float vdd, ad; char temp[1024], time_format[160]; time_t mytime; int cad = 0; int try; int result = FALSE; for( try = 0; try < MAX_READ_TRIES; try++ ) { /* Read the temperature */ temp_c = Get_Temperature(0); if (temp_c == -999.0) return result; /* Read Vdd, the supply voltage */ if( (vdd = Volt_Reading(0, 1, &cad)) != -1.0 ) { /* Read A/D reading from the humidity sensor */ if( (ad = Volt_Reading(0, 0, NULL)) != -1.0 ) { result = TRUE; break; } } owTouchReset(0); msDelay(read_time); } /* Log the temperature */ mytime = time(NULL); switch( log_type ) { /* Multiple Centigrade temps per line */ case 2: sprintf(temp, "\t%3.2f", temp_c); break; /* Multiple Fahrenheit temps per line */ case 3: sprintf(temp, "\t%3.2f", c2f(temp_c)); break; default: sprintf(time_format, "%%b %%d %%H:%%M:%%S Sensor %d VDD: %0.2f AD: %0.2f CAD: %d C: %0.2f", sensor, vdd, ad, cad, temp_c); /* Handle the time format tokens */ strftime(temp, 1024, time_format, localtime(&mytime)); strcat(temp, "\n"); break; } /* switch( log_type ) */ /* Log it to stdout, logfile or both */ log_string(temp); return TRUE; } /* ----------------------------------------------------------------------- (This routine is modified from code by Eric Wilde) Read the humidity from one sensor (e.g. the AAG TAI8540x). Log the temperature value and relative humidity. Calculated using formula cribbed from the Dallas source code (gethumd.c), DS2438 data sheet and HIH-3610 data sheet. Sensors like the TAI8540x use a DS2438 battery monitor to sense temperature and convert humidity readings from a Honeywell HIH-3610. The DS2438 scratchpad is: Status/config = scratchpad[2] Temp LSB = scratchpad[3] Temp MSB = scratchpad[4] Voltage LSB = scratchpad[5] Voltage MSB = scratchpad[6] CRC = scratchpad[10] Temp LSB temp = (Temp MSB * 32) + -------- * 0.03125 8 The temperature is a two's complement signed number. voltage = ((Voltage MSB * 256) + Voltage LSB) / 100 There are two voltages that must be read to get an accurate humidity reading. The supply voltage (VDD) is read to determine what voltage the humidity sensor is running at (this affects the zero offset and slope of the humidity curve). The sensor voltage (VAD) is read to get the humidity value. Here is the formula for the humidity (temperature and voltage compensated): ((VAD/VDD) - 0.16) * 161.29 humidity = --------------------------- 1.0546 - (0.00216 * temp) The humidity sensor is linear from approx 10% to 100% R.H. Accuracy is approx 2%. !!!! Not Finished !!!! ----------------------------------------------------------------------- */ int read_humidity( int sensor_family, int sensor ) { double temp_c; /* Converted temperature in degrees C */ float sup_voltage, /* Supply voltage in volts */ hum_voltage, /* Humidity sensor voltage in volts */ humidity = 0.0; /* Calculated humidity in %RH */ unsigned char TempSN[8]; int try; int result = FALSE; for( try = 0; try < MAX_READ_TRIES; try++ ) { /* Read the temperature */ temp_c = Get_Temperature(0); if (temp_c == -999.0) return result; /* Read Vdd, the supply voltage */ if( (sup_voltage = Volt_Reading(0, 1, NULL)) != -1.0 ) { /* Read A/D reading from the humidity sensor */ if( (hum_voltage = Volt_Reading(0, 0, NULL)) != -1.0 ) { /* Convert the measured voltage to humidity */ humidity = (((hum_voltage/sup_voltage) - 0.16) * 161.29) / (1.0546 - (0.00216 * temp_c)); if( humidity > 100.0 ) humidity = 100.0; else if( humidity < 0.0 ) humidity = 0.0; result = TRUE; break; } } owTouchReset(0); msDelay(read_time); } /* Log the temperature and humidity */ owSerialNum( 0, &TempSN[0], TRUE ); log_humidity( sensor, temp_c, humidity, TempSN ); return result; } /* ----------------------------------------------------------------------- Read the DS1923 Hygrochton Temperature/Humidity Logger ----------------------------------------------------------------------- */ int read_temperature_DS1923( int sensor_family, int sensor ) { unsigned char TempSN[8], block2[2]; int try; /* Number of tries at reading device */ int b; int pre_t; float temp_c; int ival; float adval; float humidity; for( try = 0; try < MAX_READ_TRIES; try++ ) { if( owAccess(0) ) { /* Force Conversion */ if( !owWriteByte( 0, 0x55 ) || !owWriteByte( 0, 0x55 )) { return FALSE; } /* TODO CRC checking and read the addresses 020Ch to 020Fh (results)i * and the Device Sample Counter at address 0223h to 0225h. * If the count has incremented, the command was executed successfully. */ /* Sleep for conversion (spec says it takes max 666ms */ /* Q. Is it possible to poll? */ msDelay( 666 ); /* Now read the memory 0x20C:0x020F */ if( owAccess(0) ) { if( !owWriteByte( 0, 0x69 ) ) { return FALSE; } /* "Latest Temp" in the memory */ block2[0] = 0x0c; block2[1] = 0x02; /* Send the block */ if( owBlock( 0, FALSE, block2, 2 ) ) { if (block2[0] != 0x0c && block2[1] != 0x02) return FALSE; /* Send dummy password */ for(b = 0; b < 8; ++b) { owWriteByte(0, 0x04); } /* Read the temperature */ block2[0] = owReadByte(0); block2[1] = owReadByte(0); pre_t = (block2[1]/2)-41; temp_c = 1.0f * pre_t + block2[0]/512.0f; /* Read the humidity */ block2[0] = owReadByte(0); block2[1] = owReadByte(0); ival = (block2[1]*256 + block2[0])/16; adval = 1.0f * ival * 5.02f/4096; humidity = (adval-0.958f) / 0.0307f; /* Log the temperature and humidity */ /* TUTAJ masz wartosci we floatach dla Thermochrona sensor to nr sensora z pliku konfiguracyjnego, a tempsn to pewnie id urzadzenia 1wire */ owSerialNum( 0, &TempSN[0], TRUE ); log_humidity( sensor, temp_c, humidity, TempSN ); /* Good conversion finished */ return TRUE; } /* Scratchpad Read */ } /* owAccess failed */ } /* owAccess failed */ /* Failed to read, rest the network, delay and try again */ owTouchReset(0); msDelay( read_time ); } /* for try < 3 */ /* Failed, no good reads after MAX_READ_TRIES */ return FALSE; } /* ----------------------------------------------------------------------- Select the indicated device, turning on any required couplers ----------------------------------------------------------------------- */ int read_device( struct _roms *sensor_list, int sensor ) { unsigned char TempSN[8], a[3]; int s, status = 0, sensor_family; struct _coupler *c_ptr; /* Coupler linked list */ /* Tell the sensor to do a temperature conversion */ /* Sort out how to address the sensor. If sensor < num_sensors then it can be directly addressed if sensor >= num_sensors then the coupler must first be addressed and the correct branch turned on. */ if( sensor < sensor_list->max ) { /* Address the sensor directly */ owSerialNum( 0, &sensor_list->roms[sensor*8], FALSE ); } else { /* Step through the coupler list until the right sensor is found. Sensors are in order. */ s = sensor - sensor_list->max; c_ptr = coupler_top; while( c_ptr ) { if( s < c_ptr->num_main ) { /* Found the right area */ /* Is this coupler & branch already on? */ if( !cmpSN( c_ptr->SN, Last2409, 0 ) ) { /* Turn on the main branch */ if(!SetSwitch1F(0, c_ptr->SN, DIRECT_MAIN_ON, 0, a, TRUE)) { printf("Setting Switch to Main ON state failed\n"); return FALSE; } /* Remember the last selected coupler & Branch */ memcpy( &Last2409, &c_ptr->SN, 8 ); Last2409[8] = 0; } /* Select the sensor */ owSerialNum( 0, &c_ptr->main[s*8], FALSE ); break; } else { s -= c_ptr->num_main; if( s < c_ptr->num_aux ) { /* Found the right area */ /* Is this coupler & branch already on? */ if( !cmpSN( c_ptr->SN, Last2409, 1 ) ) { /* Turn on the aux branch */ if(!SetSwitch1F(0, c_ptr->SN, AUXILARY_ON, 2, a, TRUE)) { printf("Setting Switch to Aux ON state failed\n"); return FALSE; } /* Remember the last selected coupler & Branch */ memcpy( &Last2409, &c_ptr->SN, 8 ); Last2409[8] = 1; } /* Last2409 check */ /* Select the sensor */ owSerialNum( 0, &c_ptr->aux[s*8], FALSE ); break; } } s -= c_ptr->num_aux; c_ptr = c_ptr->next; } } /* Get the Serial # selected */ owSerialNum( 0, &TempSN[0], TRUE ); sensor_family = TempSN[0]; switch( sensor_family ) { case DS28EA00_FAMILY: case DS2413_FAMILY: if( (opts & OPT_DS2438) || (sensor_family==DS2413_FAMILY) ) { // read PIO status = read_pio_ds28ea00( sensor_family, sensor ); break; } // else - drop through to DS1822 case DS1820_FAMILY: case DS1822_FAMILY: case DS18B20_FAMILY: status = read_temperature( sensor_family, sensor ); // also for DS28EA00 break; case DS1923_FAMILY: status = read_temperature_DS1923( sensor_family, sensor ); break; case DS2422_FAMILY: case DS2423_FAMILY: status = read_counter( sensor_family, sensor ); break; case DS2438_FAMILY: // What type is it? { int page; for( page=3; page<8; page++) { get_ibl_type( 0, page, 0); } } if( opts & OPT_DS2438 ) { status = read_ds2438( sensor_family, sensor ); } else { status = read_humidity( sensor_family, sensor ); } break; } return status; } /* ----------------------------------------------------------------------- Read the temperaturess for all the connected sensors Step through all the sensors in the list of serial numbers ----------------------------------------------------------------------- */ int read_all( struct _roms *sensor_list ) { int x; for( x = 0; x < (num_cs+sensor_list->max); x++ ) { read_device( sensor_list, x ); } return 0; } /* ----------------------------------------------------------------------- Read a .digitemprc file from the current directory The rc file contains: TTY LOG READ_TIME