📄 onewireserver.java
字号:
try { for ( Iterator i = path2device.keySet().iterator(); i.hasNext(); ) { try { lockToken = lock.getWriteLock(); complain(LOG_DEBUG, CH_LOCK, "Poll: got lock in " + (System.currentTimeMillis() - start) + "ms"); start = System.currentTimeMillis(); OWPath path = (OWPath)i.next(); try { path.open(); } catch ( NullPointerException npex ) { // VT: FIXME: This is weird... complain(LOG_ERR, CH_ONEWIRE, "null path encountered, all paths: " + path2device.keySet(), npex); lockToken = lock.release(lockToken); start = System.currentTimeMillis(); continue; } complain(LOG_DEBUG, CH_ONEWIRE, "Path open: " + path + " in " + (System.currentTimeMillis() - start) + "ms"); Map address2device = (Map)path2device.get(path); if ( address2device == null || address2device.keySet().isEmpty() ) { complain(LOG_WARNING, CH_ONEWIRE, "Null address set for '" + path + "'"); lockToken = lock.release(lockToken); // Let's give the others a courtesy pause // VT: NOTE: This will not work if there are devices // present, but none of them are of interest to us Thread.sleep(500); start = System.currentTimeMillis(); continue; } else { // VT: FIXME: To speed things up, it would make sense to go // a level down. Issue a temperature convert command for all // the temperature sensors on this branch, then read them // all. Don't forget to check if there are any temperature // sensors on the branch. for ( Iterator ai = address2device.keySet().iterator(); ai.hasNext(); ) { // To improve the shutdown time, let's check if we're // still enabled, otherwise we might be just going, and // going, and going... if ( !isEnabled() ) { complain(LOG_INFO, CH_ONEWIRE, "Oops! Not enabled anymore..."); return; } String address = ai.next().toString(); OneWireDeviceContainer dc = (OneWireDeviceContainer)address2device.get(address); OneWireContainer owc = dc.container; if ( owc instanceof TemperatureContainer ) { TemperatureContainer tc = (TemperatureContainer)owc; try { double temp = getTemperature(tc); complain(LOG_DEBUG, CH_DATA, address + ": " + temp + "C"); localDataMap.put(address, new Double(temp)); currentTemperatureChanged(address, temp); } catch ( OneWireIOException owioex ) { throw owioex; } catch ( Throwable t ) { complain(LOG_WARNING, CH_DATA, "Failed to read " + address + ", cause:", t); } } else if ( owc instanceof SwitchContainer ) { // Don't do it if the device is DS2409 - we'll get // screwed up trying to restore the state. They are // managed automatically when the path is selected // anyway. if ( !"DS2409".equals(owc.getName()) ) { localDataMap.put(address, getState((SwitchContainer)owc)); } } } } } finally { lockToken = lock.release(lockToken); complain(LOG_DEBUG, CH_LOCK, "Poll: path complete in " + (System.currentTimeMillis() - start) + "ms"); // Let others live, we're quite greedy Thread.sleep(100); start = System.currentTimeMillis(); } } complain(LOG_DEBUG, CH_ONEWIRE, "poll done"); if ( path2device.isEmpty() ) { Thread.sleep(1000); } } finally { lock.release(lockToken); } // VT: FIXME: This way, the device state for the device that has // departed will be lost. Instead, we have to iterate through the // map, and transfer the new values into the global data map. for ( Iterator i = localDataMap.keySet().iterator(); i.hasNext(); ) { Object key = i.next(); dataMap.put(key, localDataMap.get(key)); } complain(LOG_DEBUG, CH_DATA, "Data map: " + dataMap); } /** * Get the temperature container reading. * * @param tc Temperature container to get the reading from. * * @exception OneWireException if there was a problem talking to * 1-Wire® device. * * @exception InterruptedException if there was a problem waiting for * the {@link #lock lock}. * */ double getTemperature(TemperatureContainer tc) throws OneWireException, OneWireIOException, InterruptedException { // get the current resolution and other settings of the device long start = System.currentTimeMillis(); long now = start; String address = ((OneWireContainer)tc).getAddressAsString(); double lastTemp; // VT: FIXME: What if the state is not available yet? // Theoretically, it should be 'cause setHiRes should have been // called, but this has to be verified byte[] state = (byte [])stateMap.get(address); if ( state == null ) { complain(LOG_WARNING, CH_ONEWIRE, "device state is not available yet, possibly setHiRes failed"); state = tc.readDevice(); } now = System.currentTimeMillis(); complain(LOG_DEBUG, CH_DATA, "ReadDevice/0: " + (now - start)); // perform a temperature conversion tc.doTemperatureConvert(state); now = System.currentTimeMillis(); complain(LOG_DEBUG, CH_DATA, "doTemperatureConvert: " + (now - start)); // read the result of the conversion state = tc.readDevice(); now = System.currentTimeMillis(); complain(LOG_DEBUG, CH_DATA, "ReadDevice/1: " + (now - start)); // extract the result out of state lastTemp = tc.getTemperature(state); if ( lastTemp == 85.0 ) { // Known bug, ignore throw new IllegalStateException("Temp read is 85C, ignored"); } stateMap.put(address, state); return lastTemp; } /** * Try to set the highest possible resolution available from the * temperature container. * * @param tc Temperature container to set the resolution of. */ private void setHiRes(TemperatureContainer tc, OWPath path) { Object lockToken = null; try { lockToken = lock.getWriteLock(); String address = ((OneWireContainer)tc).getAddressAsString(); path.open(); byte state[] = tc.readDevice(); if (tc.hasSelectableTemperatureResolution()) { double[] resolution = tc.getTemperatureResolutions(); String s = ""; for ( int idx = 0; idx < resolution.length; idx++ ) { s += Double.toString(resolution[idx]) + " "; } complain(LOG_DEBUG, CH_DATA, "Temperature resolutions available: " + s); tc.setTemperatureResolution(resolution [resolution.length - 1], state); } tc.writeDevice(state); stateMap.put(((OneWireContainer)tc).getAddressAsString(), state); } catch ( Throwable t ) { complain(LOG_WARNING, CH_DATA, "Failed to set high resolution on " + ((OneWireContainer)tc).getAddressAsString() + ", cause:", t); } finally { lock.release(lockToken); } } /** * Get the switch container state. * * @param sc Switch container to get the state of. * * @return The switch state object. */ private SwitchState getState(SwitchContainer sc) throws OneWireException, InterruptedException { // We don't have to get the lock here, because we're in the lock // protected context already SwitchState ss = new SwitchState(); byte state[] = sc.readDevice(); ss.smart = sc.hasSmartOn(); ss.state[0] = sc.getLatchState(0, state); ss.state[1] = sc.getLatchState(1, state); return ss; } /** * Add the listener. * * @param listener The listener to add. */ public synchronized void addListener(OneWireContainerListener listener) { // VT: FIXME: Dump the set of arrival notifications on'em? Better be // done from a different thread... listenerSet.add(listener); } public void removeListener(OneWireContainerListener listener) { listenerSet.remove(listener); } /** * Broadcast the notification. * * @param address Sensor whose temperature has changed. * * @param temp Current sensor temperature. */ private void currentTemperatureChanged(String address, double temp) { for ( Iterator i = listenerSet.iterator(); i.hasNext(); ) { OneWireContainerListener l = (OneWireContainerListener)i.next(); if ( l instanceof TemperatureContainerListener ) { try { TemperatureContainerListener tcl = (TemperatureContainerListener)l; tcl.currentTemperatureChanged(address, temp); } catch ( Throwable t ) { complain(LOG_WARNING, CH_DATA, "Can't notify, cause:", t); } } } } public void networkArrival(OneWireNetworkEvent e) { // We know it's actually a different class... OwapiNetworkEvent e2 = (OwapiNetworkEvent)e; // It is assumed that the device that came with this event is not in // the device map. If it is, we've screwed up somewhere else... OneWireContainer owc = e2.getDeviceContainer(); String address = owc.getAddressAsString(); // Let's set the resolution before registering the device with the // device map so the poll doesn't interfere, and the device state // gets cached if ( owc instanceof TemperatureContainer ) { for ( int retry = 0; retry < 5; retry++ ) { try { setHiRes((TemperatureContainer)owc, e2.path); break; } catch ( Throwable t ) { complain(LOG_WARNING, CH_ONEWIRE, "Failed to setHiRes on " + address + ", trying again (" + retry + ")"); } } } else if ( owc instanceof SwitchContainer ) { // Restore the device state. DS2409 are not included in the map // anyway. SwitchState ss = (SwitchState)dataMap.get(address); if ( ss != null ) { // Yup, we've seen this device before SwitchContainer sc = (SwitchContainer)owc; Object lockToken = null; try { lockToken = lock.getWriteLock(); byte state[] = sc.readDevice(); sc.setLatchState(0, ss.state[0], ss.smart, state); sc.setLatchState(1, ss.state[1], ss.smart, state);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -