package org.hwo.io.servicelink; import java.io.IOException; import java.lang.ref.ReferenceQueue; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.List; import org.hwo.BitField; import org.hwo.ChkSum; import org.hwo.interactiveobjects.InteractiveObject; import org.hwo.io.SerialPort; import org.hwo.models.TableMapper.TableColumn; /* ServiceLink * * Kommunikation via USB mit RegBus fŠhigem System * * †bertragungssicherheit wird durch USB sichergestellt * * †bertragen werden Telegramme mit folgendem Aufbau: * * Offset Type Inhalt * 0 Byte RequestTyp ( 0 = NoOP, 1 = Wert lesen, 2 = Wert schreiben, 3 = Ereignis senden ) * 1 Byte Achse * 2 Byte Knoten * 3 Short Register Nummer * 5 Int32/Float Wert (nur bei schreiben oder lesen antwort) * */ public class ServiceLink { static int REQ_READ = 0x01; static int REQ_WRITE = 0x02; static int REQ_EVENT = 0x04; static int REQ_FAIL = 0x08; static int REQ_INT = 0x10; static int REQ_FLOAT = 0x20; static int REQ_ACK = 0x40; static int SL_MAGIC = 0x66; class ServiceTelegram { byte request; byte achse; byte knoten; int register; byte[] value; public ServiceTelegram() { request = 0; achse = 0; knoten = 0; register = 0; value = new byte[4]; ByteBuffer.wrap(value).asIntBuffer().put(0); } public void send() { byte[] txbuffer = new byte[12]; ByteBuffer bb = ByteBuffer.wrap(txbuffer).order(ByteOrder.LITTLE_ENDIAN); bb.put( (byte)SL_MAGIC ); bb.put(request); bb.put(achse); bb.put(knoten); bb.putShort((short)register); if ((request & REQ_WRITE) == REQ_WRITE) bb.put(value); short chk = ChkSum.chksum(txbuffer, 1, bb.position()-1); bb.putShort(chk); try { getSerialPort().getOutputStream().write(txbuffer,0,bb.position()); } catch (IOException ex) { getSerialPort().close(); System.err.println(ex.toString()); } } public void recv() throws ServiceLinkException { byte[] rxbuffer = new byte[12]; ByteBuffer bb = ByteBuffer.wrap(rxbuffer).order(ByteOrder.LITTLE_ENDIAN); try { int ch = getSerialPort().getInputStream().read(); while ((ch != SL_MAGIC) && (ch >= 0)) ch = getSerialPort().getInputStream().read(); getSerialPort().getInputStream().read(rxbuffer,0,5); request = bb.get(); achse = bb.get(); knoten = bb.get(); register = bb.getShort(); if ((request & (REQ_READ | REQ_ACK)) == (REQ_READ | REQ_ACK)) { getSerialPort().getInputStream().read(rxbuffer,bb.position(),4); bb.get(value); }; getSerialPort().getInputStream().read(rxbuffer,bb.position(),2); short chksum = bb.getShort(); if (chksum != ChkSum.chksum(rxbuffer, 0, bb.position() - 2)) throw new ServiceLinkException(); } catch (IOException e) { getSerialPort().close(); System.err.println(e.toString()); throw new ServiceLinkException(e); } } } public class ServiceNode { @InteractiveObject(editor=RegisterEditor.class) public class ServiceNodeRegister { @TableColumn(label="Register",readonly=true,width=60) Integer register; @TableColumn(label="Bezeichnung",readonly=true,width=150) String label; private Float floatValue; private Integer intValue; boolean floatType; private BitField bitField; public ServiceNodeRegister(int register,boolean floatType) { this.label = String.format("%d", register); this.register = register; this.floatType = floatType; } public ServiceNodeRegister(int register,String label,boolean floatType) { this.label = label; this.register = register; this.floatType = floatType; } public boolean isBitField() { return (bitField != null); } public boolean isFloat() { return floatType; } public boolean isInteger() { return (!isBitField() && !isFloat()); } @TableColumn(label="Wert",width=500) public String value() { if (bitField != null) return bitField.toText(intValue); if (intValue != null) return String.format("%d", intValue); if (floatValue != null) return String.format("%f", floatValue); return "N/A"; } public void setValue(String value) { if (floatType) floatValue = new Float(value); else intValue = new Integer(value); } public void read() { try { if (floatType) floatValue = ServiceNode.this.readFloat(register); else intValue = ServiceNode.this.readInt(register); } catch (Exception e) { floatValue = null; intValue = 0; e.printStackTrace(); }; } public void write() { try { if (floatType) ServiceNode.this.writeFloat(register, floatValue); else ServiceNode.this.writeInt(register, intValue); } catch (Exception e) { e.printStackTrace(); } } public BitField getBitField() { return bitField; } public void setBitField(BitField bitField) { this.bitField = bitField; } public Integer getIntValue() { return intValue; } public void setIntValue(Integer intValue) { this.intValue = intValue; } public Float getFloatValue() { return floatValue; } public void setFloatValue(Float floatValue) { this.floatValue = floatValue; } } private byte achse; private byte knoten; List registers; public ServiceNode(byte achse,byte knoten) { this.achse = achse; this.knoten = knoten; this.registers = new ArrayList(); } public ServiceNodeRegister createRegister(int register,String label,boolean floatType) { return new ServiceNodeRegister(register, label, floatType); } public List getRegisters() { return registers; } public void read() { for (ServiceNodeRegister r:registers) r.read(); } public ServiceLink getServiceLink() { return ServiceLink.this; } public int readInt(int register) throws IOException, ServiceLinkException { for (int n=0;n