Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release-factory.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build & Release Factory Images [Release]
name: Build & Release Factory Images with Webhook [Release]

on:
release:
Expand Down
2 changes: 2 additions & 0 deletions main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ SRCS
"./tasks/power_management_task.c"
"./tasks/statistics_task.c"
"./tasks/hashrate_monitor_task.c"
"./tasks/webhook_task.c"
"./thermal/EMC2101.c"
"./thermal/EMC2103.c"
"./thermal/EMC2302.c"
Expand Down Expand Up @@ -67,6 +68,7 @@ PRIV_REQUIRES
"esp_psram"
"esp_timer"
"esp_wifi"
"esp_http_client"
"json"
"nvs_flash"
"spiffs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,36 @@ <h3 class="mt-5">Statistics</h3>
</div>
</div>

<h3 class="mt-5">Webhook</h3>

<div class="card">
<div class="field-checkbox grid my-2">
<div class="col-1 md:col-10 md:flex-order-2">
<p-checkbox name="webhookEnabled" formControlName="webhookEnabled" inputId="webhookEnabled" [binary]="true"></p-checkbox>
</div>
<label for="webhookEnabled" class="col-11 m-0 pl-3 md:col-2 md:flex-order-1 md:p-2">Enable Webhook</label>
</div>

<div *ngIf="form.controls['webhookEnabled'].value" class="field grid p-fluid">
<label for="webhookUrl" class="col-12 md:col-2 md:m-0">Webhook URL</label>
<div class="col-12 md:col-10">
<input pInputText id="webhookUrl" formControlName="webhookUrl" type="url" placeholder="https://your-server.com/webhook" />
</div>
</div>

<div *ngIf="form.controls['webhookEnabled'].value" class="field grid p-fluid">
<label class="col-12 md:col-2 hidden md:flex md:m-0 relative hover-next-input">
Interval (seconds)
</label>
<div class="col-12 md:col-10">
<label class="block mb-1">
<span class="md:hidden mr-1">Interval:</span>{{form.controls['webhookInterval'].value}} seconds
</label>
<p-slider [min]="10" [max]="3600" [step]="10" formControlName="webhookInterval"></p-slider>
</div>
</div>
</div>

<div class="flex mt-5 gap-3">
<button pButton [disabled]="!form.dirty || form.invalid" (click)="updateSystem()"
class="btn btn-primary">Save</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ export class EditComponent implements OnInit, OnDestroy, OnChanges {
Validators.required,
Validators.min(0),
Validators.max(this.statsFrequencyMaxValue)
]],
webhookEnabled: [(info as any).webhookEnabled == 1 || (info as any).webhookEnabled === true, [Validators.required]],
webhookUrl: [{value: (info as any).webhookUrl || '', disabled: !((info as any).webhookEnabled == 1 || (info as any).webhookEnabled === true)}, [Validators.required]],
webhookInterval: [{value: (info as any).webhookInterval || 60, disabled: !((info as any).webhookEnabled == 1 || (info as any).webhookEnabled === true)}, [
Validators.required,
Validators.min(10),
Validators.max(3600)
]]
});

Expand All @@ -190,6 +197,19 @@ export class EditComponent implements OnInit, OnDestroy, OnChanges {
}
});

this.form.controls['webhookEnabled'].valueChanges.pipe(
startWith(this.form.controls['webhookEnabled'].value),
takeUntil(this.destroy$)
).subscribe(webhookEnabled => {
if (webhookEnabled) {
this.form.controls['webhookUrl'].enable();
this.form.controls['webhookInterval'].enable();
} else {
this.form.controls['webhookUrl'].disable();
this.form.controls['webhookInterval'].disable();
}
});

// Add custom value to predefined steps
if (DISPLAY_TIMEOUT_STEPS.filter(x => x === info.displayTimeout).length === 0) {
DISPLAY_TIMEOUT_STEPS.push(info.displayTimeout);
Expand Down Expand Up @@ -341,7 +361,10 @@ export class EditComponent implements OnInit, OnDestroy, OnChanges {
'manualFanSpeed',
'temptarget',
'overheat_mode',
'statsFrequency'
'statsFrequency',
'webhookEnabled',
'webhookUrl',
'webhookInterval'
];
}

