Skip to content

Instantly share code, notes, and snippets.

@Qata
Created February 19, 2016 04:28
Show Gist options
  • Save Qata/edb968491fd61d000278 to your computer and use it in GitHub Desktop.
Save Qata/edb968491fd61d000278 to your computer and use it in GitHub Desktop.
import Html exposing (..)
import Html.Attributes as Attr exposing (..)
import Html.Events exposing (..)
import Http
import Json.Encode as Encode exposing (..)
import Json.Decode as Decode exposing ((:=))
import String
import Task exposing (..)
import Graphics.Element exposing (show)
type JSONResult
= Gateway String String (List String) (List Int)
| Device Int (List Int)
| UnaddressedState Int
| RPCError String
type alias AddressedDevice =
{ address : Int
, types : List Int
}
type alias Model =
{ addressedDevices : List AddressedDevice
, addressing : Bool
}
type Action = NoOp
| StartAddressing
| StopAddressing
| AddDevice AddressedDevice
| SetLines (List Int)
| SetLineNames (List String)
main =
Signal.map (view actions.address) model
update : Result String (Action) -> Model -> Model
update action model =
case action of
Ok a ->
case a of
NoOp ->
model
StartAddressing ->
{model | addressing = True}
StopAddressing ->
{model | addressing = False}
AddDevice device ->
{model | addressedDevices = model.addressedDevices ++ [device]}
SetLines gatewayLines ->
{model | lines = gatewayLines}
Err s -> {model | addressing = False}
model : Signal Model
model =
Signal.foldp update {addressedDevices = [], addressing = False} actions.signal
view : Signal.Address (Result String (Action)) -> Model -> Html
view address model =
let deviceImages = List.map (\deviceType -> case deviceType of
1 -> "emergency"
2 -> "hid"
3 -> "downlight"
4 -> "incandescent"
5 -> "converter"
6 -> "led"
7 -> "relay"
8 -> "colour_control"
254 -> "msensor"
_ -> "fluoro")
devicesDiv =
List.map (\device -> div [] <| (List.map (\imgName -> img [src <| "/img/type_" ++ imgName ++ ".png"] []) <| deviceImages device.types) ++
[ text <| "Assigned address " ++ toString device.address ++ " to device"
]) model.addressedDevices
in
div [] <|
[ button [ onClick address <| Ok StopAddressing ] [ text "-" ]
, button [ onClick address <| Ok (AddDevice {address = 20, types = [1, 8, 254, 3, 4]}) ] [ text "+" ]
]
++ devicesDiv
echoJson : Encode.Value -> Encode.Value
echoJson value =
Encode.object [ ("method", Encode.string "echo"), ("params", Encode.list [ value ]) ]
query : Signal.Mailbox Encode.Value
query =
Signal.mailbox <| Encode.object [ ("method", Encode.string "readgateway"), ("params", Encode.list []) ]
results : Signal.Mailbox (Result String (JSONResult))
results =
Signal.mailbox <| Err ""
actions : Signal.Mailbox (Result String (Action))
actions =
Signal.mailbox <| Ok NoOp
convertJsonToOp : JSONResult -> Action
convertJsonToOp a = case a of
RPCError e -> NoOp
Gateway mac name ->
port requests : Signal (Task x ())
port requests =
Signal.map lookupGatewayMethod query.signal
|> Signal.map (\task -> Task.toResult task `andThen` (\result -> Signal.send actions.address <| Result.map (\a -> NoOp) result))
lookupGatewayMethod : Encode.Value -> Task String (JSONResult)
lookupGatewayMethod json =
let encoded_json = Encode.encode 0 json
toUrl =
if encoded_json == "null"
then fail "Click the button, m'lady"
else succeed <| "/cgi-bin/json.cgi?json=" ++ encoded_json
in
toUrl `andThen` (Http.get gatewayResolve >> mapError (\x -> toString x))
gatewayResolve : Decode.Decoder (JSONResult)
gatewayResolve =
Decode.oneOf
[ Decode.object1 RPCError (Decode.at ["error", "message"] Decode.string)
, Decode.object4 Gateway (Decode.at ["result", "mac"] Decode.string) (Decode.at ["result", "hostname"] Decode.string) (Decode.at ["result", "linenames"] <| Decode.list Decode.string) (Decode.at ["result", "activelines"] <| Decode.list Decode.int)
, Decode.object2 Device (Decode.at ["result", "address"] Decode.int) (Decode.at ["result", "type"] <| Decode.list Decode.int)
, Decode.object1 UnaddressedState (Decode.at ["result", "unaddressed"] Decode.int)
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment