Einrichten der OCCU mit dem Funkmodul HM-MOD-RPI-PCB

Problemlösungen und Hinweise von allgemeinem Interesse zur Haussteuerung mit HomeMatic

Moderator: Co-Administratoren

leonsio
Beiträge: 1107
Registriert: 07.01.2012, 14:06
Danksagung erhalten: 6 Mal

Re: Einrichten der OCCU mit dem Funkmodul HM-MOD-RPI-PCB

Beitrag von leonsio » 20.04.2016, 15:03

Hallo Community,

hat wer erfolgreich bcm2835_raw_uart Modul zum laufen bekommen (das Device ist unter /dev zu finden)?

Gruß

Leo

m-koeberl
Beiträge: 18
Registriert: 07.12.2015, 13:03

Re: Einrichten der OCCU mit dem Funkmodul HM-MOD-RPI-PCB

Beitrag von m-koeberl » 05.05.2016, 12:36

Hallo!


Versuche schon seit längerem die Seite "Einstellungen / Geräte-Firmware" zum Laufen zu bekommen.
Nachstehende Erkenntnisse hatte ich schon, allerdings reichen meine Java-Kenntnisse nicht aus um herauszufinden woran es wirklich liegt. Die Geräte-Firmware Seite wird jedenfalls, genauso wie z.B. die Diagramme vom HMServer.jar bedient.

Erst einmal hab ich es mit der "alten" HMServer.jar Version probiert die anfänglich im occu-master.zip drinnen war. Ich hab aber außer folgende Files überhaupt nichts finden oder debuggen können (keine Ahnung wie man bei Java überhaupt sinnvoll debuggen kann wenn man dazu keine Entwicklungsumgebung hat!) was irgendwie hilfreich gewesen wäre.
  • /opt/HMServer/pages/AvailableFirmware.ftl --> WebUI-Seite
  • \HMServer.jar!\de\eq3\ccu\system\http\service\DeviceFirmwareController.class --> Hier spielt sich die Firmware-Geschichte im Java ab
  • \HMServer.jar!\de\eq3\ccu\system\http\service\DeviceFirmwarePage.class --> Hier spielt sich die Firmware-Geschichte im Java ab
Zum Auslesen des Java-Sourcecodes wurde dieses Tool verwendet.
https://github.com/java-decompiler/jd-gui/releases

Nachdem nun die neue Version 2.17.15 auch im aktuellen occu-master.zip https://github.com/eq-3/occu/archive/master.zip eingepflegt ist hab ich gesehen, dass sich das HMServer.jar File verändert hat. Obwohl mein Pi noch nicht auf 2.17.15 aktualisiert ist habe ich testweise vorerst einmal nur die neue HMServer.jar geladen. Nachdem man dann auf die Geräte-Firmware Seite klickt kommt nun wundersamerweise folgende Fehlermeldung im Terminal. Ich verwende die Java-Version Java Runtime Environment 1.7.0_75 von jmaus http://homematic-forum.de/forum/viewtop ... 56&t=26917:

Code: Alles auswählen

Mai 05, 2016 12:09:45 PM org.vertx.java.core.impl.DefaultContext
SCHWERWIEGEND: Unhandled exception
java.lang.NullPointerException
        at de.eq3.ccu.system.http.service.DeviceFirmwarePage.getHTML(DeviceFirmwarePage.java:16)
        at de.eq3.ccu.system.http.service.DeviceFirmwarePage.index(DeviceFirmwarePage.java:56)
        at de.eq3.ccu.server.internal.HMServerRouteMatcher$37.handle(HMServerRouteMatcher.java:694)
        at de.eq3.ccu.server.internal.HMServerRouteMatcher$37.handle(HMServerRouteMatcher.java:688)
        at org.vertx.java.core.http.RouteMatcher.route(RouteMatcher.java:362)
        at org.vertx.java.core.http.RouteMatcher.handle(RouteMatcher.java:70)
        at org.vertx.java.core.http.RouteMatcher.handle(RouteMatcher.java:47)
        at org.vertx.java.core.http.impl.ServerConnection.handleRequest(ServerConnection.java:190)
        at org.vertx.java.core.http.impl.ServerConnection.processMessage(ServerConnection.java:301)
        at org.vertx.java.core.http.impl.ServerConnection.handleMessage(ServerConnection.java:94)
        at org.vertx.java.core.http.impl.DefaultHttpServer$ServerHandler.doMessageReceived(DefaultHttpServer.java:669)
        at org.vertx.java.core.http.impl.DefaultHttpServer$ServerHandler.doMessageReceived(DefaultHttpServer.java:600)
        at org.vertx.java.core.http.impl.VertxHttpHandler.channelRead(VertxHttpHandler.java:89)
        at org.vertx.java.core.net.impl.VertxHandler.channelRead(VertxHandler.java:155)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:163)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
        at org.vertx.java.core.http.impl.cgbystrom.FlashPolicyHandler.channelRead(FlashPolicyHandler.java:53)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:125)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
        at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
        at java.lang.Thread.run(Thread.java:745)
Hier noch der Quellcode der beiden *class-Files falls wer das jd-gui nicht runterladen will.
Bitte um Hilfe, ich verzweifle wirklich schön langsam damit ... :shock:

Danke!
Markus


DeviceFirmwarePage.class

Code: Alles auswählen

package de.eq3.ccu.system.http.service;