Expand Down
167 changes: 4 additions & 163 deletions main/http_server/http_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,171 +794,12 @@ static esp_err_t GET_system_info(httpd_req_t * req)
return ESP_OK;
}

char * ssid = nvs_config_get_string(NVS_CONFIG_WIFI_SSID);
char * hostname = nvs_config_get_string(NVS_CONFIG_HOSTNAME);
char * ipv4 = GLOBAL_STATE->SYSTEM_MODULE.ip_addr_str;
char * ipv6 = GLOBAL_STATE->SYSTEM_MODULE.ipv6_addr_str;
char * stratumURL = nvs_config_get_string(NVS_CONFIG_STRATUM_URL);
char * fallbackStratumURL = nvs_config_get_string(NVS_CONFIG_FALLBACK_STRATUM_URL);
char * stratumUser = nvs_config_get_string(NVS_CONFIG_STRATUM_USER);
char * fallbackStratumUser = nvs_config_get_string(NVS_CONFIG_FALLBACK_STRATUM_USER);
char * stratumCert = nvs_config_get_string(NVS_CONFIG_STRATUM_CERT);
char * fallbackStratumCert = nvs_config_get_string(NVS_CONFIG_FALLBACK_STRATUM_CERT);
char * display = nvs_config_get_string(NVS_CONFIG_DISPLAY);
float frequency = nvs_config_get_float(NVS_CONFIG_ASIC_FREQUENCY);

