You are here

farm_sensor.module in farmOS 7

File

modules/farm/farm_sensor/farm_sensor.module
View source
<?php

/**
 * @file
 * Code for the Farm Sensor feature.
 */
include_once 'farm_sensor.features.inc';

/**
 * Implements hook_farm_ui_entities().
 */
function farm_sensor_farm_ui_entities() {
  return array(
    'farm_asset' => array(
      'sensor' => array(
        'label' => t('Sensor'),
        'label_plural' => t('Sensors'),
        'view' => 'farm_sensors',
      ),
    ),
  );
}

/**
 * Implements hook_farm_ui_entity_view_groups().
 */
function farm_sensor_farm_ui_entity_view_groups() {
  $groups = array(
    'sensor_data' => array(
      'weight' => 80,
    ),
  );
  return $groups;
}

/**
 * Implements hook_entity_property_info_alter().
 */
function farm_sensor_entity_property_info_alter(&$info) {

  // Add a sensor type property to sensor assets.
  $info['farm_asset']['bundles']['sensor']['properties']['sensor_type'] = array(
    'type' => 'text',
    'label' => t('Sensor Type'),
    'description' => t('The type of sensor.'),
    'setter callback' => 'entity_property_verbatim_set',
  );

  // Add a sensor settings property to sensor assets.
  $info['farm_asset']['bundles']['sensor']['properties']['sensor_settings'] = array(
    'type' => 'unknown',
    'label' => t('Sensor Settings'),
    'description' => t('Settings for this sensor.'),
    'setter callback' => 'entity_property_verbatim_set',
  );
}

/**
 * Implements hook_entity_load().
 */
function farm_sensor_entity_load($entities, $type) {

  // Only act on farm_asset entities.
  if ($type != 'farm_asset') {
    return;
  }

  // Iterate through the loaded assets...
  foreach ($entities as $entity) {

    // Only act on sensors...
    if ($entity->type != 'sensor') {
      continue;
    }

    // Load the sensor information from the {farm_sensor} database.
    $query = db_select('farm_sensor', 's');
    $query
      ->fields('s');
    $query
      ->condition('id', $entity->id);
    $result = $query
      ->execute();
    $sensor_info = $result
      ->fetchAssoc();

    // Only continue if sensor info was returned.
    if (empty($sensor_info)) {
      continue;
    }

    // Assign the entity's sensor type.
    $entity->sensor_type = $sensor_info['type'];

    // Assign the entity's sensor settings.
    $entity->sensor_settings = unserialize($sensor_info['settings']);
  }
}

/**
 * Implements hook_entity_insert().
 */
function farm_sensor_entity_insert($entity, $type) {
  _farm_sensor_entity_save($entity, $type);
}

/**
 * Implements hook_entity_update().
 */
function farm_sensor_entity_update($entity, $type) {
  _farm_sensor_entity_save($entity, $type);
}

/**
 * Helper function for saving farm sensor information on entity insert and update.
 *
 * @param $entity
 *   The entity being saved.
 * @param $type
 *   The type of entity being saved.
 */
function _farm_sensor_entity_save($entity, $type) {

  // Only act on farm asset entities.
  if ($type != 'farm_asset') {
    return;
  }

  // Only act on sensor assets.
  if ($entity->type != 'sensor') {
    return;
  }

  // Only act if a sensor type is set.
  if (empty($entity->sensor_type)) {
    return;
  }

  // If sensor settings are not set, save an empty array.
  if (!isset($entity->sensor_settings)) {
    $entity->sensor_settings = array();
  }

  // Save the sensor record.
  farm_sensor_save($entity->id, $entity->sensor_type, $entity->sensor_settings);
}

/**
 * Implements hook_entity_delete().
 */
function farm_sensor_entity_delete($entity, $type) {

  // Only act on farm asset entities.
  if ($type != 'farm_asset') {
    return;
  }

  // Only act on sensor assets.
  if ($entity->type != 'sensor') {
    return;
  }

  // Delete sensor record.
  farm_sensor_delete($entity->id);
}

/**
 * Implements hook_entity_view_alter().
 */