import de.eq3.lib.webui.WebUIDetailPage;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class DeviceFirmwarePage
{
  private static String getHTML()
  {
    List<DeviceFirmwareController.Firmware> availableFirmware = DeviceFirmwareController.fetchAvailableFirmware();
    String s = "";
    Integer loop = Integer.valueOf(0);
    for (Iterator<DeviceFirmwareController.Firmware> iterator = availableFirmware.iterator(); iterator.hasNext();)
    {
      String devName = ((DeviceFirmwareController.Firmware)availableFirmware.get(loop.intValue())).getDevName().trim();
      
      s = s + "<tr class=\"DeviceListRow\">";
      s = s + "<td class='DeviceListThumbnail'><div><img id='id" + devName + "' src='' alt='" + devName + "'></div></td>";
      
      s = s + "<td class='DeviceListCell'>" + devName + "</td>";
      s = s + "<td class='DeviceListCell'>" + ((DeviceFirmwareController.Firmware)availableFirmware.get(loop.intValue())).getDevFw() + "</td>";
      s = s + "<td class='DeviceListCell'>" + ((DeviceFirmwareController.Firmware)availableFirmware.get(loop.intValue())).getCCUMinVers() + "</td>";
      s = s + "<td class='DeviceListCell'>";
      s = s + "<div class='DeviceListButton j_translate' name='btnRemove' onclick='deleteFirmware(\"" + ((DeviceFirmwareController.Firmware)availableFirmware.get(loop.intValue())).getTypeCode() + "\",\"" + ((DeviceFirmwareController.Firmware)availableFirmware.get(loop.intValue())).getDevName() + "\");'>${btnRemove}</div>";
      
      s = s + "<div class='DeviceListButton j_translate' name='btnChanglog' onclick='showChangelog(\"" + ((DeviceFirmwareController.Firmware)availableFirmware.get(loop.intValue())).getTypeCode() + "\");'>${btnChangelog}</div>";
      
      s = s + "</td>";
      s = s + "</tr>";
      s = s + "<script type='text/javascript'>";
      s = s + "try{";
      s = s + "if(DEV_PATHS['" + devName + "']['50'] != 'undefined') {";
      s = s + "picPath = DEV_PATHS['" + devName + "']['50'];";
      s = s + "jQuery('#id" + devName + "').attr('src', picPath);";
      s = s + "}";
      s = s + "} catch(e){}";
      s = s + "</script>";
      Integer localInteger1 = loop;Integer localInteger2 = loop = Integer.valueOf(loop.intValue() + 1);
      iterator.next();
    }
    return s;
  }
  
  public String get(String sid)
  {
    return index(sid);
  }
  
  public String index(String sid)
  {
    Map<String, Object> prefilledData = new HashMap();
    prefilledData.put("deviceRow", getHTML());
    
    Object value = "";
    WebUIDetailPage webUIDetailPage = new WebUIDetailPage("DeviceFirmwarePage", value, "AvailableFirmware.ftl");
    return webUIDetailPage.toHTML(prefilledData);
  }
}
und
DeviceFirmwareController.class

Code: Alles auswählen

package de.eq3.ccu.system.http.service;

import com.google.gson.Gson;
import de.eq3.ccu.http.service.JsonResponse;
import de.eq3.ccu.http.service.JsonResponseFactory;
import de.eq3.lib.util.Eq3Logger;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import org.xeustechnologies.jtar.TarEntry;
import org.xeustechnologies.jtar.TarInputStream;

public class DeviceFirmwareController
{
  private static String fileSep = System.getProperty("file.separator");
  private static String firmwareDir = fileSep + "etc" + fileSep + "config" + fileSep + "firmware";
  private static String tmpBaseDir = fileSep + "tmp";
  private static String tmpDir = tmpBaseDir + fileSep + "tmpFirmware";
  private static File rootDir = new File(fileSep + "etc" + fileSep + "config" + fileSep + "firmware");
  private static Eq3Logger log = new Eq3Logger(DeviceFirmwareController.class);
  private Gson gson;
  
  public DeviceFirmwareController()
  {
    this.gson = new Gson();
  }
  
  public static class Firmware
  {
    private String typeCode;
    private String devName;
    private String devFw;
    private String ccuMinVers;
    private String isValid;
    
    private Firmware(HashMap<String, String> data)
    {
      this.typeCode = ((String)data.get("TypeCode"));
      this.devName = ((String)data.get("Name"));
      this.devFw = ((String)data.get("FirmwareVersion"));
      this.ccuMinVers = ((String)data.get("CCUFirmwareVersionMin"));
      this.isValid = ((String)data.get("isValid"));
    }
    
    public String getTypeCode()
    {
      return this.typeCode;
    }
    
    public String getDevName()
    {
      return this.devName;
    }
    
    public String getDevFw()
    {
      return this.devFw;
    }
    
    public String getCCUMinVers()
    {
      return this.ccuMinVers;
    }
    
    public Boolean isValid()
    {
      return Boolean.valueOf(Boolean.parseBoolean(this.isValid));
    }
  }
  
  private static String getChangelog(String fwID)
  {
    String fileHandle = "-1";
    String errorReadChangelog = "${errorReadChangelog}";
    try
    {
      fileHandle = rootDir.getCanonicalPath() + fileSep + fwID + fileSep + "changelog.txt";
      File changelog = new File(fileHandle);
      StringBuilder changeLogContent = new StringBuilder((int)changelog.length());
      BufferedReader br = null;
      try
      {
        br = new BufferedReader(new FileReader(changelog));
        String sCurrentLine;
        while ((sCurrentLine = br.readLine()) != null) {
          changeLogContent.append("<p>" + sCurrentLine + "</p>");
        }
        return changeLogContent.toString();
      }
      catch (IOException e)
      {
        log.error("getChangelog: " + e.getMessage());
      }
      finally
      {
        try
        {
          if (br != null) {
            br.close();
          }
        }
        catch (IOException ex)
        {
          ex.printStackTrace();
        }
      }
      return errorReadChangelog;
    }
    catch (IOException e)
    {
      log.error("Can�t extract the changlog" + e.getMessage());
    }
    return errorReadChangelog;
  }
  
