/**
* collectd - src/apple_sensors.c
- * Copyright (C) 2006 Florian octo Forster
+ * Copyright (C) 2006,2007 Florian octo Forster
*
- * 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.
+ * 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:
*
- * 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.
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
*
- * 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.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * 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.
*
* Authors:
- * Florian octo Forster <octo at verplant.org>
+ * Florian octo Forster <octo at collectd.org>
**/
#include "collectd.h"
#include "common.h"
#include "plugin.h"
-#include "utils_debug.h"
-
-#define MODULE_NAME "apple_sensors"
#if HAVE_CTYPE_H
# include <ctype.h>
#endif
+
#if HAVE_MACH_MACH_TYPES_H
# include <mach/mach_types.h>
#endif
#if HAVE_MACH_MACH_ERROR_H
# include <mach/mach_error.h>
#endif
+#if HAVE_MACH_MACH_PORT_H
+# include <mach/mach_port.h>
+#endif
#if HAVE_COREFOUNDATION_COREFOUNDATION_H
# include <CoreFoundation/CoreFoundation.h>
#endif
# include <IOKit/IOTypes.h>
#endif
-#if HAVE_IOKIT_IOKITLIB_H
-# define IOKIT_HAVE_READ 1
-#else
-# define IOKIT_HAVE_READ 0
-#endif
-
-#if IOKIT_HAVE_READ
-static mach_port_t io_master_port;
-#endif
-
-static char *temperature_file = "apple_sensors/temperature-%s.rrd";
-static char *fanspeed_file = "apple_sensors/fanspeed-%s.rrd";
+static mach_port_t io_master_port = MACH_PORT_NULL;
-static char *ds_def[] =
+static int as_init (void)
{
- "DS:value:GAUGE:"COLLECTD_HEARTBEAT":U:U",
- NULL
-};
-static int ds_num = 1;
-
-static void as_init (void)
-{
-#if IOKIT_HAVE_READ
kern_return_t status;
- /* FIXME: de-allocate port if it's defined */
+ if (io_master_port != MACH_PORT_NULL)
+ {
+ mach_port_deallocate (mach_task_self (),
+ io_master_port);
+ io_master_port = MACH_PORT_NULL;
+ }
status = IOMasterPort (MACH_PORT_NULL, &io_master_port);
if (status != kIOReturnSuccess)
{
- syslog (LOG_ERR, "IOMasterPort failed: %s",
+ ERROR ("IOMasterPort failed: %s",
mach_error_string (status));
io_master_port = MACH_PORT_NULL;
- return;
+ return (-1);
}
-#endif
- return;
+ return (0);
}
-static void as_write (char *host, char *inst, char *val, const char *template)
+static void as_submit (const char *type, const char *type_instance,
+ double val)
{
- char filename[256];
- int status;
+ value_t values[1];
+ value_list_t vl = VALUE_LIST_INIT;
- status = snprintf (filename, 256, template, inst);
- if ((status < 1) || (status >= 256))
- return;
+ DEBUG ("type = %s; type_instance = %s; val = %f;",
+ type, type_instance, val);
- rrd_update_file (host, filename, val, ds_def, ds_num);
-}
+ values[0].gauge = val;
-static void temperature_write (char *host, char *inst, char *val)
-{
- as_write (host, inst, val, temperature_file);
-}
-
-static void fanspeed_write (char *host, char *inst, char *val)
-{
- as_write (host, inst, val, fanspeed_file);
-}
+ vl.values = values;
+ vl.values_len = 1;
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "apple_sensors", sizeof (vl.plugin));
+ sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance));
+ sstrncpy (vl.type, type, sizeof (vl.type));
+ sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
-#if IOKIT_HAVE_READ
-static void as_submit (char *type, char *inst, double value)
-{
- char buf[128];
-
- if (snprintf (buf, 1024, "%u:%f", (unsigned int) curtime,
- value) >= 128)
- return;
-
- plugin_submit (type, inst, buf);
+ plugin_dispatch_values (&vl);
}
-static void as_read (void)
+static int as_read (void)
{
kern_return_t status;
io_iterator_t iterator;
int i;
if (!io_master_port || (io_master_port == MACH_PORT_NULL))
- return;
+ return (-1);
status = IOServiceGetMatchingServices (io_master_port,
IOServiceNameMatching("IOHWSensor"),
&iterator);
if (status != kIOReturnSuccess)
{
- syslog (LOG_ERR, "IOServiceGetMatchingServices failed: %s",
+ ERROR ("IOServiceGetMatchingServices failed: %s",
mach_error_string (status));
- return;
+ return (-1);
}
while ((io_obj = IOIteratorNext (iterator)))
kNilOptions);
if (status != kIOReturnSuccess)
{
- DBG ("IORegistryEntryCreateCFProperties failed: %s",
+ DEBUG ("IORegistryEntryCreateCFProperties failed: %s",
mach_error_string (status));
continue;
}
if (CFGetTypeID (property) != CFStringGetTypeID ())
continue;
if (!CFStringGetCString (property,
- type, 128,
+ type, sizeof (type),
kCFStringEncodingASCII))
continue;
- type[127] = '\0';
+ type[sizeof (type) - 1] = '\0';
/* Copy the sensor location. This will be used as `instance'. */
property = NULL;
if (CFGetTypeID (property) != CFStringGetTypeID ())
continue;
if (!CFStringGetCString (property,
- inst, 128,
+ inst, sizeof (inst),
kCFStringEncodingASCII))
continue;
- inst[127] = '\0';
+ inst[sizeof (inst) - 1] = '\0';
for (i = 0; i < 128; i++)
{
if (inst[i] == '\0')
&value_int))
continue;
+ /* Found e.g. in the 1.5GHz PowerBooks */
if (strcmp (type, "temperature") == 0)
{
value_double = ((double) value_int) / 65536.0;
- strncpy (type, "apple_temperature", 128);
+ sstrncpy (type, "temperature", sizeof (type));
+ }
+ else if (strcmp (type, "temp") == 0)
+ {
+ value_double = ((double) value_int) / 10.0;
+ sstrncpy (type, "temperature", sizeof (type));
}
else if (strcmp (type, "fanspeed") == 0)
{
value_double = ((double) value_int) / 65536.0;
- strncpy (type, "apple_fanspeed", 128);
+ sstrncpy (type, "fanspeed", sizeof (type));
}
else if (strcmp (type, "voltage") == 0)
{
/* Leave this to the battery plugin. */
continue;
}
+ else if (strcmp (type, "adc") == 0)
+ {
+ value_double = ((double) value_int) / 10.0;
+ sstrncpy (type, "fanspeed", sizeof (type));
+ }
else
{
- DBG ("apple_sensors: Read unknown sensor type: %s",
+ DEBUG ("apple_sensors: Read unknown sensor type: %s",
type);
value_double = (double) value_int;
}
} /* while (iterator) */
IOObjectRelease (iterator);
-}
-#else
-# define as_read NULL
-#endif /* IOKIT_HAVE_READ */
+
+ return (0);
+} /* int as_read */
void module_register (void)
{
- plugin_register (MODULE_NAME, as_init, as_read, NULL);
- plugin_register ("apple_temperature", NULL, NULL, temperature_write);
- plugin_register ("apple_fanspeed", NULL, NULL, fanspeed_write);
-}
-
-#undef MODULE_NAME
+ plugin_register_init ("apple_sensors", as_init);
+ plugin_register_read ("apple_sensors", as_read);
+} /* void module_register */