280 lines
9.4 KiB
C++
280 lines
9.4 KiB
C++
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
|
|
|
#include "Pagedata.h"
|
|
#include "OBP60Extensions.h"
|
|
#include "GwXDRMappings.h"
|
|
|
|
/*
|
|
Fluid level view
|
|
|
|
0: "Fuel",
|
|
1: "Water",
|
|
2: "Gray Water",
|
|
3: "Live Well",
|
|
4: "Oil",
|
|
5: "Black Water",
|
|
6: "Fuel Gasoline",
|
|
14: "Error",
|
|
15: "Unavailable"
|
|
|
|
TODO
|
|
- Check fluid type against connected XDR-value
|
|
|
|
*/
|
|
|
|
#define fuel_width 16
|
|
#define fuel_height 16
|
|
static unsigned char fuel_bits[] = {
|
|
0xfc, 0x03, 0xfe, 0x67, 0x06, 0x86, 0x06, 0x86, 0x06, 0xe6, 0x06, 0xe6,
|
|
0x06, 0xe6, 0x06, 0xe6, 0xfe, 0x47, 0xfe, 0x47, 0xfe, 0x4f, 0xfe, 0x57,
|
|
0xfe, 0x57, 0xfe, 0x77, 0xfe, 0x07, 0xff, 0x0f };
|
|
|
|
#define water_width 16
|
|
#define water_height 16
|
|
static unsigned char water_bits[] = {
|
|
0x00, 0x00, 0x80, 0x01, 0xfc, 0x3f, 0xfc, 0x3f, 0x80, 0x01, 0xc0, 0x03,
|
|
0xc0, 0xc3, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc7,
|
|
0x87, 0x01, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00 };
|
|
|
|
#define waste_width 16
|
|
#define waste_height 16
|
|
static unsigned char waste_bits[] = {
|
|
0xf0, 0x00, 0x9f, 0x00, 0x80, 0x07, 0x80, 0x08, 0x80, 0x10, 0x9f, 0x23,
|
|
0xf0, 0x24, 0x00, 0x64, 0x10, 0x25, 0x40, 0xa4, 0x08, 0x66, 0xff, 0xff,
|
|
0x00, 0x00, 0xbc, 0x6e, 0x00, 0x00, 0xf0, 0x19 };
|
|
|
|
#define oil_width 16
|
|
#define oil_height 16
|
|
static unsigned char oil_bits[] = {
|
|
0x00, 0x01, 0x00, 0x01, 0x80, 0x03, 0xc0, 0x07, 0xc0, 0x07, 0xe0, 0x0f,
|
|
0xe0, 0x0f, 0xf0, 0x1f, 0xf0, 0x1f, 0xf8, 0x3f, 0xd8, 0x3f, 0xd8, 0x3f,
|
|
0xb8, 0x3f, 0x70, 0x1e, 0xe0, 0x0f, 0xc0, 0x07 };
|
|
|
|
#define gasoline_width 16
|
|
#define gasoline_height 16
|
|
static unsigned char gasoline_bits[] = {
|
|
0x0f, 0x00, 0xdf, 0x7f, 0xf8, 0xff, 0x70, 0xe0, 0xf8, 0xff, 0xf8, 0xff,
|
|
0x98, 0xcf, 0x38, 0xe7, 0x78, 0xf0, 0xf8, 0xfa, 0xf8, 0xfa, 0x78, 0xf0,
|
|
0x38, 0xe7, 0x98, 0xcf, 0xf8, 0xff, 0xf0, 0x7f };
|
|
|
|
#define fish_width 16
|
|
#define fish_height 16
|
|
static unsigned char fish_bits[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xf0, 0x03, 0xf8, 0x37,
|
|
0xfc, 0x7f, 0xfc, 0x7f, 0xec, 0x3f, 0xfc, 0x7f, 0xfc, 0x7f, 0xf8, 0x37,
|
|
0xf0, 0x03, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00 };
|
|
|
|
class PageFluid : public Page
|
|
{
|
|
bool simulation = false;
|
|
double simgoto;
|
|
double simval;
|
|
double simstep;
|
|
bool holdvalues = false;
|
|
int fluidtype;
|
|
|
|
public:
|
|
PageFluid(CommonData &common){
|
|
commonData = &common;
|
|
common.logger->logDebug(GwLog::LOG,"Instantiate PageFluid");
|
|
simulation = common.config->getBool(common.config->useSimuData);
|
|
holdvalues = common.config->getBool(common.config->holdvalues);
|
|
simval = double(random(0, 100));
|
|
simgoto = double(random(0, 100));
|
|
simstep = (simgoto - simval) / 20.0;
|
|
}
|
|
|
|
virtual int handleKey(int key){
|
|
// Code for keylock
|
|
if(key == 11){
|
|
commonData->keylock = !commonData->keylock;
|
|
return 0; // Commit the key
|
|
}
|
|
return key;
|
|
}
|
|
|
|
virtual void displayNew(PageData &pageData){
|
|
fluidtype = commonData->config->getInt("page" + String(pageData.pageNumber) + "fluid", 0);
|
|
commonData->logger->logDebug(GwLog::LOG,"New PageFluid: fluidtype=%d", fluidtype);
|
|
}
|
|
|
|
virtual void displayPage(PageData &pageData){
|
|
GwConfigHandler *config = commonData->config;
|
|
GwLog *logger = commonData->logger;
|
|
|
|
// Old values for hold function
|
|
static double value1old;
|
|
|
|
// Get config data
|
|
String flashLED = config->getString(config->flashLED);
|
|
String backlightMode = config->getString(config->backlight);
|
|
|
|
// Optical warning by limit violation (unused)
|
|
if(String(flashLED) == "Limit Violation"){
|
|
setBlinkingLED(false);
|
|
setFlashLED(false);
|
|
}
|
|
|
|
GwApi::BoatValue *bvalue1 = pageData.values[0];
|
|
String name1 = bvalue1->getName();
|
|
double fluidlevel = bvalue1->value;
|
|
if (!simulation) {
|
|
if (holdvalues and bvalue1->valid) {
|
|
value1old = bvalue1->value;
|
|
}
|
|
} else {
|
|
fluidlevel = simval;
|
|
simval += simstep;
|
|
if ((simgoto - simval) < 1.5 * simstep) {
|
|
simgoto = double(random(0, 100));
|
|
simstep = (simgoto - simval) / 20.0;
|
|
}
|
|
}
|
|
|
|
// Logging boat values
|
|
LOG_DEBUG(GwLog::LOG,"Drawing at PageFluid: value=%f", bvalue1->value);
|
|
|
|
// Draw page
|
|
//***********************************************************
|
|
|
|
// Set display in partial refresh mode
|
|
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height());
|
|
|
|
getdisplay().setTextColor(commonData->fgcolor);
|
|
|
|
// descriptions
|
|
getdisplay().setFont(&Ubuntu_Bold12pt7b);
|
|
getdisplay().setCursor(20, 60);
|
|
getdisplay().print("Fluid");
|
|
|
|
getdisplay().setCursor(300, 60);
|
|
getdisplay().print(xdrDelete(name1).substring(0, 6));
|
|
|
|
// analog instrument
|
|
// scale from -120 to 120
|
|
|
|
// center
|
|
Point c = {200, 150};
|
|
uint8_t r = 110;
|
|
|
|
// circular frame
|
|
getdisplay().drawCircle(c.x, c.y, r+5, commonData->fgcolor);
|
|
getdisplay().fillCircle(c.x, c.y, r+2, commonData->fgcolor);
|
|
getdisplay().fillCircle(c.x, c.y, r-1, commonData->bgcolor);
|
|
// center of pointer as dot
|
|
getdisplay().fillCircle(c.x, c.y, 8, commonData->fgcolor);
|
|
|
|
// value down centered
|
|
char buffer[6];
|
|
if (bvalue1->valid or simulation) {
|
|
snprintf(buffer, 6, "%3.0f%%", fluidlevel);
|
|
} else {
|
|
strcpy(buffer, "---");
|
|
}
|
|
drawTextCenter(c.x, c.y + r - 20, String(buffer));
|
|
|
|
// draw symbol (as bitmap)
|
|
switch (fluidtype) {
|
|
case 0:
|
|
getdisplay().drawXBitmap(c.x-8, c.y-50, fuel_bits, fuel_width, fuel_height, commonData->fgcolor);
|
|
break;
|
|
case 1:
|
|
getdisplay().drawXBitmap(c.x-8, c.y-50, water_bits, water_width, water_height, commonData->fgcolor);
|
|
break;
|
|
case 2: // gray water no symbol yet
|
|
// getdisplay().drawXBitmap(c.x-8, c.y-50, gray_bits, gray_width, gray_height, commonData->fgcolor);
|
|
break;
|
|
case 3:
|
|
getdisplay().drawXBitmap(c.x-8, c.y-50, fish_bits, fish_width, fish_height, commonData->fgcolor);
|
|
break;
|
|
case 4:
|
|
getdisplay().drawXBitmap(c.x-8, c.y-50, oil_bits, oil_width, oil_height, commonData->fgcolor);
|
|
break;
|
|
case 5:
|
|
getdisplay().drawXBitmap(c.x-8, c.y-50, waste_bits, waste_width, waste_height, commonData->fgcolor);
|
|
break;
|
|
case 6:
|
|
getdisplay().drawXBitmap(c.x-8, c.y-50, gasoline_bits, gasoline_width, gasoline_height, commonData->fgcolor);
|
|
break;
|
|
}
|
|
|
|
Point p, pr;
|
|
|
|
// scale texts
|
|
getdisplay().setFont(&Ubuntu_Bold8pt7b);
|
|
p = {c.x, c.y - r + 30};
|
|
drawTextCenter(p.x, p.y, "1/2");
|
|
pr = rotatePoint(c, p, -60);
|
|
drawTextCenter(pr.x, pr.y, "1/4");
|
|
pr = rotatePoint(c, p, 60);
|
|
drawTextCenter(pr.x, pr.y, "3/4");
|
|
|
|
// empty and full
|
|
getdisplay().setFont(&Ubuntu_Bold12pt7b);
|
|
p = rotatePoint(c, {c.x, c.y - r + 30}, -130);
|
|
drawTextCenter(p.x, p.y, "E");
|
|
p = rotatePoint(c, {c.x, c.y - r + 30}, 130);
|
|
drawTextCenter(p.x, p.y, "F");
|
|
|
|
// lines
|
|
std::vector<Point> pts = {
|
|
{c.x - 2, c.y - r},
|
|
{c.x + 2, c.y - r},
|
|
{c.x + 2, c.y - (r - 16)},
|
|
{c.x - 2, c.y - (r - 16)}
|
|
};
|
|
fillPoly4(rotatePoints(c, pts, -120), commonData->fgcolor);
|
|
fillPoly4(rotatePoints(c, pts, -60), commonData->fgcolor);
|
|
fillPoly4(rotatePoints(c, pts, 0), commonData->fgcolor);
|
|
fillPoly4(rotatePoints(c, pts, 60), commonData->fgcolor);
|
|
fillPoly4(rotatePoints(c, pts, 120), commonData->fgcolor);
|
|
|
|
// dots
|
|
// rotate 0 to 360 in 12 degree steps
|
|
for (int angle = -120; angle < 120; angle += 12) {
|
|
if (angle == -120 or angle == -60 or angle == 0 or angle == 60) {
|
|
continue;
|
|
}
|
|
p = rotatePoint(c, {c.x, c.y - r + 10}, angle);
|
|
getdisplay().fillCircle(p.x, p.y, 3, commonData->fgcolor);
|
|
}
|
|
|
|
// pointer
|
|
if (bvalue1->valid or simulation) {
|
|
pts = {
|
|
{c.x - 1, c.y - (r - 20)},
|
|
{c.x + 1, c.y - (r - 20)},
|
|
{c.x + 6, c.y + 15},
|
|
{c.x - 6, c.y + 15}
|
|
};
|
|
fillPoly4(rotatePoints(c, pts, -120 + fluidlevel * 2.4), commonData->fgcolor);
|
|
// Pointer axis is white
|
|
getdisplay().fillCircle(c.x, c.y, 6, commonData->bgcolor);
|
|
}
|
|
|
|
// Update display
|
|
getdisplay().nextPage(); // Partial update (fast)
|
|
|
|
};
|
|
};
|
|
|
|
static Page* createPage(CommonData &common){
|
|
return new PageFluid(common);
|
|
}
|
|
|
|
/**
|
|
* with the code below we make this page known to the PageTask
|
|
* we give it a type (name) that can be selected in the config
|
|
* we define which function is to be called
|
|
* and we provide the number of user parameters we expect
|
|
* this will be number of BoatValue pointers in pageData.values
|
|
*/
|
|
PageDescription registerPageFluid(
|
|
"Fluid", // Page name
|
|
createPage, // Action
|
|
1, // Number of bus values depends on selection in Web configuration
|
|
true // Show display header on/off
|
|
);
|
|
|
|
#endif
|