Integrating Boston Ma. weather conditions with Hue Bulbs in sync with the John Hancock Tower

For those of us in Boston, we know about the weather beacon that sits atop the old John Hancock building in Boston. The weather beacon has been in operation since 1950. The beacon has a clever rhyme: Steady blue, clear view/Flashing blue, clouds due/Steady red, rain ahead/Flashing red, snow instead*.* ”

We are building a house on the south shore of Boston and would like to install a weather beacon that mimics the Hancock Tower beacon. We have a Hue bridge, an HE and Action Tiles all sitting in test bed mode right now. We plan to activate the beacon with a Zooz on/off 700 series switch.

I'm not very familiar with writing complex programs nor am I good at populating the Action Tiles dashboard with a weather dashboard.

I recognize that this is potentially a real hard request but if anyone could help, we'd appreciate it.

Here's a link to the John Hancock Tower Berkeley Building Weather Beacon (Old John Hancock Tower)

Thanks!

Paul

Doable for sure but a bit of a pain. I can point you in a direction that will probably work but as you suggest this is not exactly a novice rule it set up :slight_smile:

First thing... what will you use for the actual beacon and what is the intent of the Zooz on/off switch? I'm guessing any number of Hue RGB bulbs will work, depending on whether you're going to mount the beacon outside or inside. Not sure the Zooz will help a lot since the bulb can be controlled without it.

Second thing... you'll need a weather source. There are a bunch of weather integrations available but ideally you'd like to use one that matches the Hancock Building. I assume you'll forego the Sox cancellation information? You don't actually need a tile set up. You just need to grab the data.

Then all you really need to do is poll the weather source periodically, parse the forecast information (how you do this depends on the source), and adjust your bulb accordingly. Not sure what you would use action tiles to do (unless it has some automation capability) but I'd think some work with RM is in your future!

1 Like

With all the coffee makers that have been put on the web, nobody has put the Berkeley Building Weather Beacon on the web? Articles say they poll the Weather Service every four hours but not sure how to exactly duplicate their logic . . .

Cool idea, I just checked and found some info that it's now automated and uses the NWS API to determine the status of the light.

2 Likes

And yet I still can't find one that meets my needs.

I think @bptworld had an NWS integration that he stepped away from because of inconsistencies etc with the NWS web service...