  private static Boolean deleteFw(String fw)
  {
    Boolean success = Boolean.valueOf(false);
    try
    {
      String path = rootDir.getCanonicalPath() + fileSep + fw;
      File dir = new File(path);
      for (File file : dir.listFiles()) {
        log.info(file.getName() + " deleted: " + file.delete());
      }
      success = Boolean.valueOf(dir.delete());
      log.info("Firmware successful deleted: " + success);
    }
    catch (IOException e)
    {
      log.error("Firmware could�t be deleted successfully");
    }
    return success;
  }
  
  private static void extractFileFromArchive2Tmp(TarInputStream is, TarEntry entry)
    throws IOException
  {
    boolean success = false;
    File tmpFirmware = new File(tmpDir);
    success = tmpFirmware.setWritable(true, false);
    if (!tmpFirmware.exists()) {
      success = tmpFirmware.mkdir();
    } else {
      success = true;
    }
    if (success)
    {
      byte[] data = new byte['?'];
      FileOutputStream entryStream = new FileOutputStream(tmpDir + fileSep + entry.getName());
      BufferedOutputStream dest = new BufferedOutputStream(entryStream);
      int count;
      while ((count = is.read(data)) != -1) {
        dest.write(data, 0, count);
      }
      dest.flush();
      dest.close();
      
      File folder = new File(tmpDir);
      File[] listOfFiles = folder.listFiles();
      for (File file : listOfFiles) {
        if (file.isFile()) {
          file.setReadable(true, false);
        }
      }
    }
    else
    {
      log.error("Not able to create " + tmpDir);
    }
  }
  
  private static boolean moveFileToDestination(String target)
  {
    File source = new File(tmpDir);
    for (File file : source.listFiles())
    {
      Path s = file.toPath();
      try
      {
        Files.move(s, s.resolveSibling(firmwareDir + fileSep + target + fileSep + file.getName()), new CopyOption[] { StandardCopyOption.REPLACE_EXISTING });
      }
      catch (IOException e)
      {
        e.printStackTrace();
      }
      file.delete();
    }
    return source.delete();
  }
  
  private static void delete(File file)
    throws IOException
  {
    if (file.isDirectory())
    {
      if (file.list().length == 0)
      {
        file.delete();
      }
      else
      {
        String[] files = file.list();
        for (String temp : files)
        {
          File fileDelete = new File(file, temp);
          
          delete(fileDelete);
        }
        if (file.list().length == 0) {
          file.delete();
        }
      }
    }
    else {
      file.delete();
    }
  }
  
  private static boolean createDir(File newFwDir)
  {
    boolean result = newFwDir.mkdir();
    result = newFwDir.setReadable(true, false);
    result = newFwDir.setExecutable(true, false);
    return result;
  }
  
  private static void createFirmwareDir(String name)
  {
    File newRootFirmwareDir = new File(firmwareDir);
    if (!newRootFirmwareDir.exists()) {
      newRootFirmwareDir.mkdir();
    }
    String deviceFirmwareDir = firmwareDir + fileSep + name;
    File newFwDir = new File(deviceFirmwareDir);
    if (!newFwDir.exists())
    {
      if (createDir(newFwDir)) {
        log.info(deviceFirmwareDir + " created!");
      } else {
        log.error("ERROR: " + deviceFirmwareDir + " could�t be created!");
      }
    }
    else
    {
      log.info(deviceFirmwareDir + " already exists and will be deleted!");
      try
      {
        delete(newFwDir);
        if (createDir(newFwDir)) {
          log.info(deviceFirmwareDir + " created!");
        } else {
          log.error("ERROR: " + deviceFirmwareDir + " could�t be created!");
        }
      }
      catch (IOException e)
      {
        e.printStackTrace();
      }
    }
  }
  
  private static boolean isInfoFileValid(HashMap<String, String> infoFile)
  {
    boolean valid = true;
    String[] necessaryKeys = { "TypeCode", "Name", "CCUFirmwareVersionMin", "FirmwareVersion" };
    for (String key : necessaryKeys) {
      if (infoFile.get(key) == null) {
        valid = false;
      }
    }
    return valid;
  }
  
  private static Firmware readInfoFile(File info)
  {
    BufferedReader br = null;
    HashMap<String, String> infoFile = new HashMap();
    infoFile.clear();
    try
    {
      br = new BufferedReader(new FileReader(info));
      String sCurrentLine;
      while ((sCurrentLine = br.readLine()) != null)
      {
        String[] content = sCurrentLine.split("=");
        if ((content.length == 2) && (!content[0].contains("#")) && (!content[1].contains("#"))) {
          infoFile.put(content[0].trim(), content[1].trim());
        }
      }
      Boolean infoFileIsValid = Boolean.valueOf(isInfoFileValid(infoFile));
      infoFile.put("isValid", infoFileIsValid.toString());
      return new Firmware(infoFile, null);
    }
    catch (IOException e)
    {
      log.error("readInfoFile: " + e.getMessage());
    }
    finally
    {
      try
      {
        if (br != null) {
          br.close();
        }
      }
      catch (IOException ex)
      {
        ex.printStackTrace();
      }
    }
    return null;
  }
  
