How to detect Sonos devices on your network

How to detect Sonos devices on your network

A potential project requires me to detect Sonos devices on a network and find their IP addresses. Since Sonos only has 2 Mac Address OUIs an ARP scanner seemed the best way to do this. As such, I rightfully reinvented the wheel and wrote a slightly glorified ARP scanner with detection for Sonos OUIs. Sadly, PHP wasn’t quite suitable for this due to it’s lack of AF_PACKET sockets so it’s in C.

It’ll run on Linux and scan a network when given an interface name. Tweaks more than welcome as GitHub Pull Requests.

Code’s on my GitHub at https://github.com/phil-lavin/sonos-detector.

PHP: Interfacing with HeatMiser WiFi thermostats

PHP: Interfacing with HeatMiser WiFi thermostats

I’m quite a big fan of writing code that interfaces with physical data. It somehow feels more fulfilling to see or feel the results.

On top of my repertoire of the Foscam FI8908W Recorder and TK110 GPS Tracker Server, comes a PHP interface for HeatMiser WiFi Thermostats. This too can be found on GitHub. The code is fairly self explanatory and the docs should point you in the right direction. The library will read from and write to HeatMiser WiFi thermostats. It’s tested on the PRT-TS but should probably work on others. If not, fix it up and submit a pull request on Github (or comment here).

If you came looking for an insight into this Theromstat’s binary network protocol, there’s a decent guide released by HeatMiser on the topic. This can be found on their website. The guide can be a lot to get your head around so hopefully my code will be enough to aid you in this area. Failing that, or if you’re more of a camel, there’s a good Perl implementation on Google Code. The Perl implementation is more of an example than an interface-able library but it’s a great starting point and provided a lot of inspiration for my PHP implementation.

 

PHP: Find number of weeks in a given month

The following function finds the number of weeks in a given month, assuming Monday as the first day of the week.

  1. <?php
  2. function weeks_in_month($month, $year) {
  3. // Start of month
  4. $start = mktime(0, 0, 0, $month, 1, $year);
  5. // End of month
  6. $end = mktime(0, 0, 0, $month, date('t', $start), $year);
  7. // Start week
  8. $start_week = date('W', $start);
  9. // End week
  10. $end_week = date('W', $end);
  11.  
  12. if ($end_week < $start_week) { // Month wraps
  13. return ((52 + $end_week) - $start_week) + 1;
  14. }
  15.  
  16. return ($end_week - $start_week) + 1;
  17. }

 

PHP – Why you should use the Factory Method Pattern and how you should do it

PHP – Why you should use the Factory Method Pattern and how you should do it

This article assumes you’re using PHP version 5.3 or above. If you are not, you should note that “the PHP 5.2 series is NOT supported anymore” and you should really upgrade.

The Factory method pattern is a marvelous idea. It is designed to reduce the number of instances in which you use the ‘new’ keyword in your code. An example of its use as as follows:

  1. <?php
  2.  
  3. class SomeClass {
  4. protected $foo;
  5.  
  6. protected function __construct($foo) {
  7. $this->foo = $foo;
  8. }
  9.  
  10. public static function factory($foo = 'default') {
  11. return new static($foo);
  12. }
  13.  
  14. public function get_foo() {
  15. return $this->foo;
  16. }
  17. }
  18.  
  19. echo SomeClass::factory()->get_foo();

There are a number of points to note in this code. The first of these is that the constructor is protected. This is a feature of PHP 5.3 and above which prevents a class being instantiated using the new keyword. You’ll also notice that the default value for $foo is only specified on the factory() method. This is simply because specifying it on the constructor would be redundant as the constructor will only ever be called by the factory method. There’s a method called factory() which does nothing but return a new instance of ‘static’ (the current class). There’s also an example of how the factory is used and you’ll see that the get_foo() method is chained on. This is a useful and elegant feature which you would not get using ‘new’.

So what are the other advantages? Well, the constructor cannot return a value, whereas the factory method can. This gives you significantly more control over what you return. For example, if object construction failed, you can return a false or null value. I can’t think of a use case offhand for this and it’s probably better to throw an exception (which can also be done from the constructor) so that the successful return of a factory is always an object.

Consider a scenario like this… You have an API which you have been using for a while and decide it’s time to make a new/better featured one. Many of your sites rely on this API and, as such, you need to migrate them slowly. If you had used a factory() method in the first instance, there would be no issues doing this as you can simply change the type of object which it returns. For example…

  1. <?php
  2.  
  3. class API {
  4. protected $site_id;
  5.  
  6. protected function __construct($site_id) {
  7. $this->site_id = $site_id;
  8. }
  9.  
  10. public static function factory($site_id) {
  11. if (Site::uses_new_api($site_id)) {
  12. return NewAPI::factory($site_id);
  13. }
  14.  
  15. return new static($site_id);
  16. }
  17.  
  18. public function get_info() {
  19. return file_get_contents("http://www.info.com/?site={$this->site_id}");
  20. }
  21. }
  22.  
  23. class NewAPI extends API {
  24. public static function factory($site_id) {
  25. return new static($site_id);
  26. }
  27.  
  28. public function get_more_info() {
  29. return file_get_contents("http://www.moreinfo.com/?site={$this->site_id}");
  30. }
  31. }

You’ll see here that we’ve created a NewAPI class which extends the original API and adds functionality to it. We’ve also modified the factory() method of API to use a fictitious Site::uses_new_api() function to determine if the site uses the new API – if it does, we return an instance of it. This prevents us having to modify the code of the sites which use this class in order to migrate them to the new API.

Factory methods also make your life a little easier as you can have multiple methods which instantiate the object in different ways. For example:

  1. <?php
  2.  
  3. class Image {
  4. protected $type;
  5. protected $filename;
  6.  
  7. protected __construct($type, $filename) {
  8. $this->type = $type;
  9. $this->filename = $filename;
  10. }
  11.  
  12. public static function jpeg_factory($filename) {
  13. return new static('jpeg', $filename);
  14. }
  15.  
  16. public static function gif_factory($filename) {
  17. return new static('gif', $filename);
  18. }
  19.  
  20. public function get_readable_type() {
  21. if ($this->type == 'jpeg') {
  22. return 'The image type is JPEG';
  23. }
  24. if ($this->type == 'gif') {
  25. return 'The image type is Graphics Interchange Format';
  26. }
  27. }
  28. }

You’ll see in this example we have two factory methods –  jpeg_factory() and gif_factory(). These only take in the filename and serve to ensure that only ‘gif’ and ‘jpeg’ can end up in the internal $type variable. Again, you could use exceptions to signify there being an error in what the passes into the class, but this is a very basic example.

So, the advantages we’ve established are:

  • You can prevent the use of ‘new’ and thus have more control over how a class is instantiated
  • You can chain methods onto the end of a factory() call to avoid the need for multiple lines of code (or even storing a reference to an object at all)
  • Code instantly becomes more maintainable as you have control over what is returned from the factory methods
  • You can have multiple factory methods to better control and simplify the ways in which the object is instantiated