Skip to content

Commit

Permalink
- fix XML-RPC re-init after a timeout
Browse files Browse the repository at this point in the history
- maintain a topicPrefix/connected boolean topic
  • Loading branch information
owagner committed Dec 21, 2014
1 parent 6a9e55d commit c2b1958
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 15 deletions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2014 Oliver Wagner <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
hm2mqtt
=======

Written and (C) 2014 Oliver Wagner <[email protected]>

Provided under the terms of the MIT license.

Overview
--------

Expand All @@ -25,6 +29,19 @@ hm2mqtt will try to read device and channel names from the specified HM hosts us
on port 8181. If this succeeds, channel names will be resolved into symbolic names before publishing.


Topic structure
---------------
The topics generated and accepted are of the form

`prefix/channel/datapoint`

The *channel* is either the raw address or a name resolved by querying a possibly running ReGaHSS instance
on a CCU1 or CCU2.

A special topic is *prefix/connected*. It holds a boolean value which denotes whether the adapter is
currently running. It's set to false on disconnect using a MQTT will.


MQTT Message format
--------------------

Expand All @@ -35,7 +52,9 @@ The message format accepted and generated is a JSON encoded object with the foll
are ignored, to avoid loops.
* hm_addr - source HM device address and channel number

PRESS\_SHORT and PRESS\_LONG items are sent with the MQTT retain flag set to _false_, all others with retain set to _true_.
Items which start with PRESS\_ (as of now, PRESS\_SHORT, PRESS\_LONG, PRESS\_CONT) are sent with the MQTT retain
flag set to _false_, all others with retain set to _true_.


Usage
-----
Expand Down Expand Up @@ -75,7 +94,8 @@ Examples:
See also
--------
- knm2mqtt - similiar tool for KNX integration
- hmcompanion - where most of the HM-side code was taken from
- hmcompanion - where most of the HM-side code originates from


Changelog
---------
Expand Down
3 changes: 2 additions & 1 deletion src/com/tellerulam/hm2mqtt/HM.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private void addConnection(String host,int port,String serverurl)
int ix=connections.size();
HMXRConnection c=new HMXRConnection(host, port, serverurl, ix);
connections.put("CB"+ix,c);
L.info("Adding connection to XML-RPC service at "+host+":"+port);
L.info("Adding connection "+ix+" to XML-RPC service at "+host+":"+port);
ix++;
}

Expand All @@ -117,6 +117,7 @@ public static void setValue(String address, String datapoint, String value)
HMXRMsg m=new HMXRMsg("setValue");
m.addArg(address);
m.addArg(datapoint);
// Strangely, if we send everything as string, rfd/hs485d will do conversion for us.
m.addArg(value);
try
{
Expand Down
24 changes: 18 additions & 6 deletions src/com/tellerulam/hm2mqtt/HMXRConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public HMXRConnection(String host,int port,String serverurl,int instance)
this.port=port;
this.serverurl=serverurl;
this.instance=instance;

// Queue a deinit on shutdown
Runtime.getRuntime().addShutdownHook(new Deiniter());
}

private final Set<String> assignedAddresses=new HashSet<>();
Expand Down Expand Up @@ -62,10 +65,8 @@ public void sendInit()
}
catch(Exception e)
{
/* Ignore */
L.log(Level.WARNING,"Init to "+host+":"+port+" with "+serverurl+" failed",e);
}
// Queue a deinit on shutdown
Runtime.getRuntime().addShutdownHook(new Deiniter());
}


Expand All @@ -79,10 +80,22 @@ public synchronized HMXRResponse sendRequest(HMXRMsg m,boolean retry) throws IOE
s.getOutputStream().write(m.prepareData());
return HMXRResponse.readMsg(s,false);
}
catch(IOException ioe)
catch(Exception ioe)
{
// In any case, close the socket, so it's reopened upon retry
try
{
s.close();
}
catch(Exception e)
{
/* Ignore anything that happened during closing, we don't care */
}
s=null;

if(!retry)
throw ioe; // Just rethrow

L.log(Level.WARNING,"Error during transaction handling",ioe);
try
{
Expand All @@ -92,7 +105,6 @@ public synchronized HMXRResponse sendRequest(HMXRMsg m,boolean retry) throws IOE
{
/* Ignore */
}
s=null;
return sendRequest(m,true);
}
}
Expand Down Expand Up @@ -128,7 +140,7 @@ String handleEvent(List<?> parms)
assignedAddresses.add(channelIDtoAddress(address));
}

L.info("Got CB "+address+" "+item+" "+val);
L.finest("Got CB "+address+" "+item+" "+val);

String topic;

Expand Down
11 changes: 7 additions & 4 deletions src/com/tellerulam/hm2mqtt/MQTTHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public static void init() throws MqttException
instance.doInit();
}

private static MQTTHandler instance;

private final String topicPrefix;
private MQTTHandler()
{
Expand All @@ -28,8 +30,6 @@ private MQTTHandler()
topicPrefix=tp;
}

private static MQTTHandler instance;

private MqttClient mqttc;

private void queueConnect()
Expand Down Expand Up @@ -63,14 +63,14 @@ void processMessage(String topic,MqttMessage msg)
{
if(msg.isRetained())
{
L.info("Ignoring retained message "+msg+" to "+topic);
L.fine("Ignoring retained message "+msg+" to "+topic);
return;
}
JsonObject data=JsonObject.readFrom(new String(msg.getPayload(),Charset.forName("UTF-8")));
JsonValue ack=data.get("ack");
if(ack!=null && ack.asBoolean())
{
L.info("Ignoring ack'ed message "+msg+" to "+topic);
L.fine("Ignoring ack'ed message "+msg+" to "+topic);
return;
}
L.info("Received "+msg+" to "+topic);
Expand Down Expand Up @@ -103,9 +103,12 @@ private void doConnect()
L.info("Connecting to MQTT broker "+mqttc.getServerURI()+" with CLIENTID="+mqttc.getClientId()+" and TOPIC PREFIX="+topicPrefix);

MqttConnectOptions copts=new MqttConnectOptions();
copts.setWill(topicPrefix+"connected", "{ \"val\": false, \"ack\": true }".getBytes(), 1, true);
copts.setCleanSession(true);
try
{
mqttc.connect(copts);
mqttc.publish(topicPrefix+"connected", "{ \"val\": true, \"ack\": true }".getBytes(), 1, true);
L.info("Successfully connected to broker, subscribing to "+topicPrefix+"#");
try
{
Expand Down
3 changes: 1 addition & 2 deletions src/com/tellerulam/hm2mqtt/ReGaDeviceCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,12 @@ static public void loadDeviceCache()
String lines[]=r.split("\n");
for(String l:lines)
{
System.out.println(l);
String p[]=l.split("\t");
if(p.length==4)
putRegaItem(p[0],p[1],p[2],p[3]);
}
L.info("Obtained "+itemsByName.size()+" ReGa Channel and Device items");
}

private static final Logger L=Logger.getLogger(TCLRegaHandler.class.getName());
private static final Logger L=Logger.getLogger(ReGaDeviceCache.class.getName());
}

0 comments on commit c2b1958

Please sign in to comment.