void ValveController::tick() { if (m_suggestedState == UNDEF || m_stateIsForced || !delayExpired()) { return; } changeValveToSuggestedState(); }
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(); }
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 } }
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; } }