mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-29 22:24:26 +00:00 
			
		
		
		
	Displays
This commit is contained in:
		
							
								
								
									
										56
									
								
								esphomeyaml/components/display/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								esphomeyaml/components/display/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| # coding=utf-8 | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import CONF_LAMBDA, CONF_ROTATION, CONF_UPDATE_INTERVAL | ||||
| from esphomeyaml.helpers import add, add_job, esphomelib_ns | ||||
|  | ||||
| PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ | ||||
|  | ||||
| }) | ||||
|  | ||||
| display_ns = esphomelib_ns.namespace('display') | ||||
| DisplayBuffer = display_ns.DisplayBuffer | ||||
| DisplayBufferRef = DisplayBuffer.operator('ref') | ||||
|  | ||||
| DISPLAY_ROTATIONS = { | ||||
|     0: display_ns.DISPLAY_ROTATION_0_DEGREES, | ||||
|     90: display_ns.DISPLAY_ROTATION_90_DEGREES, | ||||
|     180: display_ns.DISPLAY_ROTATION_180_DEGREES, | ||||
|     270: display_ns.DISPLAY_ROTATION_270_DEGREES, | ||||
| } | ||||
|  | ||||
|  | ||||
| def validate_rotation(value): | ||||
|     value = cv.string(value) | ||||
|     if value.endswith(u"°"): | ||||
|         value = value[:-1] | ||||
|     try: | ||||
|         value = int(value) | ||||
|     except ValueError: | ||||
|         raise vol.Invalid(u"Expected integer for rotation") | ||||
|     return cv.one_of(*DISPLAY_ROTATIONS)(value) | ||||
|  | ||||
|  | ||||
| BASIC_DISPLAY_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ | ||||
|     vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, | ||||
| }) | ||||
|  | ||||
| FULL_DISPLAY_PLATFORM_SCHEMA = BASIC_DISPLAY_PLATFORM_SCHEMA.extend({ | ||||
|     vol.Optional(CONF_LAMBDA): cv.lambda_, | ||||
|     vol.Optional(CONF_ROTATION): validate_rotation, | ||||
| }) | ||||
|  | ||||
|  | ||||
| def setup_display_core_(display_var, config): | ||||
|     if CONF_UPDATE_INTERVAL in config: | ||||
|         add(display_var.set_update_interval(config[CONF_UPDATE_INTERVAL])) | ||||
|     if CONF_ROTATION in config: | ||||
|         add(display_var.set_rotation(DISPLAY_ROTATIONS[config[CONF_ROTATION]])) | ||||
|  | ||||
|  | ||||
| def setup_display(display_var, config): | ||||
|     add_job(setup_display_core_, display_var, config) | ||||
|  | ||||
|  | ||||
| BUILD_FLAGS = '-DUSE_DISPLAY' | ||||
							
								
								
									
										74
									
								
								esphomeyaml/components/display/lcd_gpio.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								esphomeyaml/components/display/lcd_gpio.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml import pins | ||||
| from esphomeyaml.components import display | ||||
| from esphomeyaml.const import CONF_DIMENSIONS, CONF_ENABLE_PIN, CONF_ID, CONF_LAMBDA, CONF_PINS, \ | ||||
|     CONF_RS_PIN, CONF_RW_PIN | ||||
| from esphomeyaml.helpers import App, Pvariable, add, gpio_output_pin_expression, process_lambda | ||||
|  | ||||
| GPIOLCDDisplay = display.display_ns.GPIOLCDDisplay | ||||
| LCDDisplay = display.display_ns.LCDDisplay | ||||
| LCDDisplayRef = LCDDisplay.operator('ref') | ||||
|  | ||||
|  | ||||
| def validate_lcd_dimensions(value): | ||||
|     value = cv.dimensions(value) | ||||
|     if value[0] > 0x40: | ||||
|         raise vol.Invalid("LCD displays can't have more than 64 columns") | ||||
|     if value[1] > 4: | ||||
|         raise vol.Invalid("LCD displays can't have more than 4 rows") | ||||
|     return value | ||||
|  | ||||
|  | ||||
| def validate_pin_length(value): | ||||
|     if len(value) != 4 and len(value) != 8: | ||||
|         raise vol.Invalid("LCD Displays can either operate in 4-pin or 8-pin mode," | ||||
|                           "not {}-pin mode".format(len(value))) | ||||
|     return value | ||||
|  | ||||
|  | ||||
| PLATFORM_SCHEMA = display.BASIC_DISPLAY_PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID(): cv.declare_variable_id(GPIOLCDDisplay), | ||||
|     vol.Required(CONF_DIMENSIONS): validate_lcd_dimensions, | ||||
|  | ||||
|     vol.Required(CONF_PINS): vol.All([pins.gpio_output_pin_schema], validate_pin_length), | ||||
|     vol.Required(CONF_ENABLE_PIN): pins.gpio_output_pin_schema, | ||||
|     vol.Required(CONF_RS_PIN): pins.gpio_output_pin_schema, | ||||
|     vol.Optional(CONF_RW_PIN): pins.gpio_output_pin_schema, | ||||
|  | ||||
|     vol.Optional(CONF_LAMBDA): cv.lambda_, | ||||
| }) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     rhs = App.make_gpio_lcd_display(config[CONF_DIMENSIONS][0], config[CONF_DIMENSIONS][1]) | ||||
|     lcd = Pvariable(config[CONF_ID], rhs) | ||||
|     pins_ = [] | ||||
|     for conf in config[CONF_PINS]: | ||||
|         for pin in gpio_output_pin_expression(conf): | ||||
|             yield | ||||
|         pins_.append(pin) | ||||
|     add(lcd.set_data_pins(*pins_)) | ||||
|     for enable in gpio_output_pin_expression(config[CONF_ENABLE_PIN]): | ||||
|         yield | ||||
|     add(lcd.set_enable_pin(enable)) | ||||
|  | ||||
|     for rs in gpio_output_pin_expression(config[CONF_RS_PIN]): | ||||
|         yield | ||||
|     add(lcd.set_rs_pin(rs)) | ||||
|  | ||||
|     if CONF_RW_PIN in config: | ||||
|         for rw in gpio_output_pin_expression(config[CONF_RW_PIN]): | ||||
|             yield | ||||
|         add(lcd.set_rw_pin(rw)) | ||||
|  | ||||
|     if CONF_LAMBDA in config: | ||||
|         for lambda_ in process_lambda(config[CONF_LAMBDA], [(LCDDisplayRef, 'it')]): | ||||
|             yield | ||||
|         add(lcd.set_writer(lambda_)) | ||||
|  | ||||
|     display.setup_display(lcd, config) | ||||
|  | ||||
|  | ||||
| BUILD_FLAGS = '-DUSE_LCD_DISPLAY' | ||||
							
								
								
									
										37
									
								
								esphomeyaml/components/display/lcd_pcf8574.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								esphomeyaml/components/display/lcd_pcf8574.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.components import display | ||||
