Tuesday, October 31, 2017

Golang JSON Marshal And Unmarshal With Interface

Problem:


Cannot deserialize to an interface.

Example:

Pet is an interface with a method called Type() that returns the type of pet.  Dog and Cat implement Type() and return "dog" and "cat" respectively.  House has one pet.

package main

import (
"encoding/json"
"fmt"
)

func main() {
// House has a pet dog.
h := House {
Pet: &Dog{},
}

b, err := json.Marshal(h)
if err != nil {
panic(err)
}


h2 := House{}
err = json.Unmarshal(b, &h2)
if err != nil {
panic(err)
}

// Expect dog
fmt.Println(h2.Pet.Type())


// House has a pet cat.
h = House {
Pet: &Cat{},
}

b, err = json.Marshal(h)
if err != nil {
panic(err)
}

h2 = House{}
err = json.Unmarshal(b, &h2)
if err != nil {
panic(err)
}

// Expect cat
fmt.Println(h2.Pet.Type())
}

type House struct {
Pet Pet
}

type Pet interface {
Type() string
}

type Dog struct {
}

func (d *Dog) Type() string {
return `dog`
}

type Cat struct {
}

func (c *Cat) Type() string {
return `cat`
}

https://play.golang.org/p/mYYK7L7IQK


When you run this code, you get this error  "json: cannot unmarshal object into Go struct field House.Pet of type main.Pet" because it doesn't how to unmarshal it an interface Pet.

Solution:


package main

import (
"encoding/json"
"fmt"
)

func main() {
// House has a pet dog.
h := House {
Pet: &Dog{},
}

b, err := json.Marshal(h)
if err != nil {
panic(err)
}


h2 := House{}
err = json.Unmarshal(b, &h2)
if err != nil {
panic(err)
}

// Expect dog
fmt.Println(h2.Pet.Type())


// House has a pet cat.
h = House {
Pet: &Cat{},
}

b, err = json.Marshal(h)
if err != nil {
panic(err)
}

h2 = House{}
err = json.Unmarshal(b, &h2)
if err != nil {
panic(err)
}

// Expect cat
fmt.Println(h2.Pet.Type())
}

type House struct {
Pet Pet
}

func (h *House) UnmarshalJSON(data []byte) error {
var m map[string]interface{}
err := json.Unmarshal(data, &m)
if err != nil {
return err
}

pet := m["Pet"]
if pet == nil {
return fmt.Errorf("cannot unmarshal pet")
}

m = pet.(map[string]interface{})
data, err = json.Marshal(m)
if err != nil {
return err
}

name := m["PetName"]
if name == nil {
return fmt.Errorf("cannot unmarshal pet")
}


p, ok := pets[name.(string)]
if !ok {
return fmt.Errorf("cannot unmarshal pet %q", name)
}

err = json.Unmarshal(data, p)
if err != nil {
return err
}

h.Pet = p
return nil
}

var pets = map[string]Pet {`Dog`: &Dog{}, `Cat`: &Cat{}}

type Pet interface {
Type() string
}

type Dog struct {
}

func (d *Dog) Type() string {
return `dog`
}

func (d *Dog) MarshalJSON() ([]byte, error) {
type MyCopy Dog
return json.Marshal(&struct {
PetName string
*MyCopy
}{
PetName: `Dog`,
MyCopy:      (*MyCopy)(d),
})
}

type Cat struct {
}

func (c *Cat) Type() string {
return `cat`
}

func (c *Cat) MarshalJSON() ([]byte, error) {
type MyCopy Cat
return json.Marshal(&struct {
PetName string
*MyCopy
}{
PetName: `Cat`,
MyCopy:      (*MyCopy)(c),
})
}

https://play.golang.org/p/Wc_eMVtOpy

Wednesday, July 6, 2016

Best Lenses for Sony a6000 or Sony a6300

Problem:

I need great lenses for Sony a6300.



Solution:


I've been doing some research, and here's what I've gathered so far.

