Compare commits

...

14 Commits

Author SHA1 Message Date
Sebastien L
14f4caf584 Allow compiling out cspot 2022-11-28 09:22:46 -05:00
Sebastien L
46eb732d82 Merge remote-tracking branch 'origin/master-v4.3' into master-v4.3 2022-11-28 09:13:02 -05:00
Sebastien L
d092ae093c Write version.txt file before build 2022-11-28 09:12:58 -05:00
philippe44
4a51efd556 Merge pull request #206 from wizmo2/display-spi-mode-v4.3
add shaffenmeisters PR and add web config
2022-11-26 19:06:06 -08:00
Wizmo2
c1375444b4 fixed backlite 2022-11-26 21:08:39 -05:00
Wizmo2
e5eabcaf86 add shaffenmeisters PR and add web config 2022-11-25 19:40:17 -05:00
github-actions
93465db1b8 Update prebuilt objects [skip actions] 2022-11-25 19:06:15 +00:00
wizmo2
dc66d9e9dc Bluetooth Source mods (#204)
* support legacy bt pairing

* extend bt source support
2022-11-25 13:55:01 -05:00
Sebastien L
8462de1c16 Fix spotify configuration UI- release 2022-11-25 13:48:32 -05:00
Sébastien
37f48d4bc8 Align versionning in firmware - release 2022-11-24 10:07:13 -05:00
github-actions
ec019f98f3 Update prebuilt objects [skip actions] 2022-11-24 14:15:09 +00:00
Sebastien
5e5c7e0c80 Merge branch 'master-v4.3' of https://github.com/sle118/squeezelite-esp32 into master-v4.3 2022-11-24 09:07:45 -05:00
Sebastien
3144cf5f91 Change auth methods for pushing 2022-11-24 09:07:35 -05:00
github-actions
18cc0adfb4 Update prebuilt objects [skip actions] 2022-11-22 15:28:59 +00:00
39 changed files with 229 additions and 135 deletions

View File

@@ -65,7 +65,7 @@ jobs:
BUILD_NUMBER=${{ needs.job1.outputs.build_number }}
echo "BUILD_NUMBER=${BUILD_NUMBER}" >> $GITHUB_ENV
echo "DOCKER_IMAGE_NAME=sle118/squeezelite-esp32-idfv4-master" >> $GITHUB_ENV
tag="${TARGET_BUILD_NAME}.${{matrix.depth}}.${BUILD_NUMBER}.${branch_name}"
tag="${TARGET_BUILD_NAME}.${{matrix.depth}}.${build_version_prefix}${BUILD_NUMBER}.${branch_name}"
echo "tag=${tag}" >> $GITHUB_ENV
last_commit="$(git log --pretty=format:'%s' --max-count=1)"
if [[ "$last_commit" =~ .*"Release".* ]]; then echo "release_flag=1" >> $GITHUB_ENV; else echo "release_flag=0" >> $GITHUB_ENV; fi

View File

@@ -13,7 +13,7 @@ add_definitions(-DHIERARCHICAL_STATES=1)
#add_definitions(-DNETWORK_ETHERNET_LOG_LEVEL=ESP_LOG_DEBUG)
#uncomment line below to get network status debug logs
#add_definitions(-DNETWORK_STATUS_LOG_LEVEL=ESP_LOG_DEBUG)
#add_definitions(-DNETWORK_HANDLERS_LOG_LEVEL=ESP_LOG_DEBUG)
#add_definitions(-DNETWORK_HANDLERS_LOG_LEVEL=ESP_LOG_DEBUG)
#add_definitions(-DNETWORK_WIFI_LOG_LEVEL=ESP_LOG_DEBUG)
#add_definitions(-DNETWORK_MANAGER_LOG_LEVEL=ESP_LOG_DEBUG)
#add_definitions(-DNETWORK_HTTP_SERVER_LOG_LEVEL=ESP_LOG_DEBUG)

View File

@@ -90,6 +90,7 @@ RUN : \
&& pip show pygit2 \
&& python --version \
&& pip --version \
&& pip3 install protobuf grpcio-tools \
&& rm -rf $IDF_TOOLS_PATH/dist \
&& :

View File

@@ -188,13 +188,14 @@ Ground -------------------------- coax signal ground
The NVS parameter "display_config" sets the parameters for an optional display. Syntax is
```
I2C,width=<pixels>,height=<pixels>[address=<i2c_address>][,reset=<gpio>][,HFlip][,VFlip][driver=SSD1306|SSD1326[:1|4]|SSD1327|SH1106]
SPI,width=<pixels>,height=<pixels>,cs=<gpio>[,back=<gpio>][,reset=<gpio>][,speed=<speed>][,HFlip][,VFlip][driver=SSD1306|SSD1322|SSD1326[:1|4]|SSD1327|SH1106|SSD1675|ST7735|ST7789|ILI9341[:16|18][,rotate]]
SPI,width=<pixels>,height=<pixels>,cs=<gpio>[,back=<gpio>][,reset=<gpio>][,speed=<speed>][,HFlip][,VFlip][driver=SSD1306|SSD1322|SSD1326[:1|4]|SSD1327|SH1106|SSD1675|ST7735|ST7789|ILI9341[:16|18][,rotate]][,mode=<mode>]
```
- back: a LED backlight used by some older devices (ST7735). It is PWM controlled for brightness
- reset: some display have a reset pin that is should normally be pulled up if unused
- VFlip and HFlip are optional can be used to change display orientation
- rotate: for non-square *drivers*, move to portrait mode. Note that *width* and *height* must be inverted then
- Default speed is 8000000 (8MHz) but SPI can work up to 26MHz or even 40MHz
- mode: Default mode = 0. Some display modules use different transaction line timings. Check the module documentation if a non-standard mode is required.
- SH1106 is 128x64 monochrome I2C/SPI [here]((https://www.waveshare.com/wiki/1.3inch_OLED_HAT))
- SSD1306 is 128x32 monochrome I2C/SPI [here](https://www.buydisplay.com/i2c-blue-0-91-inch-oled-display-module-128x32-arduino-raspberry-pi)
- SSD1322 is 256x64 grayscale 16-levels SPI in multiple sizes [here](https://www.buydisplay.com/oled-display/oled-display-module?resolution=159) - it is very nice

View File

@@ -11,7 +11,7 @@ bool GDS_I2CInit( int PortNumber, int SDA, int SCL, int speed );
bool GDS_I2CAttachDevice( struct GDS_Device* Device, int Width, int Height, int I2CAddress, int RSTPin, int BacklightPin );
bool GDS_SPIInit( int SPI, int DC );
bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int Speed, int BacklightPin );
bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int Speed, int BacklightPin, int Mode );
#ifdef __cplusplus
}

View File

@@ -34,7 +34,7 @@ bool GDS_SPIInit( int SPI, int DC ) {
return true;
}
bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int BackLightPin, int Speed ) {
bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int CSPin, int RSTPin, int BackLightPin, int Speed, int Mode ) {
spi_device_interface_config_t SPIDeviceConfig = { };
spi_device_handle_t SPIDevice;
@@ -48,6 +48,7 @@ bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int
SPIDeviceConfig.clock_speed_hz = Speed > 0 ? Speed : SPI_MASTER_FREQ_8M;
SPIDeviceConfig.spics_io_num = CSPin;
SPIDeviceConfig.queue_size = 1;
SPIDeviceConfig.mode = Mode;
SPIDeviceConfig.flags = SPI_DEVICE_NO_DUMMY;
if (Device->SPIParams) Device->SPIParams(SPIDeviceConfig.clock_speed_hz, &SPIDeviceConfig.mode,
&SPIDeviceConfig.cs_ena_pretrans, &SPIDeviceConfig.cs_ena_posttrans);

View File

@@ -119,14 +119,15 @@ void display_init(char *welcome) {
ESP_LOGI(TAG, "Display is I2C on port %u", address);
} else if (strcasestr(config, "SPI") && spi_system_host != -1) {
int CS_pin = -1, speed = 0;
int CS_pin = -1, speed = 0, mode = 0;
PARSE_PARAM(config, "cs", '=', CS_pin);
PARSE_PARAM(config, "speed", '=', speed);
PARSE_PARAM(config, "mode", '=', mode);
init = true;
GDS_SPIInit( spi_system_host, spi_system_dc_gpio );
GDS_SPIAttachDevice( display, width, height, CS_pin, RST_pin, backlight_pin, speed );
GDS_SPIAttachDevice( display, width, height, CS_pin, RST_pin, backlight_pin, speed, mode );
ESP_LOGI(TAG, "Display is SPI host %u with cs:%d", spi_system_host, CS_pin);
} else {

View File

@@ -83,25 +83,28 @@ static void bt_app_task_handler(void *arg)
esp_bt_controller_mem_release(ESP_BT_MODE_BLE);
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
if ((err = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
ESP_LOGE(TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(err));
goto exit;
}
if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE ){
if ((err = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
ESP_LOGE(TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(err));
goto exit;
}
if ((err = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) {
ESP_LOGE(TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(err));
goto exit;
}
if ((err = esp_bt_controller_enable(ESP_BT_MODE_BTDM)) != ESP_OK) {
ESP_LOGE(TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(err));
goto exit;
}
if ((err = esp_bluedroid_init()) != ESP_OK) {
ESP_LOGE(TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(err));
goto exit;
}
if ((err = esp_bluedroid_init()) != ESP_OK) {
ESP_LOGE(TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(err));
goto exit;
}
if ((err = esp_bluedroid_enable()) != ESP_OK) {
ESP_LOGE(TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(err));
goto exit;
if ((err = esp_bluedroid_enable()) != ESP_OK) {
ESP_LOGE(TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(err));
goto exit;
}
}
/* Bluetooth device name, connection mode and profile set up */
@@ -114,6 +117,14 @@ static void bt_app_task_handler(void *arg)
esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
#endif
/*
* Set default parameters for Legacy Pairing
* Use variable pin, input pin code when pairing
*/
esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE;
esp_bt_pin_code_t pin_code;
esp_bt_gap_set_pin(pin_type, 0, pin_code);
running = true;
while (running) {

View File

@@ -672,9 +672,9 @@ static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param)
ESP_LOGV(TAG,"--Invalid class of device. Skipping.\n");
return;
}
else if (!(esp_bt_gap_get_cod_srvc(cod) & ESP_BT_COD_SRVC_RENDERING))
else if (!(esp_bt_gap_get_cod_srvc(cod) & (ESP_BT_COD_SRVC_RENDERING | ESP_BT_COD_SRVC_AUDIO)))
{
ESP_LOGV(TAG,"--Not a rendering device. Skipping.\n");
ESP_LOGV(TAG,"--Not a rendering or audio device. Skipping.\n");
return;
}

View File

@@ -634,7 +634,7 @@ cJSON * config_alloc_get_cjson(const char *key){
}
return conf_json;
}
esp_err_t config_set_cjson_str(const char *key, cJSON *value){
esp_err_t config_set_cjson_str_and_free(const char *key, cJSON *value){
char * value_str = cJSON_PrintUnformatted(value);
if(value_str==NULL){
ESP_LOGE(TAG, "Unable to print cJSON for key [%s]", key);

View File

@@ -53,7 +53,7 @@ void config_init();
void * config_alloc_get_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size);
void * config_alloc_get_str(const char *key, char *lead, char *fallback);
cJSON * config_alloc_get_cjson(const char *key);
esp_err_t config_set_cjson_str(const char *key, cJSON *value);
esp_err_t config_set_cjson_str_and_free(const char *key, cJSON *value);
void config_get_uint16t_from_str(const char *key, uint16_t *value, uint16_t default_value);
void config_delete_key(const char *key);
void config_set_default(nvs_type_t type, const char *key, void * default_value, size_t blob_size);

View File

@@ -592,8 +592,9 @@ static int is_valid_gpio_number(int gpio, const char * name, FILE *f, bool manda
}
return 0;
}
#ifdef CONFIG_CSPOT_SINK
static int do_cspot_config(int argc, char **argv){
char * name = NULL;
int nerrors = arg_parse_msg(argc, argv,(struct arg_hdr **)&cspot_args);
if (nerrors != 0) {
return 1;
@@ -610,31 +611,37 @@ static int do_cspot_config(int argc, char **argv){
cJSON * cspot_config = config_alloc_get_cjson("cspot_config");
if(!cspot_config){
nerrors++;
fprintf(f,"error: Unable to get cspot config.\n");
fprintf(f,"error: Unable to get default cspot config.\n");
}
else {
cjson_update_string(&cspot_config,cspot_args.deviceName->hdr.longopts,cspot_args.deviceName->count>0?cspot_args.deviceName->sval[0]:NULL);
// cjson_update_number(&cspot_config,cspot_args.volume->hdr.longopts,cspot_args.volume->count>0?cspot_args.volume->ival[0]:0);
cjson_update_number(&cspot_config,cspot_args.bitrate->hdr.longopts,cspot_args.bitrate->count>0?cspot_args.bitrate->ival[0]:0);
if(cspot_args.deviceName->count>0){
cjson_update_string(&cspot_config,cspot_args.deviceName->hdr.longopts,cspot_args.deviceName->sval[0]);
}
if(cspot_args.bitrate->count>0){
cjson_update_number(&cspot_config,cspot_args.bitrate->hdr.longopts,cspot_args.bitrate->ival[0]);
}
if(!nerrors ){
fprintf(f,"Storing cspot parameters.\n");
nerrors+=(config_set_cjson_str("cspot_config",cspot_config) !=ESP_OK);
nerrors+=(config_set_cjson_str_and_free("cspot_config",cspot_config) !=ESP_OK);
}
if(nerrors==0){
fprintf(f,"Device name changed to %s\n",name);
if(nerrors==0 ){
if(cspot_args.deviceName->count>0){
fprintf(f,"Device name changed to %s\n",cspot_args.deviceName->sval[0]);
}
if(cspot_args.bitrate->count>0){
fprintf(f,"Bitrate changed to %u\n",cspot_args.bitrate->ival[0]);
}
}
if(!nerrors ){
fprintf(f,"Done.\n");
}
FREE_AND_NULL(name);
fflush (f);
cmd_send_messaging(argv[0],nerrors>0?MESSAGING_ERROR:MESSAGING_INFO,"%s", buf);
fclose(f);
FREE_AND_NULL(buf);
return nerrors;
}
#endif
static int do_i2s_cmd(int argc, char **argv)
{
i2s_platform_config_t i2s_dac_pin = {
@@ -742,6 +749,7 @@ cJSON * known_model_cb(){
}
return values;
}
#ifdef CONFIG_CSPOT_SINK
cJSON * cspot_cb(){
cJSON * values = cJSON_CreateObject();
if(!values){
@@ -761,13 +769,11 @@ cJSON * cspot_cb(){
if(cspot_values){
cJSON_AddNumberToObject(values,cspot_args.bitrate->hdr.longopts,cJSON_GetNumberValue(cspot_values));
}
// cspot_values = cJSON_GetObjectItem(cspot_config,cspot_args.volume->hdr.longopts);
// if(cspot_values){
// cJSON_AddNumberToObject(values,cspot_args.volume->hdr.longopts,cJSON_GetNumberValue(cspot_values));
// }
cJSON_Delete(cspot_config);
return values;
}
#endif
cJSON * i2s_cb(){
cJSON * values = cJSON_CreateObject();
@@ -1171,7 +1177,7 @@ static void register_known_templates_config(){
cmd_to_json_with_cb(&cmd,&known_model_cb);
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
}
#ifdef CONFIG_CSPOT_SINK
static void register_cspot_config(){
cspot_args.deviceName = arg_str1(NULL,"deviceName","","Device Name");
cspot_args.bitrate = arg_int1(NULL,"bitrate","96|160|320","Streaming Bitrate (kbps)");
@@ -1187,6 +1193,7 @@ static void register_cspot_config(){
cmd_to_json_with_cb(&cmd,&cspot_cb);
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
}
#endif
static void register_i2s_config(void){
i2s_args.model_name = arg_str1(NULL,"model_name",STR_OR_BLANK(get_dac_list()),"DAC Model Name");
i2s_args.clear = arg_lit0(NULL, "clear", "Clear configuration");
@@ -1328,8 +1335,11 @@ static void register_squeezelite_config(void){
void register_config_cmd(void){
if(!is_dac_config_locked()){
register_known_templates_config();
}
#ifdef CONFIG_CSPOT_SINK
register_cspot_config();
#endif
register_audio_config();
// register_squeezelite_config();
register_bt_source_config();

View File

@@ -101,6 +101,7 @@ static struct {
struct arg_int *reset;
struct arg_lit *clear;
struct arg_lit *invert;
struct arg_int *mode;
struct arg_end *end;
} i2cdisp_args;
@@ -377,6 +378,13 @@ static int do_i2c_set_display(int argc, char **argv)
}
/* Check "--cs" option */
nerrors +=is_output_gpio(i2cdisp_args.cs,f,&config.CS_pin, false);
/* Check "--mode" option */
if (i2cdisp_args.mode->count) {
config.mode=i2cdisp_args.mode->ival[0];
}
else {
config.mode = 0;
}
}
nerrors +=is_output_gpio(i2cdisp_args.reset,f,&config.RST_pin, false);
@@ -964,6 +972,9 @@ cJSON * i2c_set_display_cb(){
cJSON_AddBoolToObject(values,"hf",conf->hflip);
cJSON_AddBoolToObject(values,"vf",conf->vflip);
cJSON_AddBoolToObject(values,"invert",conf->invert);
if(conf->mode>=0){
cJSON_AddNumberToObject(values,"mode",conf->mode);
}
}
return values;
}
@@ -986,6 +997,7 @@ static void register_i2c_set_display(){
i2cdisp_args.rotate = arg_lit0("r", "rotate", "Rotate 180 degrees");
i2cdisp_args.invert = arg_lit0("i", "invert", "Invert colors");
i2cdisp_args.clear = arg_lit0(NULL, "clear", "clear configuration and return");
i2cdisp_args.mode = arg_int0("m", "mode", "<n>","SPI Only. Transaction Line Mode (Default 0)");
i2cdisp_args.end = arg_end(8);
const esp_console_cmd_t i2c_set_display= {
.command = CFG_TYPE_HW("display"),

View File

@@ -352,6 +352,10 @@ esp_err_t config_display_set(const display_config_t * config){
snprintf(config_buffer2,buffer_size,"%s,speed=%i",config_buffer,config->speed);
strcpy(config_buffer,config_buffer2);
}
if(config->mode >=0 && strcasecmp("SPI",config->type)==0){
snprintf(config_buffer2,buffer_size,"%s,mode=%i",config_buffer,config->mode);
strcpy(config_buffer,config_buffer2);
}
snprintf(config_buffer2,buffer_size,"%s,driver=%s%s%s%s",config_buffer,config->drivername,config->hflip?",HFlip":"",config->vflip?",VFlip":"",config->rotate?",rotate":"");
strcpy(config_buffer,config_buffer2);
log_send_messaging(MESSAGING_INFO,"Updating display configuration to %s",config_buffer);
@@ -465,6 +469,7 @@ const display_config_t * config_display_get(){
.rotate = false,
.invert = false,
.colorswap = 0,
.mode = 0,
};
char *config = config_alloc_get(NVS_TYPE_STR, "display_config");
if (!config) {
@@ -484,6 +489,8 @@ const display_config_t * config_display_get(){
PARSE_PARAM(config, "address", '=', dstruct.address);
PARSE_PARAM(config, "cs", '=', dstruct.CS_pin);
PARSE_PARAM(config, "speed", '=', dstruct.speed);
PARSE_PARAM(config, "back", '=', dstruct.back);
PARSE_PARAM(config, "mode", '=', dstruct.mode);
if (strstr(config, "I2C") ) dstruct.type=i2c_name_type;
if (strstr(config, "SPI") ) dstruct.type=spi_name_type;

View File

@@ -33,6 +33,7 @@ typedef struct {
bool rotate;
bool invert;
int colorswap;
int mode;
} display_config_t;
typedef struct eth_config_struct {

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@@ -15,6 +15,9 @@ declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getStatus(): {};
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
@@ -32,6 +35,12 @@ declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;
declare function pushStatus(): void;

View File

@@ -1,5 +1,5 @@
target_add_binary_data( __idf_wifi-manager webapp/dist/css/index.7964a13ec910c36040b8.css.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/favicon-32x32.png BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/index.html.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/index.9b00af.bundle.js.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/node_vendors.9b00af.bundle.js.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/index.8cb06d.bundle.js.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/node_vendors.8cb06d.bundle.js.gz BINARY)

View File

@@ -6,29 +6,29 @@ extern const uint8_t _favicon_32x32_png_start[] asm("_binary_favicon_32x32_png_s
extern const uint8_t _favicon_32x32_png_end[] asm("_binary_favicon_32x32_png_end");
extern const uint8_t _index_html_gz_start[] asm("_binary_index_html_gz_start");
extern const uint8_t _index_html_gz_end[] asm("_binary_index_html_gz_end");
extern const uint8_t _index_9b00af_bundle_js_gz_start[] asm("_binary_index_9b00af_bundle_js_gz_start");
extern const uint8_t _index_9b00af_bundle_js_gz_end[] asm("_binary_index_9b00af_bundle_js_gz_end");
extern const uint8_t _node_vendors_9b00af_bundle_js_gz_start[] asm("_binary_node_vendors_9b00af_bundle_js_gz_start");
extern const uint8_t _node_vendors_9b00af_bundle_js_gz_end[] asm("_binary_node_vendors_9b00af_bundle_js_gz_end");
extern const uint8_t _index_8cb06d_bundle_js_gz_start[] asm("_binary_index_8cb06d_bundle_js_gz_start");
extern const uint8_t _index_8cb06d_bundle_js_gz_end[] asm("_binary_index_8cb06d_bundle_js_gz_end");
extern const uint8_t _node_vendors_8cb06d_bundle_js_gz_start[] asm("_binary_node_vendors_8cb06d_bundle_js_gz_start");
extern const uint8_t _node_vendors_8cb06d_bundle_js_gz_end[] asm("_binary_node_vendors_8cb06d_bundle_js_gz_end");
const char * resource_lookups[] = {
"/css/index.7964a13ec910c36040b8.css.gz",
"/favicon-32x32.png",
"/index.html.gz",
"/js/index.9b00af.bundle.js.gz",
"/js/node_vendors.9b00af.bundle.js.gz",
"/js/index.8cb06d.bundle.js.gz",
"/js/node_vendors.8cb06d.bundle.js.gz",
""
};
const uint8_t * resource_map_start[] = {
_index_7964a13ec910c36040b8_css_gz_start,
_favicon_32x32_png_start,
_index_html_gz_start,
_index_9b00af_bundle_js_gz_start,
_node_vendors_9b00af_bundle_js_gz_start
_index_8cb06d_bundle_js_gz_start,
_node_vendors_8cb06d_bundle_js_gz_start
};
const uint8_t * resource_map_end[] = {
_index_7964a13ec910c36040b8_css_gz_end,
_favicon_32x32_png_end,
_index_html_gz_end,
_index_9b00af_bundle_js_gz_end,
_node_vendors_9b00af_bundle_js_gz_end
_index_8cb06d_bundle_js_gz_end,
_node_vendors_8cb06d_bundle_js_gz_end
};

View File

@@ -1,6 +1,6 @@
/***********************************
webpack_headers
dist/css/index.7964a13ec910c36040b8.css.gz,dist/favicon-32x32.png,dist/index.html.gz,dist/js/index.9b00af.bundle.js.gz,dist/js/node_vendors.9b00af.bundle.js.gz
dist/css/index.7964a13ec910c36040b8.css.gz,dist/favicon-32x32.png,dist/index.html.gz,dist/js/index.8cb06d.bundle.js.gz,dist/js/node_vendors.8cb06d.bundle.js.gz
***********************************/
#pragma once
#include <inttypes.h>

View File

@@ -12,18 +12,27 @@ import io
from os import walk
from requests import Response
NEWLINE_CHAR = '\n'
def print_message(message,prefix=''):
trimmed=re.sub(r'\n', r'%0A', message,flags=re.MULTILINE)
print(f'{prefix}{trimmed}')
def print_debug(message):
print_message(message,'::debug::')
class Logger:
NEWLINE_CHAR = '\n'
@classmethod
def print_message(cls,message,prefix=''):
trimmed=re.sub(r'\n', r'%0A', message,flags=re.MULTILINE)
print(f'{prefix}{trimmed}')
@classmethod
def debug(cls,message):
cls.print_message(message,'::debug::')
def print_error(message):
print_message(message,'::error::')
@classmethod
def error(cls,message):
cls.print_message(message,'::error::')
@classmethod
def notice(cls,message):
cls.print_message(message,'::notice::')
@classmethod
def warning(cls,message):
cls.print_message(message,'::notice::')
try:
@@ -34,7 +43,6 @@ try:
import glob
import json
import logging
import re
import shutil
import stat
@@ -60,12 +68,12 @@ try:
from genericpath import isdir
except ImportError as ex:
print_error(
f'Failed importing module {ex.name}, using interpreter {sys.executable}. {NEWLINE_CHAR} Installed packages:')
Logger.error(
f'Failed importing module {ex.name}, using interpreter {sys.executable}. {Logger.NEWLINE_CHAR} Installed packages:')
installed_packages = pkg_resources.working_set
installed_packages_list = sorted(
["%s==%s" % (i.key, i.version) for i in installed_packages])
print(NEWLINE_CHAR.join(installed_packages_list))
print(Logger.NEWLINE_CHAR.join(installed_packages_list))
print(f'Environment: ')
envlist = "\n".join([f"{k}={v}" for k, v in sorted(os.environ.items())])
print(f'{envlist}')
@@ -74,13 +82,15 @@ except ImportError as ex:
tool_version = "1.0.7"
WEB_INSTALLER_DEFAULT_PATH = './web_installer/'
FORMAT = '%(asctime)s %(message)s'
logging.basicConfig(format=FORMAT)
github_env = type('', (), {})()
manifest = {
"name": "",
"version": "",
"home_assistant_domain": "slim_player",
"funding_url": "https://esphome.io/guides/supporters.html",
"new_install_prompt_erase": True,
"new_install_improv_wait_time" : 20,
"builds": [
{
"chipFamily": "ESP32",
@@ -277,21 +287,21 @@ class BinFile():
self.source_full_path = os.path.join(
source_path, file_build_path).rstrip()
self.offset = offset
self.target_name = f'{release_details.format_prefix()}-{self.name}'.rstrip()
self.target_name = f'{release_details.format_prefix()}-{release_details.bitrate}-{self.name}'.rstrip()
def get_manifest(self):
return {"path": self.target_name, "offset": self.offset}
def copy(self, target_folder) -> str:
self.target_fullpath = os.path.join(target_folder, self.target_name)
print_debug(
Logger.debug(
f'File {self.source_full_path} will be copied to {self.target_fullpath}')
try:
os.makedirs(target_folder, exist_ok=True)
shutil.copyfile(self.source_full_path,
self.target_fullpath, follow_symlinks=True)
except Exception as ex:
print_error(f"Error while copying {self.source_full_path} to {self.target_fullpath}{NEWLINE_CHAR}Content of {os.path.dirname(self.source_full_path.rstrip())}:{NEWLINE_CHAR}{NEWLINE_CHAR.join(get_file_list(os.path.dirname(self.source_full_path.rstrip())))}")
Logger.error(f"Error while copying {self.source_full_path} to {self.target_fullpath}{Logger.NEWLINE_CHAR}Content of {os.path.dirname(self.source_full_path.rstrip())}:{Logger.NEWLINE_CHAR}{Logger.NEWLINE_CHAR.join(get_file_list(os.path.dirname(self.source_full_path.rstrip())))}")
@@ -323,7 +333,7 @@ class PlatformRelease():
flash_file_path: str
def get_manifest_name(self) -> str:
return f'{self.name_prefix}-{self.release_details.format_prefix()}.json'
return f'{self.name_prefix}-{self.release_details.format_prefix()}-{self.release_details.bitrate}.json'
def __init__(self, flash_file_path, git_release, build_dir, branch, name_prefix) -> None:
self.name = git_release.tag_name
@@ -389,8 +399,7 @@ class PlatformRelease():
self.has_artifacts = False
def cleanup(self):
print(
f'removing temp directory for platform release {self.name}')
Logger.debug(f'removing temp directory for platform release {self.name}')
shutil.rmtree(self.tempfolder)
def get_attributes(self):
@@ -438,7 +447,6 @@ class Releases():
return result
def append(self, value: PlatformRelease):
# optional processing here
if self.count(value) == 0:
self._dict[value.platform()] = []
if self.should_add(value):
@@ -465,8 +473,7 @@ class Releases():
def add_package(self, package: PlatformRelease, with_artifacts: bool = True):
if self.branch != package.branch:
print(
f'Skipping release {package.name} from branch {package.branch}')
Logger.debug(f'Skipping release {package.name} from branch {package.branch}')
elif package.has_artifacts or not with_artifacts:
self.append(package)
@@ -476,7 +483,7 @@ class Releases():
if last is None:
return ''
else:
return last.message.replace(NEWLINE_CHAR, ' ')
return last.message.replace(Logger.NEWLINE_CHAR, ' ')
@classmethod
def get_last_author(cls, repo_obj: Repository = None) -> Signature:
@@ -505,7 +512,7 @@ class Releases():
print(
f'Last commit for {head.shorthand} is {format_commit(cls.last_commit)}')
except Exception as e:
print_error(
Logger.error(
f'Unable to retrieve last commit for {head.shorthand}/{target}: {e}')
cls.last_commit = None
return cls.last_commit
@@ -517,7 +524,7 @@ class Releases():
print(f'Opening repository from {path}')
cls.repo = Repository(path=path)
except GitError as ex:
print_error(f"Unable to access the repository.\nContent of {path}:\n{NEWLINE_CHAR.join(get_file_list(path, 1))}")
print_error(f"Unable to access the repository({ex}).\nContent of {path}:\n{NEWLINE_CHAR.join(get_file_list(path, 1))}")
raise
return cls.repo
@@ -558,11 +565,11 @@ class Releases():
packages: Releases = cls(branch=repo.head.shorthand, maxcount=maxcount)
build_dir = os.path.dirname(flash_file_path)
for page in range(1, 999):
print_debug(f'Getting releases page {page}')
Logger.debug(f'Getting releases page {page}')
releases = get_github_data(
repo, f'releases?per_page=50&page={page}')
if len(releases) == 0:
print_debug(f'No more release found for page {page}')
Logger.debug(f'No more release found for page {page}')
break
for release_entry in [AttributeDict(platform) for platform in releases]:
packages.add_package(PlatformRelease(flash_file_path, release_entry, build_dir,
@@ -588,14 +595,14 @@ class Releases():
break
except Exception as e:
print_error(
Logger.error(
f'Unable to get commit list starting at {last.id}: {e}')
return commit_list
@classmethod
def get_commit_list_descriptions(cls) -> str:
return '<<~EOD\n### Revision Log\n'+NEWLINE_CHAR.join(cls.get_commit_list())+'\n~EOD'
return '<<~EOD\n### Revision Log\n'+Logger.NEWLINE_CHAR.join(cls.get_commit_list())+'\n~EOD'
def update(self, *args, **kwargs):
if args:
@@ -626,34 +633,27 @@ def parse_json(filename: str):
try:
with open(fname) as f:
content = f.read()
print_debug(f'Loading json\n{content}')
Logger.debug(f'Loading json\n{content}')
return json.loads(content)
except JSONDecodeError as ex:
print_error(f'Error parsing {content}')
Logger.error(f'Error parsing {content}')
except Exception as ex:
print_error(
f"Unable to parse flasher args json file. Content of {folder}:{NEWLINE_CHAR.join(get_file_list(folder))}")
Logger.error(
f"Unable to parse flasher args json file. Content of {folder}:{Logger.NEWLINE_CHAR.join(get_file_list(folder))}")
raise
def write_github_env(args):
print(f'Writing environment details to {args.env_file}...')
with open(args.env_file, "w") as env_file:
for attr in [attr for attr in dir(github_env) if not attr.startswith('_')]:
line = f'{attr}{"=" if attr != "description" else ""}{getattr(github_env,attr)}'
def write_github_env_file(values,env_file):
print(f'Writing content to {env_file}...')
with open(env_file, "w") as env_file:
for attr in [attr for attr in dir(values) if not attr.startswith('_')]:
line = f'{attr}{"=" if attr != "description" else ""}{getattr(values,attr)}'
print(line)
env_file.write(f'{line}\n')
os.environ[attr] = str(getattr(github_env, attr))
print(f'Done writing environment details to {args.env_file}!')
os.environ[attr] = str(getattr(values, attr))
print(f'Done writing to {env_file}!')
def set_workflow_output(args):
print(f'Outputting job variables ...')
for attr in [attr for attr in dir(github_env) if not attr.startswith('_')]:
print(f'::set-output name={attr}::{getattr(github_env,attr)}')
os.environ[attr] = str(getattr(github_env, attr))
print(f'Done outputting job variables!')
def format_artifact_from_manifest(manif_json: AttributeDict):
if len(manif_json) == 0:
@@ -674,7 +674,19 @@ def handle_build_flags(args):
github_env.release_flag = 1 if args.mock or args.force or 'release' in commit_message.lower() else 0
github_env.ui_build = 1 if args.mock or args.ui_build or '[ui-build]' in commit_message.lower(
) or github_env.release_flag == 1 else 0
set_workflow_output(github_env)
write_github_env_file(github_env,os.environ.get('GITHUB_OUTPUT'))
def write_version_number(file_path:str,env_details):
# app_name="${TARGET_BUILD_NAME}.${DEPTH}.dev-$(git log --pretty=format:'%h' --max-count=1).${branch_name}"
# echo "${app_name}">version.txt
try:
version:str = f'{env_details.TARGET_BUILD_NAME}.{env_details.DEPTH}.{env_details.major}.{env_details.BUILD_NUMBER}.{env_details.branch_name}'
with open(file_path, "w") as version_file:
version_file.write(version)
except Exception as ex:
Logger.error(f'Unable to set version string {version} in file {file_path}')
raise Exception('Version error')
Logger.notice(f'Firmware version set to {version}')
def handle_environment(args):
@@ -706,7 +718,8 @@ def handle_environment(args):
github_env.artifact_bin_file_name = f"{github_env.artifact_prefix}.bin"
github_env.PROJECT_VER = f'{args.node}-{ args.build }'
github_env.description = Releases.get_commit_list_descriptions()
write_github_env(args)
write_github_env_file(github_env,args.env_file)
write_version_number("version.txt",github_env)
def handle_artifacts(args):
@@ -722,7 +735,7 @@ def handle_artifacts(args):
os.makedirs(target_dir, exist_ok=True)
shutil.copyfile(source, target, follow_symlinks=True)
except Exception as ex:
print_error(f"Error while copying {source} to {target}\nContent of {target_dir}:\n{NEWLINE_CHAR.join(get_file_list(os.path.dirname(attr[0].rstrip())))}")
Logger.error(f"Error while copying {source} to {target}\nContent of {target_dir}:\n{Logger.NEWLINE_CHAR.join(get_file_list(os.path.dirname(attr[0].rstrip())))}")
raise
@@ -731,16 +744,16 @@ def delete_folder(path):
for root, dirs, files in os.walk(path, topdown=True):
for dir in dirs:
fulldirpath = os.path.join(root, dir)
print_debug(f'Drilling down in {fulldirpath}')
Logger.debug(f'Drilling down in {fulldirpath}')
delete_folder(fulldirpath)
for fname in files:
full_path = os.path.join(root, fname)
print_debug(f'Setting file read/write {full_path}')
Logger.debug(f'Setting file read/write {full_path}')
os.chmod(full_path, stat.S_IWRITE)
print_debug(f'Deleting file {full_path}')
Logger.debug(f'Deleting file {full_path}')
os.remove(full_path)
if os.path.exists(path):
print_debug(f'Changing folder read/write {path}')
Logger.debug(f'Changing folder read/write {path}')
os.chmod(path, stat.S_IWRITE)
print(f'WARNING: Deleting Folder {path}')
os.rmdir(path)
@@ -797,7 +810,7 @@ def handle_manifest(args):
man['builds'][0]['parts'] = release.process_files(args.outdir)
man['name'] = release.platform()
man['version'] = release.release_details.version
print_debug(f'Generated manifest: \n{json.dumps(man)}')
Logger.debug(f'Generated manifest: \n{json.dumps(man)}')
fullpath = os.path.join(args.outdir, release.get_manifest_name())
print(f'Writing manifest to {fullpath}')
with open(fullpath, "w") as f:
@@ -827,7 +840,7 @@ def copy_no_overwrite(source: str, target: str):
print(f'Copying {f} to target')
shutil.copy(source_file, target_file)
else:
print_debug(f'Skipping existing file {f}')
Logger.debug(f'Skipping existing file {f}')
def get_changed_items(repo: Repository) -> Dict:
@@ -844,6 +857,14 @@ def get_changed_items(repo: Repository) -> Dict:
def is_dirty(repo: Repository) -> bool:
return len(get_changed_items(repo)) > 0
def push_with_method(auth_method:str,token:str,remote: Remote,reference):
success:bool = False
try:
remote.push(reference, callbacks=RemoteCallbacks(pygit2.UserPass(auth_method, token)))
success=True
except Exception as ex:
print_error(f'Error pushing with auth method {auth_method}: {ex}.')
return success
def push_if_change(repo: Repository, token: str, source_path: str, manif_json):
if is_dirty(repo):
@@ -861,7 +882,6 @@ def push_if_change(repo: Repository, token: str, source_path: str, manif_json):
origin: Remote = repo.remotes['origin']
print(
f'Pushing commit {format_commit(repo[commit])} to url {origin.url}')
credentials = UserPass(token, 'x-oauth-basic') # passing credentials
remote: Remote = repo.remotes['origin']
# remote.credentials = credentials
auth_method = 'x-access-token'
@@ -914,8 +934,8 @@ def handle_show(args):
def extract_files_from_archive(url):
tempfolder = tempfile.mkdtemp()
platform:Response = requests.get(url)
print_debug(f'Downloading {url} to {tempfolder}')
print_debug(f'Transfer status code: {platform.status_code}. Expanding content')
Logger.debug(f'Downloading {url} to {tempfolder}')
Logger.debug(f'Transfer status code: {platform.status_code}. Expanding content')
z = zipfile.ZipFile(io.BytesIO(platform.content))
z.extractall(tempfolder)
return tempfolder
@@ -923,7 +943,7 @@ def extract_files_from_archive(url):
def handle_list_files(args):
print(f'Content of {args.cwd}:')
print(NEWLINE_CHAR.join(get_file_list(args.cwd)))
print(Logger.NEWLINE_CHAR.join(get_file_list(args.cwd)))
parser_environment.set_defaults(func=handle_environment, cmd='environment')
@@ -948,7 +968,7 @@ def main():
try:
func(args)
except Exception as e:
print_error(f'Critical error while running {args.command}\n{" ".join(traceback.format_exception(etype=type(e), value=e, tb=e.__traceback__))}')
Logger.error(f'Critical error while running {args.command}\n{" ".join(traceback.format_exception(etype=type(e), value=e, tb=e.__traceback__))}')
exit_result_code = 1
else:
# No subcommand was provided, so call help

View File

@@ -281,28 +281,53 @@ void register_default_string_val(const char * key, char * value){
FREE_AND_NULL(existing);
}
void register_default_with_mac(const char* key, char* defval) {
char * alloc_get_string_with_mac(const char * val) {
uint8_t mac[6];
char macStr[LOCAL_MAC_SIZE + 1];
char* fullvalue = NULL;
esp_read_mac((uint8_t*)&mac, ESP_MAC_WIFI_STA);
snprintf(macStr, LOCAL_MAC_SIZE - 1, "-%x%x%x", mac[3], mac[4], mac[5]);
fullvalue = malloc_init_external(strlen(defval)+sizeof(macStr)+1);
fullvalue = malloc_init_external(strlen(val)+sizeof(macStr)+1);
if(fullvalue){
strcpy(fullvalue, defval);
strcpy(fullvalue, val);
strcat(fullvalue, macStr);
}
else {
ESP_LOGE(TAG,"Memory allocation failed when getting mac value for %s", val);
}
return fullvalue;
}
void register_default_with_mac(const char* key, char* defval) {
char * fullvalue=alloc_get_string_with_mac(defval);
if(fullvalue){
register_default_string_val(key,fullvalue);
FREE_AND_NULL(fullvalue);
}
else {
ESP_LOGE(TAG,"Memory allocation failed when registering default value for %s", key);
}
}
void register_default_nvs(){
#ifdef CONFIG_CSPOT_SINK
register_default_string_val("enable_cspot", STR(CONFIG_CSPOT_SINK));
cJSON * cspot_config=config_alloc_get_cjson("cspot_config");
if(!cspot_config){
char * name = alloc_get_string_with_mac(DEFAULT_HOST_NAME);
if(name){
cjson_update_string(&cspot_config,"deviceName",name);
cjson_update_number(&cspot_config,"bitrate",160);
// the call below saves the config and frees the json pointer
config_set_cjson_str_and_free("cspot_config",cspot_config);
FREE_AND_NULL(name);
}
else {
register_default_string_val("cspot_config", "");
}
}
#endif
#ifdef CONFIG_AIRPLAY_SINK
@@ -368,10 +393,6 @@ void register_default_nvs(){
register_default_string_val("ethtmout","8");
register_default_string_val("dhcp_tmout","8");
register_default_string_val("target", CONFIG_TARGET);
#ifdef CONFIG_CSPOT_SINK
register_default_string_val("enable_cspot", STR(CONFIG_CSPOT_SINK));
register_default_string_val("cspot_config", "");
#endif
wait_for_commit();
ESP_LOGD(TAG,"Done setting default values in nvs.");
}
@@ -523,8 +544,7 @@ void app_main()
network_register_state_callback(NETWORK_INITIALIZING_STATE,-1, "handle_ap_connect", &handle_ap_connect);
network_register_state_callback(NETWORK_ETH_ACTIVE_STATE,ETH_ACTIVE_LINKDOWN_STATE, "handle_network_up", &handle_network_up);
network_register_state_callback(NETWORK_WIFI_ACTIVE_STATE,WIFI_INITIALIZING_STATE, "handle_network_up", &handle_network_up);
MEMTRACE_PRINT_DELTA();
MEMTRACE_PRINT_DELTA();
}
MEMTRACE_PRINT_DELTA_MESSAGE("Starting Console");
console_start();

View File

@@ -134,7 +134,7 @@ buildMap(sdkconfig).then((sdkConfigResult ) => {
}
}
}
console.log(`\n\nproperties that are different between the 2 files \n**************************`);
console.log(`\n\nproperties that are different ${sdkconfig}<->${comparedFile} \n**************************`);
for (const prop in sdkconfigMap) {
entry = sdkconfigMap[prop];
if(entry.type==map_types.COMMENT) continue;
@@ -159,7 +159,7 @@ buildMap(sdkconfig).then((sdkConfigResult ) => {
}
});
console.log(`\n\${comparedFile} with missing properties\n**************************`);
console.log(`\n\n${comparedFile} with missing properties\n**************************`);
newlines.forEach(line => {
console.log(line);
});

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
server_certs/rootca1.cer.18 Normal file

Binary file not shown.

BIN
server_certs/rootca1.cer.19 Normal file

Binary file not shown.

BIN
server_certs/rootca1.cer.20 Normal file

Binary file not shown.