function farm_sensor_entity_view_alter(&$build, $type) {

  /*
   * Alter farm assets to display sensor information.
   */

  // If it's not a farm_asset, bail.
  if ($type != 'farm_asset') {
    return;
  }

  // If the entity information isn't available, bail.
  if (empty($build['#entity'])) {
    return;
  }
  $asset = $build['#entity'];

  // If the asset does not have a sensor type, bail.
  if (empty($asset->sensor_type)) {
    return;
  }

  // Load the list of sensor types.
  $sensor_types = farm_sensor_types();

  // Get the sensor type label if it exists.
  if (!empty($sensor_types[$asset->sensor_type])) {
    $sensor_type_label = $sensor_types[$asset->sensor_type]['label'];
  }
  else {
    $sensor_type_label = $asset->sensor_type . ' (undefined)';
  }

  // Add the sensor type.
  $build['sensor_type'] = array(
    '#markup' => '<p><strong>Sensor type:</strong> ' . $sensor_type_label . '</p>',
  );

  // Ask other modules for sensor asset view content.
  $module_content = module_invoke_all('farm_sensor_view', $asset);

  // Merge the asset view content into the build array.
  if (!empty($module_content)) {
    $build = array_merge_recursive($build, $module_content);
  }
}

/**
 * Implements hook_form_alter().
 */
