Added possibility to xfer tag-side config options

This commit is contained in:
Jelmer
2023-06-15 13:18:12 +02:00
parent 054146677f
commit 94be1ea3aa
8 changed files with 206 additions and 6 deletions

View File

@@ -406,5 +406,132 @@
"type": "text"
}
]
},
{
"id": 17,
"name": "Send Command",
"desc": "Send a command to a tag to execute",
"hwtype": [
0,
1,
2,
17,
240
],
"param": [
{
"key": "cmd",
"name": "CMD",
"desc": "Action",
"type": "select",
"options": {
"0": "Reboot",
"1": "Scan Channels",
"2": "Clear settings"
}
}
]
},
{
"id": 18,
"name": "Set Tag Config",
"desc": "Sets tag options. The options you see below are the default options. This may or may not match current tag settings",
"hwtype": [
0,
1,
2,
17,
240
],
"param": [
{
"key": "fastboot",
"name": "Boot method",
"desc": "How the tag should boot, fast or normal",
"type": "select",
"options": {
"0": "-Normal boot",
"1": "Fast boot"
}
},
{
"key": "rfwake",
"name": "RF Wake",
"desc": "If the tag should support RF wake or not. This adds a 0.9µA current draw",
"type": "select",
"options": {
"0": "-Disabled",
"1": "Enabled"
}
},
{
"key": "tagroaming",
"name": "Tag Roaming",
"desc": "If enabled, the tag will periodically scan for AP's and will switch to a different channel if a stronger signal is found",
"type": "select",
"options": {
"0": "-Disabled",
"1": "Enabled"
}
},
{
"key": "tagscanontimeout",
"name": "Scan for AP on timeout",
"desc": "If a tag hasn't found an AP for an hour, should it rescan the channels for another AP?",
"type": "select",
"options": {
"1": "-Enabled",
"0": "Disabled"
}
},
{
"key": "showlowbat",
"name": "Low Battery symbol",
"desc": "Should the tag display the 'low battery' symbol if the battery a voltage threshold has been reached?",
"type": "select",
"options": {
"1": "-Enabled",
"0": "Disabled"
}
},
{
"key": "shownorf",
"name": "No AP symbol",
"desc": "Should the tag display the 'No-signal/AP' symbol if it hasn't been able to contact an AP?",
"type": "select",
"options": {
"1": "-Enabled",
"0": "Disabled"
}
},
{
"key": "lowvoltage",
"name": "Low voltage threshold",
"desc": "Below what voltage should the tag display the 'low bat' symbol?",
"type": "select",
"options": {
"2600": "-2.6v",
"2500": "2.5v",
"2400": "2.4v",
"2300": "2.3v",
"2200": "2.2v"
}
},
{
"key": "fixedchannel",
"name": "Fixed Channel",
"desc": "What channel should the tag initially join?",
"type": "select",
"options": {
"0": "-Auto",
"11": "11",
"15": "15",
"20": "20",
"25": "25",
"26": "26",
"27": "27"
}
}
]
}
]

View File

