Automatically update devices on an interval

This commit is contained in:
Charles Magahern
2015-12-31 23:29:48 -08:00
parent e6dd661338
commit 697a7e1de9
4 changed files with 107 additions and 2 deletions

View File

@@ -13,6 +13,7 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate {
private var _visualizationController: VisualizationViewController = VisualizationViewController()
private var _switchesController: SwitchesViewController = SwitchesViewController()
private var _headerView: HeaderView = HeaderView()
private var _updateDevices: Bool = false
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
{
@@ -92,6 +93,7 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate {
_server.connect { (error: NSError?) -> Void in
if (error == nil) {
self._reloadDevices()
self._startUpdatingDevices()
} else {
self._updateConnectivityStatus(.Error)
}
@@ -164,8 +166,27 @@ class MainViewController: UIViewController, SwitchesViewControllerDelegate {
} else {
self.devices = []
self._updateConnectivityStatus(.Error)
self._stopUpdatingDevices()
}
}
})
}
internal func _startUpdatingDevices()
{
_updateDevices = true
let interval = dispatch_time(DISPATCH_TIME_NOW, Int64(10 * Double(NSEC_PER_SEC)))
dispatch_after(interval, dispatch_get_main_queue()) { () -> Void in
if (self._updateDevices) {
self._reloadDevices()
self._startUpdatingDevices()
}
}
}
internal func _stopUpdatingDevices()
{
_updateDevices = false
}
}

View File

@@ -25,6 +25,7 @@ class SwitchesViewController: UIViewController,
weak var delegate: SwitchesViewControllerDelegate?
private var _collectionView: UICollectionView = UICollectionView(frame: CGRectZero,
collectionViewLayout: UICollectionViewFlowLayout())
private var _currentDevicesHash: Int = 0
static private let collectionViewDeviceSwitchCellReuseIdentifier = "DeviceSwitchReuseID"
static private let collectionViewActionCellReuseIdentifier = "ActionCellReuseID"
@@ -87,7 +88,69 @@ class SwitchesViewController: UIViewController,
{
didSet
{
_collectionView.reloadData()
let hash = self.devices.reduce(0, combine: {$0 ^ $1.hashValue})
if (hash != _currentDevicesHash) {
// sort by name
self.devices.sortInPlace({ (d1: WemoDevice, d2: WemoDevice) -> Bool in
return (d1.name.compare(d2.name) == .OrderedAscending)
})
// replace "Dance Dance Revolution" names with "DDR" to save space
for device in self.devices {
if let range = device.name.rangeOfString("Dance Dance Revolution") {
device.name.replaceRange(range, with: "DDR")
}
}
let previousSet = NSOrderedSet(array: oldValue)
let newSet = NSOrderedSet(array: self.devices)
var insertedIndexPaths: [NSIndexPath] = []
var updatedIndexPaths: [NSIndexPath] = []
var deletedIndexPaths: [NSIndexPath] = []
// if we have devices now and we didn't before, or vice versa,
// we need to update the action cells
if ((oldValue.count == 0 && self.devices.count != 0) || (self.devices.count == 0 && oldValue.count != 0)) {
for var actionCellIdx = 0; actionCellIdx < ActionCell.count; ++actionCellIdx {
let actionCellIndexPath = NSIndexPath(forItem: actionCellIdx, inSection: 0)
updatedIndexPaths.append(actionCellIndexPath)
}
}
// find deletes and updates
for (idx, device) in previousSet.enumerate() {
let itemIndex = idx + ActionCell.count
let curIndexPath = NSIndexPath(forItem: itemIndex, inSection: 0)
if (!newSet.containsObject(device)) {
deletedIndexPaths.append(curIndexPath)
} else if (idx < newSet.count) {
let deviceInNewSet = newSet.objectAtIndex(idx) as! WemoDevice
if (deviceInNewSet != (device as! WemoDevice)) {
updatedIndexPaths.append(curIndexPath)
}
}
}
// find insertions
for (idx, device) in newSet.enumerate() {
if (!previousSet.containsObject(device)) {
let itemIndex = idx + ActionCell.count
let insertedIndexPath = NSIndexPath(forItem: itemIndex, inSection: 0)
insertedIndexPaths.append(insertedIndexPath)
}
}
UIView.performWithoutAnimation { () -> Void in
self._collectionView.performBatchUpdates({ () -> Void in
self._collectionView.deleteItemsAtIndexPaths(deletedIndexPaths)
self._collectionView.reloadItemsAtIndexPaths(updatedIndexPaths)
self._collectionView.insertItemsAtIndexPaths(insertedIndexPaths)
}, completion: nil)
}
_currentDevicesHash = hash
}
}
}
@@ -114,6 +177,7 @@ class SwitchesViewController: UIViewController,
let deviceIdx = indexPath.item - ActionCell.count
let device = self.devices[deviceIdx]
cell.device = device
cell.toggled = (device.state == .On)
cell.ordinal = deviceIdx + 1
return cell

View File

@@ -8,7 +8,7 @@
import Foundation
class WemoDevice {
class WemoDevice: Hashable {
enum State {
case Off
case On
@@ -57,4 +57,22 @@ class WemoDevice {
self.serial = String(serial)
}
}
var hashValue: Int
{
var hash: Int = 0x0
hash ^= self.name.hash
hash ^= self.host.hash
hash ^= self.model.hash
hash ^= self.state.hashValue
hash ^= self.type.hashValue
hash ^= self.serial.hashValue
return hash
}
}
func ==(lhs: WemoDevice, rhs: WemoDevice) -> Bool
{
return (lhs.serial == rhs.serial)
}

View File

@@ -132,6 +132,7 @@ public class WemoDeviceCellView: WemoCellView {
{
_device = device
_nameLabel.text = _device?.name.uppercaseString
self.setNeedsLayout()
}
}
@@ -146,6 +147,7 @@ public class WemoDeviceCellView: WemoCellView {
{
_ordinal = ordinal
_ordinalLabel.text = String(format: "%.2d", _ordinal)
self.setNeedsLayout()
}
}