Hi

  1. The Zooz switch is planned to be a "kill power" option to shut off the sockets in the event of a doozie (N'or Easter). We want all external power to be off when the stuff hits the fan. This planned home is right on the seacoast and gets schmacked when bad weather arrives.

2 In terms of a weather source we have ABC/CBS/NBC local channels that have weather data on their websites. We also have NOAA .... I can't find the Hancock Tower's weather source. I suppose I could call them.... But the way this beacon works, is that the lights show just about real time weather conditions. I'd be ok with that.

3 The Action Tile dash board would be cool to display the scene on the various dashboards. I do plan to us Remote Management either through you or via some type of tunnel into my router as well

  1. No..We don't need Red Sox data

Thanks for the prompt reply by everyone... I hope this will help move the discussion along. I'm sure the rule setup will not be easy. But it will be really cool for Hubitat to mimic the John Hancock Beacon in the Hub of the universe! Hub of the Universe, Boston, Massachusetts
Paul

ps... My favorite dumb coffee maker is the good old electric percolator.

Since there are already several weather drivers available for Hubitat, writing an app that uses those to reproduce those 4 conditions should be pretty simple really. I can probably throw something together when I have some free time.

Awesome... Thank you very much

Paul

ABC is : https://www.wcvb.com/
NBC is : https://www.nbcboston.com/
CBS is: CBS Boston - Breaking News, Sports, Weather, I-Team Investigations
NOAA is: Boston / Norton, MA

Here we are, this works using the built in OpenWeatherMap driver or the "OpenWeatherMap-Alerts Weather Driver". Other drivers should be able to work, possibly with some minor changes.

/**
 *  John Hancock Weather Beacon
 *	Reproduction of the John Hancock building weather beacon in Boston
 *
 *  http://www.celebrateboston.com/strange/weather-beacon.htm
 * 
 *  Copyright 2022 Peter Miller
 */

definition(
	name: "John Hancock Weather Beacon",
	namespace: "hyposphere.net",
	//parent: "hyposphere.net:P's Light Controls",
	author: "Peter Miller",
	description: "Reproduction of the John Hancock building weather beacon in Boston",
	iconUrl: "",
	iconX2Url: "",
)

preferences {
	section() {
		input 'isPaused', 'bool', title: 'Pause app', defaultValue: false
	}
	section('<b>Devices</b>') {
		input 'weather', 'capability.temperatureMeasurement', title: 'Weather device', required: true, multiple: false
		input 'light', 'capability.colorControl', title: 'Light', required: true, multiple: false
		input 'beaconSwitch', 'capability.switch', title: 'Beacon power switch', required: true
	}
	section('<b>Settings</b>') {
		input 'saturationOption', 'decimal', title: 'Saturation (0..1)', required: true, defaultValue: 0.95, range: '0..1'
		input 'flash_interval', 'number', title: 'Flash rate', required: true, defaultValue: 3, range: '1..10'
	}
	section('<b>Debug</b>') {
		input 'debugMode', 'bool', title: 'Debug Mode', submitOnChange: true
		if (debugMode) {
			input 'forecastDebug', 'string', title: 'Forecast override'
			input 'cloudinessDebug', 'number', title: 'Cloudiness override'
		}
	}
}

void installed() {
	initialize()
}

void updated() {
	initialize()
}

void initialize() {
	if (isPaused) {
		unsubscribe()
		unschedule()
		light.off()
	} else {
		subscribe(beaconSwitch, 'switch', 'switchHandler')
		if (beaconSwitch.latestValue("switch") == "off") {
			unsubscribe('updateLight')
			unschedule()
			light.off()
		} else {
			subscribe(weather, 'weather', 'updateLight')
			subscribe(weather, 'condition_text', 'updateLight')
			subscribe(weather, 'cloudiness', 'updateLight')
			subscribe(weather, 'clouds', 'updateLight')
			updateLight()
		}
	}
}

void switchHandler(evt) {
	if (beaconSwitch.latestValue("switch") == "off") {
		unsubscribe(updateLight)
		unschedule()
		light.off()
	} else {
		initialize()
	}
}

void updateLight(evt) {
	Float tempOut
	List<Integer> hsvColor = null
	Float satLevel = saturationOption
	
	if (satLevel > 1) {
		satLevel = 1.0
	} else if (satLevel < 0) {
		satLevel = 0
	} 

	if (weather.getStatus() != "ACTIVE") {
		log.warn "Weather device is not updating, do nothing"	
	} else {
		hsvColor = getColor()
		light.setColor(["hue": hsvColor[0], "saturation": hsvColor[1], "level": light.latestValue("level")])
	}
}

List<Integer> getColor() {
	List<Integer> red = [0, 100, 0] // red
	List<Integer> blue = [60, 100, 0] // blue
	String forecast
	Integer cloudiness
	
	if (debugMode) {
		forecast = forecastDebug.toLowerCase()
		cloudiness = cloudinessDebug
	} else {
		if (weather.latestValue("weather")) {
			forecast = weather.latestValue("weather").toLowerCase()
		} else if (weather.latestValue("condition_text")) {
			forecast = weather.latestValue("condition_text").toLowerCase()
		} else {
			log.error("No forecast attribute found for this device")
		}
		
		if (weather.latestValue("cloudiness")) {
			cloudiness = weather.latestValue("cloudiness") as Integer
		} else if (weather.latestValue("cloud")) {
			cloudiness = weather.latestValue("cloud") as Integer
		} else {
			log.error("No cloudiness attribute found for this device")
		}
	}
	
	//log.debug("$cloudiness; $forecast")
	
	// Weather codes per openweathermap.org/weather-conditions
	switch (forecast) {
		case ~/.*snow.*/:
		case ~/.*sleet.*/:
			log.debug("Flashing red, snow instead")
			schedule('*/' + flash_interval + ' * * ? * *', 'flash')
			return red
			break
		case ~/.*rain.*/:
		case ~/.*drizzle.*/:
		case ~/.*thunderstorm.*/:
			log.debug("Steady red, rain ahead")
			unschedule('flash')
			light.on()
			return red
			break
		default:
			if (cloudiness > 15) {
				log.debug("Flashing blue, clouds due")
				schedule('*/' + flash_interval + ' * * ? * *', 'flash')
				return blue
			} else {
				log.debug("Steady blue, clear view")
				unschedule('flash')
				light.on()
				return blue
			}
	}
}

void flash() {
	if (light.latestValue("switch") == "on") {
		light.off()
	} else {
		light.on()
	}
}

2023-Feb-28: Updated message for weather device is not updating to more accurately reflect the issue

2 Likes

THANK YOU!!!

I will plug this into the testbed later this week when I get back home and advise

You guys are terrific...

Paul

1 Like

I used to live in Boston but now live in Florida. I have always wanted to do the same thing, except change the color of our terrace lights (Generic ZigBee RGBW Light) based on local weather forecasts. I would have to adjust flashing red, as we don’t get snow🙃.

Even though I have written a bit of Rule Machine code and currently change the light colors based on the time, I’m not sure what the baby steps are to integrate and adapt the brilliant code provided.

Can someone help me with those steps?

Much appreciated.

Don

Flashing red - storms ahead.

Hi Donald, this is the part of the code which is matching the weather conditions to determine the light state:

	case ~/.*snow.*/:
	case ~/.*sleet.*/:
		log.debug("Flashing red, snow instead")
		schedule('*/' + flash_interval + ' * * ? * *', 'flash')
		return red
		break
	case ~/.*rain.*/:
	case ~/.*drizzle.*/:
	case ~/.*thunderstorm.*/:
		log.debug("Steady red, rain ahead")
		unschedule('flash')
		light.on()
		return red
		break

Do you know what you want to use for flashing red instead of snow? If you want to do storms as aaiyar suggests then just move the "thunderstorm" line up with the snow and sleet lines. So it would be like this:

	case ~/.*thunderstorm.*/:
	case ~/.*snow.*/:
	case ~/.*sleet.*/:
		log.debug("Flashing red, snow instead")
		schedule('*/' + flash_interval + ' * * ? * *', 'flash')
		return red
		break
	case ~/.*rain.*/:
	case ~/.*drizzle.*/:
		log.debug("Steady red, rain ahead")
		unschedule('flash')
		light.on()
		return red
		break
1 Like

Thank you so much for offering your help! As a Rule Machine programmer, I am naive with regard to taking the baby steps to make this code work. I suppose I have to copy and paste it into ‘apps code’, but from there on out I am lost. Do I write some Rule Machine code to define when the code runs (I only want it to run from sunset to 11pm) and then somehow drive my 4 Sylvania LED floods that respond to the generic driver mentioned above?

I will certainly change the definition of flashing red to be a storm, The Sylvania’s don’t ‘flash’ well and I don’t think my family or the neighborhood will appreciate that as much as I appreciated seeing the Hancock Building flash, so I will likely do something like having 2 lights red and 2 blue to indicate bad weather is coming.

Hope you can get me over the hurdle in getting this code working…

Yes, just copy the code into the apps code, move the one line I suggested in my previous comment (optionally update the "Flashing red... " message too, if you want). Then save the code.

When you run the app there are 3 device settings you need to select, "weather" is your weather driver, either the built in "OpenWeatherMap" or the "OpenWeatherMap-Alerts Weather Driver" have been tested. Then there is the light or light group that you want to control, and "beaconSwitch" is a switch you use to turn the controlled lights on and off. If you want the light active during certain hours then create a virtual switch then use Rule Machine to turn that virtual switch on and off at the appropriate times.

Wow, what a neat project! Never saw this before, but I do something similar with my kitchen cabinet lights. Every night before bed they change color to indicate tomorrow's weather. Yellow=sun, blue=rain, purple=snow. I wrote the piston years ago for Smartthings and it made the move with us to Hubitat.

You can see our house from a main road. This makes me want to make something passersby can see...

Thank you for the easy to follow directions. Everything went well, except the result doesn’t work. My Sylvania RGB lights don’t turn on when I turn on the virtual switch specified in the setup of the app. Here are some screen shots if you can help me figure out what I have done wrong. So close!




Looks like the problem was that I hadn’t set up an account with OpenWeatherMap and received an API key for the built in weather app. I have now done that and it appears to be working! Make sense?

1 Like