  public static List<Firmware> fetchAvailableFirmware()
  {
    List<Firmware> listOfFw = new ArrayList();
    try
    {
      File[] files = rootDir.listFiles();
      if (files != null) {
        for (File file : files) {
          if (file.isDirectory())
          {
            File info = new File(file.getCanonicalPath() + fileSep + "info");
            listOfFw.add(readInfoFile(info));
          }
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    return listOfFw;
  }
  
  public String delete(String sid, String bodyParams)
  {
    String result = "Unknown message";
    
    Map<String, Object> parameter = (Map)this.gson.fromJson(bodyParams, Map.class);
    String fwID = parameter.get("firmwareID").toString();
    String devName = parameter.get("deviceName").toString();
    if (deleteFw(fwID).booleanValue()) {
      result = "${delDevFirmwareSuccessA} " + devName + " (" + fwID + ")" + "${delDevFirmwareSuccessB}";
    } else {
      result = "${delDevFirmwareFailed}";
    }
    return JsonResponseFactory.getInstance().getValidResponse(result).toJson();
  }
  
  public String showChangelog(String sid, String bodyParams)
  {
    Map<String, Object> parameter = (Map)this.gson.fromJson(bodyParams, Map.class);
    String fwID = parameter.get("firmwareID").toString();
    String result = getChangelog(fwID);
    return JsonResponseFactory.getInstance().getValidResponse(result).toJson();
  }
  
  public boolean isValidFilename(String filename)
  {
    String tgzExtension = ".tgz";
    String targzExtension = ".tar.gz";
    
    String fileNameToCheck = filename.toLowerCase();
    return (fileNameToCheck.contains(tgzExtension)) || (fileNameToCheck.contains(targzExtension));
  }
  
  public String getTempFirmwarePath(String filename)
  {
    return tmpBaseDir + fileSep + filename;
  }
  
  public String addFirmware(String sid, String firmwareFilePath)
  {
    String errorAddNewFile = "${addDevFirmwareInvalid}";
    try
    {
      File firmwareFile = new File(firmwareFilePath);
      GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(firmwareFile));
      TarInputStream is = new TarInputStream(gzipInputStream);
      TarEntry entryx = null;
      while ((entryx = is.getNextEntry()) != null) {
        if (!entryx.isDirectory()) {
          extractFileFromArchive2Tmp(is, entryx);
        }
      }
      Firmware fwInfo = readInfoFile(new File(tmpDir + fileSep + "info"));
      if ((fwInfo != null) && (fwInfo.isValid().booleanValue()))
      {
        createFirmwareDir(fwInfo.getTypeCode());
        is.close();
        gzipInputStream.close();
        firmwareFile.delete();
        
        return moveFileToDestination(fwInfo.getTypeCode()) ? "${addDevFirmwareSuccess}" : "${addDevFirmwareFailed}";
      }
      is.close();
      gzipInputStream.close();
      firmwareFile.delete();
      log.debug("The info file is corrupt or not available!");
      errorAddNewFile = "${addDevFirmwareInfoCorrupt}";
    }
    catch (Exception e)
    {
      System.err.println("Something is wrong with the file: " + e.getLocalizedMessage());
    }
    return errorAddNewFile;
  }
}

leonsio
Beiträge: 1107
Registriert: 07.01.2012, 14:06
Danksagung erhalten: 6 Mal

Re: Einrichten der OCCU mit dem Funkmodul HM-MOD-RPI-PCB

Beitrag von leonsio » 19.05.2016, 10:33

Hi lade dir die aktuelle 2.19FW runter und nimm daraus HMIPServer, anscheinend hat eq3 da nachgebessert, stützt nicht mehr ab wenn HMIP nicht vorhanden ist
m-koeberl hat geschrieben:Hallo!


Versuche schon seit längerem die Seite "Einstellungen / Geräte-Firmware" zum Laufen zu bekommen.
Nachstehende Erkenntnisse hatte ich schon, allerdings reichen meine Java-Kenntnisse nicht aus um herauszufinden woran es wirklich liegt. Die Geräte-Firmware Seite wird jedenfalls, genauso wie z.B. die Diagramme vom HMServer.jar bedient.

Erst einmal hab ich es mit der "alten" HMServer.jar Version probiert die anfänglich im occu-master.zip drinnen war. Ich hab aber außer folgende Files überhaupt nichts finden oder debuggen können (keine Ahnung wie man bei Java überhaupt sinnvoll debuggen kann wenn man dazu keine Entwicklungsumgebung hat!) was irgendwie hilfreich gewesen wäre.
  • /opt/HMServer/pages/AvailableFirmware.ftl --> WebUI-Seite
  • \HMServer.jar!\de\eq3\ccu\system\http\service\DeviceFirmwareController.class --> Hier spielt sich die Firmware-Geschichte im Java ab
  • \HMServer.jar!\de\eq3\ccu\system\http\service\DeviceFirmwarePage.class --> Hier spielt sich die Firmware-Geschichte im Java ab
Zum Auslesen des Java-Sourcecodes wurde dieses Tool verwendet.
https://github.com/java-decompiler/jd-gui/releases

Nachdem nun die neue Version 2.17.15 auch im aktuellen occu-master.zip https://github.com/eq-3/occu/archive/master.zip eingepflegt ist hab ich gesehen, dass sich das HMServer.jar File verändert hat. Obwohl mein Pi noch nicht auf 2.17.15 aktualisiert ist habe ich testweise vorerst einmal nur die neue HMServer.jar geladen. Nachdem man dann auf die Geräte-Firmware Seite klickt kommt nun wundersamerweise folgende Fehlermeldung im Terminal. Ich verwende die Java-Version Java Runtime Environment 1.7.0_75 von jmaus http://homematic-forum.de/forum/viewtop ... 56&t=26917:

Code: Alles auswählen

Mai 05, 2016 12:09:45 PM org.vertx.java.core.impl.DefaultContext
SCHWERWIEGEND: Unhandled exception
java.lang.NullPointerException
        at de.eq3.ccu.system.http.service.DeviceFirmwarePage.getHTML(DeviceFirmwarePage.java:16)
        at de.eq3.ccu.system.http.service.DeviceFirmwarePage.index(DeviceFirmwarePage.java:56)
        at de.eq3.ccu.server.internal.HMServerRouteMatcher$37.handle(HMServerRouteMatcher.java:694)
        at de.eq3.ccu.server.internal.HMServerRouteMatcher$37.handle(HMServerRouteMatcher.java:688)
        at org.vertx.java.core.http.RouteMatcher.route(RouteMatcher.java:362)
        at org.vertx.java.core.http.RouteMatcher.handle(RouteMatcher.java:70)
        at org.vertx.java.core.http.RouteMatcher.handle(RouteMatcher.java:47)
        at org.vertx.java.core.http.impl.ServerConnection.handleRequest(ServerConnection.java:190)
        at org.vertx.java.core.http.impl.ServerConnection.processMessage(ServerConnection.java:301)
        at org.vertx.java.core.http.impl.ServerConnection.handleMessage(ServerConnection.java:94)
        at org.vertx.java.core.http.impl.DefaultHttpServer$ServerHandler.doMessageReceived(DefaultHttpServer.java:669)
        at org.vertx.java.core.http.impl.DefaultHttpServer$ServerHandler.doMessageReceived(DefaultHttpServer.java:600)
        at org.vertx.java.core.http.impl.VertxHttpHandler.channelRead(VertxHttpHandler.java:89)
        at org.vertx.java.core.net.impl.VertxHandler.channelRead(VertxHandler.java:155)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:163)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
        at org.vertx.java.core.http.impl.cgbystrom.FlashPolicyHandler.channelRead(FlashPolicyHandler.java:53)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:125)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
        at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
        at java.lang.Thread.run(Thread.java:745)
