Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions config.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#loc_city = "No longer supported" # Enter your city name (this is for the weather)
#loc_region = "No longer supported" # Enter either your state or country
weather_location = "" # Seems pretty flexible: city, state; major city name; zip code; city, country
#loc_city = "" # Enter your city name (this is for the weather)
#loc_region = "" # Enter either your state or country
weather_location = ""
news_count = 2 # How many news stories Vector should read (max is 7 to 9)
vector_mood = "normal" # Normal is the only mood at the moment
temperature = "farenheit" # Enter "farenheit" or "celsius"
temperature = "imperial" # Enter "imperial" or "metric"
chattiness = 6 # Enter a number between "1" and "10". The number "5" is average. ("10" is VERY chatty.) This feature still needs work.
sound_volume = 1 # Vector's sound effects between "1" and "5". (5 is very loud)
voice_volume = 2 # Vector's voice volume between "1" and "5". (5 is very loud)
voice_volume = 3 # Vector's voice volume between "1" and "5". (5 is very loud)
news_feed = "https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml" #I think you can use any rss feed for this
140 changes: 89 additions & 51 deletions vectorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from anki_vector.user_intent import UserIntent, UserIntentEvent
import apis
import config
import sys, traceback

# (I think these are called enums in Python... They relate to my dialogue.csv file)
NAME = 0
Expand Down Expand Up @@ -204,17 +205,23 @@ def vector_react(arg):

# This makes Vector talk by looking up dialogue in the dlg file
def say(arg_name):
row_start = dic[arg_name]
row_end = row_start + int(dlg[row_start][LINES]) # Use row_start and LINES (from dialogue file) to figure out where the dialogue starts/stops
num_row = get_low(row_start,row_end-1)
to_say = dlg[num_row][MOOD] # Vector's default mood is "normal", eventually he will say different dialogue based on his mood
if arg_name in dic:
row_start = dic[arg_name]
print(row_start)
row_end = row_start + int(dlg[row_start][LINES]) # Use row_start and LINES (from dialogue file) to figure out where the dialogue starts/stops
num_row = get_low(row_start,row_end-1)
to_say = dlg[num_row][MOOD] # Vector's default mood is "normal", eventually he will say different dialogue based on his mood
else:
to_say = ""

if arg_name == "wake_word" : return # If wake_word then skip talking for a bit
if arg_name == "news_intro": to_say = to_say + get_news() + get_weather("forecast") # if news then add to end of intro
if arg_name == "joke_intro": to_say = to_say + get_joke() # if joke then add to end of intro
if arg_name == "fact_intro": to_say = to_say + get_fact() # if fact then add to end of intro
if arg_name == "time_intro": to_say = to_say + get_time() # Randomly announce the time
if arg_name == "random_weather": to_say = get_weather("random_weather") # Randomly announce a weather fact
if arg_name == "stranger": to_say = to_say + get_pickupline()
if arg_name == "weather_forecast": to_say = get_weather("forecast")

to_say = randomizer(to_say) # This replaces certain words with synonyms
max_attempts = 15 # Had to add this after the last update. I'm having trouble getting control of Vector to speak
Expand All @@ -227,7 +234,10 @@ def say(arg_name):
robot.audio.set_master_volume(VOL[config.voice_volume]) # Change voice volume to config setting
robot.behavior.say_text(to_say, duration_scalar=1.15) # I slow voice down slightly to make him easier to understand
if arg_name == "joke_intro":
robot.anim.play_animation_trigger(random.choice(JOKE_ANIM)) # If a joke, play a random animation trigger
anim_trigger_names = robot.anim.anim_trigger_list
#robot.anim.play_animation_trigger(random.choice(JOKE_ANIM)) # If a joke, play a random animation trigger
robot.anim.play_animation_trigger(
random.choice(anim_trigger_names)) # If a joke, play a random animation trigger
robot.conn.release_control()
robot.audio.set_master_volume(VOL[config.sound_volume]) # Change sound effects volume back to config setting
return
Expand Down Expand Up @@ -272,12 +282,20 @@ def say_sleep(arg_name):
robot.audio.set_master_volume(VOL[config.sound_volume])
robot.conn.release_control()


def average(number1, number2):
return (number1 + number2) / 2

# An API call that allows Vector to deliver a weather forecast (it's not always accurate, in my experience)
def get_weather(var):
#10/23/2019 JDR new API endpoint (and terms)
try:
#location can be city, state; city, country; zip code.
url = f"http://api.weatherstack.com/current?access_key={apis.api_weather}&query={config.weather_location}&units={config.temperature[0]}"

