defmodule Morse do @moduledoc """ Transmit a morse message by blinking a Hue light """ @signs %{ " " => " ", "A" => ".-", "B" => "-...", "C" => "-.-.", "D" => "-..", "E" => ".", "F" => "..-.", "G" => "--.", "H" => "....", "I" => "..", "J" => ".---", "K" => "-.-.", "L" => ".-..", "M" => "--", "N" => "-.", "O" => "---", "P" => ".--.", "Q" => "--.-", "R" => ".-.", "S" => "...", "T" => "-", "U" => "..-", "V" => "...-", "W" => ".--", "X" => "-..-", "Y" => "-.--", "Z" => "--..", "1" => ".----", "2" => "..---", "3" => "...--", "4" => "....-", "5" => ".....", "6" => "-....", "7" => "--...", "8" => "---..", "9" => "----.", } @default_unit_duration 750 @between_letters "/" def transmit(message, {_bridge, _light} = blinker, unit_duration \\ @default_unit_duration) do message |> sanitize |> translate |> blinks(blinker, unit_duration) end defp sanitize(message), do: message |> String.upcase |> String.strip defp translate(sanitized_message) do sanitized_message |> String.codepoints |> Enum.map(fn (letter) -> @signs[letter] end) end defp blinks(signs, blinker, unit_duration) do Enum.each(signs, fn (sign) -> blink_letter(sign, blinker, unit_duration) end) end # Blinks a whole letter defp blink_letter("", _blinker, unit_duration), do: wait(@between_letters, unit_duration) defp blink_letter(<< part :: binary-size(1), parts :: binary >>, blinker, unit_duration) do blink_part(part, blinker, unit_duration) blink_letter(parts, blinker, unit_duration) end # Blinks a single dot, dash or space defp blink_part(part, blinker, unit_duration) do blinker |> on wait(part, unit_duration) blinker |> off wait(unit_duration) end @transition_time 0 defp on({bridge, light}), do: bridge |> Huex.turn_on(light, @transition_time) defp off({bridge, light}), do: bridge |> Huex.turn_off(light, @transition_time) defp wait(unit_duration), do: :timer.sleep(unit_duration) defp wait(".", unit_duration), do: wait(unit_duration) defp wait("-", unit_duration), do: wait(unit_duration * 3) defp wait("/", unit_duration), do: wait(unit_duration * 3) defp wait(" ", unit_duration), do: wait(unit_duration * 7) end # # Demo # bridge_host = System.get_env("HUEX_HOST") || "192.168.1.100" bridge_user = System.get_env("HUEX_USER") || "huexexamples" light = 1 bridge = Huex.connect(bridge_host, bridge_user) blinker = {bridge, light} Morse.transmit("SOS", blinker)