Hier noch der Quellcode der beiden *class-Files falls wer das jd-gui nicht runterladen will.
Bitte um Hilfe, ich verzweifle wirklich schön langsam damit ... :shock:

Danke!
Markus


DeviceFirmwarePage.class

Code: Alles auswählen

package de.eq3.ccu.system.http.service;

import de.eq3.lib.webui.WebUIDetailPage;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class DeviceFirmwarePage
{
  private static String getHTML()
  {
    List<DeviceFirmwareController.Firmware> availableFirmware = DeviceFirmwareController.fetchAvailableFirmware();
    String s = "";
    Integer loop = Integer.valueOf(0);
    for (Iterator<DeviceFirmwareController.Firmware> iterator = availableFirmware.iterator(); iterator.hasNext();)
    {
      String devName = ((DeviceFirmwareController.Firmware)availableFirmware.get(loop.intValue())).getDevName().trim();
      
      s = s + "<tr class=\"DeviceListRow\">";
      s = s + "<td class='DeviceListThumbnail'><div><img id='id" + devName + "' src='' alt='" + devName + "'></div></td>";
      
      s = s + "<td class='DeviceListCell'>" + devName + "</td>";
      s = s + "<td class='DeviceListCell'>" + ((DeviceFirmwareController.Firmware)availableFirmware.get(loop.intValue())).getDevFw() + "</td>";
      s = s + "<td class='DeviceListCell'>" + ((DeviceFirmwareController.Firmware)availableFirmware.get(loop.intValue())).getCCUMinVers() + "</td>";
      s = s + "<td class='DeviceListCell'>";
      s = s + "<div class='DeviceListButton j_translate' name='btnRemove' onclick='deleteFirmware(\"" + ((DeviceFirmwareController.Firmware)availableFirmware.get(loop.intValue())).getTypeCode() + "\",\"" + ((DeviceFirmwareController.Firmware)availableFirmware.get(loop.intValue())).getDevName() + "\");'>${btnRemove}</div>";
      
      s = s + "<div class='DeviceListButton j_translate' name='btnChanglog' onclick='showChangelog(\"" + ((DeviceFirmwareController.Firmware)availableFirmware.get(loop.intValue())).getTypeCode() + "\");'>${btnChangelog}</div>";
      
      s = s + "</td>";
      s = s + "</tr>";
      s = s + "<script type='text/javascript'>";
      s = s + "try{";
      s = s + "if(DEV_PATHS['" + devName + "']['50'] != 'undefined') {";
      s = s + "picPath = DEV_PATHS['" + devName + "']['50'];";
      s = s + "jQuery('#id" + devName + "').attr('src', picPath);";
      s = s + "}";
      s = s + "} catch(e){}";
      s = s + "</script>";
      Integer localInteger1 = loop;Integer localInteger2 = loop = Integer.valueOf(loop.intValue() + 1);
      iterator.next();
    }
    return s;
  }
  
  public String get(String sid)
  {
    return index(sid);
  }
  
  public String index(String sid)
  {
    Map<String, Object> prefilledData = new HashMap();
    prefilledData.put("deviceRow", getHTML());
    
    Object value = "";
    WebUIDetailPage webUIDetailPage = new WebUIDetailPage("DeviceFirmwarePage", value, "AvailableFirmware.ftl");
    return webUIDetailPage.toHTML(prefilledData);
  }
}
und
DeviceFirmwareController.class

Code: Alles auswählen

package de.eq3.ccu.system.http.service;

import com.google.gson.Gson;
import de.eq3.ccu.http.service.JsonResponse;
import de.eq3.ccu.http.service.JsonResponseFactory;
import de.eq3.lib.util.Eq3Logger;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import org.xeustechnologies.jtar.TarEntry;
import org.xeustechnologies.jtar.TarInputStream;

public class DeviceFirmwareController
{
  private static String fileSep = System.getProperty("file.separator");
  private static String firmwareDir = fileSep + "etc" + fileSep + "config" + fileSep + "firmware";
  private static String tmpBaseDir = fileSep + "tmp";
  private static String tmpDir = tmpBaseDir + fileSep + "tmpFirmware";
  private static File rootDir = new File(fileSep + "etc" + fileSep + "config" + fileSep + "firmware");
  private static Eq3Logger log = new Eq3Logger(DeviceFirmwareController.class);
  private Gson gson;
  
