Exemplo n.º 1
0
void ValveController::tick()
{
  if (m_suggestedState == UNDEF || m_stateIsForced
      || !delayExpired()) {
    return;
  }
  changeValveToSuggestedState();
}
Exemplo n.º 2
0
void ValveController::changeValveState(bool ignoreDelay, e_valveState state)
{
  if (!ignoreDelay && m_stateIsForced) {
    #ifdef DEBUG
      Serial.print(F("Told to change valve state on pin "));
      Serial.print(m_valveSignalPin);
      Serial.print(F(" while in a forced state. State: "));
      Serial.println(state);
    #endif
    if (m_suggestedState != state) {
      m_suggestedState = state;
    }
    return;
  }
  if (!ignoreDelay && !delayExpired()) {
    #ifdef DEBUG
      Serial.print(F("Told to change valve state on pin "));
      Serial.print(m_valveSignalPin);
      Serial.print(F(" before delay finish. State:"));
      Serial.println(state);
    #endif
    if (m_suggestedState != state) {
      m_suggestedState = state;
    }
    return;
  }
  if (ignoreDelay && !m_stateIsForced) {
    #ifdef DEBUG
      Serial.print(F("Forcing change of valve state on pin "));
      Serial.println(m_valveSignalPin);
    #endif
    if (m_suggestedState == UNDEF) {
      m_suggestedState = m_valveState;
    }
    m_stateIsForced = true;
    m_isStateForced = true;
  }  
  if (m_valveState != state) {
    m_valveState = state;    
    switch(state)
    {
      case OPEN:
        digitalWrite(m_valveSignalPin, HIGH);
        break;
      case CLOSED:
        digitalWrite(m_valveSignalPin, LOW);
        break;
    }
    #ifdef DEV
      Serial.print(F("VALVE ON PIN "));
      Serial.print(m_valveSignalPin);
      Serial.print(F(" SET TO STATE: "));
      Serial.println(state);
    #endif
    notify();
  }
  resetDelay();
}
Exemplo n.º 3
0
void WebServiceFSM::update() {

  if(state == UpstreamState::IDLE && !command_available && delayExpired()) {
    state = UpstreamState::FETCH_CMD;
  }
  if(state == UpstreamState::IDLE && command_completed) {
    state = UpstreamState::ACKING;
  }

  if(state == UpstreamState::ACKING && delayExpired()) {
    JsonObject& obj = jsonBuffer.createObject();
    command.toJson(obj);
    if (transmitJson("PUT","http://localhost:8080/commands",obj)) {
      state = UpstreamState::IDLE;
    } else {
      setDelay(READ_AGAIN_COOLDOWN_TIME); // which delay period to use?
    }
  }
  if(state == UpstreamState::FETCH_CMD) {
    auto& obj = getJson("http://localhost:8080/commands?pid=0");
    if (!obj.success()) {
      setDelay(READ_AGAIN_COOLDOWN_TIME);
      state = UpstreamState::IDLE;
    } else {
      if (command.fromJson(obj)) {
        command_available = true;
        command_completed = false;
        state = UpstreamState::IDLE;
      } else {
        setDelay(READ_AGAIN_COOLDOWN_TIME);
        state = UpstreamState::IDLE;
      }
    }
  }
  if(state == UpstreamState::SENDING && delayExpired()) {
    // to be implemented later, when mothership has sensor status
  }
}
Exemplo n.º 4
0
void RealProtocolFSM::update() {
  if(state == DISCONNECTED_COOLDOWN && delayExpired()) {
    state = DISCONNECTED;
  }

  if(state == DISCONNECTED) {
    /*
     * Arduino is a pure I2C slave. This client writes commands to it and
     * reads the response after enough time has passed.
     */

    // attempt connection
    fprintf(stderr, "I2C: Connecting\n");
    if((fp = open(bus, O_RDWR)) < 0) {
      fprintf(stderr, "I2C: Failed to access %s: %s\n", bus, strerror(errno));
      state = DISCONNECTED_COOLDOWN;
      setDelay(DISCONNECTED_COOLDOWN_TIME);

      return;
    }

    fprintf(stderr, "I2C: acquiring bus to %#x\n", dev);

    if (ioctl(fp, I2C_SLAVE, dev) < 0) {
      fprintf(stderr, "I2C: Failed to acquire bus access/talk to slave %#x: %s\n",
              dev, strerror(errno));
      ::close(fp);
      state = DISCONNECTED_COOLDOWN;
      setDelay(DISCONNECTED_COOLDOWN_TIME);

      return;
    }

    fprintf(stderr, "I2C: Connection successful\n");
    state = IDLE;
  }

  if(state == IDLE && outbound_message_waiting) {
    state = SENDING;
    sending = to_send;
    sending_offset = 0;
    outbound_message_waiting = false;
  }

  if(state == SENDING && delayExpired()) {
    uint8_t* msg = (uint8_t*)&sending;
    ssize_t wrote = write(fp, (const void*)&msg[sending_offset], sizeof(Message) - sending_offset);
    if(wrote == -1) {
      fprintf(stderr, "I2C: write failed: (%d) %s\n", errno, strerror(errno));
      if(errno == EAGAIN || errno == EWOULDBLOCK) {
        setDelay(WRITE_AGAIN_COOLDOWN_TIME);
      } else if(errno == EBADF) {
        state = DISCONNECTED;
      } else {
        // switch to a fail state so the user can decide what happens next
        state = SENDING_FAILED;
        failure_acknowledged = false;
      }
      return;
    }
    sending_offset += wrote;
    if(sending_offset == sizeof(Message)) {
      state = ACKING;
      last_sent = sending;
      ack_attempts = 0;
      receiving_offset = 0;
    }
  }

  if(state == ACKING && delayExpired()) {
    uint8_t* msg = (uint8_t*)&receiving;
    ssize_t nread = read(fp, (void*)&msg[receiving_offset], sizeof(Message) - receiving_offset);
    if(nread == -1) {
      if(errno == EAGAIN || errno == EWOULDBLOCK) {
        setDelay(READ_AGAIN_COOLDOWN_TIME);
      } else if(errno == EBADF) {
        state = DISCONNECTED;
      } else {
        fprintf(stderr, "I2C: read failed: (%d) %s\n", errno, strerror(errno));
        state = ACKING_FAILED;
        failure_acknowledged = false;
      }
      return;
    }
    receiving_offset += nread;
    if(receiving_offset == sizeof(Message)) {
      last_received = receiving;

      if(last_received.type == last_sent.type && last_received.id == last_sent.id) {
        state = ACK_COMPLETE;
        ack_acknowledged = false;
      } else {
        ack_attempts++;
        receiving_offset = 0;

        /*
          fprintf(stderr, "Attempt %d: type %d vs %d, id %d vs %d\n", ack_attempts,
          last_received.type, last_sent.type,
          last_received.id, last_sent.id);
        */
        if(ack_attempts == MAX_ACK_ATTEMPTS) {
          state = ACKING_FAILED;
          failure_acknowledged = false;
        } else {
          //fprintf(stderr, "read succeeded but wrong result, retry\n");
          setDelay(ACK_AGAIN_COOLDOWN_TIME);
        }
      }
    }
  }

  if(state == ACK_COMPLETE && ack_acknowledged) {
    state = IDLE;
  }

  if(state == ACKING_FAILED && failure_acknowledged) {
    state = IDLE;
  }

  if(state == SENDING_FAILED && failure_acknowledged) {
    state = IDLE;
  }
}