<commit_before>package org.openhab.binding.maxcul.internal.message.sequencers;

import org.openhab.binding.maxcul.internal.MaxCulBindingConfig;
import org.openhab.binding.maxcul.internal.MaxCulDevice;
import org.openhab.binding.maxcul.internal.MaxCulMsgHandler;
import org.openhab.binding.maxcul.internal.messages.AckMsg;
import org.openhab.binding.maxcul.internal.messages.BaseMsg;
import org.openhab.binding.maxcul.internal.messages.MaxCulMsgType;
import org.openhab.binding.maxcul.internal.messages.PairPingMsg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Handle the pairing and initialisation sequence of a new device. This should be called
 * when the device has been verified etc as this will just send the pong without verifying
 * whether we should or not.
 *
 * @author <NAME> (cyclingengineer)
 * @since 1.6.0
 */
public class PairingInitialisationSequence implements MessageSequencer {

	private enum PairingInitialisationState
	{
		INITIAL_PING,
		PONG_ACKED,
		WAKEUP_ACKED,
		TIME_ACKED,
		GROUP_ID_ACKED,
		CONFIG_TEMPS_ACKED,
		SENDING_WEEK_PROFILE,
		CONFIG_TEMPS_2_ACKED,
		FINISHED;
	}

	private static final Logger logger =
			LoggerFactory.getLogger(PairingInitialisationSequence.class);

	private PairingInitialisationState state = PairingInitialisationState.INITIAL_PING;

	private String devAddr;
	private byte group_id;
	private String tzStr;
	private MaxCulMsgHandler messageHandler;
	private int pktLostCount = 0;
	private MaxCulDevice deviceType = MaxCulDevice.UNKNOWN;
	private MaxCulBindingConfig config;

	public PairingInitialisationSequence(byte group_id, String tzStr, MaxCulMsgHandler messageHandler, MaxCulBindingConfig cfg)
	{
		this.group_id = group_id;
		this.tzStr = tzStr;
		this.messageHandler = messageHandler;
		this.config = cfg;
	}