Prime:


These are excellent, affordable primes.

Sigma 30mm f/1.4 DC DN Contemporary Lens for Sony E

Price: $339.00 (Amazon)
DxOMark Score: 29
Weight: 265 grams


Sigma 30mm F2.8 EX DN Art for Sony SE

Price: $169.00 (Amazon)
DxOMark Score: 23
Weight: 130 grams


Sony E 35mm f/1.8 OSS

Price: $398.00 (Amazon)
DxOMark Score: 23
Weight: 155 grams


Sony E 50mm f/1.8 OSS

Price: $248.00 (Amazon)
DxOMark Score: 25
Weight: 202 grams



Sony 55mm F1.8 Sonnar T* FE ZA 

Price: $898.00 (Amazon)  (This is the most expensive one on the list.  I won't be getting it! :)
DxOMark Score: 27
Weight: 281 grams



Sigma 60mm F2.8 EX DN Art for Sony SE

Price: $209.00 (Amazon)
DxOMark Score: 25
Weight: 190 grams


Zoom:


Sony Vario-Tessar T E 16-70mm F4 ZA OSS

Price: $998.00 (Amazon)
DxOMark Score: 17
Weight: 308 grams


Sony E PZ 18-105mm F4 G OSS

Price: $598.00 (Amazon)
DxOMark Score: 15
Weight: 427 grams



Conclusion:


I'm leaning toward getting the Sigma 30mm 1.4 for street photography/portrait, the Sony 50mm or Sigma 60mm for portrait photography, and Sony 18-105mm for everything else.

Note that the sigma lenses do not have image stabilization.  The sigma 30mm 1.4 is similar in size to Sony 55mm.  The Sony 18-105mm has internal zoom, meaning that it doesn't protrude.

Wednesday, May 4, 2016

Force quit and force restart a unresponsive application in MacOS

Problem:

Cannot force quit a not responding application in MacOS.  Try force quit from the Dock.  Try Command+Option+Esc to bring up the dialog to force quit there.  Try restart the computer.  The computer doesn't restart and does nothing

Solution:

Open up Terminal and restart there

sudo shutdown -r now

WeMo LED Lighting Starter Set - Bulbs Not Detected

Context:

WeMo Lighting Starter Set
iOS Wemo App

Problem:

 The WeMo Lighting Starter Set comes with two bulbs, but they cannot be detected.  It is one of the most frustrating things!  I've lost hours trying to get them to work.  Stupid thing!  I've tried resetting the link, reinstalling the app, resetting the bulbs so many times, but the bulbs do not get detected during scan.  The link somehow does not see them.

Solution:

After a lot of tries, I have finally been able to detect them and add them.  Victory at last!

Ok, I'm not sure if this will help you, but you can try my steps:
  1. Reset the link
    1. Press and hold the little reset button on the link for about 5 seconds while plugging it in (same as instructions written on it) to restore to factory settings.
    2.  You will first see the amber light blinking.  This may take some time, and then, you will see the light blinks amber and green alternately.  When you see this, it is ready to be hooked up.
    3. Go WiFi into Settings (iPhone) and connect to the Wemo link.  You should see an SSID something .Link.
    4. Connect to it
    5. Open Wemo app.  It should say that you are connected to the link and that it's trying to open a connection.
    6. It will try to connect to your WiFi network next.
    7. If all successful, it will go into the scanning mode to detect the bulbs.
    8. If your bulbs are found, great!  (For me, nothing is found!)
  2. If your bulbs are not detected, follow the steps below to reset the bulbs.  You can try one bulb, and then add another later.  Note that you do not have to reset the link every time you add a bulb.  You can go to the "Add a device" in the settings of the WeMo App to scan and add new devices.
    1. The instructions on the support page as listed below.  However, I followed exactly that and it DID NOT work for me.  What worked for me was that instead of 1 second as instructed in step 2, 4, 6, I did about 3 seconds for each of the steps.  If the bulb flashes, it's been reset successfully.  If it succeeds, open the WeMo app, go to add a device and scan.  If all is good, you should be able to detect the bulb.  Repeat the same process to add the other bulb.
      Step 1:
      Start with the WEMO LED Lightbulb being in the ON position.
      User-added image

      Step 2:
      Turn it OFF for one (1) second.

      Step 3:
      Turn it ON for 3-4 seconds.

      Step 4:
      Turn it OFF for one (1) second.

      Step 5:
      Turn it ON for 3-4 seconds.

      Step 6:
      Turn it OFF for one (1) second.

      Step 7:
      Turn it ON and leave it as it is.  After about five (5) seconds, the WEMO LED Lightbulb will flash which shows a successful reset.

Wednesday, December 2, 2015

WIFI Information in Mac OS


What's my connection mode: 802.11g or 802.11n or whatnot?  What's my current transmission speed?

Hold down the "alt/option" key on the keyboard and click on the Wifi indicator as shown in the picture below.  As you can see, you ca see more information.  Right now, I'm connecting with 802.11n at 52Mbps.  The speed fluctuates.  



WD My Cloud EX2 - Fan Problem - Manual Control

Context:


WD My Cloud EX2 8TB

Problem:


Fan speed is always at 0 RPM even when the temperature gets around 56 degrees Celsius.  I thought it was just a defective unit, so I called Western Digital to get a replacement.  Unfortunately, the replacement had the same problem.

Side note:  you have to pay for shipping to return the old unit to them.  I thought that they would send me a prepaid label, but that wasn't the case.  I paid around $20 for UPS shipping.

Solution:


The problem is a software one.  To manually control the fan, you will have to ssh in and run the fan.

First to enable SSH, go to Settings -> Network, under Network Services, you will find SSH.  Turn that on.  You will get a warning about voiding the warranty.  This warning stopped me first time for not going in.

Anyway, if you decide to proceed and configure your SSH.

I'm using a Mac, so from my terminal, I run

ssh sshd@[name of your unit here]

Once you're in, there's a command call "fan_control"

fan_control -h

Will give you a list of options

*** Fan Cobtrol Help Message ***

fan_control b c: for NAS booting
fan_control 0 d : [auto] open debug msg
fan_control 0 c : [auto] close debug msg
fan_control -L [value] : set Lower (THYST)
fan_control -H [value] : set Upper(TOS)
fan_control -g 0 : get current temperature
fan_control -g 1 : get Lower temperature
fan_control -g 2 : get Upper temperature
fan_control -g 3 : get fan state
fan_control -g 4 : get fan rpm
fan_control -f 0 : set fan stop
fan_control -f 1 : set fan rpm4000
fan_control -f 2 : set fan rpm5000
fan_control -f 3 : set fan rpm6000
fan_control -f 4 : set fan rpm7000
fan_control -f 5 : set fan rpm8000
fan_control -f 6 : set fan rpm9000

Now as you can see, to get the current temperature, you run

fan_control -g 0

To set the fan speed at rpm4000, you can run

fan_control -f 1

To stop, run

fan_control -f 0

And friends, that's how you can manually control it.

If you want to monitor the temperature, say every minute, included is another utility called "watch" that you can use.

watch -n 60 fan_control -g 0

Here, I'm saying that gives me the temperature every minute.  60 there is 60 seconds.  To quit, you can simply do Control + C

Hope that they will fix the issue in the next firmware update.

Friday, January 25, 2013

iPad Mini 2? When?

I can't wait for iPad Mini 2 to come out with Retina Display.  I played around with the current iPad Mini, and the display really bothered me.  Since I'm using a Retina Display MacPro, a Retina Display iPad and a Retina Display iPhone, I notice the resolution difference right away, and I can't stand it.  If you're coming from "Retina Display" (Apple's Marketing Term), you better wait for a next generation of the iPad Mini.  If you buy one now, you will be greatly disappointed.  Don't know when that will come out though.  There have been a lot of rumors around the March time frame.