first commit
This commit is contained in:
5
ESP01-IMAS/.gitignore
vendored
Normal file
5
ESP01-IMAS/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
10
ESP01-IMAS/.vscode/extensions.json
vendored
Normal file
10
ESP01-IMAS/.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
39
ESP01-IMAS/include/README
Normal file
39
ESP01-IMAS/include/README
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
46
ESP01-IMAS/lib/README
Normal file
46
ESP01-IMAS/lib/README
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
15
ESP01-IMAS/platformio.ini
Normal file
15
ESP01-IMAS/platformio.ini
Normal file
@ -0,0 +1,15 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:esp12e]
|
||||
platform = espressif8266
|
||||
board = esp12e
|
||||
framework = arduino
|
||||
lib_deps = bblanchon/ArduinoJson@^7.2.1
|
124
ESP01-IMAS/src/main.cpp
Normal file
124
ESP01-IMAS/src/main.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
// Wi-Fi 连接信息
|
||||
const char *ssid = "Xiaomi_3A40";
|
||||
const char *password = "112233ww";
|
||||
|
||||
// 服务器信息
|
||||
const char *serverIP = "192.168.31.184"; // 服务器 IP 地址
|
||||
const int serverPort = 80; // 端口号
|
||||
const char *requestPath = "/ESP01/getData.php"; // 请求路径
|
||||
|
||||
#define Sleep_Pin 2
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
// 连接到 Wi-Fi
|
||||
Serial.print("Connecting to Wi-Fi");
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
delay(1000);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("\nWi-Fi connected!");
|
||||
|
||||
pinMode(Sleep_Pin, OUTPUT);
|
||||
digitalWrite(Sleep_Pin, LOW);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// 确保 Wi-Fi 连接正常
|
||||
if (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
Serial.println("Wi-Fi disconnected, reconnecting...");
|
||||
WiFi.begin(ssid, password);
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
delay(1000);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("\nReconnected to Wi-Fi!");
|
||||
}
|
||||
|
||||
// 创建客户端
|
||||
WiFiClient client;
|
||||
|
||||
if (client.connect(serverIP, serverPort))
|
||||
{
|
||||
Serial.println("Connected to server");
|
||||
|
||||
// 发送 GET 请求
|
||||
client.println(String("GET ") + requestPath + " HTTP/1.1");
|
||||
client.println(String("Host: ") + serverIP);
|
||||
client.println("Connection: close");
|
||||
client.println();
|
||||
|
||||
// 等待响应
|
||||
while (client.connected() || client.available())
|
||||
{
|
||||
if (client.available())
|
||||
{
|
||||
String line = client.readStringUntil('\n');
|
||||
if (line == "\r")
|
||||
{
|
||||
break; // 头部结束
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 读取 JSON 数据
|
||||
String jsonData;
|
||||
while (client.available())
|
||||
{
|
||||
jsonData += client.readString();
|
||||
}
|
||||
|
||||
// 打印获取到的 JSON 数据
|
||||
Serial.println("Received JSON:");
|
||||
Serial.println(jsonData);
|
||||
|
||||
// 解析 JSON 数据
|
||||
StaticJsonDocument<512> doc;
|
||||
DeserializationError error = deserializeJson(doc, jsonData);
|
||||
if (error)
|
||||
{
|
||||
Serial.print("Failed to parse JSON: ");
|
||||
Serial.println(error.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// 提取 JSON 数据
|
||||
if (doc.containsKey("standby"))
|
||||
{
|
||||
String standby = doc["standby"];
|
||||
Serial.print("Standby mode: ");
|
||||
Serial.println(standby);
|
||||
if (standby == "1")
|
||||
{
|
||||
Serial.println("Standby mode");
|
||||
digitalWrite(Sleep_Pin, HIGH); // 打开休眠模式
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Normal mode");
|
||||
digitalWrite(Sleep_Pin, LOW); // 关闭休眠模式
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Key 'standby' not found in JSON data");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Failed to connect to server");
|
||||
}
|
||||
|
||||
// 延时一段时间再发送下一次请求
|
||||
delay(100);
|
||||
}
|
11
ESP01-IMAS/test/README
Normal file
11
ESP01-IMAS/test/README
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
5
STM32-IMAS/.gitignore
vendored
Normal file
5
STM32-IMAS/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
10
STM32-IMAS/.vscode/extensions.json
vendored
Normal file
10
STM32-IMAS/.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
39
STM32-IMAS/include/README
Normal file
39
STM32-IMAS/include/README
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
69
STM32-IMAS/include/weather_icon.h
Normal file
69
STM32-IMAS/include/weather_icon.h
Normal file
@ -0,0 +1,69 @@
|
||||
#define __HEIGHT 64
|
||||
#define __WIDTH 64
|
||||
|
||||
// array size is 40000
|
||||
unsigned char cloudy_icon[__HEIGHT * __WIDTH] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x92, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x97, 0x7b, 0x9b, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x7b, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x97, 0xbf, 0x00, 0x00, 0x00, 0x92, 0x7b, 0x7b, 0x7b, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x97, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x97, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x93, 0x92, 0xff, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0xff, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xbf, 0x77, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x9b, 0x1f, 0x00, 0xff, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x9f, 0x57, 0x97, 0xbf, 0xbf, 0xbf, 0x56, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x57, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x92, 0x92, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x1f, 0x00, 0xb7, 0x97, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x57, 0x00, 0x00, 0x00, 0x1f, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0xbf, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x9b, 0x9b, 0x00, 0xff, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xbf, 0x9b, 0x7b, 0x7b, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x93, 0x00, 0x1f, 0x9b, 0x9f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x9f, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x93, 0x9b, 0x7b, 0x9b, 0x9b, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x9b, 0x9b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x77, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x9b, 0x7b, 0x97, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x57, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x9b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x57, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x77, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x57, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x9b, 0x7b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x7b, 0x9b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x9b, 0x9b, 0x9b, 0x7b, 0x7b, 0x9b, 0x7b, 0x7b, 0x7b, 0x9b, 0x9b, 0x9b, 0x7b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x7b, 0x9b, 0x9b, 0x7b, 0x7b, 0x9b, 0x7b, 0x9b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x96, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x9f, 0x57, 0x56, 0x56, 0x57, 0x57, 0x57, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x96, 0xbf, 0x57, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
46
STM32-IMAS/lib/README
Normal file
46
STM32-IMAS/lib/README
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
23
STM32-IMAS/platformio.ini
Normal file
23
STM32-IMAS/platformio.ini
Normal file
@ -0,0 +1,23 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:genericSTM32F103RC]
|
||||
platform = ststm32
|
||||
board = genericSTM32F103RC
|
||||
framework = arduino
|
||||
upload_protocol = serial
|
||||
upload_speed = 500000
|
||||
lib_deps =
|
||||
adafruit/Adafruit Unified Sensor@^1.1.14
|
||||
adafruit/DHT sensor library@^1.4.6
|
||||
bodmer/TFT_eSPI@^2.5.43
|
||||
bblanchon/ArduinoJson@^7.2.1
|
||||
adafruit/Adafruit GFX Library@^1.11.11
|
||||
adafruit/Adafruit SSD1306@^2.5.13
|
340
STM32-IMAS/src/main.cpp
Normal file
340
STM32-IMAS/src/main.cpp
Normal file
@ -0,0 +1,340 @@
|
||||
/*
|
||||
An example digital clock using a TFT LCD screen to show the time.
|
||||
Demonstrates use of the font printing routines. (Time updates but date does not.)
|
||||
|
||||
It uses the time of compile/upload to set the time
|
||||
For a more accurate clock, it would be better to use the RTClib library.
|
||||
But this is just a demo...
|
||||
|
||||
Make sure all the display driver and pin connections are correct by
|
||||
editing the User_Setup.h file in the TFT_eSPI library folder.
|
||||
|
||||
#########################################################################
|
||||
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
|
||||
#########################################################################
|
||||
|
||||
Based on clock sketch by Gilchrist 6/2/2014 1.0
|
||||
|
||||
A few colour codes:
|
||||
|
||||
code color
|
||||
0x0000 Black
|
||||
0xFFFF White
|
||||
0xBDF7 Light Gray
|
||||
0x7BEF Dark Gray
|
||||
0xF800 Red
|
||||
0xFFE0 Yellow
|
||||
0xFBE0 Orange
|
||||
0x79E0 Brown
|
||||
0x7E0 Green
|
||||
0x7FF Cyan
|
||||
0x1F Blue
|
||||
0xF81F Pink
|
||||
|
||||
*/
|
||||
/******************************/
|
||||
// #define TFT_CS PB12
|
||||
// #define TFT_RST PB10
|
||||
// #define TFT_DC PB1
|
||||
|
||||
// #define TFT_MOSI PA7
|
||||
// #define TFT_SCLK PA5
|
||||
// #define TFT_MISO PA6
|
||||
|
||||
// #define TOUCH_CS PB15
|
||||
#include <Arduino.h>
|
||||
#include <TFT_eSPI.h> // TFT 库
|
||||
#include <SPI.h> // SPI 库
|
||||
#include "DHT.h"
|
||||
#include "Wire.h"
|
||||
#include "Adafruit_GFX.h"
|
||||
#include "Adafruit_SSD1306.h"
|
||||
#include "weather_icon.h"
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "ArduinoJson.h"
|
||||
|
||||
|
||||
#define DHTPIN PA1
|
||||
#define DHTTYPE DHT11 // DHT 11
|
||||
|
||||
|
||||
#define MAX_IMAGE_WIDTH 200 // Adjust for your images
|
||||
|
||||
// 定义OLED显示屏的尺寸
|
||||
#define SCREEN_WIDTH 128 // OLED display width, in pixels
|
||||
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
|
||||
|
||||
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
|
||||
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
|
||||
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||||
DHT dht(DHTPIN, DHTTYPE);
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI(); // 创建 TFT 对象
|
||||
|
||||
HardwareSerial serial1(PA10, PA9); // RX, TX
|
||||
HardwareSerial serial2(PA3, PA2); // RX, TX
|
||||
|
||||
char receivedData0[100]; // 用于存储接收到的数据
|
||||
// char receivedData[100]; // 用于存储接收到的数据
|
||||
String receivedData; // 用于存储接收到的数据
|
||||
int dataIndex = 0; // 数据接收指针
|
||||
int braceCount = 0; // 用于跟踪大括号的数量
|
||||
|
||||
String jsonBuffer = ""; // 用于存储接收的 JSON 数据
|
||||
bool isJsonComplete = false; // 标记 JSON 是否完整
|
||||
|
||||
String humidityStr = "";
|
||||
String temperatureStr = "";
|
||||
String fahrenheitStr = "";
|
||||
|
||||
String data = "";
|
||||
|
||||
enum weather{
|
||||
SUNNY = 1,
|
||||
CLOUDY,
|
||||
RAINY,
|
||||
SNOWY,
|
||||
WINDY,
|
||||
FOG,
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
// PNG png; // PNG decoder instance
|
||||
|
||||
// int16_t xpos = 100;
|
||||
// int16_t ypos = 100;
|
||||
|
||||
|
||||
// void pngDraw(PNGDRAW *pDraw);
|
||||
void displayData(const char *data); // 显示接收到的数据
|
||||
void displayLocalData(String data);
|
||||
// void pngDraw(PNGDRAW *pDraw);
|
||||
void serialEvent1();
|
||||
void parseJson();
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
// 初始化I²C
|
||||
Wire.begin();
|
||||
|
||||
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
|
||||
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
|
||||
{
|
||||
Serial.println(F("SSD1306 allocation failed"));
|
||||
for (;;)
|
||||
; // Don't proceed, loop forever
|
||||
}
|
||||
|
||||
// 初始化 TFT 屏幕
|
||||
tft.init();
|
||||
tft.setRotation(2); // 设置屏幕方向
|
||||
tft.fillScreen(TFT_WHITE); // 清屏
|
||||
|
||||
dht.begin(); // 初始化 DHT 传感器
|
||||
serial1.begin(115200);
|
||||
serial2.begin(115200);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
float h = dht.readHumidity();
|
||||
// Read temperature as Celsius (the default)
|
||||
float t = dht.readTemperature();
|
||||
// Read temperature as Fahrenheit (isFahrenheit = true)
|
||||
float f = dht.readTemperature(true);
|
||||
|
||||
// Check if any reads failed and exit early (to try again).
|
||||
if (isnan(h) || isnan(t) || isnan(f))
|
||||
{
|
||||
Serial.println(F("Failed to read from DHT sensor!"));
|
||||
display.clearDisplay(); // 清屏
|
||||
display.setCursor(0, 0);
|
||||
display.setTextColor(SSD1306_WHITE); // Draw white text
|
||||
display.setTextSize(2); // Normal 1:1 pixel scale
|
||||
display.println(F("Failed to read from DHT sensor!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// serialEvent(); // 检查串口数据
|
||||
humidityStr = String(h,2);
|
||||
temperatureStr = String(t,2);
|
||||
fahrenheitStr = String(f,2);
|
||||
|
||||
serial1.print("Humidity: ");
|
||||
serial1.print(humidityStr);
|
||||
serial1.print("%\n");
|
||||
serial1.print("Temperature: ");
|
||||
serial1.print(temperatureStr);
|
||||
serial1.print("C\n");
|
||||
|
||||
serial2.print("Humidity: ");
|
||||
serial2.print(humidityStr);
|
||||
serial2.print("%\n");
|
||||
serial2.print("Temperature: ");
|
||||
serial2.print(temperatureStr);
|
||||
serial2.print("C\n");
|
||||
|
||||
data = "Humidity: " + humidityStr + "%\n" + "Temperature: " + temperatureStr + "C\n" + "Fahrenheit: " + fahrenheitStr + "F\n";
|
||||
|
||||
serial1.print(data); // 打印接收到的数据
|
||||
|
||||
display.clearDisplay(); // Clear display
|
||||
display.setTextSize(1); // Normal 1:1 pixel scale
|
||||
display.setTextColor(SSD1306_WHITE); // Draw white text
|
||||
display.setCursor(0, 0); // Start at top-left corner
|
||||
display.print(F("Temperature: "));
|
||||
display.print(temperatureStr);
|
||||
display.println(F("C"));
|
||||
|
||||
display.display();
|
||||
// displayLocalData(data); // 显示接收到的数据
|
||||
|
||||
// serialEvent1(); // 检查串口数据
|
||||
}
|
||||
|
||||
void serialEvent(){
|
||||
// 检查是否有数据传入
|
||||
if (serial2.available())
|
||||
{
|
||||
// 从串口读取一个字符
|
||||
char incomingByte = serial2.read();
|
||||
serial1.print(incomingByte); // 打印接收到的字符
|
||||
|
||||
// 如果接收到换行符或最大长度限制,则显示数据
|
||||
if (incomingByte == '\n' || dataIndex >= 100)
|
||||
{
|
||||
receivedData0[dataIndex] = '\0'; // 结束字符串
|
||||
displayData(receivedData0); // 显示数据
|
||||
dataIndex = 0; // 重置接收指针
|
||||
}
|
||||
else
|
||||
{
|
||||
receivedData0[dataIndex++] = incomingByte; // 将字符存入缓冲区
|
||||
}
|
||||
}
|
||||
|
||||
// int16_t rc = png.openFLASH((uint8_t *)cloudy_icon, sizeof(cloudy_icon), pngDraw);
|
||||
// if (rc == PNG_SUCCESS)
|
||||
// {
|
||||
// Serial.printf("image specs: (%d x %d), %d bpp, pixel type: %d\n", png.getWidth(), png.getHeight(), png.getBpp(), png.getPixelType());
|
||||
// tft.startWrite();
|
||||
// uint32_t dt = millis();
|
||||
// rc = png.decode(NULL, 0);
|
||||
// Serial.print(millis() - dt);
|
||||
// Serial.println("ms");
|
||||
// tft.endWrite();
|
||||
// // png.close(); // not needed for memory->memory decode
|
||||
// }
|
||||
}
|
||||
|
||||
void displayData(const char *data)
|
||||
{
|
||||
// 清除屏幕内容
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
// 在屏幕上显示接收到的数据
|
||||
tft.setCursor(10, 10); // 设置光标位置
|
||||
tft.setTextSize(2); // 设置文本大小
|
||||
tft.setTextColor(TFT_YELLOW, TFT_BLACK); // 设置文本颜色
|
||||
tft.println("Received Data: ");
|
||||
tft.setCursor(10, 26); // 设置光标位置
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK); // 设置文本颜色
|
||||
tft.setTextSize(3); // 设置文本大小
|
||||
tft.println(data); // 显示接收到的数据
|
||||
// tft.drawRect(10, 26, 300, 100, TFT_BLACK); // 绘制矩形框
|
||||
delay(1000); // 延时 5 秒
|
||||
}
|
||||
|
||||
void displayLocalData(String data)
|
||||
{
|
||||
tft.setFreeFont(NULL); // 选择默认字体
|
||||
// 在屏幕上显示接收到的数据
|
||||
tft.setTextColor(TFT_RED, TFT_WHITE); // 设置文本颜色
|
||||
// tft.drawRect(10, 26, 300, 100, TFT_WHITE); // 绘制矩形框
|
||||
tft.setCursor(10, 0, 1); // 设置光标位置
|
||||
tft.setTextSize(2); // 设置文本大小
|
||||
tft.println(data); //
|
||||
delay(1000); // 延时 5 秒
|
||||
}
|
||||
|
||||
// void pngDraw(PNGDRAW *pDraw)
|
||||
// {
|
||||
// uint16_t lineBuffer[MAX_IMAGE_WIDTH];
|
||||
// png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_BIG_ENDIAN, 0xffffffff);
|
||||
// tft.pushImage(xpos, ypos + pDraw->y, pDraw->iWidth, 1, lineBuffer);
|
||||
// }
|
||||
|
||||
// void serialEvent1()
|
||||
// {
|
||||
// while (serial2.available() > 0)
|
||||
// {
|
||||
// char c = serial2.read(); // 读取单个字符
|
||||
// jsonBuffer += c; // 拼接到缓冲区
|
||||
// // 读取串口数据
|
||||
|
||||
// if (c == '{')
|
||||
// {
|
||||
// braceCount++;
|
||||
// }
|
||||
// if (c == '}')
|
||||
// {
|
||||
// braceCount--;
|
||||
// }
|
||||
// if (braceCount == 0)
|
||||
// {
|
||||
// isJsonComplete = true;
|
||||
// }
|
||||
// }
|
||||
// if (isJsonComplete)
|
||||
// {
|
||||
// serial1.println("Received complete JSON:");
|
||||
// serial1.println(jsonBuffer);
|
||||
// parseJson();
|
||||
// // 处理完 JSON 数据后,清空缓冲区
|
||||
// jsonBuffer = "";
|
||||
// isJsonComplete = false;
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// void parseJson()
|
||||
// {
|
||||
// StaticJsonDocument<512> doc; // 根据你的JSON数据大小调整这个值
|
||||
// DeserializationError error = deserializeJson(doc, jsonBuffer);
|
||||
// if (error)
|
||||
// {
|
||||
// // 如果解析失败,打印错误信息
|
||||
// serial1.printf("deserializeJson() failed: %s\n", error.c_str());
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // 解析成功后,你可以通过doc来访问JSON中的数据
|
||||
// const char *temperature = doc["lives"][0]["temperature"];
|
||||
// const char *humidity = doc["lives"][0]["humidity"];
|
||||
// const char *weather = doc["lives"][0]["weather"];
|
||||
// const char *city = doc["lives"][0]["city"];
|
||||
// // 根据你的JSON结构添加更多的键
|
||||
|
||||
// serial1.printf("temperature: %s\n", temperature);
|
||||
// serial1.printf("humidity: %s\n", humidity);
|
||||
// serial1.printf("weather: %s\n", weather);
|
||||
// serial1.printf("city: %s\n", city);
|
||||
// serial1.println();
|
||||
// // 处理其他键的数据
|
||||
|
||||
// // 你可以在这里将解析得到的数据发送到TFT屏幕或其他处理
|
||||
// tft.setCursor(10, 100, 2);
|
||||
// tft.setTextColor(TFT_BLACK, TFT_WHITE); // 设置文本颜色
|
||||
// tft.setTextSize(1); // 设置文本大小
|
||||
// tft.println("city:" + String(city)); // 显示城市名称
|
||||
// tft.setCursor(10, 120, 2);
|
||||
// tft.println("Temperature: " + String(temperature) + "C");
|
||||
// tft.setCursor(10, 136, 2);
|
||||
// tft.println("Humidity: " + String(humidity) + "%");
|
||||
// tft.setCursor(10, 152, 2);
|
||||
// tft.println("Weather: " + String(weather));
|
||||
// }
|
11
STM32-IMAS/test/README
Normal file
11
STM32-IMAS/test/README
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
5
TFT-ESP32/.gitignore
vendored
Normal file
5
TFT-ESP32/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
10
TFT-ESP32/.vscode/extensions.json
vendored
Normal file
10
TFT-ESP32/.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
BIN
TFT-ESP32/data/san28.bin
Normal file
BIN
TFT-ESP32/data/san28.bin
Normal file
Binary file not shown.
39
TFT-ESP32/include/README
Normal file
39
TFT-ESP32/include/README
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
46
TFT-ESP32/lib/README
Normal file
46
TFT-ESP32/lib/README
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
42
TFT-ESP32/platformio.ini
Normal file
42
TFT-ESP32/platformio.ini
Normal file
@ -0,0 +1,42 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:esp32dev]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
bodmer/TFT_eSPI@^2.5.43
|
||||
bblanchon/ArduinoJson@^7.2.1
|
||||
bodmer/JPEGDecoder@^2.0.0
|
||||
build_flags =
|
||||
-Os
|
||||
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
|
||||
-DUSER_SETUP_LOADED=1
|
||||
-DTFT_INVERSION_ON=1
|
||||
-DILI9341_DRIVER=1
|
||||
-DTFT_WIDTH=320
|
||||
-DTFT_HEIGHT=240
|
||||
-DTFT_MISO=19
|
||||
-DTFT_MOSI=23
|
||||
-DTFT_SCLK=18
|
||||
-DTFT_CS=15
|
||||
-DTFT_DC=2
|
||||
-DTFT_RST=4
|
||||
-DTOUCH_CS=33
|
||||
-DLOAD_GLCD=1
|
||||
-DLOAD_FONT2=1
|
||||
-DLOAD_FONT4=1
|
||||
-DLOAD_FONT6=1
|
||||
-DLOAD_FONT7=1
|
||||
-DLOAD_FONT8=1
|
||||
-DLOAD_GFXFF=1
|
||||
-DSMOOTH_FONT=1
|
||||
-DSPI_FREQUENCY=27000000
|
768
TFT-ESP32/src/main.cpp
Normal file
768
TFT-ESP32/src/main.cpp
Normal file
@ -0,0 +1,768 @@
|
||||
// Font file is stored on SD card
|
||||
#include <SD.h>
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
// Graphics and font library
|
||||
#include <TFT_eSPI.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include <esp_sleep.h>
|
||||
#include <JPEGDecoder.h>
|
||||
|
||||
#define SD_CS 22 // Set GPIO 5 as chip select for SD card
|
||||
#define LED_PIN 14 // Set GPIO 14 as LED output
|
||||
#define HUMIDIFIER_PIN 13 // Set GPIO 13 as humidifier output
|
||||
// TX (发送):GPIO16(UART2_TXD)
|
||||
// RX (接收):GPIO17(UART2_RXD)
|
||||
|
||||
#define MAX_IMAGE_WIDTH 240
|
||||
int16_t xpos = 0;
|
||||
int16_t ypos = 0;
|
||||
|
||||
const char *ssid = "Xiaomi_3A40";
|
||||
const char *password = "112233ww";
|
||||
|
||||
const char *jsonUrl = "http://monjack.cn/weatherInfo.php";
|
||||
const char *postUrl = "http://192.168.131.51/postLocalData.php";
|
||||
const char *postStatusUrl = "http://192.168.131.51/postStatus.php";
|
||||
|
||||
int dataIndex = 0;
|
||||
char receivedData0[100]; // 用于存储接收到的数据
|
||||
HardwareSerial serial2(2); // UART1 实例化
|
||||
|
||||
float local_humidity = 0.0;
|
||||
float temp_local_humidity = 0.0;
|
||||
float local_temperature = 0.0;
|
||||
float temp_local_temperature = 0.0;
|
||||
|
||||
u8_t standby = 0;
|
||||
u8_t reboot = 0;
|
||||
u8_t humidifier = 1;
|
||||
u8_t screen = 1;
|
||||
|
||||
bool boot = true;
|
||||
|
||||
String weather = "晴";
|
||||
String temp_weather = "";
|
||||
String temperature = "25";
|
||||
String temp_temperature = "";
|
||||
String humidity = "60";
|
||||
String temp_humidity = "";
|
||||
String wind_direction = "东北";
|
||||
String temp_wind_direction = "";
|
||||
|
||||
String comfort_clothing = "穿短裙、短裤、短袖、短外套";
|
||||
|
||||
SemaphoreHandle_t xMutex;
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI(); // Invoke library
|
||||
|
||||
void showTime(uint32_t msTime)
|
||||
{
|
||||
// tft.setCursor(0, 0);
|
||||
// tft.setTextFont(1);
|
||||
// tft.setTextSize(2);
|
||||
// tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
// tft.print(F(" JPEG drawn in "));
|
||||
// tft.print(msTime);
|
||||
// tft.println(F(" ms "));
|
||||
Serial.print(F(" JPEG drawn in "));
|
||||
Serial.print(msTime);
|
||||
Serial.println(F(" ms "));
|
||||
}
|
||||
|
||||
// ####################################################################################################
|
||||
// Draw a JPEG on the TFT, images will be cropped on the right/bottom sides if they do not fit
|
||||
// ####################################################################################################
|
||||
// This function assumes xpos,ypos is a valid screen coordinate. For convenience images that do not
|
||||
// fit totally on the screen are cropped to the nearest MCU size and may leave right/bottom borders.
|
||||
void jpegRender(int xpos, int ypos)
|
||||
{
|
||||
|
||||
// jpegInfo(); // Print information from the JPEG file (could comment this line out)
|
||||
|
||||
uint16_t *pImg;
|
||||
uint16_t mcu_w = JpegDec.MCUWidth;
|
||||
uint16_t mcu_h = JpegDec.MCUHeight;
|
||||
uint32_t max_x = JpegDec.width;
|
||||
uint32_t max_y = JpegDec.height;
|
||||
|
||||
bool swapBytes = tft.getSwapBytes();
|
||||
tft.setSwapBytes(true);
|
||||
|
||||
// Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs)
|
||||
// Typically these MCUs are 16x16 pixel blocks
|
||||
// Determine the width and height of the right and bottom edge image blocks
|
||||
uint32_t min_w = jpg_min(mcu_w, max_x % mcu_w);
|
||||
uint32_t min_h = jpg_min(mcu_h, max_y % mcu_h);
|
||||
|
||||
// save the current image block size
|
||||
uint32_t win_w = mcu_w;
|
||||
uint32_t win_h = mcu_h;
|
||||
|
||||
// record the current time so we can measure how long it takes to draw an image
|
||||
uint32_t drawTime = millis();
|
||||
|
||||
// save the coordinate of the right and bottom edges to assist image cropping
|
||||
// to the screen size
|
||||
max_x += xpos;
|
||||
max_y += ypos;
|
||||
|
||||
// Fetch data from the file, decode and display
|
||||
while (JpegDec.read())
|
||||
{ // While there is more data in the file
|
||||
pImg = JpegDec.pImage; // Decode a MCU (Minimum Coding Unit, typically a 8x8 or 16x16 pixel block)
|
||||
|
||||
// Calculate coordinates of top left corner of current MCU
|
||||
int mcu_x = JpegDec.MCUx * mcu_w + xpos;
|
||||
int mcu_y = JpegDec.MCUy * mcu_h + ypos;
|
||||
|
||||
// check if the image block size needs to be changed for the right edge
|
||||
if (mcu_x + mcu_w <= max_x)
|
||||
win_w = mcu_w;
|
||||
else
|
||||
win_w = min_w;
|
||||
|
||||
// check if the image block size needs to be changed for the bottom edge
|
||||
if (mcu_y + mcu_h <= max_y)
|
||||
win_h = mcu_h;
|
||||
else
|
||||
win_h = min_h;
|
||||
|
||||
// copy pixels into a contiguous block
|
||||
if (win_w != mcu_w)
|
||||
{
|
||||
uint16_t *cImg;
|
||||
int p = 0;
|
||||
cImg = pImg + win_w;
|
||||
for (int h = 1; h < win_h; h++)
|
||||
{
|
||||
p += mcu_w;
|
||||
for (int w = 0; w < win_w; w++)
|
||||
{
|
||||
*cImg = *(pImg + w + p);
|
||||
cImg++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// calculate how many pixels must be drawn
|
||||
uint32_t mcu_pixels = win_w * win_h;
|
||||
|
||||
// draw image MCU block only if it will fit on the screen
|
||||
if ((mcu_x + win_w) <= tft.width() && (mcu_y + win_h) <= tft.height())
|
||||
tft.pushImage(mcu_x, mcu_y, win_w, win_h, pImg);
|
||||
else if ((mcu_y + win_h) >= tft.height())
|
||||
JpegDec.abort(); // Image has run off bottom of screen so abort decoding
|
||||
}
|
||||
|
||||
tft.setSwapBytes(swapBytes);
|
||||
|
||||
showTime(millis() - drawTime); // These lines are for sketch testing only
|
||||
}
|
||||
|
||||
// ####################################################################################################
|
||||
// Print image information to the serial port (optional)
|
||||
// ####################################################################################################
|
||||
// JpegDec.decodeFile(...) or JpegDec.decodeArray(...) must be called before this info is available!
|
||||
void jpegInfo()
|
||||
{
|
||||
|
||||
// Print information extracted from the JPEG file
|
||||
Serial.println("JPEG image info");
|
||||
Serial.println("===============");
|
||||
Serial.print("Width :");
|
||||
Serial.println(JpegDec.width);
|
||||
Serial.print("Height :");
|
||||
Serial.println(JpegDec.height);
|
||||
Serial.print("Components :");
|
||||
Serial.println(JpegDec.comps);
|
||||
Serial.print("MCU / row :");
|
||||
Serial.println(JpegDec.MCUSPerRow);
|
||||
Serial.print("MCU / col :");
|
||||
Serial.println(JpegDec.MCUSPerCol);
|
||||
Serial.print("Scan type :");
|
||||
Serial.println(JpegDec.scanType);
|
||||
Serial.print("MCU width :");
|
||||
Serial.println(JpegDec.MCUWidth);
|
||||
Serial.print("MCU height :");
|
||||
Serial.println(JpegDec.MCUHeight);
|
||||
Serial.println("===============");
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
// ####################################################################################################
|
||||
// Show the execution time (optional)
|
||||
// ####################################################################################################
|
||||
// WARNING: for UNO/AVR legacy reasons printing text to the screen with the Mega might not work for
|
||||
// sketch sizes greater than ~70KBytes because 16-bit address pointers are used in some libraries.
|
||||
|
||||
// The Due will work fine with the HX8357_Due library.
|
||||
void listDir(fs::FS &fs, const char *dirname, uint8_t levels);
|
||||
void serialEvent();
|
||||
void ParseData(char *data);
|
||||
void displayTask(void *parameter);
|
||||
void fetchDataTask(void *parameters);
|
||||
void parseJson(String jsonData);
|
||||
void getWeatherInfo();
|
||||
void postData();
|
||||
void postStatus();
|
||||
void parseJson2(String jsonData);
|
||||
void checkStatusTask(void *parameters);
|
||||
void drawSdJpeg(const char *filename, int xpos, int ypos);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Setup
|
||||
// -------------------------------------------------------------------------
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(115200); // Used for messages
|
||||
serial2.begin(115200); // Used for messages
|
||||
Serial.println("UART2 initialized");
|
||||
|
||||
// Connect to WiFi
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
delay(1000);
|
||||
Serial.println("Connecting to WiFi...");
|
||||
}
|
||||
Serial.println("Connected to WiFi");
|
||||
|
||||
// 设置SPI频率为40MHz
|
||||
SPISettings spiSettings(40000000, MSBFIRST, SPI_MODE0);
|
||||
|
||||
// Initialise the SD library before the TFT so the chip select is defined
|
||||
if (!SD.begin(SD_CS))
|
||||
{
|
||||
Serial.println("Card Mount Failed");
|
||||
return;
|
||||
}
|
||||
// Initialise the TFT after the SD card!
|
||||
tft.init();
|
||||
tft.setRotation(3);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
listDir(SD, "/", 0);
|
||||
pinMode(LED_PIN, OUTPUT); // Set LED pin as output
|
||||
pinMode(HUMIDIFIER_PIN, OUTPUT); // Set humidifier pin as output
|
||||
digitalWrite(LED_PIN, HIGH); // Turn on LED
|
||||
digitalWrite(HUMIDIFIER_PIN, HIGH); // Turn on humidifier
|
||||
Serial.println("SD and TFT initialisation done.");
|
||||
|
||||
Serial.println("👌👌👌👌");
|
||||
postStatus();
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
drawSdJpeg("/Photos/background.jpg", x, y); // This draws a jpeg pulled off the SD Card
|
||||
|
||||
|
||||
// 配置 GPIO 触发唤醒
|
||||
esp_sleep_enable_ext0_wakeup(GPIO_NUM_35, 0); // GPIO_NUM_35 为低电平唤醒
|
||||
|
||||
// 创建互斥锁
|
||||
xMutex = xSemaphoreCreateMutex();
|
||||
|
||||
// 创建任务
|
||||
xTaskCreate(displayTask, "Display Task", 4096, NULL, 1, NULL);
|
||||
xTaskCreate(fetchDataTask, "Fetch Data Task", 4096, NULL, 2, NULL);
|
||||
xTaskCreate(checkStatusTask, "Check Status Task", 4096, NULL, 3, NULL);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Main loop
|
||||
// -------------------------------------------------------------------------
|
||||
void loop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void fetchDataTask(void *parameters){
|
||||
while (true)
|
||||
{
|
||||
getWeatherInfo();
|
||||
|
||||
postData();
|
||||
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS); // 每0.5秒获取一次JSON数据
|
||||
}
|
||||
}
|
||||
|
||||
void getWeatherInfo(){
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
HTTPClient http;
|
||||
|
||||
// 配置HTTP请求
|
||||
http.begin(jsonUrl);
|
||||
|
||||
// 发送HTTP GET请求
|
||||
int httpCode = http.GET();
|
||||
|
||||
if (httpCode > 0)
|
||||
{
|
||||
// 如果请求成功
|
||||
if (httpCode == HTTP_CODE_OK)
|
||||
{
|
||||
String payload = http.getString(); // 获取响应字符串
|
||||
Serial.println("Received JSON data:");
|
||||
Serial.println(payload);
|
||||
|
||||
// 解析JSON数据
|
||||
parseJson(payload);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果请求失败
|
||||
Serial.print("Error on sending GET: ");
|
||||
Serial.println(http.errorToString(httpCode).c_str());
|
||||
}
|
||||
|
||||
http.end(); // 结束HTTP请求
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Error in WiFi connection");
|
||||
}
|
||||
}
|
||||
|
||||
void postStatus()
|
||||
{
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
HTTPClient http;
|
||||
// 配置HTTP请求
|
||||
http.begin(postStatusUrl);
|
||||
// 设置HTTP头部
|
||||
http.addHeader("Content-Type", "application/json");
|
||||
StaticJsonDocument<100> doc;
|
||||
doc["standby"] = standby;
|
||||
doc["reboot"] = reboot;
|
||||
doc["humidifier"] = humidifier;
|
||||
doc["screen"] = screen;
|
||||
|
||||
// 序列化JSON数据
|
||||
String jsonPayload;
|
||||
serializeJson(doc, jsonPayload);
|
||||
Serial.print("JSON Payload: ");
|
||||
Serial.println(jsonPayload);
|
||||
|
||||
// 发送HTTP POST请求
|
||||
int httpCode = http.POST(jsonPayload);
|
||||
if (httpCode > 0)
|
||||
{
|
||||
// 如果请求成功
|
||||
if (httpCode == HTTP_CODE_OK)
|
||||
{
|
||||
String payload = http.getString(); // 获取响应字符串
|
||||
Serial.println("poststatus状态信息:");
|
||||
Serial.println(payload);
|
||||
// 解析JSON数据
|
||||
parseJson2(payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print("Unexpected HTTP code: ");
|
||||
Serial.println(httpCode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果请求失败
|
||||
Serial.print("Error on sending POST: ");
|
||||
Serial.println(http.errorToString(httpCode).c_str());
|
||||
}
|
||||
|
||||
http.end(); // 结束HTTP请求
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("WiFi is not connected.");
|
||||
}
|
||||
}
|
||||
|
||||
void postData()
|
||||
{
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
HTTPClient http;
|
||||
// 配置HTTP请求
|
||||
http.begin(postUrl);
|
||||
|
||||
// 设置HTTP头部
|
||||
http.addHeader("Content-Type", "application/json");
|
||||
|
||||
StaticJsonDocument<200> doc;
|
||||
doc["Humidity"] = local_humidity;
|
||||
doc["Temperature"] = local_temperature;
|
||||
|
||||
// 序列化JSON数据
|
||||
String jsonPayload;
|
||||
serializeJson(doc, jsonPayload);
|
||||
|
||||
Serial.print("JSON Payload: ");
|
||||
Serial.println(jsonPayload);
|
||||
|
||||
// 发送HTTP POST请求
|
||||
int httpCode = http.POST(jsonPayload);
|
||||
if (httpCode > 0)
|
||||
{
|
||||
// 如果请求成功
|
||||
if (httpCode == HTTP_CODE_OK)
|
||||
{
|
||||
String payload = http.getString(); // 获取响应字符串
|
||||
Serial.println("状态信息:");
|
||||
Serial.println(payload);
|
||||
// 解析JSON数据
|
||||
parseJson2(payload);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果请求失败
|
||||
Serial.print("Error on sending POST: ");
|
||||
Serial.println(http.errorToString(httpCode).c_str());
|
||||
}
|
||||
|
||||
http.end(); // 结束HTTP请求
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Error in WiFi connection");
|
||||
}
|
||||
}
|
||||
|
||||
//解析天气情况
|
||||
void parseJson(String jsonData){
|
||||
// 定义JSON文档的大小,根据实际情况调整
|
||||
const size_t capacity = JSON_OBJECT_SIZE(2) + 300;
|
||||
StaticJsonDocument<capacity> doc;
|
||||
|
||||
// 解析JSON数据
|
||||
DeserializationError error = deserializeJson(doc, jsonData);
|
||||
if (error)
|
||||
{
|
||||
Serial.print("deserializeJson() failed: ");
|
||||
Serial.println(error.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取JSON中的值
|
||||
String newHumidity = doc["lives"][0]["humidity"] | "0.0";
|
||||
String newTemperature = doc["lives"][0]["temperature"] | "0.0";
|
||||
String newWeather = doc["lives"][0]["weather"] | "晴";
|
||||
String newWindDirection = doc["lives"][0]["winddirection"] | "东北";
|
||||
if(newTemperature.toInt()<4){
|
||||
comfort_clothing = "棉衣或羽绒服";
|
||||
}else if(newTemperature.toInt()<10){
|
||||
comfort_clothing = "厚外套";
|
||||
}else if(newTemperature.toInt()<20){
|
||||
comfort_clothing = "薄外套、长袖";
|
||||
}else{
|
||||
comfort_clothing = "短外套、短裤、短裙";
|
||||
}
|
||||
|
||||
Serial.print("newHumidity: ");
|
||||
Serial.println(newHumidity);
|
||||
Serial.print("newTemperature: ");
|
||||
Serial.println(newTemperature);
|
||||
Serial.print("Weather: ");
|
||||
Serial.println(newWeather);
|
||||
Serial.print("WindDirection: ");
|
||||
Serial.println(newWindDirection);
|
||||
// 获取互斥锁
|
||||
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE)
|
||||
{
|
||||
humidity = newHumidity;
|
||||
temperature = newTemperature;
|
||||
weather = newWeather;
|
||||
wind_direction = newWindDirection;
|
||||
// 释放互斥锁
|
||||
xSemaphoreGive(xMutex);
|
||||
}
|
||||
}
|
||||
|
||||
//解析状态信息
|
||||
void parseJson2(String jsonData){
|
||||
// 定义JSON文档的大小,根据实际情况调整
|
||||
const size_t capacity = JSON_OBJECT_SIZE(2) + 300;
|
||||
StaticJsonDocument<capacity> doc;
|
||||
|
||||
// 解析JSON数据
|
||||
DeserializationError error = deserializeJson(doc, jsonData);
|
||||
|
||||
if (error)
|
||||
{
|
||||
Serial.print("deserializeJson() failed: ");
|
||||
Serial.println(error.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取JSON中的值
|
||||
u8_t newStandby = doc["standby"].as<u8_t>();
|
||||
u8_t newReboot = doc["reboot"].as<u8_t>();
|
||||
u8_t newHumidifier = doc["humidifier"].as<u8_t>();
|
||||
u8_t newScreen = doc["screen"].as<u8_t>();
|
||||
|
||||
Serial.print("😊😊screen::😊😊");
|
||||
Serial.println(newScreen);
|
||||
Serial.print("😊😊standby::😊😊");
|
||||
Serial.println(newStandby);
|
||||
Serial.print("😊😊reboot::😊😊");
|
||||
Serial.println(newReboot);
|
||||
Serial.print("😊😊humidifier::😊😊");
|
||||
Serial.println(newHumidifier);
|
||||
|
||||
// 获取互斥锁
|
||||
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE)
|
||||
{
|
||||
standby = newStandby;
|
||||
reboot = newReboot;
|
||||
humidifier = newHumidifier;
|
||||
screen = newScreen;
|
||||
// 释放互斥锁
|
||||
xSemaphoreGive(xMutex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void displayTask(void *parameter)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// Check for incoming serial data
|
||||
serialEvent();
|
||||
|
||||
// Name of font file (library adds leading / and .vlw)
|
||||
String fileName = "MiSan20Chinese";
|
||||
|
||||
if(boot){
|
||||
tft.loadFont(fileName, SD);
|
||||
tft.setTextColor(0x5ACB, TFT_WHITE, true);
|
||||
tft.setCursor(30, 135);
|
||||
tft.print("病房空气指标");
|
||||
boot = false;
|
||||
tft.loadFont("BigFonts45", SD);
|
||||
tft.setCursor(50, 160);
|
||||
tft.print("良好");
|
||||
}
|
||||
tft.loadFont(fileName, SD); // Use font stored on SD
|
||||
if (temp_local_temperature != local_temperature)
|
||||
{
|
||||
tft.loadFont("MiddleNumFonts25", SD);
|
||||
tft.setTextColor(0x5ACB, TFT_WHITE, true);
|
||||
tft.fillRect(220, 195, 70, 20, TFT_WHITE); // Clear screen
|
||||
tft.setCursor(220, 195);
|
||||
tft.print(local_temperature);
|
||||
tft.println("℃");
|
||||
temp_local_temperature = local_temperature;
|
||||
}
|
||||
if (temp_local_humidity != local_humidity)
|
||||
{
|
||||
tft.loadFont("MiddleNumFonts25",SD);
|
||||
tft.setTextColor(0x5ACB, TFT_WHITE, true);
|
||||
tft.fillRect(220, 140, 70, 20, TFT_WHITE); // Clear screen
|
||||
tft.setCursor(220, 140);
|
||||
tft.print(local_humidity);
|
||||
tft.println("%");
|
||||
|
||||
temp_local_humidity = local_humidity;
|
||||
}
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
if(temp_weather != weather)
|
||||
{
|
||||
tft.loadFont("BigFonts45", SD);
|
||||
tft.setTextColor(TFT_WHITE, 0x5873FF, true);
|
||||
drawSdJpeg("/Photos/cloudy.jpg",23,20);
|
||||
tft.setCursor(112, 20);
|
||||
tft.print(weather);
|
||||
temp_weather = weather;
|
||||
}
|
||||
if(temp_temperature != temperature){
|
||||
tft.loadFont(fileName, SD);
|
||||
tft.setTextColor(TFT_WHITE, 0x5873FF,true);
|
||||
tft.setCursor(240, 20);
|
||||
tft.print(temperature);
|
||||
tft.print("℃");
|
||||
temp_temperature = temperature;
|
||||
}
|
||||
if(temp_humidity != humidity){
|
||||
tft.setTextColor(TFT_WHITE, 0x5873FF,true);
|
||||
tft.setCursor(240, 60);
|
||||
tft.print(humidity);
|
||||
tft.print("%");
|
||||
temp_humidity = humidity;
|
||||
}
|
||||
// if(temp_wind_direction != wind_direction){
|
||||
// tft.fillRect(80,130,60,20,TFT_BLACK);
|
||||
// tft.print(" ");
|
||||
// tft.print(wind_direction);
|
||||
// tft.print("风");
|
||||
// temp_wind_direction = wind_direction;
|
||||
// }
|
||||
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS); // 每1秒刷新一次屏幕
|
||||
}
|
||||
}
|
||||
|
||||
void checkStatusTask(void *parameters){
|
||||
while (true)
|
||||
{
|
||||
if(screen == 1){
|
||||
digitalWrite(LED_PIN, HIGH); // Turn on LED
|
||||
}else{
|
||||
digitalWrite(LED_PIN, LOW); // Turn off LED
|
||||
}
|
||||
if(reboot == 1){
|
||||
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE){
|
||||
reboot = 0;
|
||||
xSemaphoreGive(xMutex);
|
||||
}
|
||||
postStatus();
|
||||
delay(1000);
|
||||
ESP.restart();
|
||||
}
|
||||
if(standby == 1){
|
||||
Serial.println("进入待机模式");
|
||||
delay(1000);
|
||||
esp_light_sleep_start(); // 进入低功耗模式
|
||||
}
|
||||
if(humidifier == 1){
|
||||
digitalWrite(HUMIDIFIER_PIN, HIGH); // Turn on humidifier
|
||||
}else{
|
||||
digitalWrite(HUMIDIFIER_PIN, LOW); // Turn off humidifier
|
||||
}
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS); // 每0.秒检查一次数据
|
||||
}
|
||||
}
|
||||
|
||||
void listDir(fs::FS & fs, const char *dirname, uint8_t levels)
|
||||
{
|
||||
Serial.printf("Listing directory: %s\n", dirname);
|
||||
|
||||
File root = fs.open(dirname);
|
||||
if (!root)
|
||||
{
|
||||
Serial.println("Failed to open directory");
|
||||
return;
|
||||
}
|
||||
if (!root.isDirectory())
|
||||
{
|
||||
Serial.println("Not a directory");
|
||||
return;
|
||||
}
|
||||
|
||||
File file = root.openNextFile();
|
||||
while (file)
|
||||
{
|
||||
if (file.isDirectory())
|
||||
{
|
||||
Serial.print(" DIR : ");
|
||||
Serial.println(file.name());
|
||||
if (levels)
|
||||
{
|
||||
listDir(fs, file.name(), levels - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(" FILE: ");
|
||||
Serial.print(file.name());
|
||||
Serial.print(" SIZE: ");
|
||||
Serial.println(file.size());
|
||||
}
|
||||
file = root.openNextFile();
|
||||
}
|
||||
}
|
||||
|
||||
void serialEvent()
|
||||
{
|
||||
// 检查是否有数据传入
|
||||
while (serial2.available())
|
||||
{
|
||||
// 从串口读取一个字符
|
||||
char incomingByte = serial2.read();
|
||||
|
||||
// 如果接收到换行符或最大长度限制,则显示数据
|
||||
if (incomingByte == '\n' || dataIndex >= 100)
|
||||
{
|
||||
receivedData0[dataIndex] = '\0'; // 结束字符串
|
||||
ParseData(receivedData0); // 显示数据
|
||||
// Serial.println(receivedData0);
|
||||
dataIndex = 0; // 重置接收指针
|
||||
}
|
||||
else
|
||||
{
|
||||
receivedData0[dataIndex++] = incomingByte; // 将字符存入缓冲区
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParseData(char *data) // 解析数据
|
||||
{
|
||||
char *token = strtok(data, ":");
|
||||
while (token != NULL)
|
||||
{
|
||||
char *value = strtok(NULL, "C\r\n");
|
||||
if (value != NULL)
|
||||
{
|
||||
if (strcmp(token, "Humidity") == 0)
|
||||
{
|
||||
local_humidity = atof(value);
|
||||
Serial.print("Humidity: ");
|
||||
Serial.println(local_humidity);
|
||||
}
|
||||
else if (strcmp(token, "Temperature") == 0)
|
||||
{
|
||||
local_temperature = atof(value);
|
||||
Serial.print("Temperature: ");
|
||||
Serial.println(local_temperature);
|
||||
}
|
||||
}
|
||||
token = strtok(NULL, ":");
|
||||
}
|
||||
}
|
||||
|
||||
void drawSdJpeg(const char *filename, int xpos, int ypos)
|
||||
{
|
||||
|
||||
// Open the named file (the Jpeg decoder library will close it)
|
||||
File jpegFile = SD.open(filename, FILE_READ); // or, file handle reference for SD library
|
||||
|
||||
if (!jpegFile)
|
||||
{
|
||||
Serial.print("ERROR: File \"");
|
||||
Serial.print(filename);
|
||||
Serial.println("\" not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.println("===========================");
|
||||
Serial.print("Drawing file: ");
|
||||
Serial.println(filename);
|
||||
Serial.println("===========================");
|
||||
|
||||
// Use one of the following methods to initialise the decoder:
|
||||
bool decoded = JpegDec.decodeSdFile(jpegFile); // Pass the SD file handle to the decoder,
|
||||
// bool decoded = JpegDec.decodeSdFile(filename); // or pass the filename (String or character array)
|
||||
|
||||
if (decoded)
|
||||
{
|
||||
// print information about the image to the serial port
|
||||
jpegInfo();
|
||||
// render the image onto the screen at given coordinates
|
||||
jpegRender(xpos, ypos);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Jpeg file format not supported!");
|
||||
}
|
||||
}
|
11
TFT-ESP32/test/README
Normal file
11
TFT-ESP32/test/README
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
82
TFT-ESP32/test/test.cpp
Normal file
82
TFT-ESP32/test/test.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include <TFT_eSPI.h> // TFT 显示屏库
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI(); // 初始化 TFT 实例
|
||||
|
||||
const int screenWidth = 240; // 根据你的屏幕分辨率设置
|
||||
const int screenHeight = 320;
|
||||
const int byteWidth = (screenWidth + 7) / 8; // 每行需要的字节数
|
||||
|
||||
// 数组用于存储二值化后的屏幕数据
|
||||
uint8_t binaryImage[screenHeight][byteWidth];
|
||||
|
||||
// 将屏幕数据读取并二值化,存储到数组中
|
||||
void binaryScreenToArray()
|
||||
{
|
||||
for (int y = 0; y < screenHeight; y++)
|
||||
{
|
||||
uint8_t byteValue = 0;
|
||||
for (int x = 0; x < screenWidth; x++)
|
||||
{
|
||||
// 读取像素颜色
|
||||
uint16_t color = tft.readPixel(x, y);
|
||||
|
||||
// 将颜色二值化(假设TFT_WHITE为白色,其它为黑色)
|
||||
if (color == TFT_WHITE)
|
||||
{
|
||||
byteValue |= (1 << (7 - (x % 8))); // 设置当前位为1(白色)
|
||||
}
|
||||
|
||||
// 每8个像素存储为一个字节
|
||||
if (x % 8 == 7 || x == screenWidth - 1)
|
||||
{
|
||||
binaryImage[y][x / 8] = byteValue;
|
||||
byteValue = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 将二值化后的屏幕数据通过串口发送到电脑,值之间用逗号隔开
|
||||
void sendArrayToPC()
|
||||
{
|
||||
Serial.println("Start sending binary screen data:");
|
||||
|
||||
for (int y = 0; y < screenHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < byteWidth; x++)
|
||||
{
|
||||
Serial.print(binaryImage[y][x], HEX); // 以十六进制格式发送每个字节
|
||||
|
||||
// 如果不是最后一个字节,则添加逗号
|
||||
if (x < byteWidth - 1)
|
||||
{
|
||||
Serial.print(","); // 用逗号分隔
|
||||
}
|
||||
}
|
||||
Serial.println(); // 每行结束后换行
|
||||
}
|
||||
|
||||
Serial.println("Binary screen data sent.");
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200); // 初始化串口通信
|
||||
tft.init(); // 初始化屏幕
|
||||
tft.setRotation(1); // 根据需要设置屏幕的旋转
|
||||
tft.fillScreen(TFT_BLACK); // 将屏幕设置为黑色
|
||||
|
||||
// 绘制一些内容(测试用)
|
||||
tft.fillCircle(120, 160, 50, TFT_WHITE); // 在屏幕中间绘制一个白色的圆圈
|
||||
|
||||
// 读取并二值化屏幕内容
|
||||
binaryScreenToArray();
|
||||
|
||||
// 将二值化后的数组通过串口传输到电脑
|
||||
sendArrayToPC();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// 主要功能在 setup 中执行,loop 中不做任何操作
|
||||
}
|
111
TFT-ESP32/test/testmain.cpp
Normal file
111
TFT-ESP32/test/testmain.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
//<App !Start!>
|
||||
// FILE: [main.cpp]
|
||||
// Created by GUIslice Builder version: [0.17.b34]
|
||||
//
|
||||
// GUIslice Builder Generated File
|
||||
//
|
||||
// For the latest guides, updates and support view:
|
||||
// https://github.com/ImpulseAdventure/GUIslice
|
||||
//
|
||||
//<App !End!>
|
||||
|
||||
// ------------------------------------------------
|
||||
// Headers to include
|
||||
// ------------------------------------------------
|
||||
#include "GUIsliceProjects_GSLC.h"
|
||||
|
||||
// ------------------------------------------------
|
||||
// Program Globals
|
||||
// ------------------------------------------------
|
||||
|
||||
// Save some element references for direct access
|
||||
//<Save_References !Start!>
|
||||
//<Save_References !End!>
|
||||
|
||||
// Define debug message function
|
||||
static int16_t DebugOut(char ch)
|
||||
{
|
||||
if (ch == (char)'\n')
|
||||
Serial.println("");
|
||||
else
|
||||
Serial.write(ch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------
|
||||
// Callback Methods
|
||||
// ------------------------------------------------
|
||||
// Common Button callback
|
||||
bool CbBtnCommon(void *pvGui, void *pvElemRef, gslc_teTouch eTouch, int16_t nX, int16_t nY)
|
||||
{
|
||||
// Typecast the parameters to match the GUI and element types
|
||||
gslc_tsGui *pGui = (gslc_tsGui *)(pvGui);
|
||||
gslc_tsElemRef *pElemRef = (gslc_tsElemRef *)(pvElemRef);
|
||||
gslc_tsElem *pElem = gslc_GetElemFromRef(pGui, pElemRef);
|
||||
|
||||
if (eTouch == GSLC_TOUCH_UP_IN)
|
||||
{
|
||||
// From the element's ID we can determine which button was pressed.
|
||||
switch (pElem->nId)
|
||||
{
|
||||
//<Button Enums !Start!>
|
||||
case E_ELEM_BTN1:
|
||||
break;
|
||||
case E_ELEM_BTN2:
|
||||
break;
|
||||
//<Button Enums !End!>
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//<Checkbox Callback !Start!>
|
||||
//<Checkbox Callback !End!>
|
||||
//<Keypad Callback !Start!>
|
||||
//<Keypad Callback !End!>
|
||||
//<Spinner Callback !Start!>
|
||||
//<Spinner Callback !End!>
|
||||
//<Listbox Callback !Start!>
|
||||
//<Listbox Callback !End!>
|
||||
//<Draw Callback !Start!>
|
||||
//<Draw Callback !End!>
|
||||
//<Slider Callback !Start!>
|
||||
//<Slider Callback !End!>
|
||||
//<Tick Callback !Start!>
|
||||
//<Tick Callback !End!>
|
||||
|
||||
void setup()
|
||||
{
|
||||
// ------------------------------------------------
|
||||
// Initialize
|
||||
// ------------------------------------------------
|
||||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
// delay(1000); // NOTE: Some devices require a delay after Serial.begin() before serial port can be used
|
||||
|
||||
gslc_InitDebug(&DebugOut);
|
||||
|
||||
// ------------------------------------------------
|
||||
// Create graphic elements
|
||||
// ------------------------------------------------
|
||||
InitGUIslice_gen();
|
||||
}
|
||||
|
||||
// -----------------------------------
|
||||
// Main event loop
|
||||
// -----------------------------------
|
||||
void loop()
|
||||
{
|
||||
|
||||
// ------------------------------------------------
|
||||
// Update GUI Elements
|
||||
// ------------------------------------------------
|
||||
|
||||
// TODO - Add update code for any text, gauges, or sliders
|
||||
|
||||
// ------------------------------------------------
|
||||
// Periodically call GUIslice update function
|
||||
// ------------------------------------------------
|
||||
gslc_Update(&m_gui);
|
||||
}
|
8
Web/imasBackend/.idea/.gitignore
generated
vendored
Normal file
8
Web/imasBackend/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
12
Web/imasBackend/.idea/dataSources.xml
generated
Normal file
12
Web/imasBackend/.idea/dataSources.xml
generated
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||
<data-source source="LOCAL" name="@localhost" uuid="76688b31-a8ea-4f6d-a3ba-125f73939125">
|
||||
<driver-ref>mysql.8</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:mysql://localhost:3306</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
9
Web/imasBackend/.idea/imas-backend.iml
generated
Normal file
9
Web/imasBackend/.idea/imas-backend.iml
generated
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="jquery" level="application" />
|
||||
</component>
|
||||
</module>
|
6
Web/imasBackend/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
Web/imasBackend/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
6
Web/imasBackend/.idea/jsLibraryMappings.xml
generated
Normal file
6
Web/imasBackend/.idea/jsLibraryMappings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptLibraryMappings">
|
||||
<file url="PROJECT" libraries="{jquery}" />
|
||||
</component>
|
||||
</project>
|
8
Web/imasBackend/.idea/modules.xml
generated
Normal file
8
Web/imasBackend/.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/imas-backend.iml" filepath="$PROJECT_DIR$/.idea/imas-backend.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
20
Web/imasBackend/.idea/php.xml
generated
Normal file
20
Web/imasBackend/.idea/php.xml
generated
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MessDetectorOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCSFixerOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCodeSnifferOptionsConfiguration">
|
||||
<option name="highlightLevel" value="WARNING" />
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="7.2" />
|
||||
<component name="PhpStanOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PsalmOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
</project>
|
4
Web/imasBackend/.idea/vcs.xml
generated
Normal file
4
Web/imasBackend/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings" defaultProject="true" />
|
||||
</project>
|
21
Web/imasBackend/ESP01/getData.php
Normal file
21
Web/imasBackend/ESP01/getData.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
include_once("../db_config.php");
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
header("Content-Type: application/json"); // 返回 JSON 格式的响应
|
||||
header("Access-Control-Allow-Origin: *"); // 允许跨域请求
|
||||
header("Access-Control-Allow-Methods: POST, OPTIONS"); // 允许的方法
|
||||
header("Access-Control-Allow-Headers: Content-Type"); // 允许的请求头
|
||||
|
||||
$queryString = "SELECT * FROM status LIMIT 1";
|
||||
$result = mysqli_query($conn, $queryString);
|
||||
$row = mysqli_fetch_assoc($result);
|
||||
$standby = $row['standby'];
|
||||
$reboot = $row['reboot'];
|
||||
|
||||
$data = array(
|
||||
"standby" => $standby,
|
||||
"reboot" => $reboot
|
||||
);
|
||||
echo json_encode($data);
|
||||
|
||||
|
8
Web/imasBackend/db_config.php
Normal file
8
Web/imasBackend/db_config.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
$servername = "localhost";
|
||||
$username = "root";
|
||||
$password = "";
|
||||
$dbname = "IMAS";
|
||||
|
||||
// Create connection
|
||||
$conn = mysqli_connect($servername, $username, $password, $dbname);
|
62
Web/imasBackend/debug.php
Normal file
62
Web/imasBackend/debug.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
include_once 'db_config.php';
|
||||
//header('Content-Type: application/json');
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
|
||||
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
|
||||
|
||||
if($_SERVER['REQUEST_METHOD'] == 'POST'){
|
||||
|
||||
// 获取 POST 数据
|
||||
$postData = file_get_contents('php://input');
|
||||
echo $postData;
|
||||
// 解析 JSON 数据
|
||||
$data = json_decode($postData, true);
|
||||
|
||||
// 检查是否成功解析
|
||||
if ($data === null && json_last_error() !== JSON_ERROR_NONE) {
|
||||
echo json_encode(['error' => 'JSON 解析错误: ' . json_last_error_msg()]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// 处理数据
|
||||
$standby = isset($data['standby']) ? $data['standby'] : 0;
|
||||
$reboot = isset($data['reboot']) ? $data['reboot'] : 0;
|
||||
$humidifier = isset($data['humidifier']) ? $data['humidifier'] : 0;
|
||||
$screen = isset($data['screen']) ? $data['screen'] : 1;
|
||||
|
||||
|
||||
// 处理逻辑示例
|
||||
$response = [
|
||||
'message' => '数据接收成功',
|
||||
'standby' => $standby,
|
||||
'reboot' => $reboot,
|
||||
'humidifier' => $humidifier,
|
||||
'screen' => $screen,
|
||||
];
|
||||
|
||||
// 返回 JSON 响应
|
||||
|
||||
$queryString = "UPDATE `status` SET `standby`='$standby', `reboot`='$reboot', `humidifier`='$humidifier', `screen`='$screen'";
|
||||
mysqli_query($conn, $queryString);
|
||||
|
||||
$queryString = "select * FROM status";
|
||||
$result = mysqli_query($conn, $queryString);
|
||||
if(mysqli_num_rows($result) > 0){
|
||||
$data = []; // 初始化为空数组
|
||||
while ($row = mysqli_fetch_object($result)) { // 获取查询结果作为对象
|
||||
$data[] = $row; // 将对象追加到数组中
|
||||
}
|
||||
echo substr(json_encode($data),1,58) ; // 输出 JSON 格式的响应
|
||||
}
|
||||
}else{
|
||||
$queryString = "select * FROM status";
|
||||
$result = mysqli_query($conn, $queryString);
|
||||
if(mysqli_num_rows($result) > 0){
|
||||
$data = []; // 初始化为空数组
|
||||
while ($row = mysqli_fetch_object($result)) { // 获取查询结果作为对象
|
||||
$data[] = $row; // 将对象追加到数组中
|
||||
}
|
||||
echo substr(json_encode($data),1,58) ; // 输出 JSON 格式的响应
|
||||
}
|
||||
}
|
33
Web/imasBackend/getLocalData.php
Normal file
33
Web/imasBackend/getLocalData.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
include_once "db_config.php"; // 数据库配置文件
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
header("Content-Type: application/json"); // 返回 JSON 格式的响应
|
||||
header("Access-Control-Allow-Origin: *"); // 允许跨域请求
|
||||
header("Access-Control-Allow-Methods: POST, OPTIONS"); // 允许的方法
|
||||
header("Access-Control-Allow-Headers: Content-Type"); // 允许的请求头
|
||||
|
||||
// 这里假设连接已经建立,并且您有 $link 变量代表数据库连接
|
||||
|
||||
// 定义SQL查询,获取最近的10条记录
|
||||
$query = "SELECT * FROM localdata ORDER BY time DESC LIMIT 1";
|
||||
|
||||
// 执行查询
|
||||
$result = mysqli_query($conn, $query);
|
||||
|
||||
// 检查查询结果
|
||||
if (!$result) {
|
||||
die("查询失败: " . mysqli_error($conn)); // 处理错误
|
||||
}
|
||||
|
||||
// 处理查询结果
|
||||
$data = [];
|
||||
while ($row = mysqli_fetch_assoc($result)) {
|
||||
$data[] = $row; // 将每一行数据存入数组
|
||||
}
|
||||
|
||||
// 返回 JSON 格式的数据
|
||||
header("Content-Type: application/json");
|
||||
echo json_encode($data);
|
||||
|
||||
// 关闭数据库连接
|
||||
mysqli_close($conn);
|
22
Web/imasBackend/getSetting.php
Normal file
22
Web/imasBackend/getSetting.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
include_once("db_config.php");
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
header("Content-Type: application/json"); // 返回 JSON 格式的响应
|
||||
header("Access-Control-Allow-Origin: *"); // 允许跨域请求
|
||||
header("Access-Control-Allow-Methods: POST, OPTIONS"); // 允许的方法
|
||||
header("Access-Control-Allow-Headers: Content-Type"); // 允许的请求头
|
||||
|
||||
$queryString = "SELECT * FROM control_list";
|
||||
$result = mysqli_query($conn, $queryString);
|
||||
if(mysqli_error($conn)){
|
||||
echo json_encode(["code" => 1, "msg" => mysqli_error($conn)]);
|
||||
exit();
|
||||
}
|
||||
else{
|
||||
$data = array();
|
||||
while($row = mysqli_fetch_assoc($result)){
|
||||
$data[] = $row;
|
||||
}
|
||||
echo json_encode($data);
|
||||
}
|
||||
|
52
Web/imasBackend/postLocalData.php
Normal file
52
Web/imasBackend/postLocalData.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
include_once "db_config.php";
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
header("Content-Type: application/json"); // 返回 JSON 格式的响应
|
||||
header("Access-Control-Allow-Origin: *"); // 允许跨域请求
|
||||
header("Access-Control-Allow-Methods: POST, OPTIONS"); // 允许的方法
|
||||
header("Access-Control-Allow-Headers: Content-Type"); // 允许的请求头
|
||||
|
||||
|
||||
// 处理 OPTIONS 请求
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||
http_response_code(204);
|
||||
exit();
|
||||
}
|
||||
|
||||
// 获取原始 POST 数据
|
||||
$input = json_decode(file_get_contents("php://input"), true); // 将 JSON 转换为 PHP 数组
|
||||
|
||||
// 检查是否成功解析 JSON
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
echo json_encode(["error" => "无效的 JSON 数据"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
$local_temperature = $input["Temperature"] ?? "";
|
||||
$local_humidity = $input["Humidity"] ?? "";
|
||||
|
||||
//$standby = $input["status"]["standby"] ?? 0;
|
||||
//$reboot = $input["status"]["reboot"] ?? 0;
|
||||
//$humidifier = $input["status"]["humidifier"] ?? 0;
|
||||
//$screen = $input["status"]["screen"] ?? 1;
|
||||
|
||||
|
||||
$time = time();
|
||||
$date = date("Y-m-d H:i:s", $time);
|
||||
|
||||
$queryString = "INSERT INTO localdata (time, temperature, humidity) VALUES ('$date', '$local_temperature', '$local_humidity')";
|
||||
|
||||
mysqli_query($conn, $queryString);
|
||||
if(mysqli_error($conn)){
|
||||
echo json_encode(["error" => "数据库错误"]);
|
||||
}
|
||||
|
||||
$queryString = "select * FROM status";
|
||||
$result = mysqli_query($conn, $queryString);
|
||||
if(mysqli_num_rows($result) > 0){
|
||||
$data = []; // 初始化为空数组
|
||||
while ($row = mysqli_fetch_object($result)) { // 获取查询结果作为对象
|
||||
$data[] = $row; // 将对象追加到数组中
|
||||
echo substr(json_encode($data),1, 58); // 返回 JSON 格式的响应
|
||||
}
|
||||
}
|
54
Web/imasBackend/postSetting.php
Normal file
54
Web/imasBackend/postSetting.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
include_once "db_config.php";
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
|
||||
header("Access-Control-Allow-Headers: Content-Type");
|
||||
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
if (!isset($input["boot"]) || !isset($input["shutdown"]) || !isset($input["start"]) ||
|
||||
!isset($input["end"]) || !isset($input["min_humidity"]) || !isset($input["max_humidity"]) ||
|
||||
!isset($input["min_temperature"]) || !isset($input["max_temperature"]) ||
|
||||
!isset($input["enable_boot"]) || !isset($input["enable_humidify"]) ||
|
||||
!isset($input["enable_temp_threshold"]) || !isset($input["enable_humi_threshold"])) {
|
||||
echo json_encode(["error" => "无效的请求数据"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
// 获取输入数据
|
||||
$boot = $input["boot"];
|
||||
$shutdown = $input["shutdown"];
|
||||
$start = $input["start"];
|
||||
$end = $input["end"];
|
||||
$min_humidity = $input["min_humidity"];
|
||||
$max_humidity = $input["max_humidity"];
|
||||
$min_temperature = $input["min_temperature"];
|
||||
$max_temperature = $input["max_temperature"];
|
||||
$enable_boot = $input["enable_boot"];
|
||||
$enable_humidify = $input["enable_humidify"];
|
||||
$enable_temp_threshold = $input["enable_temp_threshold"];
|
||||
$enable_humi_threshold = $input["enable_humi_threshold"];
|
||||
|
||||
|
||||
// 更新数据库
|
||||
$queryString = "UPDATE control_list SET
|
||||
boot='$boot',
|
||||
shutdown='$shutdown',
|
||||
start='$start',
|
||||
end='$end',
|
||||
min_humidity='$min_humidity',
|
||||
max_humidity='$max_humidity',
|
||||
min_temperature='$min_temperature',
|
||||
max_temperature='$max_temperature',
|
||||
enable_boot='$enable_boot',
|
||||
enable_humidify='$enable_humidify',
|
||||
enable_temp_threshold='$enable_temp_threshold',
|
||||
enable_humi_threshold='$enable_humi_threshold'";
|
||||
|
||||
if (mysqli_query($conn, $queryString)) {
|
||||
echo json_encode(["success" => "设置更新成功"]);
|
||||
} else {
|
||||
echo json_encode(["error" => "设置更新失败: " . mysqli_error($conn)]);
|
||||
}
|
||||
|
41
Web/imasBackend/postStatus.php
Normal file
41
Web/imasBackend/postStatus.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
include_once "db_config.php";
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
header("Content-Type: application/json"); // 返回 JSON 格式的响应
|
||||
header("Access-Control-Allow-Origin: *"); // 允许跨域请求
|
||||
header("Access-Control-Allow-Methods: POST, OPTIONS"); // 允许的方法
|
||||
header("Access-Control-Allow-Headers: Content-Type"); // 允许的请求头
|
||||
|
||||
|
||||
// 处理 OPTIONS 请求
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||
http_response_code(204);
|
||||
exit();
|
||||
}
|
||||
|
||||
// 获取原始 POST 数据
|
||||
$input = json_decode(file_get_contents("php://input"), true); // 将 JSON 转换为 PHP 数组
|
||||
|
||||
// 检查是否成功解析 JSON
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
echo json_encode(["error" => "无效的 JSON 数据"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
$standby = $input["standby"];
|
||||
$reboot = $input["reboot"];
|
||||
$humidifier = $input["humidifier"];
|
||||
$screen = $input["screen"];
|
||||
|
||||
|
||||
$queryString = "UPDATE status SET standby='$standby', reboot='$reboot', humidifier='$humidifier', screen='$screen'";
|
||||
mysqli_query($conn, $queryString);
|
||||
if(mysqli_error($conn)){
|
||||
echo json_encode(["error" => "状态更新失败"]);
|
||||
}
|
||||
else{
|
||||
echo json_encode(["success" => "状态更新成功"]);
|
||||
}
|
||||
|
||||
|
||||
|
18
Web/imasBackend/test.php
Normal file
18
Web/imasBackend/test.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Methods: GET, POST');
|
||||
header('Access-Control-Allow-Headers: Content-Type');
|
||||
header('Access-Control-Allow-Headers: Authorization');
|
||||
header('Access-Control-Allow-Headers: X-Requested-With');
|
||||
header("Content-Type: application/json"); // 返回 JSON 格式的响应
|
||||
include_once "db_config.php";
|
||||
$queryString = "select * FROM status";
|
||||
$result = mysqli_query($conn, $queryString);
|
||||
if(mysqli_num_rows($result) > 0){
|
||||
$data = []; // 初始化为空数组
|
||||
while ($row = mysqli_fetch_object($result)) { // 获取查询结果作为对象
|
||||
$data[] = $row; // 将对象追加到数组中
|
||||
}
|
||||
echo substr(json_encode($data),1,58) ; // 输出 JSON 格式的响应
|
||||
}
|
7
Web/imasBackend/weatherInfo.php
Normal file
7
Web/imasBackend/weatherInfo.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Access-Control-Allow-Origin: *"); // 允许所有域名访问
|
||||
header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); // 允许的请求方法
|
||||
header("Access-Control-Allow-Headers: Content-Type"); // 允许的请求头
|
||||
header("Content-type:application/json");
|
||||
$weather = json_decode(file_get_contents('https://restapi.amap.com/v3/weather/weatherInfo?key=12085a54026b8e80ed3f69ec9c328e3e&city=510115&extensions=base&output=JSON'));
|
||||
echo json_encode($weather);
|
5
Web/imasFrontend/babel.config.js
Normal file
5
Web/imasFrontend/babel.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
19
Web/imasFrontend/jsconfig.json
Normal file
19
Web/imasFrontend/jsconfig.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "esnext",
|
||||
"baseUrl": "./",
|
||||
"moduleResolution": "node",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
}
|
||||
}
|
12412
Web/imasFrontend/package-lock.json
generated
Normal file
12412
Web/imasFrontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
58
Web/imasFrontend/package.json
Normal file
58
Web/imasFrontend/package.json
Normal file
@ -0,0 +1,58 @@
|
||||
{
|
||||
"name": "imas",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.7.9",
|
||||
"bootstrap": "^5.3.3",
|
||||
"bootstrap-icons": "^1.11.3",
|
||||
"bootstrap-timepicker": "^0.5.2",
|
||||
"bootstrap-vue": "^2.23.1",
|
||||
"core-js": "^3.8.3",
|
||||
"flatpickr": "^4.6.13",
|
||||
"lodash": "^4.17.21",
|
||||
"pinia": "^2.3.0",
|
||||
"toastify-js": "^1.12.0",
|
||||
"vue": "^3.2.13",
|
||||
"vue-json-viewer": "^3.0.4",
|
||||
"vue-router": "^4.5.0",
|
||||
"vue3-timepicker": "^1.0.0-beta.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.16",
|
||||
"@babel/eslint-parser": "^7.12.16",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@vue/cli-plugin-babel": "~5.0.0",
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"bootstrap": "^5.3.3",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"jquery": "^3.7.1"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/vue3-essential",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "@babel/eslint-parser"
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead",
|
||||
"not ie 11"
|
||||
]
|
||||
}
|
BIN
Web/imasFrontend/public/favicon.ico
Normal file
BIN
Web/imasFrontend/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
17
Web/imasFrontend/public/index.html
Normal file
17
Web/imasFrontend/public/index.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
105
Web/imasFrontend/src/App.vue
Normal file
105
Web/imasFrontend/src/App.vue
Normal file
@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<div class="Main-title h1 mt-0 ms-2 mb-3 ps-3 border-start border-5 border-dark-subtle" @click="clickTitle" >控制中心</div>
|
||||
<router-view></router-view>
|
||||
<footer class="mt-5 text-center border-top border-1">Copyright © 2024-2025 <a href="https://blog.monjack.cn" class="btn-link" style="text-decoration: none">王仁杰</a></footer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
},
|
||||
methods: {
|
||||
clickTitle() {
|
||||
this.$router.push('/HomeView');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@100..900&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&family=ZCOOL+KuaiLe&display=swap');
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
color: #2c3e50;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.roboto-thin {
|
||||
font-family: "Roboto", serif;
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.roboto-light {
|
||||
font-family: "Roboto", serif;
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.roboto-regular {
|
||||
font-family: "Roboto", serif;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.roboto-medium {
|
||||
font-family: "Roboto", serif;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.roboto-bold {
|
||||
font-family: "Roboto", serif;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.roboto-black {
|
||||
font-family: "Roboto", serif;
|
||||
font-weight: 900;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.roboto-thin-italic {
|
||||
font-family: "Roboto", serif;
|
||||
font-weight: 100;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.roboto-light-italic {
|
||||
font-family: "Roboto", serif;
|
||||
font-weight: 300;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.roboto-regular-italic {
|
||||
font-family: "Roboto", serif;
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.roboto-medium-italic {
|
||||
font-family: "Roboto", serif;
|
||||
font-weight: 500;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.roboto-bold-italic {
|
||||
font-family: "Roboto", serif;
|
||||
font-weight: 700;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.roboto-black-italic {
|
||||
font-family: "Roboto", serif;
|
||||
font-weight: 900;
|
||||
font-style: italic;
|
||||
}
|
||||
.Main-title:hover {
|
||||
color: #007bff;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
BIN
Web/imasFrontend/src/assets/logo.png
Normal file
BIN
Web/imasFrontend/src/assets/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
BIN
Web/imasFrontend/src/assets/triangles-1430105_1280.png
Normal file
BIN
Web/imasFrontend/src/assets/triangles-1430105_1280.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 595 KiB |
59
Web/imasFrontend/src/components/APIView.vue
Normal file
59
Web/imasFrontend/src/components/APIView.vue
Normal file
@ -0,0 +1,59 @@
|
||||
<script>
|
||||
import {getWeather} from '@/services/weatherService'
|
||||
import TitleBlock from "@/components/TitleBlock.vue";
|
||||
|
||||
export default {
|
||||
name: "APIView",
|
||||
components: {
|
||||
TitleBlock
|
||||
},
|
||||
data(){
|
||||
return(
|
||||
{
|
||||
res: '',
|
||||
weather: '',
|
||||
temperature: '',
|
||||
winddirection: '',
|
||||
windpower: '',
|
||||
reporttime: ''
|
||||
}
|
||||
)
|
||||
},
|
||||
async created() {
|
||||
try {
|
||||
const weatherData = await getWeather();
|
||||
this.res = weatherData;
|
||||
this.weather = weatherData.weather;
|
||||
this.winddirection = weatherData.winddirection;
|
||||
this.windpower = weatherData.windpower;
|
||||
this.temperature = weatherData.temperature;
|
||||
this.reporttime = weatherData.reporttime;
|
||||
} catch (error) {
|
||||
console.error('获取天气数据失败:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TitleBlock :title="'查看API数据'" />
|
||||
<div class="ms-4 p-2 border rounded-3">
|
||||
<div>天气 : {{ weather }}</div>
|
||||
<div>温度 : {{temperature}}</div>
|
||||
<div>风向 : {{winddirection}}</div>
|
||||
<div>风力 : {{windpower}}</div>
|
||||
<div>更新时间 : {{reporttime}}</div>
|
||||
</div>
|
||||
<div class="ms-4 mt-3 p-2 border rounded-3">
|
||||
<json-viewer
|
||||
:value="res"
|
||||
:expand-depth=5
|
||||
copyable
|
||||
boxed
|
||||
sort></json-viewer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
37
Web/imasFrontend/src/components/ButtonArea.vue
Normal file
37
Web/imasFrontend/src/components/ButtonArea.vue
Normal file
@ -0,0 +1,37 @@
|
||||
<script>
|
||||
import Toastify from 'toastify-js';
|
||||
export default {
|
||||
|
||||
name: "ButtonArea",
|
||||
methods: {
|
||||
showToast() {
|
||||
Toastify({
|
||||
text: "请以管理员身份登录",
|
||||
duration: 3000,
|
||||
close: true
|
||||
}).showToast();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mt-4 text-center">
|
||||
<router-link to="/APIView">
|
||||
<button class="btn btn-secondary w-25 shadow-sm m-2 fs-4"><a>查看API</a></button>
|
||||
</router-link>
|
||||
<router-link to="/SettingsView">
|
||||
<button class="btn btn-secondary w-25 shadow-sm m-2 fs-4"><a>设置</a></button>
|
||||
</router-link>
|
||||
<router-link to="/DebugView">
|
||||
<button class="btn btn-secondary w-25 shadow-sm m-2 fs-4">调试</button>
|
||||
</router-link>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
template{
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
198
Web/imasFrontend/src/components/DebugView.vue
Normal file
198
Web/imasFrontend/src/components/DebugView.vue
Normal file
@ -0,0 +1,198 @@
|
||||
<script>
|
||||
import TitleBlock from "@/components/TitleBlock.vue";
|
||||
import $ from "jquery";
|
||||
|
||||
export default {
|
||||
name: "DebugView",
|
||||
components: {TitleBlock},
|
||||
created() {
|
||||
this.getStatusData();
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
Label_button1: "待机",
|
||||
Label_button2: "重启",
|
||||
Label_button3: "启动加湿",
|
||||
Label_button4: "关闭屏幕",
|
||||
button1: false,
|
||||
button2: false,
|
||||
button3: false,
|
||||
button4: false,
|
||||
data: {
|
||||
standby: 0,
|
||||
reboot: 0,
|
||||
humidifier: 0,
|
||||
screen: 1,
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
button1_click() {
|
||||
console.log("待机");
|
||||
this.button1 = true;
|
||||
setTimeout(() => {
|
||||
this.button1 = false;
|
||||
}, 5000);
|
||||
if (this.Label_button1 === "待机") {
|
||||
this.Label_button1 = "工作";
|
||||
this.button2 = true;
|
||||
this.button3 = true;
|
||||
this.button4 = true;
|
||||
this.data.standby = 1;
|
||||
} else {
|
||||
this.Label_button1 = "待机";
|
||||
this.button2 = false;
|
||||
this.button3 = false;
|
||||
this.button4 = false;
|
||||
this.data.standby = 0;
|
||||
}
|
||||
this.updateData();
|
||||
},
|
||||
button2_click() {
|
||||
console.log("重启");
|
||||
this.button1 = true;
|
||||
this.button2 = true;
|
||||
this.button3 = true;
|
||||
this.button4 = true;
|
||||
setTimeout(() => {
|
||||
this.button1 = false;
|
||||
this.button2 = false;
|
||||
this.button3 = false;
|
||||
this.button4 = false;
|
||||
}, 5000);
|
||||
|
||||
|
||||
this.data.reboot = 1;
|
||||
this.updateData();
|
||||
this.data.reboot = 0;
|
||||
},
|
||||
button3_click() {
|
||||
console.log("启动加湿");
|
||||
this.button3 = true;
|
||||
setTimeout(() => {
|
||||
this.button3 = false;
|
||||
}, 1000);
|
||||
if (this.Label_button3 === "启动加湿") {
|
||||
this.Label_button3 = "停止加湿";
|
||||
this.data.humidifier = 1;
|
||||
} else {
|
||||
this.Label_button3 = "启动加湿";
|
||||
this.data.humidifier = 0;
|
||||
}
|
||||
this.updateData();
|
||||
},
|
||||
button4_click() {
|
||||
console.log("关闭屏幕");
|
||||
this.button4 = true;
|
||||
setTimeout(() => {
|
||||
this.button4 = false;
|
||||
}, 1000);
|
||||
if (this.Label_button4 === "关闭屏幕") {
|
||||
this.Label_button4 = "打开屏幕";
|
||||
this.data.screen = 0;
|
||||
} else {
|
||||
this.Label_button4 = "关闭屏幕";
|
||||
this.data.screen = 1;
|
||||
}
|
||||
this.updateData();
|
||||
},
|
||||
updateData() {
|
||||
$.ajax({
|
||||
url: "http://localhost/debug.php",
|
||||
type: "POST",
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify(this.data),
|
||||
success: (response) => {
|
||||
console.log(response);
|
||||
},
|
||||
error: (xhr, status, error) => {
|
||||
console.log(error);
|
||||
console.log(xhr.responseText);
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
getStatusData(){
|
||||
$.ajax({
|
||||
url: "http://localhost/debug.php",
|
||||
type: "GET",
|
||||
contentType: "application/json",
|
||||
success: (response) => {
|
||||
console.log(response);
|
||||
this.data.standby = parseInt(JSON.parse(response).standby);
|
||||
this.data.reboot = parseInt(JSON.parse(response).reboot);
|
||||
this.data.humidifier = parseInt(JSON.parse(response).humidifier);
|
||||
this.data.screen = parseInt(JSON.parse(response).screen);
|
||||
if (this.data.standby) {
|
||||
this.Label_button1 = "工作";
|
||||
} else {
|
||||
this.Label_button1 = "待机";
|
||||
}
|
||||
if (this.data.reboot) {
|
||||
this.Label_button2 = "重启中";
|
||||
} else {
|
||||
this.Label_button2 = "重启";
|
||||
}
|
||||
if (this.data.humidifier) {
|
||||
this.Label_button3 = "停止加湿";
|
||||
} else {
|
||||
this.Label_button3 = "启动加湿";
|
||||
}
|
||||
if (this.data.screen) {
|
||||
this.Label_button4 = "关闭屏幕";
|
||||
} else {
|
||||
this.Label_button4 = "打开屏幕";
|
||||
}
|
||||
},
|
||||
error: (xhr, status, error) => {
|
||||
console.log(error);
|
||||
console.log(xhr.responseText);
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TitleBlock class="mb-4" title="调试" /><br>
|
||||
|
||||
<div class="text-center me-1 pe-5 ps-5">
|
||||
<table class="table table-sm w-25">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>功能</th>
|
||||
<th>状态</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="table-group-divider">
|
||||
<tr>
|
||||
<td>在线状态</td>
|
||||
<td>{{ data.standby? "离线" : data.reboot? "重启中": "在线" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>启动加湿</td>
|
||||
<td>{{ data.humidifier? "启动中" : "已停止" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>关闭屏幕</td>
|
||||
<td>{{ data.screen? "打开" : "关闭" }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="ms-5 mt-4 btn-group">
|
||||
<button class="btn btn-outline-secondary" v-bind:disabled="button1" @click="button1_click" hidden>{{ Label_button1 }}</button>
|
||||
<button class="btn btn-outline-secondary" v-bind:disabled="button2" @click="button2_click">{{ Label_button2 }}</button>
|
||||
<button class="btn btn-outline-secondary" v-bind:disabled="button3" @click="button3_click">{{ Label_button3 }}</button>
|
||||
<button class="btn btn-outline-secondary" v-bind:disabled="button4" @click="button4_click">{{ Label_button4 }}</button>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
20
Web/imasFrontend/src/components/HomeView.vue
Normal file
20
Web/imasFrontend/src/components/HomeView.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<script>
|
||||
import ButtonArea from "@/components/ButtonArea.vue";
|
||||
import WeatherCard from "@/components/WeatherCard.vue";
|
||||
import RoomCard from "@/components/RoomCard.vue";
|
||||
|
||||
export default {
|
||||
name: "HomeView",
|
||||
components: {RoomCard, WeatherCard, ButtonArea}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<WeatherCard style=""></WeatherCard>
|
||||
<RoomCard></RoomCard>
|
||||
<ButtonArea></ButtonArea>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
68
Web/imasFrontend/src/components/RoomCard.vue
Normal file
68
Web/imasFrontend/src/components/RoomCard.vue
Normal file
@ -0,0 +1,68 @@
|
||||
<script>
|
||||
import {getLocalData} from "@/services/weatherService";
|
||||
|
||||
export default {
|
||||
name: "RoomCard",
|
||||
data() {
|
||||
return {
|
||||
RoomTemp: 20,
|
||||
RoomHumidity: 40,
|
||||
LastUpdateTime: "未获取",
|
||||
RoomNumber: "101",
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
TempMap(temp) {
|
||||
if (temp < 18) {
|
||||
return "冷";
|
||||
} else if (temp < 25) {
|
||||
return "适中";
|
||||
} else if (temp >34) {
|
||||
return "热";
|
||||
} else{
|
||||
return "暖";
|
||||
}
|
||||
},
|
||||
HumidityMap(humidity) {
|
||||
if (humidity < 30) {
|
||||
return "较干燥";
|
||||
} else if (humidity < 60) {
|
||||
return "正常";
|
||||
} else {
|
||||
return "较湿";
|
||||
}
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
const localData = await getLocalData();
|
||||
console.log(localData);
|
||||
this.RoomTemp = localData[0].temperature;
|
||||
console.log(this.RoomTemp);
|
||||
this.RoomHumidity = localData[0].humidity;
|
||||
console.log(this.RoomHumidity);
|
||||
this.LastUpdateTime = localData[0].time;
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="border border-0 border-dark-subtle m-3 p-4 rounded-4 shadow">
|
||||
<div class="h1 ms-2 mb-2 fw-semibold roboto-bold">房间</div>
|
||||
<div class="fs-3 ms-3 text-black-75">
|
||||
<div class="fs-2 mt-3 mb-2 border-bottom border-2">
|
||||
<span class=""></span>
|
||||
</div>
|
||||
|
||||
<i class="bi bi-thermometer-half"></i>
|
||||
{{ TempMap(RoomTemp) }} {{ RoomTemp }}℃
|
||||
<div class="mt-4 ms-1 fs-4">
|
||||
<i class="bi bi-moisture"></i> <span class="ms-1 me-4">{{HumidityMap(RoomHumidity)}}</span><span>{{ RoomHumidity }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-end fs-6 fw-light mt-3"><span class="me-4">更新时间</span><span>{{ LastUpdateTime }}</span></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
155
Web/imasFrontend/src/components/SettingsView.vue
Normal file
155
Web/imasFrontend/src/components/SettingsView.vue
Normal file
@ -0,0 +1,155 @@
|
||||
<script>
|
||||
import TitleBlock from "@/components/TitleBlock.vue";
|
||||
import TimePicker from "@/components/TimePicker.vue";
|
||||
import ThresholdPicker from "@/components/ThresholdPicker.vue";
|
||||
|
||||
import axios from "axios";
|
||||
export default {
|
||||
name: "SettingsView",
|
||||
components: {TimePicker, TitleBlock, ThresholdPicker},
|
||||
created() {
|
||||
this.getSettings();
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
timeSettings:{
|
||||
times_Power: {
|
||||
times:{
|
||||
PowerOn: "12:00",
|
||||
PowerOff: "12:30"
|
||||
},
|
||||
enable_boot: false,
|
||||
},
|
||||
times_Humidity: {
|
||||
times:{
|
||||
HumidityOn: "12:00",
|
||||
HumidityOff: "12:30",
|
||||
},
|
||||
enable_boot: false,
|
||||
},
|
||||
},
|
||||
thresholdSettings:{
|
||||
Threshold_Humidity:{
|
||||
thresholds: {
|
||||
min: 20,
|
||||
max: 80,
|
||||
},
|
||||
enable_boot: false,
|
||||
},
|
||||
Threshold_Temperature:{
|
||||
thresholds: {
|
||||
min: 20,
|
||||
max: 26,
|
||||
},
|
||||
enable_boot: false,
|
||||
},
|
||||
},
|
||||
loaded: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
save() {
|
||||
this.postSettings();
|
||||
},
|
||||
cancel() {
|
||||
window.location.reload();
|
||||
},
|
||||
getSettings() {
|
||||
axios.get("http://locahost/getSetting.php").then(response => {
|
||||
console.log(response.data);
|
||||
this.timeSettings.times_Power = {
|
||||
times: {
|
||||
PowerOn: response.data[0].boot,
|
||||
PowerOff: response.data[0].shutdown,
|
||||
},
|
||||
enable_boot: response.data[0].enable_boot == 1,
|
||||
}
|
||||
console.log(this.timeSettings.times_Power);
|
||||
this.timeSettings.times_Humidity = {
|
||||
times: {
|
||||
HumidityOn: response.data[0].start,
|
||||
HumidityOff: response.data[0].end,
|
||||
},
|
||||
enable_boot: response.data[0].enable_humidify == 1,
|
||||
}
|
||||
this.thresholdSettings.Threshold_Humidity = {
|
||||
thresholds: {
|
||||
min: response.data[0].min_humidity,
|
||||
max: response.data[0].max_humidity,
|
||||
},
|
||||
enable_boot: response.data[0].enable_humi_threshold == 1,
|
||||
}
|
||||
this.thresholdSettings.Threshold_Temperature = {
|
||||
thresholds: {
|
||||
min: response.data[0].min_temperature,
|
||||
max: response.data[0].max_temperature,
|
||||
},
|
||||
enable_boot: response.data[0].enable_temp_threshold == 1,
|
||||
}
|
||||
this.loaded = true;
|
||||
}).catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
postSettings() {
|
||||
axios.post("http://locahost/postSetting.php", {
|
||||
boot: this.timeSettings.times_Power.times.PowerOn,
|
||||
shutdown: this.timeSettings.times_Power.times.PowerOff,
|
||||
start: this.timeSettings.times_Humidity.times.HumidityOn,
|
||||
end: this.timeSettings.times_Humidity.times.HumidityOff,
|
||||
min_humidity: this.thresholdSettings.Threshold_Humidity.thresholds.min,
|
||||
max_humidity: this.thresholdSettings.Threshold_Humidity.thresholds.max,
|
||||
min_temperature: this.thresholdSettings.Threshold_Temperature.thresholds.min,
|
||||
max_temperature: this.thresholdSettings.Threshold_Temperature.thresholds.max,
|
||||
enable_boot: this.timeSettings.times_Power.enable_boot? 1 : 0,
|
||||
enable_humidify: this.timeSettings.times_Humidity.enable_boot? 1 : 0,
|
||||
enable_humi_threshold: this.thresholdSettings.Threshold_Humidity.enable_boot? 1 : 0,
|
||||
enable_temp_threshold: this.thresholdSettings.Threshold_Temperature.enable_boot? 1 : 0,
|
||||
}).then(response => {
|
||||
console.log(response);
|
||||
this.loaded = false;
|
||||
}).catch(error => {
|
||||
console.log(error);
|
||||
this.loaded = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="loaded">
|
||||
<TitleBlock title="设置" />
|
||||
<span hidden>{{timeSettings.times_Power.times.PowerOn}}</span>
|
||||
<span hidden>{{timeSettings.times_Power.times.PowerOff}}</span>
|
||||
<span hidden>{{timeSettings.times_Humidity.times.HumidityOn}}</span>
|
||||
<span hidden>{{timeSettings.times_Humidity.times.HumidityOff}}</span>
|
||||
<span hidden>{{thresholdSettings.Threshold_Humidity.thresholds.min}}</span>
|
||||
<span hidden>{{thresholdSettings.Threshold_Humidity.thresholds.max}}</span>
|
||||
<span hidden>{{thresholdSettings.Threshold_Temperature.thresholds.min}}</span>
|
||||
<span hidden>{{thresholdSettings.Threshold_Temperature.thresholds.max}}</span>
|
||||
|
||||
<div class="ms-5 mt-2 fs-5 ">
|
||||
<TimePicker :pickers="timeSettings.times_Power.times" v-model="timeSettings.times_Power" :title="'定时开关机'" :enable="timeSettings.times_Power.enable_boot" />
|
||||
</div>
|
||||
|
||||
<div class="ms-5 mt-2 fs-5 ">
|
||||
<TimePicker v-model="timeSettings.times_Humidity" :title="'定时加湿'" :enable="timeSettings.times_Humidity.enable_boot" :pickers=timeSettings.times_Humidity.times />
|
||||
</div>
|
||||
|
||||
<div class="ms-5 mt-2 fs-5 ">
|
||||
<ThresholdPicker v-model="thresholdSettings.Threshold_Temperature" :title="'温度阈值'" :enable="thresholdSettings.Threshold_Temperature.enable_boot" :Thresholds=thresholdSettings.Threshold_Temperature.thresholds />
|
||||
</div>
|
||||
<div class="ms-5 mt-2 fs-5 ">
|
||||
<ThresholdPicker v-model="thresholdSettings.Threshold_Humidity" :title="'湿度阈值'" :enable="thresholdSettings.Threshold_Humidity.enable_boot" :Thresholds=thresholdSettings.Threshold_Humidity.thresholds />
|
||||
</div>
|
||||
<div class="mt-5">
|
||||
<button class="btn btn-secondary ms-5 mt-2 fs-5" @click="save">保存</button>
|
||||
<button class="btn btn-secondary ms-5 mt-2 fs-5" @click="cancel">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
85
Web/imasFrontend/src/components/ThresholdPicker.vue
Normal file
85
Web/imasFrontend/src/components/ThresholdPicker.vue
Normal file
@ -0,0 +1,85 @@
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "ThresholdPicker",
|
||||
components: {},
|
||||
mounted() {
|
||||
this.LocalThresholds = this.Thresholds
|
||||
this.showThresholdPicker = this.enable
|
||||
},
|
||||
methods: {
|
||||
updateThresholds() {
|
||||
this.$emit("update:Thresholds", this.LocalThresholds)
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showThresholdPicker: false,
|
||||
LocalThresholds: {
|
||||
min: "",
|
||||
max: "",
|
||||
},
|
||||
unit: "%"
|
||||
}
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
Thresholds: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
min: "",
|
||||
max: "",
|
||||
})
|
||||
},
|
||||
enable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="d-flex align-items-center flex-wrap">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="form-check-input"
|
||||
role="switch"
|
||||
id="showThresholdPicker"
|
||||
v-model="showThresholdPicker"
|
||||
/>
|
||||
<label class="form-check-label me-4" for="showThresholdPicker">{{ title }}</label>
|
||||
</div>
|
||||
<div v-if="showThresholdPicker">
|
||||
<input
|
||||
v-for="(threshold, index) in LocalThresholds"
|
||||
:key="index"
|
||||
:placeholder="index ==='min'? '输入最小阈值' : '输入最大阈值'"
|
||||
@input="updateThresholds"
|
||||
v-model="LocalThresholds[index]"
|
||||
type="text"
|
||||
class="picker-input fs-5" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.picker-input {
|
||||
width: 200px;
|
||||
margin-left: 9px;
|
||||
padding: 10px 10px 10px;
|
||||
font-size: 14px;
|
||||
border: 1px solid #ccc;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.picker-input:focus {
|
||||
border: 2px solid #101010;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
</style>
|
72
Web/imasFrontend/src/components/TimePicker.vue
Normal file
72
Web/imasFrontend/src/components/TimePicker.vue
Normal file
@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<div class="d-flex align-items-center flex-wrap ">
|
||||
<!-- Checkbox to toggle timepicker visibility -->
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="form-check-input"
|
||||
role="switch"
|
||||
id="showTimepicker"
|
||||
v-model="showTimepicker"
|
||||
/>
|
||||
<label class="form-check-label me-4" for="showTimepicker">{{ title }}</label>
|
||||
</div>
|
||||
<div v-if="showTimepicker">
|
||||
<VueTimepicker
|
||||
v-for="(picker, index) in pickers"
|
||||
:key="index"
|
||||
:picker="picker"
|
||||
class="mt-2 ms-2"
|
||||
:placeholder="index"
|
||||
v-model="time[index]"
|
||||
@change="updateTime(index)"
|
||||
>
|
||||
<template v-slot:icon>
|
||||
<i class="bi bi-clock"></i>
|
||||
</template>
|
||||
</VueTimepicker>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VueTimepicker from "vue3-timepicker";
|
||||
export default {
|
||||
name: "TimePicker",
|
||||
props: {
|
||||
title: String,
|
||||
pickers: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({
|
||||
time: "00:00",
|
||||
}),
|
||||
},
|
||||
enable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showTimepicker: false,
|
||||
time: {}, // 本地时间数据
|
||||
};
|
||||
},
|
||||
components: {
|
||||
VueTimepicker,
|
||||
},
|
||||
mounted() {
|
||||
this.showTimepicker = this.enable;
|
||||
this.time = { ...this.pickers }; // 初始化 time 数据
|
||||
},
|
||||
methods: {
|
||||
updateTime() {
|
||||
this.$emit("update:pickers", Object.assign({}, this.time, this.showTimepicker)); // 确保事件名称和父组件一致
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
24
Web/imasFrontend/src/components/TitleBlock.vue
Normal file
24
Web/imasFrontend/src/components/TitleBlock.vue
Normal file
@ -0,0 +1,24 @@
|
||||
<script>
|
||||
export default {
|
||||
name: "TitleBlock",
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="title ms-4 ps-1 pt-2 pe-1 mb-3 mt-1 border-bottom border-3 ">
|
||||
<h2>{{ title }}</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.title {
|
||||
display: inline-block; /* 使宽度适应内容 */
|
||||
user-select: none; /* 防止选中文本 */
|
||||
}
|
||||
</style>
|
152
Web/imasFrontend/src/components/WeatherCard.vue
Normal file
152
Web/imasFrontend/src/components/WeatherCard.vue
Normal file
@ -0,0 +1,152 @@
|
||||
<script>
|
||||
|
||||
import {getWeather, getIPInfo} from "@/services/weatherService";
|
||||
import TitleBlock from "@/components/TitleBlock.vue";
|
||||
|
||||
export default {
|
||||
name: "WeatherCard",
|
||||
components: {
|
||||
TitleBlock
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
weather: '',
|
||||
temperature: '',
|
||||
winddirection: '',
|
||||
windpower: '',
|
||||
reporttime: '',
|
||||
clothingIndex: '',
|
||||
windspeedMap: {
|
||||
'0': 0.5,
|
||||
'1': 0.9,
|
||||
'2': 2.5,
|
||||
'3': 4.4,
|
||||
'4': 6.7,
|
||||
'5': 9.3,
|
||||
'6': 12.5,
|
||||
'7': 15.5,
|
||||
'8': 19.0,
|
||||
'9': 22.6,
|
||||
'10': 26.45,
|
||||
'11': 30.55,
|
||||
'12': 32
|
||||
},
|
||||
CloudMap: {
|
||||
'晴': 0,
|
||||
'阴': 9,
|
||||
'多云': 6,
|
||||
'雨': 10,
|
||||
},
|
||||
ip: '',
|
||||
address: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
GetClothingIndex(temp, windSpeed) {
|
||||
const tFelt = calculateWindChill(temp, windSpeed);
|
||||
function calculateWindChill(temp, windSpeed) {
|
||||
return (
|
||||
13.12 +
|
||||
0.6215 * temp -
|
||||
11.37 * Math.pow(windSpeed, 0.16) +
|
||||
0.3965 * temp * Math.pow(windSpeed, 0.16)
|
||||
);
|
||||
}
|
||||
if (tFelt > 26) {
|
||||
return "短袖或薄长袖";
|
||||
} else if (tFelt >= 20 && tFelt <= 26) {
|
||||
return "薄外套、长袖";
|
||||
} else if (tFelt >= 10 && tFelt < 20) {
|
||||
return "厚外套";
|
||||
} else if (tFelt >= 0 && tFelt < 10) {
|
||||
return "棉衣或羽绒服";
|
||||
} else {
|
||||
return "加厚羽绒服,注意保暖";
|
||||
}
|
||||
}
|
||||
},
|
||||
// GetClothingIndex() {
|
||||
// let Ic, Ts, Tv, Tr, Ta, H, Rat, Ia, V, Nt, Nl;
|
||||
// Nl = 0;
|
||||
// Ts = 33;
|
||||
// V = this.windspeedMap[this.windpower.match(/\d+/g)];
|
||||
// Nt = this.weather in this.CloudMap? this.CloudMap[this.weather] : 5;
|
||||
// Ta = 20;
|
||||
// Ia = 0.40 / Math.pow(V, 0.406);
|
||||
// Tv = 0.0246 * Math.pow(Math.log10(7.23 * V), 3) - 0.4525 * Math.pow(Math.log10(7.23 * V), 2) + 3.2398 * Math.log10(7.23 * V);
|
||||
// Tr = 0.42 * (1- 0.45 * (Nt + Nl)) * 0.5 * Ia;
|
||||
// H = 0.93244 * 4.1841 * (0.104 * Ta*Ta - 5.1403 * Ta + 117.13);
|
||||
// Ta >= 25?
|
||||
// Rat = 0.0775 + 0.001 * Ta * (0.1 * Ta * (0.01 * Ta * (1.235 * Ta - 54.8752) + 10.1044) - 3.2813)
|
||||
// : Rat = 0.24;
|
||||
// Ic = (Ts - Ta - Tv + Tr)/(H * (1 - Rat) * 0.043) - Ia;
|
||||
// console.log(Ic);
|
||||
// return Ic;
|
||||
//
|
||||
// }
|
||||
async created() {
|
||||
try {
|
||||
const weatherData = await getWeather();
|
||||
const ipInfo = await getIPInfo();
|
||||
this.address = ipInfo.province + ipInfo.city;
|
||||
this.weather = weatherData.weather;
|
||||
this.winddirection = weatherData.winddirection;
|
||||
this.windpower = weatherData.windpower;
|
||||
this.temperature = weatherData.temperature;
|
||||
this.reporttime = weatherData.reporttime;
|
||||
} catch (error) {
|
||||
console.error('获取天气数据失败:', error);
|
||||
}
|
||||
this.clothingIndex = this.GetClothingIndex(this.temperature, this.windspeedMap[this.windpower.match(/\d+/g)]);
|
||||
|
||||
},
|
||||
computed: {
|
||||
iconClass() {
|
||||
switch (this.weather) {
|
||||
case '晴':
|
||||
return 'bi-sun';
|
||||
case '阴':
|
||||
return 'bi-cloud-drizzle';
|
||||
case '多云':
|
||||
return 'bi-cloud-fog';
|
||||
case '雨':
|
||||
return 'bi-cloud-rain';
|
||||
case '雪':
|
||||
return 'bi-cloud-snow';
|
||||
default:
|
||||
return 'bi-cloud';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TitleBlock title="概览"></TitleBlock>
|
||||
<div class="border border-0 border-dark-subtle m-3 p-4 rounded-4 shadow">
|
||||
<div class="h1 ms-2 mb-2 fw-semibold roboto-bold">天气</div>
|
||||
<div class="fs-3 ms-3 text-black-75">
|
||||
<div class="fs-2 mt-3 mb-2 border-bottom border-2">
|
||||
<span class=""></span>
|
||||
</div>
|
||||
|
||||
<div class="fs-4 mb-3 mt-3">{{ address }}</div>
|
||||
<i :class="iconClass"></i>
|
||||
{{ weather }} {{ temperature }} ℃
|
||||
<div class="mt-2 fs-4">
|
||||
<i class="bi bi-wind"></i> <span class="me-4">{{ winddirection }}</span><span>{{ windpower }}</span>
|
||||
</div>
|
||||
<div class="mt-2 fs-4">
|
||||
<span class="me-4">适宜衣物</span><span>{{ clothingIndex }}</span>
|
||||
</div>
|
||||
<div class="text-end fs-6 fw-light mt-3">
|
||||
点击查看未来天气
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-end fs-6 fw-light mt-1"><span class="me-4">更新时间</span><span>{{reporttime}}</span></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
28
Web/imasFrontend/src/main.js
Normal file
28
Web/imasFrontend/src/main.js
Normal file
@ -0,0 +1,28 @@
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
import 'jquery/dist/jquery.min.js'
|
||||
import 'bootstrap/dist/css/bootstrap.min.css'
|
||||
import 'bootstrap/dist/js/bootstrap.min.js'
|
||||
import 'bootstrap-icons/font/bootstrap-icons.css'
|
||||
import "toastify-js/src/toastify.css"
|
||||
import Toastify from 'toastify-js'
|
||||
|
||||
|
||||
|
||||
import 'vue3-timepicker/dist/VueTimepicker.css'
|
||||
import VueTimepicker from 'vue3-timepicker'
|
||||
|
||||
import JsonViewer from 'vue-json-viewer'
|
||||
import router from './router'
|
||||
import App from './App.vue'
|
||||
|
||||
const pinia = createPinia()
|
||||
const app = createApp(App);
|
||||
app.use(router);
|
||||
app.use(JsonViewer);
|
||||
app.use(VueTimepicker);
|
||||
app.use(Toastify);
|
||||
app.use(pinia);
|
||||
|
||||
app.mount('#app');
|
52
Web/imasFrontend/src/router/index.js
Normal file
52
Web/imasFrontend/src/router/index.js
Normal file
@ -0,0 +1,52 @@
|
||||
import {createRouter, createWebHistory} from "vue-router";
|
||||
import WeatherCard from "@/components/WeatherCard.vue";
|
||||
import RoomCard from "@/components/RoomCard.vue";
|
||||
import HomeView from "@/components/HomeView.vue";
|
||||
import DebugView from "@/components/DebugView.vue";
|
||||
import APIView from "@/components/APIView.vue";
|
||||
import SettingsView from "@/components/SettingsView.vue";
|
||||
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/WeatherCard',
|
||||
name: 'WeatherCard',
|
||||
component: WeatherCard
|
||||
},
|
||||
{
|
||||
path: '/RoomCard',
|
||||
name: 'RoomCard',
|
||||
component: RoomCard
|
||||
},
|
||||
{
|
||||
path: '/DebugView',
|
||||
name: 'DebugView',
|
||||
component: DebugView
|
||||
},
|
||||
{
|
||||
path: '/HomeView',
|
||||
name: 'HomeView',
|
||||
component: HomeView
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/HomeView',
|
||||
},
|
||||
{
|
||||
path: '/APIView',
|
||||
name: 'APIView',
|
||||
component: APIView
|
||||
},
|
||||
{
|
||||
path: '/SettingsView',
|
||||
name: 'SettingsView',
|
||||
component: SettingsView
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes
|
||||
});
|
||||
|
||||
export default router
|
35
Web/imasFrontend/src/services/weatherService.js
Normal file
35
Web/imasFrontend/src/services/weatherService.js
Normal file
@ -0,0 +1,35 @@
|
||||
// weatherService.js
|
||||
import axios from "axios";
|
||||
|
||||
export async function getWeather() {
|
||||
try {
|
||||
const response = await axios.get("http://monjack.cn/weatherInfo.php");
|
||||
const weatherData = response.data.lives[0];
|
||||
return weatherData;
|
||||
// 将 API 数据更新到 Pinia Store
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch weather data:", error);
|
||||
throw error; // 确保将错误抛出,以便调用者可以捕获
|
||||
}
|
||||
}
|
||||
|
||||
export async function getIPInfo() {
|
||||
try {
|
||||
const response = await axios.get("https://restapi.amap.com/v3/ip?key=12085a54026b8e80ed3f69ec9c328e3e");
|
||||
return response.data;
|
||||
// 将 API 数据更新到 Pinia Store
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch IP info:", error);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getLocalData() {
|
||||
try {
|
||||
const response = await axios.get("http://localhost/getLocalData.php");
|
||||
return response.data;
|
||||
// 将 API 数据更新到 Pinia Store
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch local data:", error);
|
||||
}
|
||||
}
|
||||
|
22
Web/imasFrontend/vue.config.js
Normal file
22
Web/imasFrontend/vue.config.js
Normal file
@ -0,0 +1,22 @@
|
||||
const { defineConfig } = require('@vue/cli-service')
|
||||
// module.exports = defineConfig({
|
||||
// transpileDependencies: true
|
||||
// })
|
||||
// defineConfig 这里是vue3 的默认代码
|
||||
const webpack = require("webpack")
|
||||
|
||||
module.exports = defineConfig({
|
||||
// 配置插件参数
|
||||
configureWebpack: {
|
||||
plugins: [
|
||||
// 配置 jQuery 插件的参数
|
||||
new webpack.ProvidePlugin({
|
||||
$: 'jquery',
|
||||
jQuery: 'jquery',
|
||||
'window.jQuery': 'jquery',
|
||||
Popper: ['popper.js', 'default']
|
||||
})
|
||||
]
|
||||
}
|
||||
})
|
||||
|
Reference in New Issue
Block a user