| from esphomeyaml.components.display.lcd_gpio import LCDDisplayRef, validate_lcd_dimensions | ||||
| from esphomeyaml.const import CONF_ADDRESS, CONF_DIMENSIONS, CONF_ID, CONF_LAMBDA | ||||
| from esphomeyaml.helpers import App, Pvariable, add, process_lambda | ||||
|  | ||||
| DEPENDENCIES = ['i2c'] | ||||
|  | ||||
| PCF8574LCDDisplay = display.display_ns.PCF8574LCDDisplay | ||||
|  | ||||
| PLATFORM_SCHEMA = display.BASIC_DISPLAY_PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID(): cv.declare_variable_id(PCF8574LCDDisplay), | ||||
|     vol.Required(CONF_DIMENSIONS): validate_lcd_dimensions, | ||||
|     vol.Optional(CONF_ADDRESS): cv.i2c_address, | ||||
|  | ||||
|     vol.Optional(CONF_LAMBDA): cv.lambda_, | ||||
| }) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     rhs = App.make_pcf8574_lcd_display(config[CONF_DIMENSIONS][0], config[CONF_DIMENSIONS][1]) | ||||
|     lcd = Pvariable(config[CONF_ID], rhs) | ||||
|  | ||||
|     if CONF_ADDRESS in config: | ||||
|         add(lcd.set_address(config[CONF_ADDRESS])) | ||||
|  | ||||
|     if CONF_LAMBDA in config: | ||||
|         for lambda_ in process_lambda(config[CONF_LAMBDA], [(LCDDisplayRef, 'it')]): | ||||
|             yield | ||||
|         add(lcd.set_writer(lambda_)) | ||||
|  | ||||
|     display.setup_display(lcd, config) | ||||
|  | ||||
|  | ||||
| BUILD_FLAGS = ['-DUSE_LCD_DISPLAY', '-DUSE_LCD_DISPLAY_PCF8574'] | ||||
							
								
								
									
										49
									
								
								esphomeyaml/components/display/max7129.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								esphomeyaml/components/display/max7129.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml import pins | ||||
| from esphomeyaml.components import display | ||||
| from esphomeyaml.components.spi import SPIComponent | ||||
| from esphomeyaml.const import CONF_CS_PIN, CONF_ID, CONF_INTENSITY, CONF_LAMBDA, CONF_NUM_CHIPS, \ | ||||
|     CONF_SPI_ID | ||||
| from esphomeyaml.helpers import App, Pvariable, add, get_variable, gpio_output_pin_expression, \ | ||||
|     process_lambda | ||||
|  | ||||
| DEPENDENCIES = ['spi'] | ||||
|  | ||||
| MAX7219Component = display.display_ns.MAX7219Component | ||||
| MAX7219ComponentRef = MAX7219Component.operator('ref') | ||||
|  | ||||
| PLATFORM_SCHEMA = display.BASIC_DISPLAY_PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID(): cv.declare_variable_id(MAX7219Component), | ||||
|     cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent), | ||||
|     vol.Required(CONF_CS_PIN): pins.gpio_output_pin_schema, | ||||
|  | ||||
|     vol.Optional(CONF_NUM_CHIPS): vol.All(cv.uint8_t, vol.Range(min=1)), | ||||
|     vol.Optional(CONF_INTENSITY): vol.All(cv.uint8_t, vol.Range(min=0, max=15)), | ||||
|     vol.Optional(CONF_LAMBDA): cv.lambda_, | ||||
| }) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     for spi in get_variable(config[CONF_SPI_ID]): | ||||
|         yield | ||||
|     for cs in gpio_output_pin_expression(config[CONF_CS_PIN]): | ||||
|         yield | ||||
|     rhs = App.make_max7219(spi, cs) | ||||
|     max7219 = Pvariable(config[CONF_ID], rhs) | ||||
|  | ||||
|     if CONF_NUM_CHIPS in config: | ||||
|         add(max7219.set_num_chips(config[CONF_NUM_CHIPS])) | ||||
|     if CONF_INTENSITY in config: | ||||
|         add(max7219.set_intensity(config[CONF_INTENSITY])) | ||||
|  | ||||
|     if CONF_LAMBDA in config: | ||||
|         for lambda_ in process_lambda(config[CONF_LAMBDA], [(MAX7219ComponentRef, 'it')]): | ||||
|             yield | ||||
|         add(max7219.set_writer(lambda_)) | ||||
|  | ||||
|     display.setup_display(max7219, config) | ||||
|  | ||||
|  | ||||
| BUILD_FLAGS = '-DUSE_MAX7219' | ||||
							
								
								
									
										39
									
								
								esphomeyaml/components/display/ssd1306_i2c.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								esphomeyaml/components/display/ssd1306_i2c.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml import pins | ||||