uint8_t mac[6];
esp_wifi_get_mac(WIFI_IF_STA, mac);
char formattedMac[18];
snprintf(formattedMac, sizeof(formattedMac), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

int8_t wifi_rssi = -90;
get_wifi_current_rssi(&wifi_rssi);

cJSON * root = cJSON_CreateObject();
cJSON_AddFloatToObject(root, "power", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.power);
cJSON_AddFloatToObject(root, "voltage", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.voltage);
cJSON_AddFloatToObject(root, "current", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.current);
cJSON_AddFloatToObject(root, "temp", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.chip_temp_avg);
cJSON_AddFloatToObject(root, "temp2", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.chip_temp2_avg);
cJSON_AddFloatToObject(root, "vrTemp", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.vr_temp);
cJSON_AddNumberToObject(root, "maxPower", GLOBAL_STATE->DEVICE_CONFIG.family.max_power);
cJSON_AddNumberToObject(root, "nominalVoltage", GLOBAL_STATE->DEVICE_CONFIG.family.nominal_voltage);
cJSON_AddFloatToObject(root, "hashRate", GLOBAL_STATE->SYSTEM_MODULE.current_hashrate);
cJSON_AddFloatToObject(root, "hashRate_1m", GLOBAL_STATE->SYSTEM_MODULE.hashrate_1m);
cJSON_AddFloatToObject(root, "hashRate_10m", GLOBAL_STATE->SYSTEM_MODULE.hashrate_10m);
cJSON_AddFloatToObject(root, "hashRate_1h", GLOBAL_STATE->SYSTEM_MODULE.hashrate_1h);
cJSON_AddFloatToObject(root, "expectedHashrate", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.expected_hashrate);
cJSON_AddFloatToObject(root, "errorPercentage", GLOBAL_STATE->SYSTEM_MODULE.error_percentage);
cJSON_AddNumberToObject(root, "bestDiff", GLOBAL_STATE->SYSTEM_MODULE.best_nonce_diff);
cJSON_AddNumberToObject(root, "bestSessionDiff", GLOBAL_STATE->SYSTEM_MODULE.best_session_nonce_diff);
cJSON_AddNumberToObject(root, "poolDifficulty", GLOBAL_STATE->pool_difficulty);

cJSON_AddNumberToObject(root, "isUsingFallbackStratum", GLOBAL_STATE->SYSTEM_MODULE.is_using_fallback);
cJSON_AddStringToObject(root, "poolConnectionInfo", GLOBAL_STATE->SYSTEM_MODULE.pool_connection_info);

cJSON_AddNumberToObject(root, "isPSRAMAvailable", GLOBAL_STATE->psram_is_available);

cJSON_AddNumberToObject(root, "freeHeap", esp_get_free_heap_size());

cJSON_AddNumberToObject(root, "freeHeapInternal", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
cJSON_AddNumberToObject(root, "freeHeapSpiram", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));

cJSON_AddNumberToObject(root, "coreVoltage", nvs_config_get_u16(NVS_CONFIG_ASIC_VOLTAGE));
cJSON_AddNumberToObject(root, "coreVoltageActual", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.core_voltage);
cJSON_AddNumberToObject(root, "frequency", frequency);
cJSON_AddStringToObject(root, "ssid", ssid);
cJSON_AddStringToObject(root, "macAddr", formattedMac);
cJSON_AddStringToObject(root, "hostname", hostname);
cJSON_AddStringToObject(root, "ipv4", ipv4);
cJSON_AddStringToObject(root, "ipv6", ipv6);
cJSON_AddStringToObject(root, "wifiStatus", GLOBAL_STATE->SYSTEM_MODULE.wifi_status);
cJSON_AddNumberToObject(root, "wifiRSSI", wifi_rssi);
cJSON_AddNumberToObject(root, "apEnabled", GLOBAL_STATE->SYSTEM_MODULE.ap_enabled);
cJSON_AddNumberToObject(root, "sharesAccepted", GLOBAL_STATE->SYSTEM_MODULE.shares_accepted);
cJSON_AddNumberToObject(root, "sharesRejected", GLOBAL_STATE->SYSTEM_MODULE.shares_rejected);

cJSON *error_array = cJSON_CreateArray();
cJSON_AddItemToObject(root, "sharesRejectedReasons", error_array);

for (int i = 0; i < GLOBAL_STATE->SYSTEM_MODULE.rejected_reason_stats_count; i++) {
cJSON *error_obj = cJSON_CreateObject();
cJSON_AddStringToObject(error_obj, "message", GLOBAL_STATE->SYSTEM_MODULE.rejected_reason_stats[i].message);
cJSON_AddNumberToObject(error_obj, "count", GLOBAL_STATE->SYSTEM_MODULE.rejected_reason_stats[i].count);
cJSON_AddItemToArray(error_array, error_obj);
}

cJSON_AddNumberToObject(root, "uptimeSeconds", (esp_timer_get_time() - GLOBAL_STATE->SYSTEM_MODULE.start_time) / 1000000);
cJSON_AddNumberToObject(root, "smallCoreCount", GLOBAL_STATE->DEVICE_CONFIG.family.asic.small_core_count);
cJSON_AddStringToObject(root, "ASICModel", GLOBAL_STATE->DEVICE_CONFIG.family.asic.name);
cJSON_AddStringToObject(root, "stratumURL", stratumURL);
cJSON_AddNumberToObject(root, "stratumPort", nvs_config_get_u16(NVS_CONFIG_STRATUM_PORT));
cJSON_AddStringToObject(root, "stratumUser", stratumUser);
cJSON_AddNumberToObject(root, "stratumSuggestedDifficulty", nvs_config_get_u16(NVS_CONFIG_STRATUM_DIFFICULTY));
cJSON_AddNumberToObject(root, "stratumExtranonceSubscribe", nvs_config_get_bool(NVS_CONFIG_STRATUM_EXTRANONCE_SUBSCRIBE));
cJSON_AddNumberToObject(root, "stratumTLS", nvs_config_get_u16(NVS_CONFIG_STRATUM_TLS));
cJSON_AddStringToObject(root, "stratumCert", stratumCert);
cJSON_AddStringToObject(root, "fallbackStratumURL", fallbackStratumURL);
cJSON_AddNumberToObject(root, "fallbackStratumPort", nvs_config_get_u16(NVS_CONFIG_FALLBACK_STRATUM_PORT));
cJSON_AddStringToObject(root, "fallbackStratumUser", fallbackStratumUser);
cJSON_AddNumberToObject(root, "fallbackStratumSuggestedDifficulty", nvs_config_get_u16(NVS_CONFIG_FALLBACK_STRATUM_DIFFICULTY));
cJSON_AddNumberToObject(root, "fallbackStratumExtranonceSubscribe", nvs_config_get_bool(NVS_CONFIG_FALLBACK_STRATUM_EXTRANONCE_SUBSCRIBE));
cJSON_AddNumberToObject(root, "fallbackStratumTLS", nvs_config_get_u16(NVS_CONFIG_FALLBACK_STRATUM_TLS));
cJSON_AddStringToObject(root, "fallbackStratumCert", fallbackStratumCert);
cJSON_AddNumberToObject(root, "responseTime", GLOBAL_STATE->SYSTEM_MODULE.response_time);

cJSON_AddStringToObject(root, "version", GLOBAL_STATE->SYSTEM_MODULE.version);
cJSON_AddStringToObject(root, "axeOSVersion", GLOBAL_STATE->SYSTEM_MODULE.axeOSVersion);

cJSON_AddStringToObject(root, "idfVersion", esp_get_idf_version());
cJSON_AddStringToObject(root, "boardVersion", GLOBAL_STATE->DEVICE_CONFIG.board_version);
cJSON_AddStringToObject(root, "resetReason", esp_reset_reason_to_string(esp_reset_reason()));
cJSON_AddStringToObject(root, "runningPartition", esp_ota_get_running_partition()->label);

cJSON_AddNumberToObject(root, "overheat_mode", nvs_config_get_bool(NVS_CONFIG_OVERHEAT_MODE));
cJSON_AddNumberToObject(root, "overclockEnabled", nvs_config_get_bool(NVS_CONFIG_OVERCLOCK_ENABLED));
cJSON_AddStringToObject(root, "display", display);
cJSON_AddNumberToObject(root, "rotation", nvs_config_get_u16(NVS_CONFIG_ROTATION));
cJSON_AddNumberToObject(root, "invertscreen", nvs_config_get_bool(NVS_CONFIG_INVERT_SCREEN));
cJSON_AddNumberToObject(root, "displayTimeout", nvs_config_get_i32(NVS_CONFIG_DISPLAY_TIMEOUT));

cJSON_AddNumberToObject(root, "autofanspeed", nvs_config_get_bool(NVS_CONFIG_AUTO_FAN_SPEED));

cJSON_AddFloatToObject(root, "fanspeed", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.fan_perc);
cJSON_AddNumberToObject(root, "manualFanSpeed", nvs_config_get_u16(NVS_CONFIG_MANUAL_FAN_SPEED));
cJSON_AddNumberToObject(root, "minFanSpeed", nvs_config_get_u16(NVS_CONFIG_MIN_FAN_SPEED));
cJSON_AddNumberToObject(root, "temptarget", nvs_config_get_u16(NVS_CONFIG_TEMP_TARGET));
cJSON_AddNumberToObject(root, "fanrpm", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.fan_rpm);
cJSON_AddNumberToObject(root, "fan2rpm", GLOBAL_STATE->POWER_MANAGEMENT_MODULE.fan2_rpm);

cJSON_AddNumberToObject(root, "statsFrequency", nvs_config_get_u16(NVS_CONFIG_STATISTICS_FREQUENCY));

cJSON_AddNumberToObject(root, "blockFound", GLOBAL_STATE->SYSTEM_MODULE.block_found);

if (GLOBAL_STATE->SYSTEM_MODULE.power_fault > 0) {
cJSON_AddStringToObject(root, "power_fault", VCORE_get_fault_string(GLOBAL_STATE));
}

if (GLOBAL_STATE->block_height > 0) {
cJSON_AddNumberToObject(root, "blockHeight", GLOBAL_STATE->block_height);
cJSON_AddStringToObject(root, "scriptsig", GLOBAL_STATE->scriptsig);
cJSON_AddNumberToObject(root, "networkDifficulty", GLOBAL_STATE->network_nonce_diff);
}

cJSON *hashrate_monitor = cJSON_CreateObject();
cJSON_AddItemToObject(root, "hashrateMonitor", hashrate_monitor);

cJSON *asics_array = cJSON_CreateArray();
cJSON_AddItemToObject(hashrate_monitor, "asics", asics_array);

if (GLOBAL_STATE->HASHRATE_MONITOR_MODULE.is_initialized) {
for (int asic_nr = 0; asic_nr < GLOBAL_STATE->DEVICE_CONFIG.family.asic_count; asic_nr++) {
cJSON *asic = cJSON_CreateObject();
cJSON_AddItemToArray(asics_array, asic);
cJSON_AddFloatToObject(asic, "total", GLOBAL_STATE->HASHRATE_MONITOR_MODULE.total_measurement[asic_nr].hashrate);

int hash_domains = GLOBAL_STATE->DEVICE_CONFIG.family.asic.hash_domains;
cJSON* hash_domain_array = cJSON_CreateArray();
for (int domain_nr = 0; domain_nr < hash_domains; domain_nr++) {
cJSON *hashrate = cJSON_CreateFloat(GLOBAL_STATE->HASHRATE_MONITOR_MODULE.domain_measurements[asic_nr][domain_nr].hashrate);
cJSON_AddItemToArray(hash_domain_array, hashrate);
}
cJSON_AddItemToObject(asic, "domains", hash_domain_array);

cJSON_AddNumberToObject(asic, "errorCount", GLOBAL_STATE->HASHRATE_MONITOR_MODULE.error_measurement[asic_nr].value);
}
cJSON * root = SYSTEM_create_info_json(GLOBAL_STATE);
if (root == NULL) {
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to create system info");
return ESP_OK;
}

free(ssid);
free(hostname);
free(stratumURL);
free(fallbackStratumURL);
free(stratumCert);
free(fallbackStratumCert);
free(stratumUser);
free(fallbackStratumUser);
free(display);

esp_err_t res = HTTP_send_json(req, root, &system_info_prebuffer_len);

cJSON_Delete(root);
Expand Down
4 changes: 4 additions & 0 deletions main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "create_jobs_task.h"
#include "hashrate_monitor_task.h"
#include "statistics_task.h"
#include "webhook_task.h"
#include "system.h"
#include "http_server.h"
#include "serial.h"
Expand Down Expand Up @@ -118,4 +119,7 @@ void app_main(void)
if (xTaskCreateWithCaps(statistics_task, "statistics", 8192, (void *) &GLOBAL_STATE, 3, NULL, MALLOC_CAP_SPIRAM) != pdPASS) {
ESP_LOGE(TAG, "Error creating statistics task");
}
if (xTaskCreate(webhook_task, "webhook", 8192, (void *) &GLOBAL_STATE, 2, NULL) != pdPASS) {
ESP_LOGE(TAG, "Error creating webhook task");
}
}
4 changes: 4 additions & 0 deletions main/nvs_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ static Settings settings[NVS_CONFIG_COUNT] = {
[NVS_CONFIG_TPS546] = {.nvs_key_name = "TPS546", .type = TYPE_BOOL},
[NVS_CONFIG_TMP1075] = {.nvs_key_name = "TMP1075", .type = TYPE_BOOL},
[NVS_CONFIG_POWER_CONSUMPTION_TARGET] = {.nvs_key_name = "power_cons_tgt", .type = TYPE_U16},

[NVS_CONFIG_WEBHOOK_ENABLED] = {.nvs_key_name = "webhook_enabled", .type = TYPE_BOOL, .default_value = {.b = false}, .rest_name = "webhookEnabled", .min = 0, .max = 1},
[NVS_CONFIG_WEBHOOK_URL] = {.nvs_key_name = "webhook_url", .type = TYPE_STR, .default_value = {.str = ""}, .rest_name = "webhookUrl", .min = 0, .max = NVS_STR_LIMIT},
[NVS_CONFIG_WEBHOOK_INTERVAL] = {.nvs_key_name = "webhook_interval", .type = TYPE_U16, .default_value = {.u16 = 60}, .rest_name = "webhookInterval", .min = 10, .max = 3600},
};

Settings *nvs_config_get_settings(NvsConfigKey key)
Expand Down
4 changes: 4 additions & 0 deletions main/nvs_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ typedef enum {
NVS_CONFIG_TPS546,
NVS_CONFIG_TMP1075,
NVS_CONFIG_POWER_CONSUMPTION_TARGET,

NVS_CONFIG_WEBHOOK_ENABLED,
NVS_CONFIG_WEBHOOK_URL,
NVS_CONFIG_WEBHOOK_INTERVAL,
NVS_CONFIG_COUNT
} NvsConfigKey;

Expand Down
Loading