	@Override
	public void runSequencer(BaseMsg msg)
	{
		/* This sequence is taken from observations of activity between the
		 * MAX! Cube and a wall thermostat
		 */
		pktLostCount = 0; // reset counter - ack received
		switch (state)
		{
		case INITIAL_PING:
			/* get device type */
			PairPingMsg ppMsg = new PairPingMsg(msg.rawMsg);
			this.deviceType = MaxCulDevice.getDeviceTypeFromInt(ppMsg.type);
			/* Send PONG - assumes PING is checked*/
			logger.debug("Sending PONG");
			this.devAddr = msg.srcAddrStr;
			messageHandler.sendPairPong(devAddr, this);
			state = PairingInitialisationState.PONG_ACKED;
			break;
		case PONG_ACKED:
			if (msg.msgType == MaxCulMsgType.ACK)
			{
				AckMsg ack = new AckMsg(msg.rawMsg);
				if (!ack.getIsNack())
				{
					if (this.deviceType == MaxCulDevice.PUSH_BUTTON)
					{
						/* for a push button send group id */
						logger.debug("Sending GROUP_ID");
						messageHandler.sendSetGroupId(devAddr, group_id, this);
						state = PairingInitialisationState.GROUP_ID_ACKED;
					}
					else
					{
						/* send a wake up packet */
						logger.debug("Sending WAKEUP");
						messageHandler.sendWakeup(devAddr, this);
						state = PairingInitialisationState.WAKEUP_ACKED;
					}
				} else {
					logger.error("PONG was nacked. Ending sequence");
					state = PairingInitialisationState.FINISHED;
				}
			}
			break;
		case WAKEUP_ACKED:
			if (msg.msgType == MaxCulMsgType.ACK)
			{
				AckMsg ack = new AckMsg(msg.rawMsg);
				if (!ack.getIsNack())
				{
					/* send time information */
					logger.debug("Sending TIME_INFO");
					messageHandler.sendTimeInfo(devAddr, tzStr, this);
					state = PairingInitialisationState.TIME_ACKED;
				} else {
					logger.error("WAKEUP was nacked. Ending sequence");
					state = PairingInitialisationState.FINISHED;<commit_msg>Push button NACKs set group id. So skip it. Just do pair pong.<commit_after>package org.openhab.binding.maxcul.internal.message.sequencers;

import org.openhab.binding.maxcul.internal.MaxCulBindingConfig;
import org.openhab.binding.maxcul.internal.MaxCulDevice;
import org.openhab.binding.maxcul.internal.MaxCulMsgHandler;
import org.openhab.binding.maxcul.internal.messages.AckMsg;
import org.openhab.binding.maxcul.internal.messages.BaseMsg;
import org.openhab.binding.maxcul.internal.messages.MaxCulMsgType;
import org.openhab.binding.maxcul.internal.messages.PairPingMsg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Handle the pairing and initialisation sequence of a new device. This should be called
 * when the device has been verified etc as this will just send the pong without verifying
 * whether we should or not.
 *
 * @author <NAME> (cyclingengineer)
 * @since 1.6.0
 */
public class PairingInitialisationSequence implements MessageSequencer {

	private enum PairingInitialisationState
	{
		INITIAL_PING,
		PONG_ACKED,
		WAKEUP_ACKED,
		TIME_ACKED,
		GROUP_ID_ACKED,
		CONFIG_TEMPS_ACKED,
		SENDING_WEEK_PROFILE,
		CONFIG_TEMPS_2_ACKED,
		FINISHED;
	}

	private static final Logger logger =
			LoggerFactory.getLogger(PairingInitialisationSequence.class);

	private PairingInitialisationState state = PairingInitialisationState.INITIAL_PING;

	private String devAddr;
	private byte group_id;
	private String tzStr;
	private MaxCulMsgHandler messageHandler;
	private int pktLostCount = 0;
	private MaxCulDevice deviceType = MaxCulDevice.UNKNOWN;
	private MaxCulBindingConfig config;

	public PairingInitialisationSequence(byte group_id, String tzStr, MaxCulMsgHandler messageHandler, MaxCulBindingConfig cfg)
	{
		this.group_id = group_id;
		this.tzStr = tzStr;
		this.messageHandler = messageHandler;
		this.config = cfg;
	}

	@Override
	public void runSequencer(BaseMsg msg)
	{
		/* This sequence is taken from observations of activity between the
		 * MAX! Cube and a wall thermostat
		 */
		pktLostCount = 0; // reset counter - ack received
		switch (state)
		{
		case INITIAL_PING:
			/* get device type */
			PairPingMsg ppMsg = new PairPingMsg(msg.rawMsg);
			this.deviceType = MaxCulDevice.getDeviceTypeFromInt(ppMsg.type);
			/* Send PONG - assumes PING is checked*/
			logger.debug("Sending PONG");
			this.devAddr = msg.srcAddrStr;
			messageHandler.sendPairPong(devAddr, this);
			state = PairingInitialisationState.PONG_ACKED;
			break;
		case PONG_ACKED:
			if (msg.msgType == MaxCulMsgType.ACK)
			{
				AckMsg ack = new AckMsg(msg.rawMsg);
				if (!ack.getIsNack())
				{
					if (this.deviceType == MaxCulDevice.PUSH_BUTTON)
					{
						/* for a push button we're done now */
						state = PairingInitialisationState.FINISHED;
					}
					else
					{
						/* send a wake up packet */
						logger.debug("Sending WAKEUP");
						messageHandler.sendWakeup(devAddr, this);
						state = PairingInitialisationState.WAKEUP_ACKED;
					}
				} else {
					logger.error("PONG was nacked. Ending sequence");
					state = PairingInitialisationState.FINISHED;
				}
			}
			break;
		case WAKEUP_ACKED:
			if (msg.msgType == MaxCulMsgType.ACK)
			{
				AckMsg ack = new AckMsg(msg.rawMsg);
				if (!ack.getIsNack())
				{
					/* send time information */
					logger.debug("Sending TIME_INFO");
					messageHandler.sendTimeInfo(devAddr, tzStr, this);
					state = PairingInitialisationState.TIME_ACKED;
				} else {
					logger.error("WAKEUP was nacked. Ending sequence");
					state = PairingInitialisationState.FINISHED;
{'fraction_non_alphanumeric': 0.08934038408015586, 'fraction_numerical': 0.002226551628165878, 'mean_word_length': 4.001391788448156, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7398082', 'n_tokens_mistral': 2742, 'n_tokens_neox': 2322, 'n_words': 526}