001package jmri.jmrix.ipocs;
002
003import org.slf4j.Logger;
004import org.slf4j.LoggerFactory;
005
006import jmri.Light;
007import jmri.implementation.AbstractLight;
008import jmri.jmrix.ipocs.protocol.Message;
009import jmri.jmrix.ipocs.protocol.enums.RqOutputCommand;
010import jmri.jmrix.ipocs.protocol.packets.OutputStatusPacket;
011import jmri.jmrix.ipocs.protocol.packets.Packet;
012import jmri.jmrix.ipocs.protocol.packets.SetOutputPacket;
013
014/**
015 *
016 * @author Fredrik Elestedt Copyright (C) 2020
017 * @since 4.21.2
018 */
019public class IpocsLight extends AbstractLight implements IpocsClientListener {
020  private final static Logger log = LoggerFactory.getLogger(IpocsLight.class);
021  private final IpocsPortController portController;
022
023  public IpocsLight(IpocsPortController portController, String systemName, String userName) {
024    super(systemName, userName);
025    this.portController = portController;
026    this.portController.addListener(this);
027  }
028
029  @Override
030  protected void doNewState(int oldState, int newState) {
031    Message order = new Message();
032    order.setObjectName(getUserName());
033    SetOutputPacket packet = new SetOutputPacket();
034    switch (newState) {
035      case ON:
036        packet.setCommand(RqOutputCommand.On);
037        break;
038      case OFF:
039        packet.setCommand(RqOutputCommand.Off);
040        break;
041      case UNKNOWN:
042        // ignore, but not an error as normal during AbstractTurnout testCreate()
043        return;
044      default:
045        log.error("Unknown light order state");
046        return;
047    }
048    order.getPackets().add(packet);
049    portController.send(order);
050  }
051
052  @Override
053  public void setState(int newState) {
054      log.debug("setState {} was {}", newState, mState);
055      
056      //int oldState = mState;
057      if (newState != ON && newState != OFF && newState != UNKNOWN) {
058          throw new IllegalArgumentException("cannot set state value " + newState);
059      }
060      
061      // do the state change in the hardware
062      doNewState(mState, newState); // old state, new state
063      // change value and tell listeners
064      notifyStateChange(mState, newState);
065  }
066
067  @Override
068  public void clientConnected(IpocsClientHandler client) {
069  }
070
071  @Override
072  public void clientDisconnected(IpocsClientHandler client) {
073    setState(Light.UNKNOWN);
074  }
075
076  @Override
077  public void onMessage(IpocsClientHandler client, Message msg) {
078    if (!msg.getObjectName().equals(super.getUserName())) {
079      return;
080    }
081    // We have a status, let's interpret it.
082    for (Packet packet : msg.getPackets()) {
083      switch (packet.getId()) {
084        case OutputStatusPacket.IDENT:
085          switch (((OutputStatusPacket) packet).getState()) {
086            case On:
087              setState(Light.ON);
088              break;
089            case Off:
090              setState(Light.OFF);
091              break;
092            default:
093              log.error("Unknown light state {}", ((OutputStatusPacket) packet).getState().toString());
094              break;
095          }
096          break;
097        default:
098          break;
099      }
100    }
101  }
102}