-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDeviceStore.cpp
More file actions
144 lines (120 loc) · 3.82 KB
/
Copy pathDeviceStore.cpp
File metadata and controls
144 lines (120 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include "DeviceStore.h"
#include <ArduinoJson.h>
#include <LittleFS.h>
#include <algorithm>
#include <set>
#include "Config.h"
namespace {
std::vector<RegisteredDevice> g_devices;
int indexOfMac(const String &mac) {
for (size_t i = 0; i < g_devices.size(); i++) {
if (g_devices[i].mac.equalsIgnoreCase(mac)) return int(i);
}
return -1;
}
void load() {
g_devices.clear();
if (!LittleFS.exists(DEVICES_JSON_PATH)) return;
File f = LittleFS.open(DEVICES_JSON_PATH, "r");
if (!f) return;
JsonDocument doc;
DeserializationError err = deserializeJson(doc, f);
f.close();
if (err) {
Serial.printf("DeviceStore: failed to parse %s: %s\n", DEVICES_JSON_PATH, err.c_str());
return;
}
for (JsonObject o : doc["devices"].as<JsonArray>()) {
RegisteredDevice d;
d.mac = o["mac"].as<const char *>();
d.name = o["name"].as<const char *>();
d.model = o["model"].as<const char *>();
for (JsonVariant t : o["tags"].as<JsonArray>()) {
d.tags.push_back(String(t.as<const char *>()));
}
g_devices.push_back(d);
}
}
} // namespace
namespace DeviceStore {
void begin() {
// LittleFS.begin()が既定で探すパーティション名は "spiffs" です
// (ファイルシステムの種類とは関係のない、arduino-esp32の古い既定値)。
// このプロジェクトのpartitions.csvは中身に合わせて "littlefs" と名付けて
// いるので、名前を明示しないとマウント先を見つけられません。
if (!LittleFS.begin(true, "/littlefs", 10, "littlefs")) { // trueはマウント失敗時に初期化する指定
Serial.println("DeviceStore: LittleFS mount failed");
return;
}
load();
}
const std::vector<RegisteredDevice> &devices() { return g_devices; }
bool isRegistered(const String &mac) { return indexOfMac(mac) >= 0; }
bool addDevice(const String &mac, const String &name, const String &model) {
if (isRegistered(mac)) return false;
if (g_devices.size() >= MAX_REGISTERED_DEVICES) return false;
RegisteredDevice d;
d.mac = mac;
d.name = name;
d.model = model;
g_devices.push_back(d);
return save();
}
bool removeDevice(const String &mac) {
int idx = indexOfMac(mac);
if (idx < 0) return false;
g_devices.erase(g_devices.begin() + idx);
return save();
}
bool renameDevice(const String &mac, const String &newName) {
int idx = indexOfMac(mac);
if (idx < 0) return false;
g_devices[idx].name = newName;
return save();
}
bool setTags(const String &mac, const std::vector<String> &tags) {
int idx = indexOfMac(mac);
if (idx < 0) return false;
g_devices[idx].tags = tags;
return save();
}
bool reorder(const std::vector<String> &macOrder) {
if (macOrder.size() != g_devices.size()) return false;
std::vector<RegisteredDevice> reordered;
reordered.reserve(g_devices.size());
for (const String &mac : macOrder) {
int idx = indexOfMac(mac);
if (idx < 0) return false; // 登録済みの集合と一致しないので受け付けません
reordered.push_back(g_devices[idx]);
}
g_devices = reordered;
return save();
}
std::vector<String> allTags() {
std::set<String> unique;
for (const auto &d : g_devices) {
for (const auto &t : d.tags) unique.insert(t);
}
return std::vector<String>(unique.begin(), unique.end());
}
bool save() {
JsonDocument doc;
JsonArray arr = doc["devices"].to<JsonArray>();
for (const auto &d : g_devices) {
JsonObject o = arr.add<JsonObject>();
o["mac"] = d.mac;
o["name"] = d.name;
o["model"] = d.model;
JsonArray tagsArr = o["tags"].to<JsonArray>();
for (const auto &t : d.tags) tagsArr.add(t);
}
File f = LittleFS.open(DEVICES_JSON_PATH, "w");
if (!f) {
Serial.println("DeviceStore: failed to open devices.json for writing");
return false;
}
serializeJson(doc, f);
f.close();
return true;
}
} // namespace DeviceStore