Mam sobie taki oto soft:
Code: Select all
/*
Copyright (C) AC SOFTWARE SP. Z O.O.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define STATUS_LED_GPIO 2
#include <SuplaDevice.h>
#include <supla/network/esp_wifi.h>
#include <supla/device/status_led.h>
#include <supla/storage/littlefs_config.h>
#include <supla/network/esp_web_server.h>
#include <supla/network/html/device_info.h>
#include <supla/network/html/protocol_parameters.h>
#include <supla/network/html/status_led_parameters.h>
#include <supla/network/html/wifi_parameters.h>
#include <supla/device/supla_ca_cert.h>
#include <supla/control/virtual_relay.h>
#include <supla/storage/eeprom.h>
Supla::Eeprom eeprom;
Supla::ESPWifi wifi;
Supla::LittleFsConfig configSupla;
Supla::Device::StatusLed statusLed(STATUS_LED_GPIO, true); // inverted state
Supla::EspWebServer suplaServer;
Supla::Control::VirtualRelay *vr = nullptr;
// Ustawienia MikroTik
const char* mt_ip = "192.168.1.1";
const int mt_port = 1234;
const char* mt_user = "supla";
const char* mt_pass = "alpus";
bool stan_portu_sfp_aktualny;
bool stan_jaki_powinien_byc;
unsigned long lastcheck_port = 0;
WiFiClient client;
void setup() {
Serial.begin(115200);
// HTML www component
new Supla::Html::DeviceInfo(&SuplaDevice);
new Supla::Html::WifiParameters;
new Supla::Html::ProtocolParameters;
new Supla::Html::StatusLedParameters;
// Channel #0 Virtual Relay
vr = new Supla::Control::VirtualRelay();
vr->setDefaultFunction(SUPLA_CHANNELFNC_POWERSWITCH);
// Enable state restore after device restart:
vr->setDefaultStateRestore();
// configure defualt Supla CA certificate
SuplaDevice.setSuplaCACert(suplaCACert);
SuplaDevice.setSupla3rdPartyCACert(supla3rdCACert);
SuplaDevice.begin();
}
void loop() {
SuplaDevice.iterate();
if(WiFi.status() == WL_CONNECTED){
if (millis() - lastcheck_port >= 1000) {
lastcheck_port = millis();
checkPort("sfp");
stan_jaki_powinien_byc = 0;
if(vr->isOn()){stan_jaki_powinien_byc = 1;}
}
if(stan_jaki_powinien_byc == 0 && stan_portu_sfp_aktualny == 1){
disablePort("sfp");
Serial.println("DISABLE SFP");
}
if(stan_jaki_powinien_byc == 1 && stan_portu_sfp_aktualny == 0){
enablePort("sfp");
Serial.println("ENABLE SFP");
}
}
}
// -------------------------------
// Funkcja sprawdzająca stan portu
bool checkPort(const String& iface) {
if (!mtLogin()) return false;
//Serial.println("Sprawdzanie stanu portu: " + iface);
writeWord("/interface/ethernet/print");
writeWord("=.proplist=name,disabled");
writeWord("?name"); // <-- bez "="
writeWord(iface); // <-- nazwa portu jako osobne słowo
endSentence();
delay(200);
bool portEnabled = false;
while (client.available()) {
String line = client.readStringUntil(0x00);
//Serial.println("DEBUG: " + line); // debug całej odpowiedzi
if (line.indexOf("disabled=") >= 0) {
portEnabled = line.indexOf("true") < 0; // true → wyłączony, false → włączony
}
}
if(portEnabled == true){
stan_portu_sfp_aktualny = 1;
}else{
stan_portu_sfp_aktualny = 0;
}
mtLogout();
if(stan_portu_sfp_aktualny == 1){
Serial.println("Port SFP jest ENABLE");
}
if(stan_portu_sfp_aktualny == 0){
Serial.println("Port SFP jest DISABLE");
}
return portEnabled;
}
// Flaga stanu portu
unsigned long lastToggle = 0;
// -------------------------------
// Funkcja: wyślij "słowo" do MikroTik API
void writeWord(const String& word) {
int len = word.length();
client.write((uint8_t)len);
client.print(word);
}
// Funkcja: zakończenie sekwencji komendy
void endSentence() {
client.write((uint8_t)0x00);
}
// -------------------------------
// Funkcja logowania do MikroTik
bool mtLogin() {
if (!client.connect(mt_ip, mt_port)) {
Serial.println("❌ Brak połączenia z MikroTik");
return false;
}
// Login i hasło (RouterOS v6/v7 – prosty login)
writeWord("/login");
writeWord("=name=" + String(mt_user));
writeWord("=password=" + String(mt_pass));
endSentence();
delay(200);
while (client.available()) client.read(); // czyszczenie bufora
//Serial.println("Zalogowano");
return true;
}
// Funkcja: wylogowanie (zamknięcie sesji)
void mtLogout() {
if (client.connected()) {
client.stop(); // zamyka socket
//Serial.println("Wylogowano (rozłączono)");
}
}
// -------------------------------
// Funkcja: włączanie portu
void enablePort(const String& iface) {
if (!mtLogin()) return;
writeWord("/interface/ethernet/enable");
writeWord("=numbers=" + iface);
endSentence();
Serial.println("Wysłano rozkaz: ENABLE " + iface);
delay(100);
mtLogout();
}
// Funkcja: wyłączanie portu
void disablePort(const String& iface) {
if (!mtLogin()) return;
writeWord("/interface/ethernet/disable");
writeWord("=numbers=" + iface);
endSentence();
Serial.println("Wysłano rozkaz: DISABLE " + iface);
delay(100);
mtLogout();
}Funkcja checkPort("sfp") zwraca mi w zmiennej stan_portu_sfp_aktualny to czy port jest włączony czy wyłaczony (1 = włączony, 0 = wyłaczony).
O ile komunikacja wysyłania rozkazów poprzez wirtualny przekaźnik działa w jedną stronę (sterowanie z telefonu), to mam problem z aktualizacją stanów w drugą stronę gdy ręcznie na mikrotiku zmienie ENABLE / DISABLE to chciałbym to odzwierciedlić w apce.
Wiem że muszę użyć opcji vr-TurnOn() i vr-TurnOff(), ale wszystko się rozbija o kierunkowość rozkazu.
Pomoże ktoś?
