001package jmri.jmrix.ipocs; 002 003import org.slf4j.Logger; 004import org.slf4j.LoggerFactory; 005 006import jmri.Turnout; 007import jmri.implementation.AbstractTurnout; 008import jmri.jmrix.ipocs.protocol.Message; 009import jmri.jmrix.ipocs.protocol.enums.RqPointsCommand; 010import jmri.jmrix.ipocs.protocol.packets.Packet; 011import jmri.jmrix.ipocs.protocol.packets.PointsStatusPacket; 012import jmri.jmrix.ipocs.protocol.packets.ThrowPointsPacket; 013 014/** 015 * 016 * @author Fredrik Elestedt Copyright (C) 2020 017 * @since 4.21.2 018 */ 019public class IpocsTurnout extends AbstractTurnout implements IpocsClientListener { 020 021 private final static Logger log = LoggerFactory.getLogger(IpocsTurnout.class); 022 private final IpocsPortController portController; 023 024 IpocsTurnout(IpocsPortController portController, String systemName, String userName) { 025 super(systemName, userName); 026 this.portController = portController; 027 this.portController.addListener(this); 028 super._validFeedbackNames = new String[]{"MONITORING"}; 029 super._validFeedbackModes = new int[]{MONITORING}; 030 super._validFeedbackTypes = MONITORING; 031 super._activeFeedbackType = MONITORING; 032 Message msg = portController.getLastStatus(userName); 033 if (msg != null) { 034 onMessage(null, msg); 035 } 036 } 037 038 @Override 039 protected void forwardCommandChangeToLayout(int s) { 040 Message order = new Message(); 041 order.setObjectName(getUserName()); 042 ThrowPointsPacket packet = new ThrowPointsPacket(); 043 switch (s) { 044 case THROWN: 045 packet.setCommand(RqPointsCommand.Left); 046 break; 047 case CLOSED: 048 packet.setCommand(RqPointsCommand.Right); 049 break; 050 case UNKNOWN: 051 // ignore, but not an error as normal during AbstractTurnout testCreate() 052 return; 053 default: 054 log.error("Unknown turnout order state: {}", s); 055 return; 056 } 057 order.getPackets().add(packet); 058 portController.send(order); 059 } 060 061 @Override 062 protected void turnoutPushbuttonLockout(boolean locked) { 063 // Not supported 064 } 065 066 // ipocs turnouts don't support inversion, no need to override super.canInvert() reply 067 068 @Override 069 public void clientConnected(IpocsClientHandler client) { 070 // Nothing to do when a client connects. 071 } 072 073 @Override 074 public void clientDisconnected(IpocsClientHandler client) { 075 newKnownState(Turnout.UNKNOWN); 076 } 077 078 @Override 079 public void onMessage(IpocsClientHandler client, Message msg) { 080 if (!msg.getObjectName().equals(super.getUserName())) { 081 return; 082 } 083 // We have a status, let's interpret it. 084 for (Packet packet : msg.getPackets()) { 085 if (packet.getId() == PointsStatusPacket.IDENT) { 086 switch (((PointsStatusPacket) packet).getState()) { 087 case Left: 088 newKnownState(Turnout.THROWN); 089 break; 090 case Right: 091 newKnownState(Turnout.CLOSED); 092 break; 093 case Moving: 094 newKnownState(Turnout.INCONSISTENT); 095 break; 096 case OutOfControl: 097 newKnownState(Turnout.UNKNOWN); 098 break; 099 default: 100 log.error("Unknown turnout state {}", ((PointsStatusPacket) packet).getState().toString()); 101 break; 102 } 103 } 104 } 105 } 106}