use of org.openhab.binding.maxcul.internal.messages.TimeInfoMsg in project openhab1-addons by openhab.
the class MaxCulMsgHandler method sendTimeInfo.
/**
* Send time information to device that has requested it as part of a
* message sequence
*
* @param dstAddr
* Address of device to respond to
* @param tzStr
* Time Zone String
* @param msgSeq
* Message sequence to associate
*/
public void sendTimeInfo(String dstAddr, String tzStr, MessageSequencer msgSeq) {
TimeInfoMsg msg = new TimeInfoMsg(getMessageCount(), (byte) 0x0, (byte) 0, this.srcAddr, dstAddr, tzStr);
msg.setMessageSequencer(msgSeq);
sendMessage(msg);
}
use of org.openhab.binding.maxcul.internal.messages.TimeInfoMsg in project openhab1-addons by openhab.
the class MaxCulBinding method maxCulMsgReceived.
@Override
public void maxCulMsgReceived(String data, boolean isBroadcast) {
logger.debug("Received data from CUL: " + data);
MaxCulMsgType msgType = BaseMsg.getMsgType(data);
/*
* Check if it's broadcast and we're in pair mode or a PAIR_PING message
* directly for us
*/
if (((pairMode && isBroadcast) || !isBroadcast) && msgType == MaxCulMsgType.PAIR_PING) {
logger.debug("Got PAIR_PING message");
MaxCulBindingConfig configWithTempsConfig = null;
/* process packet */
PairPingMsg pkt = new PairPingMsg(data);
/* Match serial number to binding configuration */
Collection<MaxCulBindingConfig> bindingConfigs = getBindingsBySerial(pkt.serial);
/*
* only respond and set pairing info if we found at least one
* binding config
*/
if (bindingConfigs != null) {
logger.debug("Found " + bindingConfigs.size() + " configs for " + pkt.serial);
for (MaxCulBindingConfig bc : bindingConfigs) {
/* Set pairing information */
bc.setPairedInfo(pkt.srcAddrStr);
/*
* where it came from gives
* the addr of the device
*/
if (bc.isTemperatureConfigSet() && configWithTempsConfig == null) {
configWithTempsConfig = bc;
}
}
/* if none have values set then send default from first config */
if (configWithTempsConfig == null) {
logger.debug("Using default temperature configuration from config 0");
configWithTempsConfig = (MaxCulBindingConfig) bindingConfigs.toArray()[0];
}
/* get device associations */
HashSet<MaxCulBindingConfig> associations = null;
for (MaxCulBindingProvider provider : super.providers) {
associations = provider.getAssociations(configWithTempsConfig.getSerialNumber());
if (associations != null && associations.isEmpty() == false) {
logger.debug("Found associations");
break;
}
}
/* start the initialisation sequence */
logger.debug("Creating pairing sequencer");
PairingInitialisationSequence ps = new PairingInitialisationSequence(this.DEFAULT_GROUP_ID, messageHandler, configWithTempsConfig, associations);
messageHandler.startSequence(ps, pkt);
} else {
logger.error("Pairing failed: Unable to find binding config for device " + pkt.serial);
}
} else {
switch(msgType) {
/*
* TODO there are other incoming messages that aren't handled that
* could be
*/
case WALL_THERMOSTAT_CONTROL:
WallThermostatControlMsg wallThermCtrlMsg = new WallThermostatControlMsg(data);
wallThermCtrlMsg.printMessage();
for (MaxCulBindingProvider provider : super.providers) {
Collection<MaxCulBindingConfig> bindingConfigs = provider.getConfigsForRadioAddr(wallThermCtrlMsg.srcAddrStr);
for (MaxCulBindingConfig bc : bindingConfigs) {
if (bc.getFeature() == MaxCulFeature.THERMOSTAT && wallThermCtrlMsg.getDesiredTemperature() != null) {
String itemName = provider.getItemNameForConfig(bc);
eventPublisher.postUpdate(itemName, new DecimalType(wallThermCtrlMsg.getDesiredTemperature()));
} else if (bc.getFeature() == MaxCulFeature.TEMPERATURE && wallThermCtrlMsg.getMeasuredTemperature() != null) {
String itemName = provider.getItemNameForConfig(bc);
eventPublisher.postUpdate(itemName, new DecimalType(wallThermCtrlMsg.getMeasuredTemperature()));
}
// TODO switch mode between manual/automatic?
}
}
/* reply only if not broadcast */
if (isBroadcast == false) {
this.messageHandler.sendAck(wallThermCtrlMsg);
}
break;
case SET_TEMPERATURE:
SetTemperatureMsg setTempMsg = new SetTemperatureMsg(data);
setTempMsg.printMessage();
for (MaxCulBindingProvider provider : super.providers) {
Collection<MaxCulBindingConfig> bindingConfigs = provider.getConfigsForRadioAddr(setTempMsg.srcAddrStr);
for (MaxCulBindingConfig bc : bindingConfigs) {
if (bc.getFeature() == MaxCulFeature.THERMOSTAT) {
String itemName = provider.getItemNameForConfig(bc);
eventPublisher.postUpdate(itemName, new DecimalType(setTempMsg.getDesiredTemperature()));
}
// TODO switch mode between manual/automatic?
}
}
/* respond to device */
if (isBroadcast == false) {
this.messageHandler.sendAck(setTempMsg);
}
break;
case THERMOSTAT_STATE:
ThermostatStateMsg thermStateMsg = new ThermostatStateMsg(data);
thermStateMsg.printMessage();
for (MaxCulBindingProvider provider : super.providers) {
Collection<MaxCulBindingConfig> bindingConfigs = provider.getConfigsForRadioAddr(thermStateMsg.srcAddrStr);
for (MaxCulBindingConfig bc : bindingConfigs) {
String itemName = provider.getItemNameForConfig(bc);
if (bc.getFeature() == MaxCulFeature.THERMOSTAT && thermStateMsg.getDesiredTemperature() != null) {
eventPublisher.postUpdate(itemName, new DecimalType(thermStateMsg.getDesiredTemperature()));
} else if (bc.getFeature() == MaxCulFeature.TEMPERATURE && thermStateMsg.getMeasuredTemperature() != null) {
eventPublisher.postUpdate(itemName, new DecimalType(thermStateMsg.getMeasuredTemperature()));
} else if (bc.getFeature() == MaxCulFeature.BATTERY) {
eventPublisher.postUpdate(itemName, thermStateMsg.getBatteryLow() ? OnOffType.ON : OnOffType.OFF);
} else if (bc.getFeature() == MaxCulFeature.MODE) {
eventPublisher.postUpdate(itemName, new DecimalType(thermStateMsg.getControlMode().toInt()));
} else if (bc.getFeature() == MaxCulFeature.VALVE_POS) {
eventPublisher.postUpdate(itemName, new DecimalType(thermStateMsg.getValvePos()));
}
// TODO switch mode between manual/automatic?
}
}
/* respond to device */
if (isBroadcast == false) {
this.messageHandler.sendAck(thermStateMsg);
}
break;
case WALL_THERMOSTAT_STATE:
WallThermostatStateMsg wallThermStateMsg = new WallThermostatStateMsg(data);
wallThermStateMsg.printMessage();
for (MaxCulBindingProvider provider : super.providers) {
Collection<MaxCulBindingConfig> bindingConfigs = provider.getConfigsForRadioAddr(wallThermStateMsg.srcAddrStr);
for (MaxCulBindingConfig bc : bindingConfigs) {
String itemName = provider.getItemNameForConfig(bc);
if (bc.getFeature() == MaxCulFeature.THERMOSTAT && wallThermStateMsg.getDesiredTemperature() != null) {
eventPublisher.postUpdate(itemName, new DecimalType(wallThermStateMsg.getDesiredTemperature()));
} else if (bc.getFeature() == MaxCulFeature.TEMPERATURE && wallThermStateMsg.getMeasuredTemperature() != null) {
eventPublisher.postUpdate(itemName, new DecimalType(wallThermStateMsg.getMeasuredTemperature()));
} else if (bc.getFeature() == MaxCulFeature.BATTERY) {
eventPublisher.postUpdate(itemName, wallThermStateMsg.getBatteryLow() ? OnOffType.ON : OnOffType.OFF);
} else if (bc.getFeature() == MaxCulFeature.MODE) {
eventPublisher.postUpdate(itemName, new DecimalType(wallThermStateMsg.getControlMode().toInt()));
}
}
}
/* respond to device */
if (isBroadcast == false) {
this.messageHandler.sendAck(wallThermStateMsg);
}
break;
case TIME_INFO:
TimeInfoMsg timeMsg = new TimeInfoMsg(data);
timeMsg.printMessage();
TimeUpdateRequestSequence timeSeq = new TimeUpdateRequestSequence(this.tzStr, messageHandler);
messageHandler.startSequence(timeSeq, timeMsg);
break;
case PUSH_BUTTON_STATE:
PushButtonMsg pbMsg = new PushButtonMsg(data);
pbMsg.printMessage();
for (MaxCulBindingProvider provider : super.providers) {
Collection<MaxCulBindingConfig> bindingConfigs = provider.getConfigsForRadioAddr(pbMsg.srcAddrStr);
for (MaxCulBindingConfig bc : bindingConfigs) {
String itemName = provider.getItemNameForConfig(bc);
if (bc.getFeature() == MaxCulFeature.SWITCH) {
// 'AUTO' maps to 'ON' and 'ECO' maps to 'OFF'
eventPublisher.postUpdate(itemName, pbMsg.getMode() == PushButtonMode.AUTO ? OnOffType.ON : OnOffType.OFF);
} else if (bc.getFeature() == MaxCulFeature.BATTERY) {
eventPublisher.postUpdate(itemName, pbMsg.getBatteryLow() ? OnOffType.ON : OnOffType.OFF);
}
}
}
if (isBroadcast == false) {
this.messageHandler.sendAck(pbMsg);
}
break;
case SHUTTER_CONTACT_STATE:
ShutterContactStateMsg shutterContactStateMsg = new ShutterContactStateMsg(data);
shutterContactStateMsg.printMessage();
for (MaxCulBindingProvider provider : super.providers) {
Collection<MaxCulBindingConfig> bindingConfigs = provider.getConfigsForRadioAddr(shutterContactStateMsg.srcAddrStr);
for (MaxCulBindingConfig bc : bindingConfigs) {
String itemName = provider.getItemNameForConfig(bc);
if (bc.getFeature() == MaxCulFeature.CONTACT) {
if (shutterContactStateMsg.getState() == ShutterContactState.CLOSED) {
eventPublisher.postUpdate(itemName, OpenClosedType.CLOSED);
} else if (shutterContactStateMsg.getState() == ShutterContactState.OPEN) {
eventPublisher.postUpdate(itemName, OpenClosedType.OPEN);
}
} else if (bc.getFeature() == MaxCulFeature.BATTERY) {
eventPublisher.postUpdate(itemName, shutterContactStateMsg.getBatteryLow() ? OnOffType.ON : OnOffType.OFF);
}
}
}
/* respond to device */
if (isBroadcast == false) {
this.messageHandler.sendAck(shutterContactStateMsg);
}
break;
default:
logger.debug("Unhandled message type " + msgType.toString());
break;
}
}
updateCreditMonitors();
}
use of org.openhab.binding.maxcul.internal.messages.TimeInfoMsg in project openhab1-addons by openhab.
the class MaxCulMsgHandler method sendTimeInfoFast.
/**
* Send time information to device in fast mode
*
* @param dstAddr
* Address of device to respond to
* @param tzStr
* Time Zone String
* @param msgSeq
* Message sequence to associate
*/
public void sendTimeInfoFast(String dstAddr, String tzStr) {
TimeInfoMsg msg = new TimeInfoMsg(getMessageCount(), (byte) 0x0, (byte) 0, this.srcAddr, dstAddr, tzStr);
msg.setFastSend(true);
sendMessage(msg);
}
use of org.openhab.binding.maxcul.internal.messages.TimeInfoMsg in project openhab1-addons by openhab.
the class MaxCulMsgHandler method listenModeHandler.
private void listenModeHandler(String data) {
switch(BaseMsg.getMsgType(data)) {
case WALL_THERMOSTAT_CONTROL:
new WallThermostatControlMsg(data).printMessage();
break;
case TIME_INFO:
new TimeInfoMsg(data).printMessage();
break;
case SET_TEMPERATURE:
new SetTemperatureMsg(data).printMessage();
break;
case ACK:
new AckMsg(data).printMessage();
break;
case PAIR_PING:
new PairPingMsg(data).printMessage();
break;
case PAIR_PONG:
new PairPongMsg(data).printMessage();
break;
case THERMOSTAT_STATE:
new ThermostatStateMsg(data).printMessage();
break;
case SET_GROUP_ID:
new SetGroupIdMsg(data).printMessage();
break;
case WAKEUP:
new WakeupMsg(data).printMessage();
break;
case WALL_THERMOSTAT_STATE:
new WallThermostatStateMsg(data).printMessage();
break;
case ADD_LINK_PARTNER:
case CONFIG_TEMPERATURES:
case CONFIG_VALVE:
case CONFIG_WEEK_PROFILE:
case PUSH_BUTTON_STATE:
case REMOVE_GROUP_ID:
case REMOVE_LINK_PARTNER:
case RESET:
case SET_COMFORT_TEMPERATURE:
case SET_DISPLAY_ACTUAL_TEMP:
case SET_ECO_TEMPERATURE:
case SHUTTER_CONTACT_STATE:
case UNKNOWN:
default:
BaseMsg baseMsg = new BaseMsg(data);
baseMsg.printMessage();
break;
}
}
use of org.openhab.binding.maxcul.internal.messages.TimeInfoMsg in project openhab1-addons by openhab.
the class MaxCulMsgHandler method sendMessage.
/**
* Send a raw Base Message
*
* @param msg
* Base message to send
* @param queueItem
* queue item (used for retransmission)
*/
private void sendMessage(BaseMsg msg, SenderQueueItem queueItem) {
Timer timer = null;
if (msg.readyToSend()) {
if (enoughCredit(msg.requiredCredit(), msg.isFastSend()) && this.sendQueue.isEmpty()) {
/*
* send message as we have enough credit and nothing is on the
* queue waiting
*/
logger.debug("Sending message immediately. Message is " + msg.msgType + " => " + msg.rawMsg);
transmitMessage(msg, queueItem);
logger.debug("Credit required " + msg.requiredCredit());
} else {
/*
* message is going on the queue - this means that the device
* may well go to standby before it receives it so change into
* long slow send format with big preamble
*/
msg.setFastSend(false);
/*
* don't have enough credit or there are messages ahead of us so
* queue up the item and schedule a task to process it
*/
SenderQueueItem qi = queueItem;
if (qi == null) {
qi = new SenderQueueItem();
qi.msg = msg;
}
TimerTask task = new TimerTask() {
@Override
public void run() {
SenderQueueItem topItem = sendQueue.remove();
logger.debug("Checking credit");
if (enoughCredit(topItem.msg.requiredCredit(), topItem.msg.isFastSend())) {
logger.debug("Sending item from queue. Message is " + topItem.msg.msgType + " => " + topItem.msg.rawMsg);
if (topItem.msg.msgType == MaxCulMsgType.TIME_INFO) {
((TimeInfoMsg) topItem.msg).updateTime();
}
transmitMessage(topItem.msg, topItem);
} else {
logger.error("Not enough credit after waiting. This is bad. Queued command is discarded");
}
}
};
timer = new Timer();
sendQueueTimers.put(qi, timer);
/*
* calculate when we want to TX this item in the queue, with a
* margin of 2 credits. x1000 as we accumulate 1 x 10ms credit
* every 1000ms
*/
int requiredCredit = msg.isFastSend() ? 0 : 100 + msg.requiredCredit() + 2;
this.endOfQueueTransmit = new Date(this.endOfQueueTransmit.getTime() + (requiredCredit * 1000));
timer.schedule(task, this.endOfQueueTransmit);
this.sendQueue.add(qi);
logger.debug("Added message to queue to be TX'd at " + this.endOfQueueTransmit.toString());
}
if (msg.isPartOfSequence()) {
/* add to sequence register if part of a sequence */
logger.debug("Message " + msg.msgCount + " is part of sequence. Adding to register.");
sequenceRegister.put(msg.msgCount, msg.getMessageSequencer());
}
} else {
logger.error("Tried to send a message that wasn't ready!");
}
}
Aggregations