Example #1
0
static void MovingLightModel_Tasks() {
  if (g_moving_light.lamp_state == LAMP_STRIKE &&
      CoarseTimer_HasElapsed(g_moving_light.lamp_strike_time,
                             LAMP_STRIKE_DELAY)) {
    g_moving_light.lamp_state = LAMP_ON;
    g_moving_light.lamp_strikes++;
  }

  if (CoarseTimer_HasElapsed(g_moving_light.clock_timer, ONE_SECOND)) {
    g_moving_light.clock_timer = CoarseTimer_GetTime();
    g_moving_light.second++;
    if (g_moving_light.second >= 60u) {
      g_moving_light.second = 0u;
      g_moving_light.minute++;
    }
    if (g_moving_light.minute >= 60u) {
      g_moving_light.minute = 0u;
      g_moving_light.hour++;
    }
    if (g_moving_light.hour >= 24u) {
      g_moving_light.hour = 0u;
      g_moving_light.day++;
    }
    if (g_moving_light.day >
        DaysInMonth(g_moving_light.year, g_moving_light.month)) {
      g_moving_light.day = 1u;
      g_moving_light.month++;
    }
    if (g_moving_light.month > 12u) {
      g_moving_light.month = 1u;
      g_moving_light.year++;
    }
  }
}
Example #2
0
int MovingLightModel_SetLampState(const RDMHeader *header,
                                  const uint8_t *param_data) {
  if (header->param_data_length != sizeof(uint8_t)) {
    return RDMResponder_BuildNack(header, NR_FORMAT_ERROR);
  }

  if (param_data[0] > LAMP_STRIKE) {
    return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE);
  }
  if (g_moving_light.lamp_state == LAMP_OFF && param_data[0] == LAMP_ON) {
    g_moving_light.lamp_strikes++;
  }
  if (g_moving_light.lamp_state != param_data[0]) {
    g_moving_light.using_factory_defaults = false;
  }
  g_moving_light.lamp_state = param_data[0];
  if (g_moving_light.lamp_state == LAMP_STRIKE) {
    g_moving_light.lamp_strike_time = CoarseTimer_GetTime();
  }
  return RDMResponder_BuildSetAck(header);
}
int DimmerModel_PerformSelfTest(const RDMHeader *header,
                                const uint8_t *param_data) {
  if (header->param_data_length != sizeof(uint8_t)) {
    return RDMResponder_BuildNack(header, NR_FORMAT_ERROR);
  }

  const uint8_t self_test_id = param_data[0];
  // We don't allow cancelling self-tests
  if (self_test_id > NUMBER_OF_SELF_TESTS) {
    return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE);
  }

  if (self_test_id == SELF_TEST_OFF) {
    g_root_device.running_self_test = SELF_TEST_OFF;
  } else {
    if (g_root_device.running_self_test) {
      return RDMResponder_BuildNack(header, NR_ACTION_NOT_SUPPORTED);
    }

    g_root_device.running_self_test = self_test_id;
    g_root_device.self_test_timer = CoarseTimer_GetTime();
  }
  return RDMResponder_BuildSetAck(header);
}
/*
 * @brief We generate status messages for each device, based on a periodic
 * timer. This makes it easier to reproduce problems (and test!).
 */
static void DimmerModel_Tasks() {
  // The cycle counter is used to generate status messages for each sub device.
  static uint8_t cycle = 0u;
  static uint16_t complete_cycles = 0u;

  if (g_root_device.running_self_test &&
      CoarseTimer_HasElapsed(
          g_root_device.self_test_timer,
          SELF_TESTS[g_root_device.running_self_test - 1].duration)) {
    // Queue a status message for the root.
    QueueStatusMessage(
        &g_root_device.status_message, SUBDEVICE_ROOT, STATUS_ADVISORY,
        (uint16_t) (g_root_device.running_self_test == 1u ?
            STS_OLP_SELFTEST_PASSED : STS_OLP_SELFTEST_FAILED),
        g_root_device.running_self_test, 0u);

    g_root_device.running_self_test = 0u;
  }

  if (!CoarseTimer_HasElapsed(g_root_device.status_message_timer,
                             STATUS_MESSAGE_TRIGGER_INTERVAL)) {
    return;
  }

  g_root_device.status_message_timer = CoarseTimer_GetTime();

  unsigned int subdevice_index = 0u;
  for (; subdevice_index < NUMBER_OF_SUB_DEVICES; subdevice_index++) {
    DimmerSubDevice *subdevice = &g_subdevices[subdevice_index];

    if (subdevice->index == 1u) {
      // The cycle for the first device is:
      //  - 0, NOOP
      //  - 1, Queue breaker trip warning
      //  - 2, NOOP
      //  - 3, Clear breaker trip warning
      //  - 4, NOOP
      if (cycle == 1) {
        // Queue a message
        QueueSubDeviceStatusMessage(subdevice, STATUS_WARNING,
                                    STS_BREAKER_TRIP, 0u, 0u);
      } else if (cycle == 3u) {
        if (subdevice->status_message.is_active) {
          // The previous message is still in the queue, cancel it.
          subdevice->status_message.is_active = false;
        } else {
          // Queue a 'cleared' message
          QueueSubDeviceStatusMessage(subdevice, STATUS_WARNING_CLEARED,
                                      STS_BREAKER_TRIP, 0u, 0u);
        }
      }
    } else if (subdevice->index == 3u) {
      // This subdevice just queues a manufacturer-defined advisory message
      // each cycle.
      QueueSubDeviceStatusMessage(subdevice, STATUS_ADVISORY,
                                  (uint16_t) STS_OLP_TESTING,
                                  complete_cycles, cycle);
    }
  }
  cycle++;
  cycle %= 5u;
  if (cycle == 0u) {
    complete_cycles++;
  }
}
static void DimmerModel_Activate() {
  g_responder->def = &ROOT_RESPONDER_DEFINITION;
  RDMResponder_InitResponder();
  g_responder->sub_device_count = NUMBER_OF_SUB_DEVICES;
  g_root_device.status_message_timer = CoarseTimer_GetTime();
}
Example #6
0
static void MovingLightModel_Activate() {
  g_responder->def = &RESPONDER_DEFINITION;
  RDMResponder_ResetToFactoryDefaults();
  g_moving_light.clock_timer = CoarseTimer_GetTime();
}