1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-23 16:16:13 +01:00

Compare commits

...

2 Commits

Author SHA1 Message Date
Harald Barth
b6a15aa5c3 version 2024-03-25 15:07:33 +01:00
Harald Barth
aacfff2e3d Z21 add turnout and sensor broadcasts 2024-03-25 15:05:14 +01:00
6 changed files with 115 additions and 20 deletions

View File

@ -31,6 +31,7 @@
#include "DCC.h"
#include "TrackManager.h"
#include "StringFormatter.h"
#include "Z21Throttle.h"
// variables to hold clock time
int16_t lastclocktime;
@ -149,6 +150,7 @@ void CommandDistributor::broadcastToClients(clientType type) {
// Public broadcast functions below
void CommandDistributor::broadcastSensor(int16_t id, bool on ) {
Z21Throttle::broadcastNotifySensor(id, on);
broadcastReply(COMMAND_TYPE, F("<%c %d>\n"), on?'Q':'q', id);
}
@ -156,6 +158,7 @@ void CommandDistributor::broadcastTurnout(int16_t id, bool isClosed ) {
// For DCC++ classic compatibility, state reported to JMRI is 1 for thrown and 0 for closed;
// The string below contains serial and Withrottle protocols which should
// be safe for both types.
Z21Throttle::broadcastNotifyTurnout(id, isClosed);
broadcastReply(COMMAND_TYPE, F("<H %d %d>\n"),id, !isClosed);
#ifdef CD_HANDLE_RING
broadcastReply(WITHROTTLE_TYPE, F("PTA%c%d\n"), isClosed?'2':'4', id);

View File

@ -1 +1 @@
#define GITHUB_SHA "devel-z21-202403241544Z"
#define GITHUB_SHA "devel-z21-202403251406Z"

37
NetworkClientUDP.h Normal file
View File

@ -0,0 +1,37 @@
/*
* © 2024 Harald Barth
* All rights reserved.
*
* This file is part of CommandStation-EX
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* It is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/
#include <WiFi.h>
#include <WiFiClient.h>
class NetworkClientUDP {
public:
NetworkClientUDP() {
};
bool ok() {
return (inUse);
};
bool inUse = true;
bool connected = false;
IPAddress remoteIP;
int remotePort;
static WiFiUDP client;
};

View File

@ -27,6 +27,7 @@
#include "DCCWaveform.h"
#include "StringFormatter.h"
#include "Turnouts.h"
#include "Sensors.h"
#include "DIAG.h"
#include "GITHUB_SHA.h"
#include "version.h"
@ -172,6 +173,17 @@ Z21Throttle* Z21Throttle::getOrAddThrottle(int clientId) {
return p;
}
void Z21Throttle::broadcastNotifyTurnout(uint16_t addr, bool isClosed) {
for (Z21Throttle* wt = firstThrottle; wt != NULL ; wt = wt->nextThrottle) {
wt->notifyTurnoutInfo(addr, isClosed);
}
}
void Z21Throttle::broadcastNotifySensor(uint16_t addr, bool state) {
for (Z21Throttle* wt = firstThrottle; wt != NULL ; wt = wt->nextThrottle) {
wt->notifySensor(addr, state);
}
}
void Z21Throttle::forget( byte clientId) {
for (Z21Throttle* wt=firstThrottle; wt!=NULL ; wt=wt->nextThrottle)
if (wt->clientid==clientId) {
@ -405,6 +417,22 @@ void Z21Throttle::notifyLocoInfo(byte inMSB, byte inLSB) {
notify(HEADER_LAN_XPRESS_NET, LAN_X_HEADER_LOCO_INFO, Z21Throttle::replyBuffer, 9, false);
}
void Z21Throttle::notifyTurnoutInfo(uint16_t addr, bool isClosed) {
char c;
Z21Throttle::replyBuffer[0] = (byte)(addr >> 8);
Z21Throttle::replyBuffer[1] = (byte)(addr & 0xFF);
if (isClosed) {
Z21Throttle::replyBuffer[2] = B00000010;
c = 'c';
} else {
Z21Throttle::replyBuffer[2] = B00000001;
c = 't';
}
if (Diag::Z21THROTTLE)
DIAG(F("Z21 Throttle %d : Turnoutinfo %d %c"), clientid, addr, c);
notify(HEADER_LAN_XPRESS_NET, LAN_X_HEADER_TURNOUT_INFO, Z21Throttle::replyBuffer, 3, false);
}
void Z21Throttle::notifyTurnoutInfo(byte inMSB, byte inLSB) {
Z21Throttle::replyBuffer[0] = inMSB; // turnout address msb
Z21Throttle::replyBuffer[1] = inLSB; // turnout address lsb
@ -426,6 +454,23 @@ void Z21Throttle::notifyTurnoutInfo(byte inMSB, byte inLSB) {
notify(HEADER_LAN_XPRESS_NET, LAN_X_HEADER_TURNOUT_INFO, Z21Throttle::replyBuffer, 3, false);
}
void Z21Throttle::notifySensor(uint16_t addr) {
Sensor *s = Sensor::get(addr);
if (s) {
notifySensor(addr, s->active);
}
}
void Z21Throttle::notifySensor(uint16_t addr, bool state) {
Z21Throttle::replyBuffer[0] = 0x01; // Status in first info byte
Z21Throttle::replyBuffer[1] = (byte)(addr & 0xFF);
Z21Throttle::replyBuffer[2] = (byte)(addr >> 8);
Z21Throttle::replyBuffer[3] = state;
if (Diag::Z21THROTTLE)
DIAG(F("Z21 Throttle %d : notifySensor %d 0x%x"), clientid, addr, Z21Throttle::replyBuffer[3]);
notify(HEADER_LAN_LOCONET_DETECTOR, Z21Throttle::replyBuffer, 4, false);
}
void Z21Throttle::notifyLocoMode(byte inMSB, byte inLSB) {
Z21Throttle::replyBuffer[0] = inMSB; // loco address msb
Z21Throttle::replyBuffer[1] = inLSB; // loco address lsb
@ -888,6 +933,23 @@ bool Z21Throttle::parse(byte *networkPacket, int len) {
notifyStatus(); // big endian here, but resend the same as received, so no problem.
done = true;
break;
case HEADER_LAN_LOCONET_DETECTOR:
{
switch(Data[0]) {
case LAN_LOCONET_TYPE_UHL_REPORTER:
{
uint16_t addr = (Data[2] << 8) + Data[1];
if (Diag::Z21THROTTLEVERBOSE) DIAG(F("%d LOCONET DETECTOR %d"), this->clientid, addr);
notifySensor(addr);
//done = true;
break;
}
case LAN_LOCONET_TYPE_DIGITRAX:
case LAN_LOCONET_TYPE_UHL_LISSY:
break;
}
}
break;
case HEADER_LAN_GET_SERIAL_NUMBER:
// XXX this has been seen, return dummy number
case HEADER_LAN_GET_BROADCASTFLAGS:
@ -899,7 +961,6 @@ bool Z21Throttle::parse(byte *networkPacket, int len) {
case HEADER_LAN_RAILCOM_DATACHANGED:
case HEADER_LAN_RAILCOM_GETDATA:
case HEADER_LAN_LOCONET_DISPATCH_ADDR:
case HEADER_LAN_LOCONET_DETECTOR:
break;
}

View File

@ -20,7 +20,7 @@
#define Z21Throttle_h
//#include "CircularBuffer.hpp"
#include "WiFiClient.h"
#include "NetworkClientUDP.h"
#define MAX_MTU 1460
#define UDPBYTE_SIZE 1500
@ -48,26 +48,12 @@ struct MYLOCOZ21 {
uint32_t functionToggles;
};
class NetworkClientUDP {
public:
NetworkClientUDP() {
};
bool ok() {
return (inUse);
};
bool inUse = true;
bool connected = false;
IPAddress remoteIP;
int remotePort;
static WiFiUDP client;
};
class Z21Throttle {
public:
static void loop();
static Z21Throttle* getOrAddThrottle(int clientId);
static void broadcastNotifyTurnout(uint16_t addr, bool isClosed);
static void broadcastNotifySensor(uint16_t addr, bool state);
static void markForBroadcast(int cab);
static void forget(byte clientId);
static void findUniqThrottle(int id, char *u);
@ -137,7 +123,10 @@ class Z21Throttle {
void notifyStatus();
void notifyLocoInfo(byte inMSB, byte inLSB);
void notifyTurnoutInfo(uint16_t addr, bool isClosed);
void notifyTurnoutInfo(byte inMSB, byte inLSB);
void notifySensor(uint16_t addr);
void notifySensor(uint16_t addr, bool state);
void notifyLocoMode(byte inMSB, byte inLSB);
void notifyFirmwareVersion();
void notifyHWInfo();
@ -182,6 +171,10 @@ class Z21Throttle {
#define LAN_GET_CONFIG 0x12
#define LAN_LOCONET_TYPE_DIGITRAX 0x80
#define LAN_LOCONET_TYPE_UHL_REPORTER 0x81
#define LAN_LOCONET_TYPE_UHL_LISSY 0x82
#define LAN_X_HEADER_GENERAL 0x21
#define LAN_X_HEADER_READ_REGISTER 0x22
#define LAN_X_HEADER_SET_STOP 0x80

View File

@ -4,6 +4,7 @@
#include "StringFormatter.h"
#define VERSION "5.X.Y"
// Z21 add turnout and sensor broadcasts
// Z21: report the (unchanged) loco mode back after every attempted change
// Add turnout functionality to Z21
// Fix index of DB[] to comply with Roco documentation