| from esphomeyaml.components import display | ||||
| from esphomeyaml.components.display import ssd1306_spi | ||||
| from esphomeyaml.const import CONF_ADDRESS, CONF_EXTERNAL_VCC, CONF_ID, CONF_MODEL, CONF_RESET_PIN | ||||
| from esphomeyaml.helpers import App, Pvariable, add, gpio_output_pin_expression | ||||
|  | ||||
| DEPENDENCIES = ['i2c'] | ||||
|  | ||||
| I2CSSD1306 = display.display_ns.I2CSSD1306 | ||||
|  | ||||
| PLATFORM_SCHEMA = display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID(): cv.declare_variable_id(I2CSSD1306), | ||||
|     vol.Required(CONF_MODEL): cv.one_of(*ssd1306_spi.MODELS), | ||||
|     vol.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema, | ||||
|     vol.Optional(CONF_EXTERNAL_VCC): cv.boolean, | ||||
|     vol.Optional(CONF_ADDRESS): cv.i2c_address, | ||||
| }) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     ssd = Pvariable(config[CONF_ID], App.make_i2c_ssd1306()) | ||||
|     add(ssd.set_model(ssd1306_spi.MODELS[config[CONF_MODEL]])) | ||||
|  | ||||
|     if CONF_RESET_PIN in config: | ||||
|         for reset in gpio_output_pin_expression(config[CONF_RESET_PIN]): | ||||
|             yield | ||||
|         add(ssd.set_reset_pin(reset)) | ||||
|     if CONF_EXTERNAL_VCC in config: | ||||
|         add(ssd.set_external_vcc(config[CONF_EXTERNAL_VCC])) | ||||
|     if CONF_ADDRESS in config: | ||||
|         add(ssd.set_address(config[CONF_ADDRESS])) | ||||
|  | ||||
|     display.setup_display(ssd, config) | ||||
|  | ||||
|  | ||||
| BUILD_FLAGS = '-DUSE_SSD1306' | ||||
							
								
								
									
										57
									
								
								esphomeyaml/components/display/ssd1306_spi.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								esphomeyaml/components/display/ssd1306_spi.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml import pins | ||||
| from esphomeyaml.components import display | ||||
| from esphomeyaml.components.spi import SPIComponent | ||||
| from esphomeyaml.const import CONF_CS_PIN, CONF_DC_PIN, CONF_EXTERNAL_VCC, CONF_ID, CONF_MODEL, \ | ||||
|     CONF_RESET_PIN, CONF_SPI_ID | ||||
| from esphomeyaml.helpers import App, Pvariable, add, get_variable, gpio_output_pin_expression | ||||
|  | ||||
| DEPENDENCIES = ['spi'] | ||||
|  | ||||
| SPISSD1306 = display.display_ns.SPISSD1306 | ||||
|  | ||||
| MODELS = { | ||||
|     'SSD1306_128X32': display.display_ns.SSD1306_MODEL_128_32, | ||||
|     'SSD1306_128X64': display.display_ns.SSD1306_MODEL_128_64, | ||||
|     'SSD1306_96X16': display.display_ns.SSD1306_MODEL_96_16, | ||||
|     'SH1106_128X32': display.display_ns.SH1106_MODEL_128_32, | ||||
|     'SH1106_128X64': display.display_ns.SH1106_MODEL_128_64, | ||||
|     'SH1106_96X16': display.display_ns.SH1106_MODEL_96_16, | ||||
| } | ||||
|  | ||||
| PLATFORM_SCHEMA = display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID(): cv.declare_variable_id(SPISSD1306), | ||||
|     cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent), | ||||
|     vol.Required(CONF_CS_PIN): pins.gpio_output_pin_schema, | ||||
|     vol.Required(CONF_DC_PIN): pins.gpio_output_pin_schema, | ||||
|     vol.Required(CONF_MODEL): cv.one_of(*MODELS), | ||||
|     vol.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema, | ||||
|     vol.Optional(CONF_EXTERNAL_VCC): cv.boolean, | ||||
| }) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     for spi in get_variable(config[CONF_SPI_ID]): | ||||
|         yield | ||||
|     for cs in gpio_output_pin_expression(config[CONF_CS_PIN]): | ||||
|         yield | ||||
|     for dc in gpio_output_pin_expression(config[CONF_DC_PIN]): | ||||
|         yield | ||||
|  | ||||
|     rhs = App.make_spi_ssd1306(spi, cs, dc) | ||||
|     ssd = Pvariable(config[CONF_ID], rhs) | ||||
|     add(ssd.set_model(MODELS[config[CONF_MODEL]])) | ||||
|  | ||||
|     if CONF_RESET_PIN in config: | ||||
|         for reset in gpio_output_pin_expression(config[CONF_RESET_PIN]): | ||||
|             yield | ||||
|         add(ssd.set_reset_pin(reset)) | ||||
|     if CONF_EXTERNAL_VCC in config: | ||||
|         add(ssd.set_external_vcc(config[CONF_EXTERNAL_VCC])) | ||||
|  | ||||
|     display.setup_display(ssd, config) | ||||
|  | ||||
|  | ||||
| BUILD_FLAGS = '-DUSE_SSD1306' | ||||
							
								
								
									
										84
									
								
								esphomeyaml/components/display/waveshare_epaper.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								esphomeyaml/components/display/waveshare_epaper.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml import pins | ||||
