1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-12-24 05:11:24 +01:00

Rebuild throttle info getters

UNTESTED... create different methods to obtain throttle info without being withrottle specific.

Also implements turnout description of "*" as hidden.
This commit is contained in:
Asbelos 2022-04-03 11:19:04 +01:00
parent 7c1c6dafa1
commit 4c8b7f8517
4 changed files with 101 additions and 73 deletions

View File

@ -40,7 +40,6 @@
T2. Extend to >64k T2. Extend to >64k
*/ */
#include <Arduino.h> #include <Arduino.h>
#include "EXRAIL2.h" #include "EXRAIL2.h"
#include "DCC.h" #include "DCC.h"
@ -347,13 +346,6 @@ bool RMFT2::parseSlash(Print * stream, byte & paramCount, int16_t p[]) {
} }
return true; return true;
case HASH_KEYWORD_ROUTES: // </ ROUTES > JMRI withrottle support
if (paramCount>1) return false;
StringFormatter::send(stream,F("</ROUTES "));
emitWithrottleRouteList(stream);
StringFormatter::send(stream,F(">"));
return true;
default: default:
break; break;
} }
@ -408,11 +400,7 @@ bool RMFT2::parseSlash(Print * stream, byte & paramCount, int16_t p[]) {
// Automations are given a state to set the button to "handoff" which implies // Automations are given a state to set the button to "handoff" which implies
// handing over the loco to the automation. // handing over the loco to the automation.
// Routes are given "Set" buttons and do not cause the loco to be handed over. // Routes are given "Set" buttons and do not cause the loco to be handed over.
void RMFT2::emitWithrottleRouteList(Print* stream) {
StringFormatter::send(stream,F("PRT]\\[Routes}|{Route]\\[Set}|{2]\\[Handoff}|{4\nPRL"));
emitWithrottleDescriptions(stream);
StringFormatter::send(stream,F("\n"));
}
RMFT2::RMFT2(int progCtr) { RMFT2::RMFT2(int progCtr) {
@ -1037,8 +1025,4 @@ void RMFT2::printMessage2(const FSH * msg) {
DIAG(F("EXRAIL(%d) %S"),loco,msg); DIAG(F("EXRAIL(%d) %S"),loco,msg);
} }
// This is called by emitRouteDescriptions to emit a withrottle description for a route or autoomation.
void RMFT2::emitRouteDescription(Print * stream, char type, int id, const FSH * description) {
StringFormatter::send(stream,F("]\\[%c%d}|{%S}|{%c"),
type,id,description, type=='R'?'2':'4');
}

View File

@ -87,17 +87,21 @@ class LookList {
RMFT2(int route, uint16_t cab); RMFT2(int route, uint16_t cab);
~RMFT2(); ~RMFT2();
static void readLocoCallback(int16_t cv); static void readLocoCallback(int16_t cv);
static void emitWithrottleRouteList(Print* stream);
static void createNewTask(int route, uint16_t cab); static void createNewTask(int route, uint16_t cab);
static void turnoutEvent(int16_t id, bool closed); static void turnoutEvent(int16_t id, bool closed);
static void activateEvent(int16_t addr, bool active); static void activateEvent(int16_t addr, bool active);
static void emitTurnoutDescription(Print* stream,int16_t id);
static const byte rosterNameCount;
static void emitWithrottleRoster(Print * stream);
static const FSH * getRosterFunctions(int16_t cabid);
static const int16_t SERVO_SIGNAL_FLAG=0x4000; static const int16_t SERVO_SIGNAL_FLAG=0x4000;
static const int16_t ACTIVE_HIGH_SIGNAL_FLAG=0x2000; static const int16_t ACTIVE_HIGH_SIGNAL_FLAG=0x2000;
// Throttle Info Access functions built by exrail macros
static const byte rosterNameCount;
static const int16_t FLASH routeIdList[];
static const int16_t FLASH rosterIdList[];
static const FSH * getRouteDescription(int16_t id);
static const FSH * getTurnoutDescription(int16_t id);
static const FSH * getRosterName(int16_t id);
static const FSH * getRosterFunctions(int16_t id);
private: private:
static void ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]); static void ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]);
static bool parseSlash(Print * stream, byte & paramCount, int16_t p[]) ; static bool parseSlash(Print * stream, byte & paramCount, int16_t p[]) ;
@ -106,8 +110,6 @@ private:
static bool getFlag(VPIN id,byte mask); static bool getFlag(VPIN id,byte mask);
static int16_t progtrackLocoId; static int16_t progtrackLocoId;
static void doSignal(VPIN id,bool red, bool amber, bool green); static void doSignal(VPIN id,bool red, bool amber, bool green);
static void emitRouteDescription(Print * stream, char type, int id, const FSH * description);
static void emitWithrottleDescriptions(Print * stream);
static RMFT2 * loopTask; static RMFT2 * loopTask;
static RMFT2 * pausingTask; static RMFT2 * pausingTask;
@ -132,6 +134,7 @@ private:
static LookList * onActivateLookup; static LookList * onActivateLookup;
static LookList * onDeactivateLookup; static LookList * onDeactivateLookup;
// Local variables - exist for each instance/task // Local variables - exist for each instance/task
RMFT2 *next; // loop chain RMFT2 *next; // loop chain
int progCounter; // Byte offset of next route opcode in ROUTES table int progCounter; // Byte offset of next route opcode in ROUTES table