  public DeviceFirmwareController()
  {
    this.gson = new Gson();
  }
  
  public static class Firmware
  {
    private String typeCode;
    private String devName;
    private String devFw;
    private String ccuMinVers;
    private String isValid;
    
    private Firmware(HashMap<String, String> data)
    {
      this.typeCode = ((String)data.get("TypeCode"));
      this.devName = ((String)data.get("Name"));
      this.devFw = ((String)data.get("FirmwareVersion"));
      this.ccuMinVers = ((String)data.get("CCUFirmwareVersionMin"));
      this.isValid = ((String)data.get("isValid"));
    }
    
    public String getTypeCode()
    {
      return this.typeCode;
    }
    
    public String getDevName()
    {
      return this.devName;
    }
    
    public String getDevFw()
    {
      return this.devFw;
    }
    
    public String getCCUMinVers()
    {
      return this.ccuMinVers;
    }
    
    public Boolean isValid()
    {
      return Boolean.valueOf(Boolean.parseBoolean(this.isValid));
    }
  }
  
  private static String getChangelog(String fwID)
  {
    String fileHandle = "-1";
    String errorReadChangelog = "${errorReadChangelog}";
    try
    {
      fileHandle = rootDir.getCanonicalPath() + fileSep + fwID + fileSep + "changelog.txt";
      File changelog = new File(fileHandle);
      StringBuilder changeLogContent = new StringBuilder((int)changelog.length());
      BufferedReader br = null;
      try
      {
        br = new BufferedReader(new FileReader(changelog));
        String sCurrentLine;
        while ((sCurrentLine = br.readLine()) != null) {
          changeLogContent.append("<p>" + sCurrentLine + "</p>");
        }
        return changeLogContent.toString();
      }
      catch (IOException e)
      {
        log.error("getChangelog: " + e.getMessage());
      }
      finally
      {
        try
        {
          if (br != null) {
            br.close();
          }
        }
        catch (IOException ex)
        {
          ex.printStackTrace();
        }
      }
      return errorReadChangelog;
    }
    catch (IOException e)
    {
      log.error("Can�t extract the changlog" + e.getMessage());
    }
    return errorReadChangelog;
  }
  
  private static Boolean deleteFw(String fw)
  {
    Boolean success = Boolean.valueOf(false);
    try
    {
      String path = rootDir.getCanonicalPath() + fileSep + fw;
      File dir = new File(path);
      for (File file : dir.listFiles()) {
        log.info(file.getName() + " deleted: " + file.delete());
      }
      success = Boolean.valueOf(dir.delete());
      log.info("Firmware successful deleted: " + success);
    }
    catch (IOException e)
    {
      log.error("Firmware could�t be deleted successfully");
    }
    return success;
  }
  
  private static void extractFileFromArchive2Tmp(TarInputStream is, TarEntry entry)
    throws IOException
  {
    boolean success = false;
    File tmpFirmware = new File(tmpDir);
    success = tmpFirmware.setWritable(true, false);
    if (!tmpFirmware.exists()) {
      success = tmpFirmware.mkdir();
    } else {
      success = true;
    }
    if (success)
    {
      byte[] data = new byte['?'];
      FileOutputStream entryStream = new FileOutputStream(tmpDir + fileSep + entry.getName());
      BufferedOutputStream dest = new BufferedOutputStream(entryStream);
      int count;
      while ((count = is.read(data)) != -1) {
        dest.write(data, 0, count);
      }
      dest.flush();
      dest.close();
      
      File folder = new File(tmpDir);
      File[] listOfFiles = folder.listFiles();
      for (File file : listOfFiles) {
        if (file.isFile()) {
          file.setReadable(true, false);
        }
      }
    }
    else
    {
      log.error("Not able to create " + tmpDir);
    }
  }
  
  private static boolean moveFileToDestination(String target)
  {
    File source = new File(tmpDir);
    for (File file : source.listFiles())
    {
      Path s = file.toPath();
      try
      {
        Files.move(s, s.resolveSibling(firmwareDir + fileSep + target + fileSep + file.getName()), new CopyOption[] { StandardCopyOption.REPLACE_EXISTING });
      }
      catch (IOException e)
      {
        e.printStackTrace();
      }
      file.delete();
    }
    return source.delete();
  }
  
  private static void delete(File file)
    throws IOException
  {
    if (file.isDirectory())
    {
      if (file.list().length == 0)
      {
        file.delete();
      }
      else
      {
        String[] files = file.list();
        for (String temp : files)
        {
          File fileDelete = new File(file, temp);
          
          delete(fileDelete);
        }
        if (file.list().length == 0) {
          file.delete();
        }
      }
    }
    else {
      file.delete();
    }
  }
  
  private static boolean createDir(File newFwDir)
  {
    boolean result = newFwDir.mkdir();
    result = newFwDir.setReadable(true, false);
    result = newFwDir.setExecutable(true, false);
    return result;
  }
  
  private static void createFirmwareDir(String name)
  {
    File newRootFirmwareDir = new File(firmwareDir);
    if (!newRootFirmwareDir.exists()) {
      newRootFirmwareDir.mkdir();
    }
    String deviceFirmwareDir = firmwareDir + fileSep + name;
    File newFwDir = new File(deviceFirmwareDir);
    if (!newFwDir.exists())
    {
      if (createDir(newFwDir)) {
        log.info(deviceFirmwareDir + " created!");
      } else {
        log.error("ERROR: " + deviceFirmwareDir + " could�t be created!");
      }
    }
    else
    {
      log.info(deviceFirmwareDir + " already exists and will be deleted!");
      try
      {
        delete(newFwDir);
        if (createDir(newFwDir)) {
          log.info(deviceFirmwareDir + " created!");
        } else {
          log.error("ERROR: " + deviceFirmwareDir + " could�t be created!");
        }
      }
      catch (IOException e)
      {
        e.printStackTrace();
      }
    }
  }
  