| from esphomeyaml.components import display | ||||
| from esphomeyaml.components.spi import SPIComponent | ||||
| from esphomeyaml.const import CONF_BUSY_PIN, CONF_CS_PIN, CONF_DC_PIN, CONF_FULL_UPDATE_EVERY, \ | ||||
|     CONF_ID, CONF_LAMBDA, CONF_MODEL, CONF_RESET_PIN, CONF_SPI_ID | ||||
| from esphomeyaml.helpers import App, Pvariable, add, get_variable, gpio_input_pin_expression, \ | ||||
|     gpio_output_pin_expression, process_lambda | ||||
|  | ||||
| DEPENDENCIES = ['spi'] | ||||
|  | ||||
| WaveshareEPaperTypeA = display.display_ns.WaveshareEPaperTypeA | ||||
| WaveshareEPaper = display.display_ns.WaveshareEPaper | ||||
|  | ||||
| MODELS = { | ||||
|     '1.54in': ('a', display.display_ns.WAVESHARE_EPAPER_1_54_IN), | ||||
|     '2.13in': ('a', display.display_ns.WAVESHARE_EPAPER_2_13_IN), | ||||
|     '2.90in': ('a', display.display_ns.WAVESHARE_EPAPER_2_9_IN), | ||||
|     '2.70in': ('b', display.display_ns.WAVESHARE_EPAPER_2_7_IN), | ||||
|     '4.20in': ('b', display.display_ns.WAVESHARE_EPAPER_4_2_IN), | ||||
|     '7.50in': ('b', display.display_ns.WAVESHARE_EPAPER_7_5_IN), | ||||
| } | ||||
|  | ||||
|  | ||||
| def validate_full_update_every_only_type_a(value): | ||||
|     if CONF_FULL_UPDATE_EVERY not in value: | ||||
|         return value | ||||
|     if MODELS[value[CONF_MODEL]][0] != 'a': | ||||
|         raise vol.Invalid("The 'full_update_every' option is only available for models " | ||||
|                           "'1.54in', '2.13in' and '2.90in'.") | ||||
|     return value | ||||
|  | ||||
|  | ||||
| PLATFORM_SCHEMA = vol.All(display.FULL_DISPLAY_PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID(): cv.declare_variable_id(None), | ||||
|     cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent), | ||||
|     vol.Required(CONF_CS_PIN): pins.gpio_output_pin_schema, | ||||
|     vol.Required(CONF_DC_PIN): pins.gpio_output_pin_schema, | ||||
|     vol.Required(CONF_MODEL): cv.one_of(*MODELS), | ||||
|     vol.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema, | ||||
|     vol.Optional(CONF_BUSY_PIN): pins.gpio_input_pin_schema, | ||||
|     vol.Optional(CONF_FULL_UPDATE_EVERY): cv.uint32_t, | ||||
| }), validate_full_update_every_only_type_a) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     for spi in get_variable(config[CONF_SPI_ID]): | ||||
|         yield | ||||
|     for cs in gpio_output_pin_expression(config[CONF_CS_PIN]): | ||||
|         yield | ||||
|     for dc in gpio_output_pin_expression(config[CONF_DC_PIN]): | ||||
|         yield | ||||
|  | ||||
|     model_type, model = MODELS[config[CONF_MODEL]] | ||||
|     if model_type == 'a': | ||||
|         rhs = App.make_waveshare_epaper_type_a(spi, cs, dc, model) | ||||
|         epaper = Pvariable(config[CONF_ID], rhs, type=WaveshareEPaperTypeA) | ||||
|     elif model_type == 'b': | ||||
|         rhs = App.make_waveshare_epaper_type_b(spi, cs, dc, model) | ||||
|         epaper = Pvariable(config[CONF_ID], rhs, type=WaveshareEPaper) | ||||
|     else: | ||||
|         raise NotImplementedError() | ||||
|  | ||||
|     if CONF_LAMBDA in config: | ||||
|         for lambda_ in process_lambda(config[CONF_LAMBDA], [(display.DisplayBufferRef, 'it')]): | ||||
|             yield | ||||
|         add(epaper.set_writer(lambda_)) | ||||
|     if CONF_RESET_PIN in config: | ||||
|         for reset in gpio_output_pin_expression(config[CONF_RESET_PIN]): | ||||
|             yield | ||||
|         add(epaper.set_reset_pin(reset)) | ||||
|     if CONF_BUSY_PIN in config: | ||||
|         for reset in gpio_input_pin_expression(config[CONF_BUSY_PIN]): | ||||
|             yield | ||||
|         add(epaper.set_busy_pin(reset)) | ||||
|     if CONF_FULL_UPDATE_EVERY in config: | ||||
|         add(epaper.set_full_update_every(config[CONF_FULL_UPDATE_EVERY])) | ||||
|  | ||||
|     display.setup_display(epaper, config) | ||||
|  | ||||
|  | ||||
| BUILD_FLAGS = '-DUSE_WAVESHARE_EPAPER' | ||||
							
								
								
									
										126
									
								
								esphomeyaml/components/font.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								esphomeyaml/components/font.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| # coding=utf-8 | ||||