if var == "forecast":
url = f"http://api.openweathermap.org/data/2.5/forecast?APPID={apis.api_weather}&q={config.weather_location}&units={config.temperature}"
else:
url = f"http://api.openweathermap.org/data/2.5/weather?APPID={apis.api_weather}&q={config.weather_location}&units={config.temperature}"
print(url)
req = urllib.request.Request(
url,
Expand All @@ -286,25 +304,36 @@ def get_weather(var):
)
data = urllib.request.urlopen(req).read()
output = json.loads(data)
#10/23/2019 JDR free api, no forecast (weather.gov for US?)
#forecast_condition = output["forecast"]["forecastday"][0]["day"]["condition"]["text"]
#10/23/2019 JDR new API object
current_condition = output["current"]["weather_descriptions"]
#forecast_avghumidity = output["forecast"]["forecastday"][0]["day"]["avghumidity"]
current_humidity = output["current"]["humidity"]

weather_name = output["location"]["name"]
weather_region = output["location"]["region"]

#New API, specify the units in the request
current_temp_feelslike = output["current"]["feelslike"]
current_temp = output["current"]["temperature"]
current_wind = output["current"]["wind_speed"]

if config.temperature == "farenheit":

print(data)

if var == "forecast":
section =output["list"][0]
forecast_condition = section["weather"][0]["description"]
forecast_humidity = section["main"]["humidity"]
forecast_temp = output["list"][0]["main"]["temp"]
forecast_temp_high = int(round(section["main"]["temp_min"]))
forecast_temp_low = int(round(section["main"]["temp_max"]))
forecast_temp_avg = int(round(average(forecast_temp_high, forecast_temp_low)))
forecast_wind = int(round(section["wind"]["speed"]))
else:
#10/23/2019 JDR free api, no forecast (weather.gov for US?)
#forecast_condition = output["forecast"]["forecastday"][0]["day"]["condition"]["text"]
#10/23/2019 JDR new API object
current_condition = output["weather"][0]["description"]
#forecast_avghumidity = output["forecast"]["forecastday"][0]["day"]["avghumidity"]
current_humidity = output["main"]["humidity"]

#weather_name = output["location"]["name"]
#weather_region = output["location"]["region"]

#New API, specify the units in the request
#current_temp_feelslike = output["current"]["feelslike"]
current_temp = int(round(average(output["main"]["temp_min"], output["main"]["temp_max"])))
current_wind = output["wind"]["speed"]

if config.temperature == "imperial":
#forecast_temp_avg = output["forecast"]["forecastday"][0]["day"]["avgtemp_f"]
#forecast_temp_high = output["forecast"]["forecastday"][0]["day"]["maxtemp_f"]
#forecast_temp_low = output["forecast"]["forecastday"][0]["day"]["mintemp_f"]
#forecast_wind = output["forecast"]["forecastday"][0]["day"]["maxwind_mph"]
wind_speed = " miles per hour"
else:
Expand All @@ -315,29 +344,31 @@ def get_weather(var):
wind_speed = " kilometers per hour"

# In the morning, Vector tells the news and weather when he sees a face
# if var == "forecast":
# weather = []
# weather.append(f". And now for some weather. Today in {config.loc_city} {config.loc_region}, it will be {forecast_condition}, with a temperature of {forecast_temp_high} degrees, and wind speeds around {forecast_wind}{wind_speed}. Right now, it is {current_temp} degrees.")
# weather.append(f". Right now in {config.loc_city} {config.loc_region}, it is {current_temp} degrees and {current_condition}. Later today, it will be {forecast_condition}, with a high of {forecast_temp_high} degrees and a low of {forecast_temp_low} degrees.")
# weather.append(f". Here's your local weather. The temperature in {config.loc_city} {config.loc_region} right now, is {current_temp} degrees. The high today will be {forecast_temp_high} degrees, and look for a low of around {forecast_temp_low}. Winds will be {forecast_wind}{wind_speed}.")
# weather.append(f". Moving to the weather. It is currently {current_condition} in {config.loc_city} {config.loc_region}. Later today it will be {forecast_condition}, with an average temperature of {forecast_temp_avg} degrees, and wind speeds around {forecast_wind}{wind_speed}.")
# return(random.choice(weather))
if var == "forecast":
weather = []
weather.append(f". And now for some weather. Today, it will be {forecast_condition}, with a temperature of {forecast_temp_high} degrees, and wind speeds around {forecast_wind}{wind_speed}.")
weather.append(f". Later today, it will be {forecast_condition}, with a high of {forecast_temp_high} degrees and a low of {forecast_temp_low} degrees.")
weather.append(f". Here's your local weather. The high today will be {forecast_temp_high} degrees, and look for a low of around {forecast_temp_low}. Winds will be {forecast_wind}{wind_speed}.")
weather.append(f". Later today it will be {forecast_condition}, with an average temperature of {forecast_temp_avg} degrees, and wind speeds around {forecast_wind}{wind_speed}.")
return(random.choice(weather))