@@ -24,13 +24,13 @@ const apstate = [
{ state: "requires power cycle", color: "purple" },
{ state: "failed", color: "red" },
{ state: "coming online", color: "yellow" }
];
];
const runstate = [
{ state: "⏹︎ stopped" },
{ state: "⏸pause" },
{ state: "" }, // hide running
{ state: "⏳︎ init" }
];
];
const imageQueue = [];
let isProcessing = false;
@@ -48,7 +48,7 @@ window.addEventListener("load", function () {
this.document.title = data.alias;
}
});
fetch('/content_cards.json')
fetch('/content_cards.json')
.then(response => response.json())
.then(data => {
cardconfig = data;
@@ -307,7 +307,7 @@ $('#taglist').addEventListener("click", (event) => {
$('#cfgalias').value = tagdata.alias;
$('#cfgmore').style.display = "none";
if (populateSelectTag(tagdata.hwType, tagdata.capabilities)) {
$('#cfgcontent').parentNode.style.display = "flex";
$('#cfgcontent').parentNode.style.display = "flex";
$('#cfgcontent').value = tagdata.contentMode;
$('#cfgcontent').dataset.json = tagdata.modecfgjson;
contentselected();
@@ -354,7 +354,7 @@ $('#cfgsave').onclick = function () {
formData.append("rotate", $('#cfgrotate').value);
formData.append("lut", $('#cfglut').value);
fetch("/save_cfg", {
method: "POST",
body: formData
@@ -530,6 +530,12 @@ function contentselected() {
const optionElement = document.createElement("option");
optionElement.value = key;
optionElement.text = element.options[key];
if (element.options[key].substring(0,1)=="-") {
optionElement.text = element.options[key].substring(1);
optionElement.selected = true;
} else {
optionElement.selected = false;
}
input.appendChild(optionElement);
}
break;

View File

@@ -107,4 +107,19 @@ struct TagInfo {
uint8_t contentMode;
} __packed;
struct tagsettings {
uint8_t settingsVer; // the version of the struct as written to the infopage
uint8_t enableFastBoot; // default 0; if set, it will skip splashscreen
uint8_t enableRFWake; // default 0; if set, it will enable RF wake. This will add about ~0.9µA idle power consumption
uint8_t enableTagRoaming; // default 0; if set, the tag will scan for an accesspoint every few check-ins. This will increase power consumption quite a bit
uint8_t enableScanForAPAfterTimeout; // default 1; if a the tag failed to check in, after a few attempts it will try to find a an AP on other channels
uint8_t enableLowBatSymbol; // default 1; tag will show 'low battery' icon on screen if the battery is depleted
uint8_t enableNoRFSymbol; // default 1; tag will show 'no signal' icon on screen if it failed to check in for a longer period of time
uint8_t fastBootCapabilities; // holds the byte with 'capabilities' as detected during a normal tag boot; allows the tag to skip detecting buttons and NFC chip
uint8_t customMode; // default 0; if anything else, tag will bootup in a different 'mode'
uint16_t batLowVoltage; // Low battery threshold voltage (2450 for 2.45v). defaults to BATTERY_VOLTAGE_MINIMUM from powermgt.h
uint16_t minimumCheckInTime; // defaults to BASE_INTERVAL from powermgt.h
uint8_t fixedChannel; // default 0; if set to a valid channel number, the tag will stick to that channel
} __packed;
#pragma pack(pop)

View File

@@ -37,5 +37,6 @@ String windDirectionIcon(int degrees);
void getLocation(JsonObject &cfgobj);
void prepareNFCReq(uint8_t* dst, const char* url);
void prepareLUTreq(uint8_t *dst, String input);
void prepareConfigFile(uint8_t *dst, JsonObject config);
void getTemplate(JsonDocument &json, const char *filePath, uint8_t id, uint8_t hwtype);
void setU8G2Font(const String &title, U8g2_for_TFT_eSPI &u8f);

View File

@@ -12,6 +12,7 @@ extern void processXferComplete(struct espXferComplete* xfc, bool local);
extern void processXferTimeout(struct espXferComplete* xfc, bool local);
extern void processDataReq(struct espAvailDataReq* adr, bool local);
extern bool sendTagCommand(uint8_t* dst, uint8_t cmd, bool local);
extern bool sendAPSegmentedData(uint8_t* dst, String data, uint16_t icons, bool inverted, bool local);
extern bool showAPSegmentedInfo(uint8_t* dst, bool local);
extern void updateTaginfoitem(struct TagInfo* taginfoitem);

View File

@@ -286,6 +286,19 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
taginfo->nextupdate = now + (cfgobj["ttl"].as<int>() < 5 ? 5 : cfgobj["ttl"].as<int>()) * 60;
updateTagImage(filename, mac, (cfgobj["ttl"].as<int>() < 5 ? 5 : cfgobj["ttl"].as<int>()), taginfo, imageParams);
break;
case 17: // tag command
sendTagCommand(mac, cfgobj["cmd"].as<int>(), (taginfo->isExternal == false));
cfgobj["filename"] = "";
taginfo->nextupdate = 3216153600;
taginfo->contentMode = Image;
break;
case 18:
prepareConfigFile(mac, cfgobj);
cfgobj["filename"] = "";
taginfo->nextupdate = 3216153600;
taginfo->contentMode = Image;
break;
}
taginfo->modeConfigJson = doc.as<String>();
@@ -1000,6 +1013,23 @@ void prepareLUTreq(uint8_t *dst, String input) {
prepareDataAvail(waveform, waveformLen, DATATYPE_CUSTOM_LUT_OTA, dst);
}
void prepareConfigFile(uint8_t *dst, JsonObject config) {
struct tagsettings tagSettings;
tagSettings.settingsVer = 1;
tagSettings.enableFastBoot = config["fastboot"].as<int>();
tagSettings.enableRFWake = config["rfwake"].as<int>();
tagSettings.enableTagRoaming = config["tagroaming"].as<int>();
tagSettings.enableScanForAPAfterTimeout = config["tagscanontimeout"].as<int>();
tagSettings.enableLowBatSymbol = config["showlowbat"].as<int>();
tagSettings.enableNoRFSymbol = config["shownorf"].as<int>();
tagSettings.customMode = 0;
tagSettings.fastBootCapabilities = 0;
tagSettings.minimumCheckInTime = 1;
tagSettings.fixedChannel = config["fixedchannel"].as<int>();
tagSettings.batLowVoltage = config["lowvoltage"].as<int>();
prepareDataAvail((uint8_t *)&tagSettings, sizeof(tagSettings), 0xA8, dst);
}
void getTemplate(JsonDocument &json, const char *filePath, uint8_t id, uint8_t hwtype) {
File jsonFile = LittleFS.open(filePath, "r");
if (!jsonFile) {

View File

@@ -587,6 +587,26 @@ bool showAPSegmentedInfo(uint8_t* dst, bool local) {
}
}
bool sendTagCommand(uint8_t* dst, uint8_t cmd, bool local) {
struct pendingData pending = {0};
memcpy(pending.targetMac, dst, 8);
pending.availdatainfo.dataType = 0xAF;
pending.availdatainfo.dataTypeArgument = cmd;
pending.availdatainfo.nextCheckIn = 0;
pending.attemptsLeft = 120;
char buffer[64];
sprintf(buffer, ">Tag CMD %02X%02X%02X%02X%02X%02X%02X%02X\n\0", dst[7], dst[6], dst[5], dst[4], dst[3], dst[2], dst[1], dst[0]);
Serial.print(buffer);
if (local) {
return sendDataAvail(&pending);
} else {
udpsync.netSendDataAvail(&pending);
return true;
}
}
void updateTaginfoitem(struct TagInfo* taginfoitem) {
tagRecord* taginfo = nullptr;
taginfo = tagRecord::findByMAC(taginfoitem->mac);

View File

@@ -606,7 +606,7 @@ bool bringAPOnline() {
}
void APTask(void* parameter) {
xTaskCreate(rxCmdProcessor, "rxCmdProcessor", 3000, NULL, configMAX_PRIORITIES - 10, NULL);
xTaskCreate(rxCmdProcessor, "rxCmdProcessor", 4000, NULL, configMAX_PRIORITIES - 10, NULL);
xTaskCreate(rxSerialTask, "rxSerialTask", 1750, NULL, configMAX_PRIORITIES - 4, NULL);
#if (AP_PROCESS_PORT == FLASHER_AP_PORT)