| import os.path | ||||
|  | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml import core | ||||
| from esphomeyaml.components import display | ||||
| from esphomeyaml.const import CONF_FILE, CONF_GLYPHS, CONF_ID, CONF_SIZE | ||||
| from esphomeyaml.core import HexInt | ||||
| from esphomeyaml.helpers import App, ArrayInitializer, MockObj, Pvariable, RawExpression, add | ||||
|  | ||||
| DEPENDENCIES = ['display'] | ||||
|  | ||||
| Font = display.display_ns.Font | ||||
| Glyph = display.display_ns.Glyph | ||||
|  | ||||
|  | ||||
| def validate_glyphs(value): | ||||
|     if isinstance(value, list): | ||||
|         value = vol.Schema([cv.string])(value) | ||||
|     value = vol.Schema([cv.string])(list(value)) | ||||
|  | ||||
|     def comparator(x, y): | ||||
|         x_ = x.encode('utf-8') | ||||
|         y_ = y.encode('utf-8') | ||||
|  | ||||
|         for c in range(min(len(x_), len(y_))): | ||||
|             if x_[c] < y_[c]: | ||||
|                 return -1 | ||||
|             if x_[c] > y_[c]: | ||||
|                 return 1 | ||||
|  | ||||
|         if len(x_) < len(y_): | ||||
|             return -1 | ||||
|         elif len(x_) > len(y_): | ||||
|             return 1 | ||||
|         else: | ||||
|             raise vol.Invalid(u"Found duplicate glyph {}".format(x)) | ||||
|  | ||||
|     value.sort(cmp=comparator) | ||||
|     return value | ||||
|  | ||||
|  | ||||
| def validate_pillow_installed(value): | ||||
|     try: | ||||
|         import PIL | ||||
|     except ImportError: | ||||
|         raise vol.Invalid("Please install the pillow python package to use fonts. " | ||||
|                           "(pip2 install pillow)") | ||||
|  | ||||
|     if PIL.__version__[0] < '4': | ||||
|         raise vol.Invalid("Please update your pillow installation to at least 4.0.x. " | ||||
|                           "(pip2 install -U pillow)") | ||||
|  | ||||
|     return value | ||||
|  | ||||
|  | ||||
| def validate_truetype_file(value): | ||||
|     value = cv.string(value) | ||||
|     path = os.path.join(core.CONFIG_PATH, value) | ||||
|     if not os.path.isfile(path): | ||||
|         raise vol.Invalid(u"Could not find file '{}'. Please make sure it exists.".format(path)) | ||||
|     if value.endswith('.zip'):  # for Google Fonts downloads | ||||
|         raise vol.Invalid(u"Please unzip the font archive '{}' first and then use the .ttf files " | ||||
|                           u"inside.".format(value)) | ||||
|     if not value.endswith('.ttf'): | ||||
|         raise vol.Invalid(u"Only truetype (.ttf) files are supported. Please make sure you're " | ||||
|                           u"using the correct format or rename the extension to .ttf") | ||||
|     return value | ||||
|  | ||||
|  | ||||
| DEFAULT_GLYPHS = u' !"%()+,-.:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz°' | ||||
| CONF_RAW_DATA_ID = 'raw_data_id' | ||||
|  | ||||
| FONT_SCHEMA = vol.Schema({ | ||||
|     vol.Required(CONF_ID): cv.declare_variable_id(Font), | ||||
|     vol.Required(CONF_FILE): validate_truetype_file, | ||||
|     vol.Optional(CONF_GLYPHS, default=DEFAULT_GLYPHS): validate_glyphs, | ||||
|     vol.Optional(CONF_SIZE, default=12): vol.All(cv.int_, vol.Range(min=1)), | ||||
|     cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(None), | ||||
| }) | ||||
|  | ||||
| CONFIG_SCHEMA = vol.All(validate_pillow_installed, cv.ensure_list, [FONT_SCHEMA]) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     from PIL import ImageFont | ||||
|  | ||||
|     for conf in config: | ||||
|         path = os.path.join(core.CONFIG_PATH, conf[CONF_FILE]) | ||||
|         try: | ||||
|             font = ImageFont.truetype(path, conf[CONF_SIZE]) | ||||
|         except Exception as e: | ||||
|             raise core.ESPHomeYAMLError(u"Could not load truetype file {}: {}".format(path, e)) | ||||
|  | ||||
|         ascent, descent = font.getmetrics() | ||||
|  | ||||
|         glyph_args = {} | ||||
|         data = [] | ||||
|         for glyph in conf[CONF_GLYPHS]: | ||||
|             mask = font.getmask(glyph, mode='1') | ||||
|             _, (offset_x, offset_y) = font.font.getsize(glyph) | ||||
|             width, height = mask.size | ||||
|             width8 = ((width + 7) // 8) * 8 | ||||
|             glyph_data = [0 for _ in range(height * width8 // 8)] | ||||
|             for y in range(height): | ||||
|                 for x in range(width): | ||||
|                     if not mask.getpixel((x, y)): | ||||
|                         continue | ||||
|                     pos = x + y * width8 | ||||
|                     glyph_data[pos // 8] |= 0x80 >> (pos % 8) | ||||
|             glyph_args[glyph] = (len(data), offset_x, offset_y, width, height) | ||||
|             data += glyph_data | ||||
|  | ||||
|         raw_data = MockObj(conf[CONF_RAW_DATA_ID]) | ||||
|         add(RawExpression('static const uint8_t {}[{}] PROGMEM = {}'.format( | ||||
|             raw_data, len(data), | ||||
|             ArrayInitializer(*[HexInt(x) for x in data], multiline=False)))) | ||||
|  | ||||
|         glyphs = [] | ||||
|         for glyph in conf[CONF_GLYPHS]: | ||||
|             glyphs.append(Glyph(glyph, raw_data, *glyph_args[glyph])) | ||||
|  | ||||
|         rhs = App.make_font(ArrayInitializer(*glyphs), ascent, ascent + descent) | ||||
|         Pvariable(conf[CONF_ID], rhs) | ||||
							
								
								
									
										85
									
								
								esphomeyaml/components/image.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								esphomeyaml/components/image.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| # coding=utf-8 | ||||
| import logging | ||||
| import os.path | ||||
|  | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml import core | ||||
| from esphomeyaml.components import display | ||||
| from esphomeyaml.const import CONF_FILE, CONF_ID, CONF_RESIZE | ||||
| from esphomeyaml.core import HexInt | ||||
| from esphomeyaml.helpers import App, ArrayInitializer, MockObj, Pvariable, RawExpression, add | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| DEPENDENCIES = ['display'] | ||||
|  | ||||
| Image_ = display.display_ns.Image | ||||
|  | ||||
|  | ||||
| def validate_pillow_installed(value): | ||||
|     try: | ||||
|         # pylint: disable=unused-variable | ||||
|         import PIL | ||||
|     except ImportError: | ||||
|         raise vol.Invalid("Please install the pillow python package to use images. " | ||||
|                           "(pip2 install pillow)") | ||||
|  | ||||
|     return value | ||||
|  | ||||
|  | ||||
| def validate_image_file(value): | ||||
|     value = cv.string(value) | ||||
|     path = os.path.join(core.CONFIG_PATH, value) | ||||
|     if not os.path.isfile(path): | ||||
|         raise vol.Invalid(u"Could not find file '{}'. Please make sure it exists.".format(path)) | ||||
|     return value | ||||
|  | ||||
|  | ||||
| CONF_RAW_DATA_ID = 'raw_data_id' | ||||
|  | ||||
| FONT_SCHEMA = vol.Schema({ | ||||
|     vol.Required(CONF_ID): cv.declare_variable_id(Image_), | ||||
|     vol.Required(CONF_FILE): validate_image_file, | ||||
|     vol.Optional(CONF_RESIZE): cv.dimensions, | ||||
|     cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(None), | ||||
| }) | ||||
|  | ||||
| CONFIG_SCHEMA = vol.All(validate_pillow_installed, cv.ensure_list, [FONT_SCHEMA]) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     from PIL import Image | ||||
|  | ||||
|     for conf in config: | ||||
|         path = os.path.join(core.CONFIG_PATH, conf[CONF_FILE]) | ||||
|         try: | ||||
|             image = Image.open(path) | ||||
|         except Exception as e: | ||||
|             raise core.ESPHomeYAMLError(u"Could not load image file {}: {}".format(path, e)) | ||||
|  | ||||
|         if CONF_RESIZE in conf: | ||||
|             image.thumbnail(conf[CONF_RESIZE]) | ||||
|  | ||||
|         image = image.convert('1') | ||||
|         width, height = image.size | ||||
|         if width > 500 or height > 500: | ||||
|             _LOGGER.warning("The image you requested is very big. Please consider using the resize " | ||||
|                             "parameter") | ||||
|         width8 = ((width + 7) // 8) * 8 | ||||
|         data = [0 for _ in range(height * width8 // 8)] | ||||
|         for y in range(height): | ||||
|             for x in range(width): | ||||
|                 if image.getpixel((x, y)): | ||||
|                     continue | ||||
|                 pos = x + y * width8 | ||||
|                 data[pos // 8] |= 0x80 >> (pos % 8) | ||||
|  | ||||
|         raw_data = MockObj(conf[CONF_RAW_DATA_ID]) | ||||
|         add(RawExpression('static const uint8_t {}[{}] PROGMEM = {}'.format( | ||||
|             raw_data, len(data), | ||||
|             ArrayInitializer(*[HexInt(x) for x in data], multiline=False)))) | ||||
|  | ||||
|         rhs = App.make_image(raw_data, width, height) | ||||
|         Pvariable(conf[CONF_ID], rhs) | ||||
| @@ -4,7 +4,7 @@ import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml import pins | ||||
| from esphomeyaml.components import binary_sensor | ||||
| from esphomeyaml.components.spi import SPIComponent | ||||
| from esphomeyaml.const import CONF_CS, CONF_ID, CONF_SPI_ID, CONF_UPDATE_INTERVAL | ||||
| from esphomeyaml.const import CONF_CS_PIN, CONF_ID, CONF_SPI_ID, CONF_UPDATE_INTERVAL | ||||
| from esphomeyaml.helpers import App, Pvariable, get_variable, gpio_output_pin_expression | ||||
|  | ||||
| DEPENDENCIES = ['spi'] | ||||
| @@ -14,7 +14,7 @@ PN532Component = binary_sensor.binary_sensor_ns.PN532Component | ||||
| CONFIG_SCHEMA = vol.All(cv.ensure_list, [vol.Schema({ | ||||
|     cv.GenerateID(): cv.declare_variable_id(PN532Component), | ||||
|     cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent), | ||||
|     vol.Required(CONF_CS): pins.gpio_output_pin_schema, | ||||
|     vol.Required(CONF_CS_PIN): pins.gpio_output_pin_schema, | ||||
|     vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, | ||||
| })]) | ||||
|  | ||||
| @@ -25,7 +25,7 @@ def to_code(config): | ||||
|         for spi in get_variable(conf[CONF_SPI_ID]): | ||||
|             yield | ||||
|         cs = None | ||||
|         for cs in gpio_output_pin_expression(conf[CONF_CS]): | ||||
|         for cs in gpio_output_pin_expression(conf[CONF_CS_PIN]): | ||||
|             yield | ||||
|         rhs = App.make_pn532_component(spi, cs, conf.get(CONF_UPDATE_INTERVAL)) | ||||
|         Pvariable(conf[CONF_ID], rhs) | ||||
|   | ||||
| @@ -4,7 +4,8 @@ import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml import pins | ||||
| from esphomeyaml.components import sensor | ||||
| from esphomeyaml.components.spi import SPIComponent | ||||
| from esphomeyaml.const import CONF_CS, CONF_MAKE_ID, CONF_NAME, CONF_SPI_ID, CONF_UPDATE_INTERVAL | ||||
| from esphomeyaml.const import CONF_CS_PIN, CONF_MAKE_ID, CONF_NAME, CONF_SPI_ID, \ | ||||
|     CONF_UPDATE_INTERVAL | ||||
| from esphomeyaml.helpers import App, Application, get_variable, gpio_output_pin_expression, variable | ||||
|  | ||||
| MakeMAX6675Sensor = Application.MakeMAX6675Sensor | ||||
| @@ -12,7 +13,7 @@ MakeMAX6675Sensor = Application.MakeMAX6675Sensor | ||||
| PLATFORM_SCHEMA = cv.nameable(sensor.SENSOR_PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID(CONF_MAKE_ID): cv.declare_variable_id(MakeMAX6675Sensor), | ||||
|     cv.GenerateID(CONF_SPI_ID): cv.use_variable_id(SPIComponent), | ||||
|     vol.Required(CONF_CS): pins.gpio_output_pin_schema, | ||||
|     vol.Required(CONF_CS_PIN): pins.gpio_output_pin_schema, | ||||
|     vol.Optional(CONF_UPDATE_INTERVAL): cv.positive_time_period_milliseconds, | ||||
| })) | ||||
|  | ||||
| @@ -22,7 +23,7 @@ def to_code(config): | ||||
|     for spi in get_variable(config[CONF_SPI_ID]): | ||||
|         yield | ||||
|     cs = None | ||||
|     for cs in gpio_output_pin_expression(config[CONF_CS]): | ||||
|     for cs in gpio_output_pin_expression(config[CONF_CS_PIN]): | ||||
|         yield | ||||
|     rhs = App.make_max6675_sensor(config[CONF_NAME], spi, cs, | ||||
|                                   config.get(CONF_UPDATE_INTERVAL)) | ||||
|   | ||||
| @@ -2,18 +2,18 @@ import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml import pins | ||||
| from esphomeyaml.const import CONF_CLK, CONF_ID, CONF_MISO, CONF_MOSI | ||||
| from esphomeyaml.const import CONF_CLK_PIN, CONF_ID, CONF_MISO_PIN, CONF_MOSI_PIN | ||||
| from esphomeyaml.helpers import App, Pvariable, esphomelib_ns, gpio_input_pin_expression, \ | ||||
|     gpio_output_pin_expression | ||||
|     gpio_output_pin_expression, add | ||||
|  | ||||
| SPIComponent = esphomelib_ns.SPIComponent | ||||
|  | ||||
| SPI_SCHEMA = vol.Schema({ | ||||
| SPI_SCHEMA = vol.All(vol.Schema({ | ||||
|     cv.GenerateID(): cv.declare_variable_id(SPIComponent), | ||||
|     vol.Required(CONF_CLK): pins.gpio_output_pin_schema, | ||||
|     vol.Required(CONF_MISO): pins.gpio_input_pin_schema, | ||||
|     vol.Optional(CONF_MOSI): pins.gpio_output_pin_schema, | ||||
| }) | ||||
|     vol.Required(CONF_CLK_PIN): pins.gpio_output_pin_schema, | ||||
|     vol.Optional(CONF_MISO_PIN): pins.gpio_input_pin_schema, | ||||
|     vol.Optional(CONF_MOSI_PIN): pins.gpio_output_pin_schema, | ||||
| }), cv.has_at_least_one_key(CONF_MISO_PIN, CONF_MOSI_PIN)) | ||||
|  | ||||
| CONFIG_SCHEMA = vol.All(cv.ensure_list, [SPI_SCHEMA]) | ||||
|  | ||||
| @@ -21,17 +21,18 @@ CONFIG_SCHEMA = vol.All(cv.ensure_list, [SPI_SCHEMA]) | ||||
| def to_code(config): | ||||
|     for conf in config: | ||||
|         clk = None | ||||
|         for clk in gpio_output_pin_expression(conf[CONF_CLK]): | ||||
|         for clk in gpio_output_pin_expression(conf[CONF_CLK_PIN]): | ||||
|             yield | ||||
|         miso = None | ||||
|         for miso in gpio_input_pin_expression(conf[CONF_MISO]): | ||||
|             yield | ||||
|         mosi = None | ||||
|         if CONF_MOSI in conf: | ||||
|             for mosi in gpio_output_pin_expression(conf[CONF_MOSI]): | ||||
|         rhs = App.init_spi(clk) | ||||
|         spi = Pvariable(conf[CONF_ID], rhs) | ||||
|         if CONF_MISO_PIN in conf: | ||||
|             for miso in gpio_input_pin_expression(conf[CONF_MISO_PIN]): | ||||
|                 yield | ||||
|         rhs = App.init_spi(clk, miso, mosi) | ||||
|         Pvariable(conf[CONF_ID], rhs) | ||||
|             add(spi.set_miso(miso)) | ||||
|         if CONF_MOSI_PIN in conf: | ||||
|             for mosi in gpio_input_pin_expression(conf[CONF_MOSI_PIN]): | ||||
|                 yield | ||||
|             add(spi.set_mosi(mosi)) | ||||
|  | ||||
|  | ||||
| BUILD_FLAGS = '-DUSE_SPI' | ||||
|   | ||||
							
								
								
									
										109
									
								
								esphomeyaml/components/time/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								esphomeyaml/components/time/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | ||||
| import datetime | ||||
| import logging | ||||
| import math | ||||
|  | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import CONF_TIMEZONE | ||||
| from esphomeyaml.helpers import add, add_job, esphomelib_ns | ||||
|  | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({ | ||||
|  | ||||
| }) | ||||
|  | ||||
| time_ns = esphomelib_ns.namespace('time') | ||||
|  | ||||
|  | ||||
| def _tz_timedelta(td): | ||||
|     offset_hour = int(td.total_seconds() / (60 * 60)) | ||||
|     offset_minute = int(abs(td.total_seconds() / 60)) % 60 | ||||
|     offset_second = int(abs(td.total_seconds())) % 60 | ||||
|     if offset_hour == 0 and offset_minute == 0 and offset_second == 0: | ||||
|         return '0' | ||||
|     elif offset_minute == 0 and offset_second == 0: | ||||
|         return '{}'.format(offset_hour) | ||||
|     elif offset_second == 0: | ||||
|         return '{}:{}'.format(offset_hour, offset_minute) | ||||
|     return '{}:{}:{}'.format(offset_hour, offset_minute, offset_second) | ||||
|  | ||||
|  | ||||
| # https://stackoverflow.com/a/16804556/8924614 | ||||
| def _week_of_month(dt): | ||||
|     first_day = dt.replace(day=1) | ||||
|     dom = dt.day | ||||
|     adjusted_dom = dom + first_day.weekday() | ||||
|     return int(math.ceil(adjusted_dom / 7.0)) | ||||
|  | ||||
|  | ||||
| def _tz_dst_str(dt): | ||||
|     td = datetime.timedelta(hours=dt.hour, minutes=dt.minute, seconds=dt.second) | ||||
|     return 'M{}.{}.{}/{}'.format(dt.month, _week_of_month(dt), dt.isoweekday() % 7, | ||||
|                                  _tz_timedelta(td)) | ||||
|  | ||||
|  | ||||
| def detect_tz(): | ||||
|     try: | ||||
|         import tzlocal | ||||
|     except ImportError: | ||||
|         raise vol.Invalid("No timezone specified and 'tzlocal' not installed. To automatically " | ||||
|                           "detect the timezone please install tzlocal (pip2 install tzlocal)") | ||||
|     tz = tzlocal.get_localzone() | ||||
|     dst_begins = None | ||||
|     dst_tzname = None | ||||
|     dst_utcoffset = None | ||||
|     dst_ends = None | ||||
|     norm_tzname = None | ||||
|     norm_utcoffset = None | ||||
|  | ||||
|     hour = datetime.timedelta(hours=1) | ||||
|     this_year = datetime.datetime.now().year | ||||
|     dt = datetime.datetime(year=this_year, month=1, day=1) | ||||
|     last_dst = None | ||||
|     while dt.year == this_year: | ||||
|         current_dst = tz.dst(dt, is_dst=not last_dst) | ||||
|         is_dst = bool(current_dst) | ||||
|         if is_dst != last_dst: | ||||
|             if is_dst: | ||||
|                 dst_begins = dt | ||||
|                 dst_tzname = tz.tzname(dt, is_dst=True) | ||||
|                 dst_utcoffset = tz.utcoffset(dt, is_dst=True) | ||||
|             else: | ||||
|                 dst_ends = dt + hour | ||||
|                 norm_tzname = tz.tzname(dt, is_dst=False) | ||||
|                 norm_utcoffset = tz.utcoffset(dt, is_dst=False) | ||||
|             last_dst = is_dst | ||||
|         dt += hour | ||||
|  | ||||
|     tzbase = '{}{}'.format(norm_tzname, _tz_timedelta(-1 * norm_utcoffset)) | ||||
|     if dst_begins is None: | ||||
|         # No DST in this timezone | ||||
|         _LOGGER.info("Auto-detected timezone '%s' with UTC offset %s", | ||||
|                      norm_tzname, _tz_timedelta(norm_utcoffset)) | ||||
|         return tzbase | ||||
|     tzext = '{}{},{},{}'.format(dst_tzname, _tz_timedelta(-1 * dst_utcoffset), | ||||
|                                 _tz_dst_str(dst_begins), _tz_dst_str(dst_ends)) | ||||
|     _LOGGER.info("Auto-detected timezone '%s' with UTC offset %s and daylight savings time from " | ||||
|                  "%s to %s", | ||||
|                  norm_tzname, _tz_timedelta(norm_utcoffset), dst_begins.strftime("%x %X"), | ||||
|                  dst_ends.strftime("%x %X")) | ||||
|     return tzbase + tzext | ||||
|  | ||||
|  | ||||
| TIME_PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ | ||||
|     vol.Optional(CONF_TIMEZONE, default=detect_tz): cv.string, | ||||
| }) | ||||
|  | ||||
|  | ||||
| def setup_time_core_(time_var, config): | ||||
|     add(time_var.set_timezone(config[CONF_TIMEZONE])) | ||||
|  | ||||
|  | ||||
| def setup_time(time_var, config): | ||||
|     add_job(setup_time_core_, time_var, config) | ||||
|  | ||||
|  | ||||
| BUILD_FLAGS = '-DUSE_TIME' | ||||
							
								
								
									
										24
									
								
								esphomeyaml/components/time/sntp.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								esphomeyaml/components/time/sntp.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| import voluptuous as vol | ||||
|  | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.components import time as time_ | ||||
| from esphomeyaml.const import CONF_ID, CONF_LAMBDA, CONF_SERVERS | ||||
| from esphomeyaml.helpers import App, Pvariable | ||||
|  | ||||
| SNTPComponent = time_.time_ns.SNTPComponent | ||||
|  | ||||
| PLATFORM_SCHEMA = time_.TIME_PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID(): cv.declare_variable_id(SNTPComponent), | ||||
|     vol.Optional(CONF_SERVERS): vol.All(cv.ensure_list, [cv.string], vol.Length(max=3)), | ||||
|     vol.Optional(CONF_LAMBDA): cv.lambda_, | ||||
| }) | ||||
|  | ||||
|  | ||||
| def to_code(config): | ||||
|     rhs = App.make_sntp_component(*config.get(CONF_SERVERS, [])) | ||||
|     sntp = Pvariable(config[CONF_ID], rhs) | ||||
|  | ||||
|     time_.setup_time(sntp, config) | ||||
|  | ||||
|  | ||||
| BUILD_FLAGS = '-DUSE_SNTP_COMPONENT' | ||||
		Reference in New Issue
	
	Block a user