function farm_sensor_form_alter(&$form, &$form_state, $form_id) {

  // Only alter the farm asset form.
  if ($form_id != 'farm_asset_form') {
    return;
  }

  // Only alter if the asset is of type 'sensor'.
  if ($form['#entity_type'] != 'farm_asset' || $form['#bundle'] != 'sensor') {
    return;
  }

  // Pull the farm asset object out of the form.
  $farm_asset = $form['farm_asset']['#value'];

  // Load the available sensor types.
  $sensor_types = farm_sensor_types();

  // Generate a list of sensor type options.
  $options = array();
  foreach ($sensor_types as $name => $type) {
    $options[$name] = $type['label'];
  }

  // Determine the type.
  $sensor_type = !empty($farm_asset->sensor_type) ? $farm_asset->sensor_type : NULL;

  // Override sensor type with $form_state value, so AJAX works.
  if (!empty($form_state['values']['sensor_type'])) {
    $sensor_type = $form_state['values']['sensor_type'];
  }

  // Add a sensor fieldset.
  $form['sensor'] = array(
    '#type' => 'fieldset',
    '#title' => t('Sensor configuration'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#weight' => 99,
  );

  // Add a sensor type selection field to the form.
  $form['sensor']['sensor_type'] = array(
    '#type' => 'select',
    '#title' => t('Sensor type'),
    '#description' => t('What type of sensor is this?'),
    '#options' => $options,
    '#default_value' => $sensor_type,
    '#required' => TRUE,
    '#ajax' => array(
      'callback' => 'farm_sensor_settings_form_ajax',
      'wrapper' => 'farm_sensor_settings',
    ),
  );

  // Load the sensor settings.
  $sensor_settings = !empty($farm_asset->sensor_settings) ? $farm_asset->sensor_settings : array();

  // Sensor settings fieldset.
  $form['sensor']['sensor_settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('Sensor settings'),
    '#description' => t('Configure settings for the sensor type selected above.'),
    '#prefix' => '<div id="farm_sensor_settings">',
    '#suffix' => '</div>',
    '#tree' => TRUE,
  );

  // If a sensor type is selected, and the type has a settings form...
  if (!empty($sensor_type) && !empty($sensor_types[$sensor_type]['form']) && function_exists($sensor_types[$sensor_type]['form'])) {

    // Load the sensor type settings form.
    $settings_form = call_user_func_array($sensor_types[$sensor_type]['form'], array(
      $farm_asset,
      $sensor_settings,
    ));

    // Add it to the fieldset.
    $form['sensor']['sensor_settings'] = array_merge($form['sensor']['sensor_settings'], $settings_form);
  }

  // Add to the "General" group.
  $form['#group_children']['sensor'] = 'group_farm_general';
}

/**
 * Farm sensor settings form ajax.
 */
function farm_sensor_settings_form_ajax($form, $form_state) {
  return $form['sensor']['sensor_settings'];
}

/**
 * Get farm sensor types.
 *
 * @return array
 *   Returns an array of sensors type information provided by other modules.
 */
function farm_sensor_types() {

  // Gather type information from other modules.
  $sensor_types = module_invoke_all('farm_sensor_type_info');

  // Return it.
  return $sensor_types;
}

/**
 * Helper function for saving farm sensor information.
 *
 * @param int $id
 *   The farm sensor asset id.
 * @param string $type
 *   The sensor type.
 * @param array $settings
 *   An array of sensor settings.
 */
function farm_sensor_save($id, $type, $settings = array()) {

  // Delete any existing
  farm_sensor_delete($id);

  // Insert a new record.
  $record = array(
    'id' => $id,
    'type' => $type,
    'settings' => $settings,
  );
  drupal_write_record('farm_sensor', $record);
}

/**
 * Helper function for deleting farm sensor information.
 *
 * @param int $id
 *   The farm sensor asset id.
 */
function farm_sensor_delete($id) {
  db_delete('farm_sensor')
    ->condition('id', $id)
    ->execute();
}

/**
 * Load an array of sensors in an area.
 *
 * @param int $area_id
 *   The area id.
 * @param string $type
 *   The sensor type (optional).
 *
 * @return array
 *   Returns an array of sensors in the area.
 */
function farm_sensor_area_sensors($area_id, $type = '') {

  // Start with a blank array.
  $sensors = array();

  // Build a query for sensor assets in the area.
  $query = db_select('farm_asset', 'fa');
  $query
    ->addField('fa', 'id');
  $query
    ->condition('fa.type', 'sensor');

  // Build a sub-select query for determining the latest movement log of assets.
  $subquery = farm_movement_asset_movement_query('fa.id');

  // Join the latest movement log for each asset.
  $query
    ->join('log', 'l', 'l.id = (' . $subquery . ')');

  // Only show assets with a movement to this area.
  $query
    ->join('field_data_field_farm_move_to', 'fdffmt', 'l.id = fdffmt.entity_id');
  $query
    ->condition('fdffmt.field_farm_move_to_tid', $area_id);

  // If a sensor type is specified in the arguments, only show that type.
  if (!empty($type)) {
    $query
      ->join('farm_sensor', 'fs', 'fa.id = fs.id');
    $query
      ->condition('fs.type', $type);
  }

  // Execute the query.
  $result = $query
    ->execute();

  // Load the sensors.
  while ($asset_id = $result
    ->fetchField()) {
    $sensors[] = farm_asset_load($asset_id);
  }

  // Return the sensors.
  return $sensors;
}

/**
 * Implements hook_farm_sensor_type_info().
 */
function farm_sensor_farm_sensor_type_info() {
  return array(
    'none' => array(
      'label' => t('None'),
      'description' => t('No sensor type.'),
    ),
  );
}

/**
 * Implements hook_farm_log_categories().
 */
function farm_sensor_farm_log_categories() {

  // Provide an "Sensors" log category.
  return array(
    'Sensors',
  );
}

Functions

Namesort descending Description
farm_sensor_area_sensors Load an array of sensors in an area.
farm_sensor_delete Helper function for deleting farm sensor information.
farm_sensor_entity_delete Implements hook_entity_delete().
farm_sensor_entity_insert Implements hook_entity_insert().
farm_sensor_entity_load Implements hook_entity_load().
farm_sensor_entity_property_info_alter Implements hook_entity_property_info_alter().
farm_sensor_entity_update Implements hook_entity_update().
farm_sensor_entity_view_alter Implements hook_entity_view_alter().
farm_sensor_farm_log_categories Implements hook_farm_log_categories().
farm_sensor_farm_sensor_type_info Implements hook_farm_sensor_type_info().
farm_sensor_farm_ui_entities Implements hook_farm_ui_entities().
farm_sensor_farm_ui_entity_view_groups Implements hook_farm_ui_entity_view_groups().
farm_sensor_form_alter Implements hook_form_alter().
farm_sensor_save Helper function for saving farm sensor information.
farm_sensor_settings_form_ajax Farm sensor settings form ajax.
farm_sensor_types Get farm sensor types.
_farm_sensor_entity_save Helper function for saving farm sensor information on entity insert and update.