mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Store Raw Remote Codes in PROGMEM (#392)
* Store Raw Remote Codes in PROGMEM * Lint * Lint * Fix
This commit is contained in:
		| @@ -10,8 +10,9 @@ from esphomeyaml.const import CONF_ADDRESS, CONF_CHANNEL, CONF_CODE, CONF_COMMAN | ||||
|     CONF_DEVICE, CONF_FAMILY, CONF_GROUP, CONF_LG, CONF_NAME, CONF_NBITS, CONF_NEC, \ | ||||
|     CONF_PANASONIC, CONF_PROTOCOL, CONF_RAW, CONF_RC_SWITCH_RAW, CONF_RC_SWITCH_TYPE_A, \ | ||||
|     CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D, CONF_SAMSUNG, CONF_SONY, \ | ||||
|     CONF_STATE | ||||
| from esphomeyaml.cpp_generator import Pvariable, get_variable | ||||
|     CONF_STATE, CONF_ID | ||||
| from esphomeyaml.cpp_generator import Pvariable, get_variable, progmem_array | ||||
| from esphomeyaml.cpp_types import int32 | ||||
|  | ||||
| DEPENDENCIES = ['remote_receiver'] | ||||
|  | ||||
| @@ -35,6 +36,18 @@ RCSwitchTypeBReceiver = remote_ns.class_('RCSwitchTypeBReceiver', RCSwitchRawRec | ||||
| RCSwitchTypeCReceiver = remote_ns.class_('RCSwitchTypeCReceiver', RCSwitchRawReceiver) | ||||
| RCSwitchTypeDReceiver = remote_ns.class_('RCSwitchTypeDReceiver', RCSwitchRawReceiver) | ||||
|  | ||||
|  | ||||
| def validate_raw(value): | ||||
|     if isinstance(value, dict): | ||||
|         return vol.Schema({ | ||||
|             cv.GenerateID(): cv.declare_variable_id(int32), | ||||
|             vol.Required(CONF_DATA): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)], | ||||
|         })(value) | ||||
|     return validate_raw({ | ||||
|         CONF_DATA: value | ||||
|     }) | ||||
|  | ||||
|  | ||||
| PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID(): cv.declare_variable_id(RemoteReceiver), | ||||
|     vol.Optional(CONF_LG): vol.Schema({ | ||||
| @@ -56,7 +69,7 @@ PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend | ||||
|         vol.Required(CONF_ADDRESS): cv.hex_uint16_t, | ||||
|         vol.Required(CONF_COMMAND): cv.hex_uint32_t, | ||||
|     }), | ||||
|     vol.Optional(CONF_RAW): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)], | ||||
|     vol.Optional(CONF_RAW): validate_raw, | ||||
|     vol.Optional(CONF_RC_SWITCH_RAW): RC_SWITCH_RAW_SCHEMA, | ||||
|     vol.Optional(CONF_RC_SWITCH_TYPE_A): RC_SWITCH_TYPE_A_SCHEMA, | ||||
|     vol.Optional(CONF_RC_SWITCH_TYPE_B): RC_SWITCH_TYPE_B_SCHEMA, | ||||
| @@ -82,7 +95,8 @@ def receiver_base(full_config): | ||||
|     if key == CONF_SONY: | ||||
|         return SonyReceiver.new(name, config[CONF_DATA], config[CONF_NBITS]) | ||||
|     if key == CONF_RAW: | ||||
|         return RawReceiver.new(name, *config) | ||||
|         arr = progmem_array(config[CONF_ID], config[CONF_DATA]) | ||||
|         return RawReceiver.new(name, arr, len(config[CONF_DATA])) | ||||
|     if key == CONF_RC_SWITCH_RAW: | ||||
|         return RCSwitchRawReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]), | ||||
|                                        binary_code(config[CONF_CODE]), len(config[CONF_CODE])) | ||||
|   | ||||
| @@ -6,8 +6,8 @@ from esphomeyaml.components import display | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import CONF_FILE, CONF_GLYPHS, CONF_ID, CONF_SIZE | ||||
| from esphomeyaml.core import CORE, HexInt | ||||
| from esphomeyaml.cpp_generator import MockObj, Pvariable, RawExpression, add, safe_exp | ||||
| from esphomeyaml.cpp_types import App | ||||
| from esphomeyaml.cpp_generator import Pvariable, progmem_array, safe_exp | ||||
| from esphomeyaml.cpp_types import App, uint8 | ||||
| from esphomeyaml.py_compat import sort_by_cmp | ||||
|  | ||||
| DEPENDENCIES = ['display'] | ||||
| @@ -74,7 +74,7 @@ FONT_SCHEMA = vol.Schema({ | ||||
|     vol.Required(CONF_FILE): validate_truetype_file, | ||||
|     vol.Optional(CONF_GLYPHS, default=DEFAULT_GLYPHS): validate_glyphs, | ||||
|     vol.Optional(CONF_SIZE, default=20): vol.All(cv.int_, vol.Range(min=1)), | ||||
|     cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(None), | ||||
|     cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(uint8), | ||||
| }) | ||||
|  | ||||
| CONFIG_SCHEMA = vol.All(validate_pillow_installed, FONT_SCHEMA) | ||||
| @@ -108,14 +108,12 @@ def to_code(config): | ||||
|         glyph_args[glyph] = (len(data), offset_x, offset_y, width, height) | ||||
|         data += glyph_data | ||||
|  | ||||
|     raw_data = MockObj(config[CONF_RAW_DATA_ID]) | ||||
|     add(RawExpression('static const uint8_t {}[{}] PROGMEM = {}'.format( | ||||
|         raw_data, len(data), | ||||
|         safe_exp([HexInt(x) for x in data])))) | ||||
|     rhs = safe_exp([HexInt(x) for x in data]) | ||||
|     prog_arr = progmem_array(config[CONF_RAW_DATA_ID], rhs) | ||||
|  | ||||
|     glyphs = [] | ||||
|     for glyph in config[CONF_GLYPHS]: | ||||
|         glyphs.append(Glyph(glyph, raw_data, *glyph_args[glyph])) | ||||
|         glyphs.append(Glyph(glyph, prog_arr, *glyph_args[glyph])) | ||||
|  | ||||
|     rhs = App.make_font(glyphs, ascent, ascent + descent) | ||||
|     Pvariable(config[CONF_ID], rhs) | ||||
|   | ||||
| @@ -8,8 +8,8 @@ from esphomeyaml.components import display, font | ||||
| import esphomeyaml.config_validation as cv | ||||
| from esphomeyaml.const import CONF_FILE, CONF_ID, CONF_RESIZE | ||||
| from esphomeyaml.core import CORE, HexInt | ||||
| from esphomeyaml.cpp_generator import MockObj, Pvariable, RawExpression, add, safe_exp | ||||
| from esphomeyaml.cpp_types import App | ||||
| from esphomeyaml.cpp_generator import Pvariable, progmem_array, safe_exp | ||||
| from esphomeyaml.cpp_types import App, uint8 | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
| @@ -24,7 +24,7 @@ IMAGE_SCHEMA = vol.Schema({ | ||||
|     vol.Required(CONF_ID): cv.declare_variable_id(Image_), | ||||
|     vol.Required(CONF_FILE): cv.file_, | ||||
|     vol.Optional(CONF_RESIZE): cv.dimensions, | ||||
|     cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(None), | ||||
|     cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(uint8), | ||||
| }) | ||||
|  | ||||
| CONFIG_SCHEMA = vol.All(font.validate_pillow_installed, IMAGE_SCHEMA) | ||||
| @@ -56,10 +56,8 @@ def to_code(config): | ||||
|             pos = x + y * width8 | ||||
|             data[pos // 8] |= 0x80 >> (pos % 8) | ||||
|  | ||||
|     raw_data = MockObj(config[CONF_RAW_DATA_ID]) | ||||
|     add(RawExpression('static const uint8_t {}[{}] PROGMEM = {}'.format( | ||||
|         raw_data, len(data), | ||||
|         safe_exp([HexInt(x) for x in data])))) | ||||
|     rhs = safe_exp([HexInt(x) for x in data]) | ||||
|     prog_arr = progmem_array(config[CONF_RAW_DATA_ID], rhs) | ||||
|  | ||||
|     rhs = App.make_image(raw_data, width, height) | ||||
|     rhs = App.make_image(prog_arr, width, height) | ||||
|     Pvariable(config[CONF_ID], rhs) | ||||
|   | ||||
| @@ -11,8 +11,9 @@ from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_FREQUENCY, CONF_CHANNEL | ||||
|     CONF_NAME, CONF_NBITS, CONF_NEC, CONF_PANASONIC, CONF_PROTOCOL, CONF_RAW, CONF_RC_SWITCH_RAW, \ | ||||
|     CONF_RC_SWITCH_TYPE_A, CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D, \ | ||||
|     CONF_REPEAT, CONF_SAMSUNG, CONF_SONY, CONF_STATE, CONF_TIMES, \ | ||||
|     CONF_WAIT_TIME | ||||
| from esphomeyaml.cpp_generator import Pvariable, add, get_variable | ||||
|     CONF_WAIT_TIME, CONF_ID | ||||
| from esphomeyaml.cpp_generator import Pvariable, add, get_variable, progmem_array | ||||
| from esphomeyaml.cpp_types import int32 | ||||
|  | ||||
| DEPENDENCIES = ['remote_transmitter'] | ||||
|  | ||||
| @@ -36,7 +37,18 @@ RCSwitchTypeBTransmitter = remote_ns.class_('RCSwitchTypeBTransmitter', RCSwitch | ||||
| RCSwitchTypeCTransmitter = remote_ns.class_('RCSwitchTypeCTransmitter', RCSwitchRawTransmitter) | ||||
| RCSwitchTypeDTransmitter = remote_ns.class_('RCSwitchTypeDTransmitter', RCSwitchRawTransmitter) | ||||
|  | ||||
| validate_raw_data = [vol.Any(vol.Coerce(int), cv.time_period_microseconds)] | ||||
|  | ||||
| def validate_raw(value): | ||||
|     if isinstance(value, dict): | ||||
|         return vol.Schema({ | ||||
|             cv.GenerateID(): cv.declare_variable_id(int32), | ||||
|             vol.Required(CONF_DATA): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)], | ||||
|             vol.Optional(CONF_CARRIER_FREQUENCY): vol.All(cv.frequency, vol.Coerce(int)), | ||||
|         })(value) | ||||
|     return validate_raw({ | ||||
|         CONF_DATA: value | ||||
|     }) | ||||
|  | ||||
|  | ||||
| PLATFORM_SCHEMA = cv.nameable(switch.SWITCH_PLATFORM_SCHEMA.extend({ | ||||
|     cv.GenerateID(): cv.declare_variable_id(RemoteTransmitter), | ||||
| @@ -59,10 +71,7 @@ PLATFORM_SCHEMA = cv.nameable(switch.SWITCH_PLATFORM_SCHEMA.extend({ | ||||
|         vol.Required(CONF_ADDRESS): cv.hex_uint16_t, | ||||
|         vol.Required(CONF_COMMAND): cv.hex_uint32_t, | ||||
|     }), | ||||
|     vol.Optional(CONF_RAW): vol.Any(validate_raw_data, vol.Schema({ | ||||
|         vol.Required(CONF_DATA): validate_raw_data, | ||||
|         vol.Optional(CONF_CARRIER_FREQUENCY): vol.All(cv.frequency, vol.Coerce(int)), | ||||
|     })), | ||||
|     vol.Optional(CONF_RAW): validate_raw, | ||||
|     vol.Optional(CONF_RC_SWITCH_RAW): RC_SWITCH_RAW_SCHEMA, | ||||
|     vol.Optional(CONF_RC_SWITCH_TYPE_A): RC_SWITCH_TYPE_A_SCHEMA, | ||||
|     vol.Optional(CONF_RC_SWITCH_TYPE_B): RC_SWITCH_TYPE_B_SCHEMA, | ||||
| @@ -94,14 +103,9 @@ def transmitter_base(full_config): | ||||
|     if key == CONF_SONY: | ||||
|         return SonyTransmitter.new(name, config[CONF_DATA], config[CONF_NBITS]) | ||||
|     if key == CONF_RAW: | ||||
|         if isinstance(config, dict): | ||||
|             data = config[CONF_DATA] | ||||
|             carrier_frequency = config.get(CONF_CARRIER_FREQUENCY) | ||||
|         else: | ||||
|             data = config | ||||
|             carrier_frequency = None | ||||
|         return RawTransmitter.new(name, data, | ||||
|                                   carrier_frequency) | ||||
|         arr = progmem_array(config[CONF_ID], config[CONF_DATA]) | ||||
|         return RawTransmitter.new(name, arr, len(config[CONF_DATA]), | ||||
|                                   config.get(CONF_CARRIER_FREQUENCY)) | ||||
|     if key == CONF_RC_SWITCH_RAW: | ||||
|         return RCSwitchRawTransmitter.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]), | ||||
|                                           binary_code(config[CONF_CODE]), len(config[CONF_CODE])) | ||||
|   | ||||
| @@ -46,6 +46,7 @@ RESERVED_IDS = [ | ||||
|  | ||||
|     'App', 'pinMode', 'delay', 'delayMicroseconds', 'digitalRead', 'digitalWrite', 'INPUT', | ||||
|     'OUTPUT', | ||||
|     'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t', 'int8_t', 'int16_t', 'int32_t', 'int64_t', | ||||
| ] | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -261,10 +261,13 @@ class ID(object): | ||||
|         self.type = type | ||||
|  | ||||
|     def resolve(self, registered_ids): | ||||
|         from esphomeyaml.config_validation import RESERVED_IDS | ||||
|  | ||||
|         if self.id is None: | ||||
|             base = str(self.type).replace('::', '_').lower() | ||||
|             name = ''.join(c for c in base if c.isalnum() or c == '_') | ||||
|             self.id = ensure_unique_string(name, registered_ids) | ||||
|             used = set(registered_ids) | set(RESERVED_IDS) | ||||
|             self.id = ensure_unique_string(name, used) | ||||
|         return self.id | ||||
|  | ||||
|     def __str__(self): | ||||
|   | ||||
| @@ -317,6 +317,27 @@ class ExpressionStatement(Statement): | ||||
|         return u"{};".format(self.expression) | ||||
|  | ||||
|  | ||||
| class ProgmemAssignmentExpression(AssignmentExpression): | ||||
|     def __init__(self, type, name, rhs, obj): | ||||
|         super(ProgmemAssignmentExpression, self).__init__( | ||||
|             type, '', name, rhs, obj | ||||
|         ) | ||||
|  | ||||
|     def __str__(self): | ||||
|         type_ = self.type | ||||
|         return u"static const {} {}[] PROGMEM = {}".format(type_, self.name, self.rhs) | ||||
|  | ||||
|  | ||||
| def progmem_array(id, rhs): | ||||
|     rhs = safe_exp(rhs) | ||||
|     obj = MockObj(id, u'.') | ||||
|     assignment = ProgmemAssignmentExpression(id.type, id, rhs, obj) | ||||
|     CORE.add(assignment) | ||||
|     CORE.register_variable(id, obj) | ||||
|     obj.requires.append(assignment) | ||||
|     return obj | ||||
|  | ||||
|  | ||||
| def statement(expression):  # type: (Union[Expression, Statement]) -> Statement | ||||
|     if isinstance(expression, Statement): | ||||
|         return expression | ||||
|   | ||||
		Reference in New Issue
	
	Block a user