Skip to content

Commit 0f3254b

Browse files
committed
added 'registerSepiaFramework' to FHEM beta (wip)
1 parent 5ef251c commit 0f3254b

File tree

1 file changed

+82
-8
lines changed

1 file changed

+82
-8
lines changed

src/main/java/net/b07z/sepia/sdk/services/uid1007/FhemDemo.java

Lines changed: 82 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ public class FhemDemo implements ServiceInterface {
4848
//Command name of your service (will be combined with userId to be unique, e.g. 'uid1007.python_bridge')
4949
private static final String CMD_NAME = "fhem";
5050

51+
//TODO: add in SEPIA v2.3.2
52+
/*
53+
@Override
54+
public ServiceRequirements getRequirements(){
55+
return new ServiceRequirements()
56+
.serverMinVersion("2.3.2")
57+
.apiAccess(ServiceRequirements.Apis.fhem)
58+
;
59+
}
60+
*/
61+
5162
//Define some sentences for testing:
5263

5364
@Override
@@ -177,7 +188,7 @@ public ServiceResult getResult(NluResult nluResult) {
177188

178189
//this services uses the 'SmartHomeHub' interface
179190
String smartHomeHubHost = "http://localhost:8083/fhem";
180-
SmartHomeHub smartHomeHUB = new Fhem(smartHomeHubHost);
191+
Fhem smartHomeHUB = new Fhem(smartHomeHubHost); //TODO: replace with 'SmartHomeHub' in SEPIA v2.3.2
181192

182193
//get required parameters
183194
Parameter device = nluResult.getRequiredParameter(PARAMETERS.SMART_DEVICE);
@@ -196,6 +207,12 @@ public ServiceResult getResult(NluResult nluResult) {
196207
//Device is FHEM server itself?
197208
if (typeIsEqual(deviceType, SmartDevice.Types.device) && deviceName.equals("FHEM")){
198209
if (typeIsEqual(actionType, Action.Type.show)){
210+
//check if SEPIA is registered - if not try to register
211+
if (!smartHomeHUB.registerSepiaFramework()){
212+
//FAIL
213+
service.setStatusFail(); //"hard"-fail (probably connection or token error)
214+
return service.buildResult();
215+
}
199216
//get devices
200217
Map<String, SmartHomeDevice> devices = smartHomeHUB.getDevices();
201218
if (devices == null){
@@ -205,7 +222,7 @@ public ServiceResult getResult(NluResult nluResult) {
205222
}else{
206223
//list devices
207224
for (SmartHomeDevice shd : devices.values()){
208-
service.addToExtendedLog("device: " + shd.getDeviceAsJson().toJSONString());
225+
service.addToExtendedLog("device: " + shd.getDeviceAsJson().toJSONString()); //DEBUG
209226
}
210227
//all good
211228
service.setStatusSuccess();
@@ -254,14 +271,20 @@ private static boolean typeIsEqual(String value, Enum<?> type){
254271
return value.equals(type.name());
255272
}
256273

257-
//------------- FHEM -------------
274+
//------------- FHEM ------------- //TODO: move to server
258275

259276
public static class Fhem implements SmartHomeHub {
260277

261278
private String host;
262279
private String csrfToken = "";
263280
public static final String NAME = "fhem";
264281

282+
private static final String TAG_NAME = "sepia-name"; //TODO: replace with SmartHomeDevice.SEPIA_TAG_.. in SEPIA v2.3.2
283+
private static final String TAG_TYPE = "sepia-type";
284+
private static final String TAG_ROOM = "sepia-room";
285+
private static final String TAG_DATA = "sepia-data";
286+
private static final String TAG_MEM_STATE = "sepia-mem-state";
287+
265288
/**
266289
* Create new FHEM instance and automatically get CSRF token.
267290
* @param host - e.g.: http://localhost:8083/fhem
@@ -287,6 +310,55 @@ public Fhem(String host, String csrfToken){
287310
this.csrfToken = csrfToken;
288311
}
289312
}
313+
314+
//TODO: add override annotation in SEPIA v2.3.2+
315+
public boolean registerSepiaFramework(){
316+
//Find attributes first
317+
String foundAttributes = "";
318+
String getUrl = URLBuilder.getString(this.host,
319+
"?cmd=", "jsonlist2 global",
320+
"&XHR=", "1",
321+
"&fwcsrf=", this.csrfToken
322+
);
323+
try {
324+
//Call and check
325+
JSONObject resultGet = Connectors.httpGET(getUrl);
326+
if (Connectors.httpSuccess(resultGet) && JSON.getIntegerOrDefault(resultGet, "totalResultsReturned", 0) == 1){
327+
foundAttributes = (String) JSON.getJObject((JSONObject) JSON.getJArray(resultGet, "Results").get(0), "Attributes").get("userattr");
328+
if (Is.nullOrEmpty(foundAttributes)){
329+
Debugger.println("FHEM - registerSepiaFramework: Failed! No existing 'userattr' found in 'global' attributes. Please add manually.", 1);
330+
return false;
331+
}else{
332+
//System.out.println("foundAttributes: " + foundAttributes); //DEBUG
333+
//check if attributes are already there (if one is there all should be there ...)
334+
if (foundAttributes.matches(".*\\b" + TAG_NAME + "\\b.*")){
335+
return true;
336+
}
337+
}
338+
}else{
339+
Debugger.println("FHEM - registerSepiaFramework: Failed! Could not load global attributes. Msg.: " + resultGet.toJSONString(), 1);
340+
return false;
341+
}
342+
//Register FHEM means adding the SEPIA tags to global attributes
343+
String setUrl = URLBuilder.getString(this.host,
344+
"?cmd=", "attr global userattr " + foundAttributes + " " + TAG_NAME + " " + TAG_TYPE + " " + TAG_ROOM + " " + TAG_DATA + " " + TAG_MEM_STATE,
345+
"&XHR=", "1",
346+
"&fwcsrf=", this.csrfToken
347+
);
348+
JSONObject resultSet = Connectors.httpGET(setUrl);
349+
if (Connectors.httpSuccess(resultSet)){
350+
//all good
351+
return true;
352+
}else{
353+
Debugger.println("FHEM - registerSepiaFramework: Failed! Could not set global attributes. Msg.: " + resultSet.toJSONString(), 1);
354+
return false;
355+
}
356+
}catch (Exception e){
357+
Debugger.println("FHEM - registerSepiaFramework: Failed! Error: " + e.getMessage(), 1);
358+
Debugger.printStackTrace(e, 3);
359+
return false;
360+
}
361+
}
290362

291363
@Override
292364
public Map<String, SmartHomeDevice> getDevices(){
@@ -375,7 +447,7 @@ private SmartHomeDevice buildDeviceFromResponse(JSONObject hubDevice){
375447
String memoryState = "";
376448
if (attributes != null){
377449
//try to find self-defined SEPIA tags first
378-
name = JSON.getStringOrDefault(attributes, "sepia-name", null);
450+
name = JSON.getStringOrDefault(attributes, "sepia-name", null); //TODO: replace with SmartHomeDevice.SEPIA_TAG_NAME in SEPIA v2.3.2+
379451
type = JSON.getStringOrDefault(attributes, "sepia-type", null);
380452
room = JSON.getStringOrDefault(attributes, "sepia-room", null);
381453
memoryState = JSON.getStringOrDefault(attributes, "sepia-mem-state", null);
@@ -390,9 +462,9 @@ private SmartHomeDevice buildDeviceFromResponse(JSONObject hubDevice){
390462
}
391463
if (type == null && internals != null){
392464
String fhemType = JSON.getString(internals, "type").toLowerCase();
393-
if (fhemType.matches("(.*\\s|^)(light.*|lamp.*)")){
465+
if (fhemType.matches("(.*\\s|^|,)(light.*|lamp.*)")){
394466
type = SmartDevice.Types.light.name(); //LIGHT
395-
}else if (fhemType.matches("(.*\\s|^)(heat.*|thermo.*)")){
467+
}else if (fhemType.matches("(.*\\s|^|,)(heat.*|thermo.*)")){
396468
type = SmartDevice.Types.heater.name(); //HEATER
397469
}else{
398470
type = fhemType; //take this if we don't have a specific type yet
@@ -406,8 +478,10 @@ private SmartHomeDevice buildDeviceFromResponse(JSONObject hubDevice){
406478
String fhemObjName = JSON.getStringOrDefault(hubDevice, "Name", null);
407479
Object stateObj = JSON.getObject(hubDevice, new String[]{"Readings", "state"});
408480
Object linkObj = (fhemObjName != null)? (this.host + "?cmd." + fhemObjName) : null;
409-
JSONObject meta = null;
410-
//TODO: we could add some stuff to meta when we need other data from response.
481+
JSONObject meta = JSON.make(
482+
"fhem-id", fhemObjName
483+
);
484+
//note: we need fhem-id for commands although it is basically already in 'link'
411485
SmartHomeDevice shd = new SmartHomeDevice(name, type, room,
412486
(stateObj != null)? stateObj.toString() : null, memoryState,
413487
(linkObj != null)? linkObj.toString() : null, meta);

0 commit comments

Comments
 (0)