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_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_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_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D, CONF_SAMSUNG, CONF_SONY, \ | ||||||
|     CONF_STATE |     CONF_STATE, CONF_ID | ||||||
| from esphomeyaml.cpp_generator import Pvariable, get_variable | from esphomeyaml.cpp_generator import Pvariable, get_variable, progmem_array | ||||||
|  | from esphomeyaml.cpp_types import int32 | ||||||
|  |  | ||||||
| DEPENDENCIES = ['remote_receiver'] | DEPENDENCIES = ['remote_receiver'] | ||||||
|  |  | ||||||
| @@ -35,6 +36,18 @@ RCSwitchTypeBReceiver = remote_ns.class_('RCSwitchTypeBReceiver', RCSwitchRawRec | |||||||
| RCSwitchTypeCReceiver = remote_ns.class_('RCSwitchTypeCReceiver', RCSwitchRawReceiver) | RCSwitchTypeCReceiver = remote_ns.class_('RCSwitchTypeCReceiver', RCSwitchRawReceiver) | ||||||
| RCSwitchTypeDReceiver = remote_ns.class_('RCSwitchTypeDReceiver', 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({ | PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({ | ||||||
|     cv.GenerateID(): cv.declare_variable_id(RemoteReceiver), |     cv.GenerateID(): cv.declare_variable_id(RemoteReceiver), | ||||||
|     vol.Optional(CONF_LG): vol.Schema({ |     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_ADDRESS): cv.hex_uint16_t, | ||||||
|         vol.Required(CONF_COMMAND): cv.hex_uint32_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_RAW): RC_SWITCH_RAW_SCHEMA, | ||||||
|     vol.Optional(CONF_RC_SWITCH_TYPE_A): RC_SWITCH_TYPE_A_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, |     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: |     if key == CONF_SONY: | ||||||
|         return SonyReceiver.new(name, config[CONF_DATA], config[CONF_NBITS]) |         return SonyReceiver.new(name, config[CONF_DATA], config[CONF_NBITS]) | ||||||
|     if key == CONF_RAW: |     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: |     if key == CONF_RC_SWITCH_RAW: | ||||||
|         return RCSwitchRawReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]), |         return RCSwitchRawReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]), | ||||||
|                                        binary_code(config[CONF_CODE]), len(config[CONF_CODE])) |                                        binary_code(config[CONF_CODE]), len(config[CONF_CODE])) | ||||||
|   | |||||||
| @@ -6,8 +6,8 @@ from esphomeyaml.components import display | |||||||
| import esphomeyaml.config_validation as cv | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml.const import CONF_FILE, CONF_GLYPHS, CONF_ID, CONF_SIZE | from esphomeyaml.const import CONF_FILE, CONF_GLYPHS, CONF_ID, CONF_SIZE | ||||||
| from esphomeyaml.core import CORE, HexInt | from esphomeyaml.core import CORE, HexInt | ||||||
| from esphomeyaml.cpp_generator import MockObj, Pvariable, RawExpression, add, safe_exp | from esphomeyaml.cpp_generator import Pvariable, progmem_array, safe_exp | ||||||
| from esphomeyaml.cpp_types import App | from esphomeyaml.cpp_types import App, uint8 | ||||||
| from esphomeyaml.py_compat import sort_by_cmp | from esphomeyaml.py_compat import sort_by_cmp | ||||||
|  |  | ||||||
| DEPENDENCIES = ['display'] | DEPENDENCIES = ['display'] | ||||||
| @@ -74,7 +74,7 @@ FONT_SCHEMA = vol.Schema({ | |||||||
|     vol.Required(CONF_FILE): validate_truetype_file, |     vol.Required(CONF_FILE): validate_truetype_file, | ||||||
|     vol.Optional(CONF_GLYPHS, default=DEFAULT_GLYPHS): validate_glyphs, |     vol.Optional(CONF_GLYPHS, default=DEFAULT_GLYPHS): validate_glyphs, | ||||||
|     vol.Optional(CONF_SIZE, default=20): vol.All(cv.int_, vol.Range(min=1)), |     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) | 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) |         glyph_args[glyph] = (len(data), offset_x, offset_y, width, height) | ||||||
|         data += glyph_data |         data += glyph_data | ||||||
|  |  | ||||||
|     raw_data = MockObj(config[CONF_RAW_DATA_ID]) |     rhs = safe_exp([HexInt(x) for x in data]) | ||||||
|     add(RawExpression('static const uint8_t {}[{}] PROGMEM = {}'.format( |     prog_arr = progmem_array(config[CONF_RAW_DATA_ID], rhs) | ||||||
|         raw_data, len(data), |  | ||||||
|         safe_exp([HexInt(x) for x in data])))) |  | ||||||
|  |  | ||||||
|     glyphs = [] |     glyphs = [] | ||||||
|     for glyph in config[CONF_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) |     rhs = App.make_font(glyphs, ascent, ascent + descent) | ||||||
|     Pvariable(config[CONF_ID], rhs) |     Pvariable(config[CONF_ID], rhs) | ||||||
|   | |||||||
| @@ -8,8 +8,8 @@ from esphomeyaml.components import display, font | |||||||
| import esphomeyaml.config_validation as cv | import esphomeyaml.config_validation as cv | ||||||
| from esphomeyaml.const import CONF_FILE, CONF_ID, CONF_RESIZE | from esphomeyaml.const import CONF_FILE, CONF_ID, CONF_RESIZE | ||||||
| from esphomeyaml.core import CORE, HexInt | from esphomeyaml.core import CORE, HexInt | ||||||
| from esphomeyaml.cpp_generator import MockObj, Pvariable, RawExpression, add, safe_exp | from esphomeyaml.cpp_generator import Pvariable, progmem_array, safe_exp | ||||||
| from esphomeyaml.cpp_types import App | from esphomeyaml.cpp_types import App, uint8 | ||||||
|  |  | ||||||
| _LOGGER = logging.getLogger(__name__) | _LOGGER = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| @@ -24,7 +24,7 @@ IMAGE_SCHEMA = vol.Schema({ | |||||||
|     vol.Required(CONF_ID): cv.declare_variable_id(Image_), |     vol.Required(CONF_ID): cv.declare_variable_id(Image_), | ||||||
|     vol.Required(CONF_FILE): cv.file_, |     vol.Required(CONF_FILE): cv.file_, | ||||||
|     vol.Optional(CONF_RESIZE): cv.dimensions, |     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) | CONFIG_SCHEMA = vol.All(font.validate_pillow_installed, IMAGE_SCHEMA) | ||||||
| @@ -56,10 +56,8 @@ def to_code(config): | |||||||
|             pos = x + y * width8 |             pos = x + y * width8 | ||||||
|             data[pos // 8] |= 0x80 >> (pos % 8) |             data[pos // 8] |= 0x80 >> (pos % 8) | ||||||
|  |  | ||||||
|     raw_data = MockObj(config[CONF_RAW_DATA_ID]) |     rhs = safe_exp([HexInt(x) for x in data]) | ||||||
|     add(RawExpression('static const uint8_t {}[{}] PROGMEM = {}'.format( |     prog_arr = progmem_array(config[CONF_RAW_DATA_ID], rhs) | ||||||
|         raw_data, len(data), |  | ||||||
|         safe_exp([HexInt(x) for x in data])))) |  | ||||||
|  |  | ||||||
|     rhs = App.make_image(raw_data, width, height) |     rhs = App.make_image(prog_arr, width, height) | ||||||
|     Pvariable(config[CONF_ID], rhs) |     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_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_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_REPEAT, CONF_SAMSUNG, CONF_SONY, CONF_STATE, CONF_TIMES, \ | ||||||
|     CONF_WAIT_TIME |     CONF_WAIT_TIME, CONF_ID | ||||||
| from esphomeyaml.cpp_generator import Pvariable, add, get_variable | from esphomeyaml.cpp_generator import Pvariable, add, get_variable, progmem_array | ||||||
|  | from esphomeyaml.cpp_types import int32 | ||||||
|  |  | ||||||
| DEPENDENCIES = ['remote_transmitter'] | DEPENDENCIES = ['remote_transmitter'] | ||||||
|  |  | ||||||
| @@ -36,7 +37,18 @@ RCSwitchTypeBTransmitter = remote_ns.class_('RCSwitchTypeBTransmitter', RCSwitch | |||||||
| RCSwitchTypeCTransmitter = remote_ns.class_('RCSwitchTypeCTransmitter', RCSwitchRawTransmitter) | RCSwitchTypeCTransmitter = remote_ns.class_('RCSwitchTypeCTransmitter', RCSwitchRawTransmitter) | ||||||
| RCSwitchTypeDTransmitter = remote_ns.class_('RCSwitchTypeDTransmitter', 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({ | PLATFORM_SCHEMA = cv.nameable(switch.SWITCH_PLATFORM_SCHEMA.extend({ | ||||||
|     cv.GenerateID(): cv.declare_variable_id(RemoteTransmitter), |     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_ADDRESS): cv.hex_uint16_t, | ||||||
|         vol.Required(CONF_COMMAND): cv.hex_uint32_t, |         vol.Required(CONF_COMMAND): cv.hex_uint32_t, | ||||||
|     }), |     }), | ||||||
|     vol.Optional(CONF_RAW): vol.Any(validate_raw_data, vol.Schema({ |     vol.Optional(CONF_RAW): validate_raw, | ||||||
|         vol.Required(CONF_DATA): validate_raw_data, |  | ||||||
|         vol.Optional(CONF_CARRIER_FREQUENCY): vol.All(cv.frequency, vol.Coerce(int)), |  | ||||||
|     })), |  | ||||||
|     vol.Optional(CONF_RC_SWITCH_RAW): RC_SWITCH_RAW_SCHEMA, |     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_A): RC_SWITCH_TYPE_A_SCHEMA, | ||||||
|     vol.Optional(CONF_RC_SWITCH_TYPE_B): RC_SWITCH_TYPE_B_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: |     if key == CONF_SONY: | ||||||
|         return SonyTransmitter.new(name, config[CONF_DATA], config[CONF_NBITS]) |         return SonyTransmitter.new(name, config[CONF_DATA], config[CONF_NBITS]) | ||||||
|     if key == CONF_RAW: |     if key == CONF_RAW: | ||||||
|         if isinstance(config, dict): |         arr = progmem_array(config[CONF_ID], config[CONF_DATA]) | ||||||
|             data = config[CONF_DATA] |         return RawTransmitter.new(name, arr, len(config[CONF_DATA]), | ||||||
|             carrier_frequency = config.get(CONF_CARRIER_FREQUENCY) |                                   config.get(CONF_CARRIER_FREQUENCY)) | ||||||
|         else: |  | ||||||
|             data = config |  | ||||||
|             carrier_frequency = None |  | ||||||
|         return RawTransmitter.new(name, data, |  | ||||||
|                                   carrier_frequency) |  | ||||||
|     if key == CONF_RC_SWITCH_RAW: |     if key == CONF_RC_SWITCH_RAW: | ||||||
|         return RCSwitchRawTransmitter.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]), |         return RCSwitchRawTransmitter.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]), | ||||||
|                                           binary_code(config[CONF_CODE]), len(config[CONF_CODE])) |                                           binary_code(config[CONF_CODE]), len(config[CONF_CODE])) | ||||||
|   | |||||||
| @@ -46,6 +46,7 @@ RESERVED_IDS = [ | |||||||
|  |  | ||||||
|     'App', 'pinMode', 'delay', 'delayMicroseconds', 'digitalRead', 'digitalWrite', 'INPUT', |     'App', 'pinMode', 'delay', 'delayMicroseconds', 'digitalRead', 'digitalWrite', 'INPUT', | ||||||
|     'OUTPUT', |     '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 |         self.type = type | ||||||
|  |  | ||||||
|     def resolve(self, registered_ids): |     def resolve(self, registered_ids): | ||||||
|  |         from esphomeyaml.config_validation import RESERVED_IDS | ||||||
|  |  | ||||||
|         if self.id is None: |         if self.id is None: | ||||||
|             base = str(self.type).replace('::', '_').lower() |             base = str(self.type).replace('::', '_').lower() | ||||||
|             name = ''.join(c for c in base if c.isalnum() or c == '_') |             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 |         return self.id | ||||||
|  |  | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|   | |||||||
| @@ -317,6 +317,27 @@ class ExpressionStatement(Statement): | |||||||
|         return u"{};".format(self.expression) |         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 | def statement(expression):  # type: (Union[Expression, Statement]) -> Statement | ||||||
|     if isinstance(expression, Statement): |     if isinstance(expression, Statement): | ||||||
|         return expression |         return expression | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user