  private static boolean isInfoFileValid(HashMap<String, String> infoFile)
  {
    boolean valid = true;
    String[] necessaryKeys = { "TypeCode", "Name", "CCUFirmwareVersionMin", "FirmwareVersion" };
    for (String key : necessaryKeys) {
      if (infoFile.get(key) == null) {
        valid = false;
      }
    }
    return valid;
  }
  
  private static Firmware readInfoFile(File info)
  {
    BufferedReader br = null;
    HashMap<String, String> infoFile = new HashMap();
    infoFile.clear();
    try
    {
      br = new BufferedReader(new FileReader(info));
      String sCurrentLine;
      while ((sCurrentLine = br.readLine()) != null)
      {
        String[] content = sCurrentLine.split("=");
        if ((content.length == 2) && (!content[0].contains("#")) && (!content[1].contains("#"))) {
          infoFile.put(content[0].trim(), content[1].trim());
        }
      }
      Boolean infoFileIsValid = Boolean.valueOf(isInfoFileValid(infoFile));
      infoFile.put("isValid", infoFileIsValid.toString());
      return new Firmware(infoFile, null);
    }
    catch (IOException e)
    {
      log.error("readInfoFile: " + e.getMessage());
    }
    finally
    {
      try
      {
        if (br != null) {
          br.close();
        }
      }
      catch (IOException ex)
      {
        ex.printStackTrace();
      }
    }
    return null;
  }
  