View File

@ -49,24 +49,38 @@
// CAUTION: The macros below are multiple passed over myAutomation.h // CAUTION: The macros below are multiple passed over myAutomation.h
#define O_DESC(id, desc) case id: return ("" desc)[0]?F("" desc):NULL;
// Pass 1 Implements aliases // Pass 1 Implements aliases
#include "EXRAIL2MacroReset.h" #include "EXRAIL2MacroReset.h"
#undef ALIAS #undef ALIAS
#define ALIAS(name,value...) const int name= 1##value##0 ==10 ? -__COUNTER__ : value##0/10; #define ALIAS(name,value...) const int name= 1##value##0 ==10 ? -__COUNTER__ : value##0/10;
#include "myAutomation.h" #include "myAutomation.h"
// Pass 2 convert descriptions to withrottle format emitter function // Pass 2 create throttle route list
#include "EXRAIL2MacroReset.h" #include "EXRAIL2MacroReset.h"
#undef ROUTE #undef ROUTE
#define ROUTE(id, description) emitRouteDescription(stream,'R',id,F(description)); #define ROUTE(id, description) id,
#undef AUTOMATION #undef AUTOMATION
#define AUTOMATION(id, description) emitRouteDescription(stream,'A',id,F(description)); #define AUTOMATION(id, description) -id,
void RMFT2::emitWithrottleDescriptions(Print * stream) { const int16_t FLASH RMFT2::routeIdList[]= {
(void)stream;
#include "myAutomation.h" #include "myAutomation.h"
0};
// Pass 3 Create route descriptions:
#undef ROUTE
#define ROUTE(id, description) case id: return F(description);
#undef AUTOMATION
#define AUTOMATION(id, description) case id: return F(description);
const FSH * RMFT2::getRouteDescription(int16_t id) {
switch(id) {
#include "myAutomation.h"
default: break;
}
return NULL;
} }
// Pass 3... Create Text sending functions // Pass 4... Create Text sending functions
#include "EXRAIL2MacroReset.h" #include "EXRAIL2MacroReset.h"
const int StringMacroTracker1=__COUNTER__; const int StringMacroTracker1=__COUNTER__;
#undef BROADCAST #undef BROADCAST
@ -96,57 +110,62 @@ void RMFT2::printMessage(uint16_t id) {
} }
// Pass 4: Turnout descriptions (optional) // Pass 5: Turnout descriptions (optional)
#include "EXRAIL2MacroReset.h" #include "EXRAIL2MacroReset.h"
#undef TURNOUT #undef TURNOUT
#define TURNOUT(id,addr,subaddr,description...) case id: desc=F("" description); break; #define TURNOUT(id,addr,subaddr,description...) O_DESC(id,description)
#undef PIN_TURNOUT #undef PIN_TURNOUT
#define PIN_TURNOUT(id,pin,description...) case id: desc=F("" description); break; #define PIN_TURNOUT(id,pin,description...) O_DESC(id,description)
#undef SERVO_TURNOUT #undef SERVO_TURNOUT
#define SERVO_TURNOUT(id,pin,activeAngle,inactiveAngle,profile,description...) case id: desc=F("" description); break; #define SERVO_TURNOUT(id,pin,activeAngle,inactiveAngle,profile,description...) O_DESC(id,description)
#undef VIRTUAL_TURNOUT #undef VIRTUAL_TURNOUT
#define VIRTUAL_TURNOUT(id,description...) case id: desc=F("" description); break; #define VIRTUAL_TURNOUT(id,description...) O_DESC(id,description)
void RMFT2::emitTurnoutDescription(Print* stream,int16_t turnoutid) { const FSH * RMFT2::getTurnoutDescription(int16_t turnoutid) {
const FSH * desc=F("");
switch (turnoutid) { switch (turnoutid) {
#include "myAutomation.h" #include "myAutomation.h"
default: break; default:break;
} }
if (GETFLASH(desc)=='\0') desc=F("%d"); return NULL;
StringFormatter::send(stream,desc,turnoutid);
} }
// Pass 5: Roster names (count) // Pass 6: Roster IDs (count)
#include "EXRAIL2MacroReset.h" #include "EXRAIL2MacroReset.h"
#undef ROSTER #undef ROSTER
#define ROSTER(cabid,name,funcmap...) +1 #define ROSTER(cabid,name,funcmap...) +1
const byte RMFT2::rosterNameCount=0 const byte RMFT2::rosterNameCount=0
#include "myAutomation.h" #include "myAutomation.h"
; ;
// Pass 6: Roster names emitter // Pass 6: Roster IDs
#include "EXRAIL2MacroReset.h" #include "EXRAIL2MacroReset.h"
#undef ROSTER #undef ROSTER
#define ROSTER(cabid,name,funcmap...) StringFormatter::send(stream,(FSH *)format,F(name),cabid,cabid<128?'S':'L'); #define ROSTER(cabid,name,funcmap...) cabid,
void RMFT2::emitWithrottleRoster(Print * stream) { const int16_t FLASH RMFT2::rosterIdList[]={
static const char format[] FLASH ="]\\[%S}|{%d}|{%c";
(void)format;
StringFormatter::send(stream,F("RL%d"), rosterNameCount);
#include "myAutomation.h" #include "myAutomation.h"
stream->write('\n'); 0};
}
// Pass 7: functions getter // Pass 7: Roster names getter
#include "EXRAIL2MacroReset.h" #include "EXRAIL2MacroReset.h"
#undef ROSTER #undef ROSTER
#define ROSTER(cabid,name,funcmap...) case cabid: return F("" funcmap); #define ROSTER(cabid,name,funcmap...) case cabid: return F(name);
const FSH * RMFT2::getRosterFunctions(int16_t cabid) { const FSH * RMFT2::getRosterName(int16_t id) {
switch(cabid) { switch(id) {
#include "myAutomation.h" #include "myAutomation.h"
default: return NULL; default: return NULL;
} }
return NULL;
}
// Pass to get roster functions
#undef ROSTER
#define ROSTER(cabid,name,funcmap...) O_DESC(cabid,funcmap)
const FSH * RMFT2::getRosterFunctions(int16_t id) {
switch(id) {
#include "myAutomation.h"
default: break;
}
return NULL;
} }
// Pass 8 Signal definitions // Pass 8 Signal definitions