# At random times, Vector will see a face and announce something about the weather
# if var == "random_weather":
rnd_weather = []
if {current_temp} != {current_temp_feelslike}:
rnd_weather.append(f"The current temperature is {current_temp} degrees, but it feels like {current_temp_feelslike} degrees.")
rnd_weather.append(f"Right now, the temperature is {current_temp} degrees.")
if current_wind < 15:
rnd_weather.append(f"Right now, it is a relatively calm {current_temp} degrees, with winds at {current_wind}{wind_speed}.")
else:
rnd_weather.append(f"Right now, it is a blustery {current_temp} degrees, with winds at {current_wind}{wind_speed}.")
rnd_weather.append(f"At this moment, the weather is {current_condition}.")
rnd_weather.append(f"Hello. It is currently {current_temp} degrees. The humidity is {current_humidity} percent.")
if var == "random_weather":
rnd_weather = []
#if {current_temp} != {current_temp_feelslike}:
# rnd_weather.append(f"The current temperature is {current_temp} degrees, but it feels like {current_temp_feelslike} degrees.")
rnd_weather.append(f"Right now, the temperature is {current_temp} degrees.")

if current_wind < 15:
rnd_weather.append(f"Right now, it is a relatively calm {current_temp} degrees, with winds at {current_wind}{wind_speed}.")
else:
rnd_weather.append(f"Right now, it is a blustery {current_temp} degrees, with winds at {current_wind}{wind_speed}.")
rnd_weather.append(f"At this moment, the weather is {current_condition}.")
rnd_weather.append(f"Hello. It is currently {current_temp} degrees. The humidity is {current_humidity} percent.")

except Exception as inst:
print(traceback.format_exc())

except:
print("Unexpected weather error:", sys.exc_info()[0])
rnd_weather.append("I'm more of an indoor robot.")
rnd_weather.append("I have no idea what it is like out there.")
rnd_weather.append("I'm a robot, not a weather forecaster.")
Expand All @@ -352,7 +383,7 @@ def get_news():
bridge = [". And in other news. ", ". In OTHER news... ", ". Taking a look at other news. ", ". Here is another news item. ", ". Here is an interesting story. "]
news = ""
news_count = config.news_count
feed = feedparser.parse("https://www.cbsnews.com/latest/rss/world")
feed = feedparser.parse(config.news_feed)
for post in feed.entries:
news = news + post.description
say_count += 1
Expand Down Expand Up @@ -410,13 +441,19 @@ def on_wake_word(robot, event_type, event):
"imperative_come", "imperative_lookatme",
"weather_response"]
if j['type'] == "weather_response":
#allow vector to do his built in weather
time.sleep(10)
say("random_weather")
if j["isForecast"] == "true":
print("weather_forecast")
say("weather_forecast")
else:
# allow vector to do his built in weather
time.sleep(10)
say("random_weather")
else:
if j['type'] in valid_response:
print("valid response")
reaction78u = random.choices(["joke_intro", "fact_intro", "time_intro", "random_weather", "last_saw_name"])
#took out the time, you can already ask for that.
#taking out last_saw_name until I check to see if he has seen a face he knows.
reaction = random.choices(["joke_intro", "fact_intro", "random_weather"])
print(reaction)
say(reaction[0])

Expand Down Expand Up @@ -524,9 +561,10 @@ def on_cube_detected(robot, event_type, event):

if not robot.status.is_on_charger:
battery_state = robot.get_battery_state()
if battery_state.battery_volts < 3.6:
if battery_state.battery_volts <= 3.63: # <3.61 was too low
print(battery_state.battery_volts)
robot.behavior.say_text("I need to find my charger soon.")
time.sleep(30)
time.sleep(90)

#if battery_state.battery_level < 2:
#robot.behavior.say_text("My battery level is low.")
Expand Down