  public static List<Firmware> fetchAvailableFirmware()
  {
    List<Firmware> listOfFw = new ArrayList();
    try
    {
      File[] files = rootDir.listFiles();
      if (files != null) {
        for (File file : files) {
          if (file.isDirectory())
          {
            File info = new File(file.getCanonicalPath() + fileSep + "info");
            listOfFw.add(readInfoFile(info));
          }
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    return listOfFw;
  }
  
  public String delete(String sid, String bodyParams)
  {
    String result = "Unknown message";
    
    Map<String, Object> parameter = (Map)this.gson.fromJson(bodyParams, Map.class);
    String fwID = parameter.get("firmwareID").toString();
    String devName = parameter.get("deviceName").toString();
    if (deleteFw(fwID).booleanValue()) {
      result = "${delDevFirmwareSuccessA} " + devName + " (" + fwID + ")" + "${delDevFirmwareSuccessB}";
    } else {
      result = "${delDevFirmwareFailed}";
    }
    return JsonResponseFactory.getInstance().getValidResponse(result).toJson();
  }
  
  public String showChangelog(String sid, String bodyParams)
  {
    Map<String, Object> parameter = (Map)this.gson.fromJson(bodyParams, Map.class);
    String fwID = parameter.get("firmwareID").toString();
    String result = getChangelog(fwID);
    return JsonResponseFactory.getInstance().getValidResponse(result).toJson();
  }
  
  public boolean isValidFilename(String filename)
  {
    String tgzExtension = ".tgz";
    String targzExtension = ".tar.gz";
    
    String fileNameToCheck = filename.toLowerCase();
    return (fileNameToCheck.contains(tgzExtension)) || (fileNameToCheck.contains(targzExtension));
  }
  
  public String getTempFirmwarePath(String filename)
  {
    return tmpBaseDir + fileSep + filename;
  }
  
  public String addFirmware(String sid, String firmwareFilePath)
  {
    String errorAddNewFile = "${addDevFirmwareInvalid}";
    try
    {
      File firmwareFile = new File(firmwareFilePath);
      GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(firmwareFile));
      TarInputStream is = new TarInputStream(gzipInputStream);
      TarEntry entryx = null;
      while ((entryx = is.getNextEntry()) != null) {
        if (!entryx.isDirectory()) {
          extractFileFromArchive2Tmp(is, entryx);
        }
      }
      Firmware fwInfo = readInfoFile(new File(tmpDir + fileSep + "info"));
      if ((fwInfo != null) && (fwInfo.isValid().booleanValue()))
      {
        createFirmwareDir(fwInfo.getTypeCode());
        is.close();
        gzipInputStream.close();
        firmwareFile.delete();
        
        return moveFileToDestination(fwInfo.getTypeCode()) ? "${addDevFirmwareSuccess}" : "${addDevFirmwareFailed}";
      }
      is.close();
      gzipInputStream.close();
      firmwareFile.delete();
      log.debug("The info file is corrupt or not available!");
      errorAddNewFile = "${addDevFirmwareInfoCorrupt}";
    }
    catch (Exception e)
    {
      System.err.println("Something is wrong with the file: " + e.getLocalizedMessage());
    }
    return errorAddNewFile;
  }
}

m-koeberl
Beiträge: 18
Registriert: 07.12.2015, 13:03

Re: Einrichten der OCCU mit dem Funkmodul HM-MOD-RPI-PCB

Beitrag von m-koeberl » 08.07.2016, 22:56

Hi leonsio!

Danke für den Hinweis mit der neuen Version der OCCU-SDK. Ich habe meinen Pi nun komplett auf 2.19.9 aktualisiert (inkl. HMIPServer).

Die gute Nachricht ... bei den Raumthermostaten konnte ich vorher mit 2.15.5 nicht in den Einstellungs-Screen (ReGaHss hat irgend einen Fehler geworfen), jetzt geht das.

Die schlechte Nachricht Nr. 1 ... die Firmware-Update Seite geht noch immer nicht. Ich hab absolut keine Ahnung woran das liegen kann. Ich weiß nur Java wirft den Error (siehe vorigen Eintrag von mir in diesem Thread) und ReGaHss schmeisst zeitgleich diesen Fehler (der scheint aber ab und an mal aufzuschlagen, ist auch oft im Forum zu lesen ohne wirkliche Lösung):

Code: Alles auswählen

ReGaHss: Error: IseESP::ExecError= Execution failed: [-1] 0 0x00 [0] 97 0x61 [1] 0 0x00 [2] 99 0x63 [3] 0 0x00 [4] 100 0x64  [../Platform/DOM/iseESPexec.cpp (11622)]
Noch eine schlechte Nachricht Nr. 2 ... seit 2.19.9 kann ich die Start-Seite im Firefox nicht mehr korrekt laden. Also, das rechte Teilfenster wo die aktuelle Firmware-Version udgl. angezeigt werden soll wird nicht geladen und der "Loading" Kreis dreht sich beständig weiter bis das Autologon von ReGaHss greift.

Noch eine gute Nachricht ... ansonsten funktioniert bei mir nach einem halben Tag noch alles genau so gut wie vorher. Vor dem Update ist der Pi mit HomeMatic übrigens 58 Tage absolut problemlos gelaufen :lol: hoffe das bleibt mit 2.19.9 auch so.

Wenn irgendwer einen Hint bezüglich der Firmware-Site hätte wäre ich wirklich unermesslich dankbar! Hab keine Lust nur wegen der Firmwareupdates temporär auf die "alte" CCU2 zurückgreifen zu müssen ... ist doch sehr, sehr umständlich.

Danke, glg und einen schönen Abend!
Markus

PS: den Umbau mit der externen Ground Plane Antenne (von jmaus beschrieben) hab ich vor etwa 2 Monaten auch gewagt ... die Qualität hat sich deutlich verbessert! Danke jmaus für den Beitrag.

malau
Beiträge: 6
Registriert: 27.07.2016, 16:49

Re: Einrichten der OCCU mit dem Funkmodul HM-MOD-RPI-PCB

Beitrag von malau » 01.08.2016, 18:36

Du schreibst das bei dir auch der HMIPServer läuft.
Kannst du somit auch erfolgreich IP-Komponenten anlernen?

Gesendet von meinem A0001 mit Tapatalk

leonsio
Beiträge: 1107
Registriert: 07.01.2012, 14:06
Danksagung erhalten: 6 Mal

Re: Einrichten der OCCU mit dem Funkmodul HM-MOD-RPI-PCB

Beitrag von leonsio » 01.08.2016, 20:25

Wird ohne angepasste Kernel Treiber nicht gehen

malau
Beiträge: 6
Registriert: 27.07.2016, 16:49

Re: Einrichten der OCCU mit dem Funkmodul HM-MOD-RPI-PCB

Beitrag von malau » 02.08.2016, 06:05

Das ist mir bewust.
Hat jemand schon den uart-Treiber erfolgreich kompilieren können? Der Loopback-Treiber ist ja kein Problem, doch bei dem Uart stoße ich an meine Grenzen.

leonsio
Beiträge: 1107
Registriert: 07.01.2012, 14:06
Danksagung erhalten: 6 Mal

Re: Einrichten der OCCU mit dem Funkmodul HM-MOD-RPI-PCB

Beitrag von leonsio » 02.08.2016, 07:30

Ich habs nur unter älteren raspi Kernel zum Laufen bekommen
Für x86 ist alles noch bei null

m-koeberl
Beiträge: 18
Registriert: 07.12.2015, 13:03

Re: Einrichten der OCCU mit dem Funkmodul HM-MOD-RPI-PCB

Beitrag von m-koeberl » 02.08.2016, 07:57

Hallo malau!

Rein vom HM(IP)Server her und dessen Konfiguration sollte es meinem Verständnis nach schon gehen, auch die Web-Oberfläche ist mit 2.19.9 entsprechend adaptiert.
Da ich aber keine HM-IP-Geräte besitze (nur die "normalen" Homematic-Geräte) kann ich Dir die Frage nicht beantworten. Treibermäßig (uart, Loopback) hab ich jedenfalls vorerst nichts angepasst.

Jetzt mal was ganz was anderes ... hat von Euch schon mal wer versucht einen Aktor oder irgend ein anderes Gerät "abzulernen"? Bei mir geht da jedesmal der ReGaHss flöten. Reboot usw. hilft gar nichts, ReGaHss startet sich immer mehrmals und kann nicht einmal mehr mit "kill" eliminiert werden. Muss dann immer die homematic.regadom (resp. das gesamte /config - Verzeichnis) zurücksichern, Pi rebooten, dann geht's wieder ... aber dann natürlich noch mit allen Geräten inkl. jener die es in meinem Haushalt nicht mehr gibt :D .

glg
Markus

malau
Beiträge: 6
Registriert: 27.07.2016, 16:49

Re: Einrichten der OCCU mit dem Funkmodul HM-MOD-RPI-PCB

Beitrag von malau » 02.08.2016, 08:56

@leonsio

Welche Änderungen hast du am Uart-Treiber vorgenommen, damit du kompilieren konntest?
Wie gesagt der Loopback läuft und läst sich auch laden. Ich scheitere nur am Uart.

@ m-koeberl

Geräte ablernen hab ich noch nicht getestet. Bin ja froh wenn er alles erkennt. :wink:
Ich werde das aber mal bei Gelegenheit testen.

Antworten

Zurück zu „HomeMatic Tipps & Tricks - keine Fragen!“