Ejemplo n.º 1
0
def mqtt2can(mqtt_msg):
    """ Convert MQTT message into CAN frame
    """
    match = re.match(r'^NODE/(?P<node>[0-9a-fA-F]+)/'
            '(?P<msg>[^/]+)/(?P<dev>[0-9a-fA-F]+)/'
            '((?P<extra>\S+)/)?(?P<op>[^/]+)$',
            mqtt_msg.topic)
    if not match:
        raise HomeCanMessageError('bad mqtt message')
    ## base format seems ok, extract parts for further processing
    node = match.group('node')
    dev = match.group('dev')
    try:
        msg = Message.mqtt_decode(match.group('msg'))
    except KeyError:
        raise HomeCanMessageError('wrong mqtt message type')
    op = Operation[match.group('op')]

    if op not in [Operation.QUERY, Operation.SET, Operation.RESET]:
        raise HomeCanBridgingForbidden('{} may not be translated from MQTT into CAN'.format(op.name))

    ## FIXME should we translate all messages back and forth?
    #if op not in [HC_MESSAGE.QUERY, HC_MESSAGE.SET]:
    #    raise HomeCanMessageError('wrong mqtt message type')`

    ## calculate CAN extended id
    can_eid = msg | Node.mqtt2can(node) | Device.mqtt2can(dev) | op
    ## prepare frame data based on msg type
    if msg == Message.PING:
        can_frame = _mqtt2can_ping(can_eid, msg, mqtt_msg.payload)
    elif msg == Message.DATETIME:
        can_frame = _mqtt2can_datetime(can_eid, msg, mqtt_msg.payload)
    elif msg == Message.KEY:
        can_frame = _mqtt2can_key(can_eid, msg, mqtt_msg.payload)
    elif msg in [Message.TEMPERATURE, Message.RHUMIDITY,
            Message.ILLUMINANCE, Message.PRESSURE]:
        can_frame = _mqtt2can_simple_sensor(can_eid, msg, mqtt_msg.payload)
    elif msg in [Message.DUST]:
        from can2mqtt.bridge_dust import _mqtt2can_dust
        can_frame = _mqtt2can_dust(can_eid, msg, mqtt_msg.payload)
    elif msg == Message.DIGITAL_OUTPUT:
        can_frame = _mqtt2can_digital_output(can_eid, msg, mqtt_msg.payload)
    elif msg == Message.PCA963x:
        from can2mqtt.bridge_pca963x import _mqtt2can_pca963x
        extra = match.group('extra')
        can_frame = _mqtt2can_pca963x(can_eid, msg, extra, mqtt_msg.payload)
    elif msg == Message.COVER:
        can_frame = _mqtt2can_cover(can_eid, msg, mqtt_msg.payload)
    else:
        raise HomeCanMessageNotSupported('mqtt message {} not yet supported'.
                format(msg.name))
    
    return can_frame
Ejemplo n.º 2
0
def test_node_mqtt2can(hc_nodes):
    for mqtt, can in hc_nodes:
        assert Node.mqtt2can(mqtt) == can