2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.lcn.internal.connection;
15 import java.util.concurrent.TimeUnit;
16 import java.util.regex.Matcher;
17 import java.util.regex.Pattern;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.openhab.binding.lcn.internal.common.LcnAddrGrp;
21 import org.openhab.binding.lcn.internal.common.LcnException;
22 import org.openhab.binding.lcn.internal.common.PckGenerator;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
27 * This state discovers the LCN segment couplers.
29 * After the authorization against the LCN-PCK gateway was successful, the LCN segment couplers are discovery, to
30 * retrieve the segment ID of the local segment. When no segment couplers were found, a timeout sets the local segment
33 * @author Fabian Wolter - Initial Contribution
36 public class ConnectionStateSegmentScan extends AbstractConnectionState {
37 private final Logger logger = LoggerFactory.getLogger(ConnectionStateSegmentScan.class);
38 public static final Pattern PATTERN_SK_RESPONSE = Pattern
39 .compile("=M(?<segId>\\d{3})(?<modId>\\d{3})\\.SK(?<id>\\d+)");
40 private final RequestStatus statusSegmentScan = new RequestStatus(-1, 3, "Segment Scan");
42 public ConnectionStateSegmentScan(ConnectionStateMachine context) {
47 public void startWorking() {
48 statusSegmentScan.refresh();
49 addTimer(getScheduler().scheduleWithFixedDelay(this::update, 0, 500, TimeUnit.MILLISECONDS));
52 private void update() {
53 long currTime = System.currentTimeMillis();
55 if (statusSegmentScan.shouldSendNextRequest(connection.getSettings().getTimeout(), currTime)) {
56 connection.queueDirectly(new LcnAddrGrp(3, 3), false, PckGenerator.segmentCouplerScan());
57 statusSegmentScan.onRequestSent(currTime);
59 } catch (LcnException e) {
60 // Give up. Probably no segments available.
61 connection.setLocalSegId(0);
62 logger.debug("No segment couplers detected");
63 nextState(ConnectionStateConnected::new);
68 public void onPckMessageReceived(String data) {
69 Matcher matcher = PATTERN_SK_RESPONSE.matcher(data);
71 if (matcher.matches()) {
72 // any segment coupler answered
73 if (Integer.parseInt(matcher.group("segId")) == 0) {
74 // local segment coupler answered
75 connection.setLocalSegId(Integer.parseInt(matcher.group("id")));
76 logger.debug("Local segment ID is {}", connection.getLocalSegId());
77 nextState(ConnectionStateConnected::new);
80 parseLcnBusDiconnectMessage(data);