View File

@ -120,13 +120,15 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
StringFormatter::send(stream,F("PTL")); StringFormatter::send(stream,F("PTL"));
for(Turnout *tt=Turnout::first();tt!=NULL;tt=tt->next()){ for(Turnout *tt=Turnout::first();tt!=NULL;tt=tt->next()){
int id=tt->getId(); int id=tt->getId();
StringFormatter::send(stream,F("]\\[%d}|{"), id); const FSH * tdesc=NULL;
#ifdef EXRAIL_ACTIVE #ifdef EXRAIL_ACTIVE
RMFT2::emitTurnoutDescription(stream,id); tdesc=RMFT2::getTurnoutDescription(id);
#else #endif
StringFormatter::send(stream,F("%d"), id); char tchar=Turnout::isClosed(id)?'2':'4';
#endif if (tdesc==NULL) // turnout with no description
StringFormatter::send(stream,F("}|{%c"), Turnout::isClosed(id)?'2':'4'); StringFormatter::send(stream,F("]\\[%d}|{T%d}|{T%c"), id,id,tchar);
else if (GETFLASH(tdesc)!='*') // ignore hidden turnouts
StringFormatter::send(stream,F("]\\[%d}|{%S}|{%c"), id,tdesc,tchar);
} }
StringFormatter::send(stream,F("\n")); StringFormatter::send(stream,F("\n"));
turnoutListHash = Turnout::turnoutlistHash; // keep a copy of hash for later comparison turnoutListHash = Turnout::turnoutlistHash; // keep a copy of hash for later comparison
@ -136,7 +138,17 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
// Send EX-RAIL routes list if not already sent (but not at same time as turnouts above) // Send EX-RAIL routes list if not already sent (but not at same time as turnouts above)
exRailSent=true; exRailSent=true;
#ifdef EXRAIL_ACTIVE #ifdef EXRAIL_ACTIVE
RMFT2::emitWithrottleRouteList(stream); StringFormatter::send(stream,F("PRT]\\[Routes}|{Route]\\[Set}|{2]\\[Handoff}|{4\nPRL"));
for (int ix=0;;ix+=2) {
int16_t id=GETFLASHW(RMFT2::routeIdList+ix);
if (id==0) break;
bool isRoute=id<0;
if (isRoute) id=-id;
const FSH * desc=RMFT2::getRouteDescription(id);
StringFormatter::send(stream,F("]\\[%c%d}|{%S}|{%c"),
isRoute?'R':'A',id,desc, isRoute?'2':'4');
}
StringFormatter::send(stream,F("\n"));
#endif #endif
// allow heartbeat to slow down once all metadata sent // allow heartbeat to slow down once all metadata sent
StringFormatter::send(stream,F("*%d\n"),HEARTBEAT_SECONDS); StringFormatter::send(stream,F("*%d\n"),HEARTBEAT_SECONDS);
@ -205,9 +217,19 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
StringFormatter::send(stream,F("HtDCC-EX v%S, %S, %S, %S\n"), F(VERSION), F(ARDUINO_TYPE), DCC::getMotorShieldName(), F(GITHUB_SHA)); StringFormatter::send(stream,F("HtDCC-EX v%S, %S, %S, %S\n"), F(VERSION), F(ARDUINO_TYPE), DCC::getMotorShieldName(), F(GITHUB_SHA));
StringFormatter::send(stream,F("PTT]\\[Turnouts}|{Turnout]\\[THROW}|{2]\\[CLOSE}|{4\n")); StringFormatter::send(stream,F("PTT]\\[Turnouts}|{Turnout]\\[THROW}|{2]\\[CLOSE}|{4\n"));
StringFormatter::send(stream,F("PPA%x\n"),DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON); StringFormatter::send(stream,F("PPA%x\n"),DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON);
// Send the roster
#ifdef EXRAIL_ACTIVE #ifdef EXRAIL_ACTIVE
RMFT2::emitWithrottleRoster(stream); StringFormatter::send(stream,F("RL%d"), RMFT2::rosterNameCount);
for (int16_t r=0;r<RMFT2::rosterNameCount;r++) {
int16_t cabid=GETFLASHW(RMFT2::rosterIdList+r);
StringFormatter::send(stream,F("]\\[%S}|{%d}|{%c"),
RMFT2::getRosterName(cabid),cabid,cabid<128?'S':'L');
}
stream->write('\n'); // end roster
#endif #endif
// set heartbeat to 1 second because we need to sync the metadata // set heartbeat to 1 second because we need to sync the metadata
StringFormatter::send(stream,F("*1\n")); StringFormatter::send(stream,F("*1\n"));
initSent = true; initSent = true;